--- parser3/src/include/pa_hash.h 2005/08/05 13:02:59 1.62.12.1 +++ parser3/src/include/pa_hash.h 2005/07/28 10:02:26 1.64.2.4 @@ -1,7 +1,7 @@ /** @file Parser: hash class decl. - Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ @@ -17,7 +17,7 @@ #ifndef PA_HASH_H #define PA_HASH_H -static const char * const IDENT_HASH_H="$Date: 2005/08/05 13:02:59 $"; +static const char * const IDENT_HASH_H="$Date: 2005/07/28 10:02:26 $"; #include "pa_memory.h" #include "pa_types.h" @@ -103,6 +103,115 @@ public: return false; } + /// put a [value] under the [key] @returns existed or not + template R replace_maybe_append(K key, V value, F prevent, I info) { + if(!value) { + // they can come here from somewhere (true with maybe_replace_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_replace_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; + } + + /// put a [value] under the [key] @returns existed or not + template + R maybe_replace_never_append(K key, V value, F1 prevent_replace, I info) + { + if(!value) { + // they can come here from somewhere (true with maybe_replace_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 + + // prevent-function intercepted put? + if(R result=prevent_replace(pair->value, info)) + return result; + + pair->value=value; + return reinterpret_cast(1); + } + + return 0; + } + /// remove the [key] @returns existed or not bool remove(K key) { uint code=hash_code(key); @@ -130,9 +239,9 @@ public: return V(0); } - + /// put a [value] under the [key] if that [key] existed @returns existed or not - bool put_replace(K key, V value) { + bool put_replaced(K key, V value) { if(!value) { remove(key); return false; @@ -150,6 +259,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) {