--- parser3/src/include/pa_hash.h 2003/02/03 13:01:06 1.58.2.11 +++ parser3/src/include/pa_hash.h 2003/03/24 15:26:02 1.58.2.18.2.6 @@ -17,9 +17,9 @@ #ifndef PA_HASH_H #define PA_HASH_H -static const char* IDENT_HASH_H="$Date: 2003/02/03 13:01:06 $"; +static const char* IDENT_HASH_H="$Date: 2003/03/24 15:26:02 $"; -#include "pa_pool.h" +#include "pa_memory.h" #include "pa_types.h" /** @@ -40,7 +40,7 @@ public: allocated=allocates[allocates_index=0]; threshold=allocated*THRESHOLD_PERCENT/100; fpairs_count=fused_refs=0; - refs=static_cast(pa_calloc(sizeof(Pair *)*allocated)); + refs=new(0) Pair*[allocated]; } Hash(const Hash& source) { @@ -49,16 +49,27 @@ public: threshold=source.threshold; fused_refs=source.fused_refs; fpairs_count=source.fpairs_count; - refs=new Pair*[allocated]; - memcpy(refs, source.refs, sizeof(Pair *)*allocated); - } - ~Hash() { - destroy_pairs(); - delete refs; + refs=new(0) Pair*[allocated]; + + // clone & rehash + Pair **old_ref=source.refs; + for(int index=0; indexlink; + + Pair **new_ref=&refs[index]; + *new_ref=new Pair(pair->code, pair->key, pair->value, *new_ref); + + pair=next; + } } /// put a [value] under the [key] @returns existed or not bool put(K key, V value) { + if(!value) { + remove(key); + return false; + } if(is_full()) expand(); @@ -105,11 +116,15 @@ public: if(pair->code==code && pair->key==key) return pair->value; - return 0; + return V(0); } /// put a [value] under the [key] if that [key] existed @returns existed or not bool put_replace(K key, V value) { + if(!value) { + remove(key); + return false; + } uint code=hash_code(key); uint index=code%allocated; for(Pair *pair=refs[index]; pair; pair=pair->link) @@ -125,6 +140,10 @@ public: /// 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) { + remove(key); + return false; + } if(is_full()) expand(); @@ -145,12 +164,13 @@ public: return false; } - /// put all 'src' values if NO with same key existed + /** put all 'src' values if NO with same key existed + @todo optimize this.allocated==src.allocated case + */ void merge_dont_replace(const Hash& src) { for(int i=0; ilink) put_dont_replace(pair->key, pair->value); - // MAY:optimize this.allocated==src.allocated case } /// number of elements in hash @@ -170,14 +190,14 @@ public: for(int index=0; indexlink) if(callback(pair->key, pair->value, info)) - return &pair->value; + return pair->value; - return 0;//V(0) + return V(0); } /// remove all elements void clear() { - destroy_pairs(); memset(refs, 0, sizeof(*refs)*allocated); + memset(refs, 0, sizeof(*refs)*allocated); fpairs_count=fused_refs=0; } @@ -231,11 +251,11 @@ private: int old_allocated=allocated; Pair **old_refs=refs; - // allocated bigger refs array allocates_index=allocates_index+1(pa_calloc(sizeof(Pair *)*allocated)); + refs=new(UseGC) Pair*[allocated]; // rehash Pair **old_ref=old_refs; @@ -251,19 +271,7 @@ private: pair=next; } - delete old_refs; - } - - void destroy_pairs() { - Pair **ref=refs; - for(int index=0; indexlink; - delete pair; - pair=next; - } - } + delete[] old_refs; } private: //disabled @@ -283,17 +291,40 @@ template int Hash::allocates_count=sizeof(allocates)/sizeof(uint); /// useful generic hash function -inline uint generic_hash_code(uint aresult, const char* start, uint allocated) { - uint result=aresult, g; - const char* end=start+allocated; - - while (start>24); + result=result^g; + } +} +/// useful generic hash function +inline void generic_hash_code(uint& result, const char* s) { + while(char c=*s++) { + result=(result<<4)+c; + if(uint g=(result&0xF0000000)) { + result=result^(g>>24); + result=result^g; + } + } +} + +/// useful generic hash function +inline void generic_hash_code(uint& result, const char* buf, size_t size) { + const char* end=buf+size; + while(buf>24); result=result^g; } } +} + +/// simple hash code of int. used by EXIF mapping +inline uint hash_code(int self) { + uint result=0; + generic_hash_code(result, (const char*)&self, sizeof(self)); return result; }