--- parser3/src/include/pa_hash.h 2005/07/26 12:43:05 1.63 +++ parser3/src/include/pa_hash.h 2005/07/27 14:04:15 1.64.2.3 @@ -17,7 +17,7 @@ #ifndef PA_HASH_H #define PA_HASH_H -static const char * const IDENT_HASH_H="$Date: 2005/07/26 12:43:05 $"; +static const char * const IDENT_HASH_H="$Date: 2005/07/27 14:04:15 $"; #include "pa_memory.h" #include "pa_types.h" @@ -106,9 +106,12 @@ public: /// put a [value] under the [key] @returns existed or not template R maybe_put(K key, V value, F prevent) { if(!value) { + // they can come here from somewhere (true with maybe_maybe_append, keeping parallel) remove(key); - return 0; + // this has nothing to do with properties, doing no special property handling here + return 0; } + if(is_full()) expand(); @@ -135,6 +138,83 @@ public: return 0; } + /// put a [value] under the [key] @returns existed or not + template R maybe_append(K key, V value, F prevent, I info) { + if(!value) { + // they can come here from somewhere (true with maybe_maybe_append, keeping parallel) + remove(key); + // this has nothing to do with properties, doing no special property handling here + return 0; + } + + if(is_full()) + expand(); + + uint code=hash_code(key); + uint index=code%allocated; + Pair **ref=&refs[index]; + for(Pair *pair=*ref; pair; pair=pair->link) + if(pair->code==code && pair->key==key) { + // found a pair with the same key + pair->value=value; + return reinterpret_cast(1); + } + + // proper pair not found + // prevent-function intercepted put? + if(R result=prevent(value, info)) + return result; + + //create&link_in new pair + if(!*ref) // root cell were fused_refs? + fused_refs++; // not, we'll use it and record the fact + *ref=new Pair(code, key, value, *ref); + fpairs_count++; + return 0; + } + + /// put a [value] under the [key] @returns existed or not + template + R maybe_maybe_append(K key, V value, F1 prevent_replace, F2 prevent_append, I info) + { + if(!value) { + // they can come here from Temp_value_element::dctor to restore some empty value + remove(key); + // this has nothing to do with properties, doing no special property handling here + return 0; + } + + if(is_full()) + expand(); + + uint code=hash_code(key); + uint index=code%allocated; + Pair **ref=&refs[index]; + for(Pair *pair=*ref; pair; pair=pair->link) + if(pair->code==code && pair->key==key) { + // found a pair with the same key + + // prevent-function intercepted put? + if(R result=prevent_replace(pair->value, info)) + return result; + + pair->value=value; + return reinterpret_cast(1); + } + + // proper pair not found + // prevent-function intercepted put? + if(R result=prevent_append(value, info)) + return result; + + //create&link_in new pair + if(!*ref) // root cell were fused_refs? + fused_refs++; // not, we'll use it and record the fact + *ref=new Pair(code, key, value, *ref); + fpairs_count++; + return 0; + } + /// remove the [key] @returns existed or not bool remove(K key) { uint code=hash_code(key); @@ -162,7 +242,7 @@ public: return V(0); } - + /// put a [value] under the [key] if that [key] existed @returns existed or not bool put_replaced(K key, V value) { if(!value) { @@ -182,6 +262,32 @@ public: return false; } + /// put a [value] under the [key] if that [key] existed @returns existed or not + template R maybe_put_replaced(K key, V value, F prevent) { + if(!value) { + // they can come here from Temp_value_element::dctor to restore some empty value + remove(key); + // this has nothing to do with properties, doing no special property handling here + return 0; + } + + uint code=hash_code(key); + uint index=code%allocated; + for(Pair *pair=refs[index]; pair; pair=pair->link) + if(pair->code==code && pair->key==key) { + // found a pair with the same key, replacing + // prevent-function intercepted put? + if(R result=prevent(pair->value)) + return result; + + pair->value=value; + return reinterpret_cast(1); + } + + // proper pair not found + return 0; + } + /// put a [value] under the [key] if that [key] NOT existed @returns existed or not bool put_dont_replace(K key, V value) { if(!value) {