--- parser3/src/main/Attic/pa_hash.C 2001/04/05 16:30:42 1.31 +++ parser3/src/main/Attic/pa_hash.C 2002/02/08 08:30:16 1.50 @@ -1,11 +1,10 @@ /** @file Parser: hash class. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) + Author: Alexandr Petrosian (http://paf.design.ru) - Author: Alexander Petrosyan (http://design.ru/paf) - - $Id: pa_hash.C,v 1.31 2001/04/05 16:30:42 paf Exp $ + $Id: pa_hash.C,v 1.50 2002/02/08 08:30:16 paf Exp $ */ /* @@ -16,12 +15,10 @@ For more information about Zend please visit http://www.zend.com/ */ -#include "pa_config_includes.h" - #include "pa_hash.h" void *Hash::Pair::operator new(size_t size, Pool& apool) { - return apool.malloc(size); + return apool.malloc(size, 6); } /* Zend comment: Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster */ @@ -34,13 +31,23 @@ int Hash::allocates_count= sizeof(allocates)/sizeof(uint); -void Hash::construct(Pool& apool) { +void Hash::construct_new() { allocated=allocates[allocates_index=0]; threshold=allocated*THRESHOLD_PERCENT/100; - used=0; + count=used=0; refs=static_cast(calloc(sizeof(Pair *)*allocated)); } +void Hash::construct_copy(const Hash& source) { + allocates_index=source.allocates_index; + allocated=source.allocated; + threshold=source.threshold; + used=source.used; + count=source.count; + size_t size=sizeof(Pair *)*allocated; + refs=static_cast(malloc(size, 7)); memcpy(refs, source.refs, size); +} + void Hash::expand() { int old_size=allocated; Pair **old_refs=refs; @@ -48,6 +55,7 @@ void Hash::expand() { // allocated bigger refs array allocates_index=allocates_index+1(calloc(sizeof(Pair *)*allocated)); // rehash @@ -80,6 +88,9 @@ uint Hash::generic_code(uint aresult, co } bool Hash::put(const Key& key, Val *value) { + if(!value) + return remove(key); + if(full()) expand(); @@ -97,6 +108,21 @@ bool Hash::put(const Key& key, Val *valu if(!*ref) // root cell were used? used++; // not, we'll use it and record the fact *ref=NEW Pair(code, key, value, *ref); + count++; + return false; +} + +bool Hash::remove(const Key& key) { + uint code=key.hash_code(); + uint index=code%allocated; + for(Pair **ref=&refs[index]; *ref; ref=&(*ref)->link) + if((*ref)->code==code && (*ref)->key==key) { + // found a pair with the same key + *ref=(*ref)->link; + --count; + return true; + } + return false; } @@ -125,6 +151,9 @@ bool Hash::put_replace(const Key& key, V } bool Hash::put_dont_replace(const Key& key, Val *value) { + if(!value) + return remove(key); + if(full()) expand(); @@ -138,9 +167,10 @@ bool Hash::put_dont_replace(const Key& k } // proper pair not found -- create&link_in new pair - *ref=NEW Pair(code, key, value, *ref); if(!*ref) // root cell were used? used++; // not, we'll use it and record the fact + *ref=NEW Pair(code, key, value, *ref); + count++; return false; } @@ -151,15 +181,30 @@ void Hash::merge_dont_replace(const Hash // MAY:optimize this.allocated==src.allocated case } -void Hash::for_each(For_each_func func, void *info) { +void Hash::for_each(For_each_func func, void *info) const { + Pair **ref=refs; + for(int index=0; indexlink) + (*func)(pair->key, pair->value, info); +} + +void Hash::for_each(For_each_func_refed func, void *info) const { Pair **ref=refs; for(int index=0; indexlink) - if(pair->value) - (*func)(pair->key, pair->value, info); + (*func)(pair->key, pair->value, info); +} + +void* Hash::first_that(First_that_func func, void *info) const { + Pair **ref=refs; + for(int index=0; indexlink) + if(void *result=(*func)(pair->key, pair->value, info)) + return result; + return 0; } void Hash::clear() { memset(refs, 0, sizeof(*refs)*allocated); - used=0; + count=used=0; }