--- parser3/src/main/Attic/pa_hash.C 2001/03/18 13:22:06 1.23 +++ parser3/src/main/Attic/pa_hash.C 2001/11/01 10:59:26 1.44 @@ -1,9 +1,10 @@ -/* - Parser +/** @file + Parser: hash class. + Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) - $Id: pa_hash.C,v 1.23 2001/03/18 13:22:06 paf Exp $ + $Id: pa_hash.C,v 1.44 2001/11/01 10:59:26 paf Exp $ */ /* @@ -14,13 +15,10 @@ For more information about Zend please visit http://www.zend.com/ */ -#include - #include "pa_hash.h" -#include "pa_threads.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 */ @@ -33,15 +31,23 @@ int Hash::allocates_count= sizeof(allocates)/sizeof(uint); -void Hash::construct(Pool& apool, bool athread_safe) { - thread_safe=athread_safe; - +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; @@ -49,6 +55,7 @@ void Hash::expand() { // allocated bigger refs array allocates_index=allocates_index+1(calloc(sizeof(Pair *)*allocated)); // rehash @@ -80,7 +87,7 @@ uint Hash::generic_code(uint aresult, co return result; } -bool Hash::put(const Key& key, Value *value) { SYNCHRONIZED(thread_safe); +bool Hash::put(const Key& key, Val *value) { if(full()) expand(); @@ -98,10 +105,23 @@ bool Hash::put(const Key& key, Value *va 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; } -Hash::Value *Hash::get(const Key& key) const { SYNCHRONIZED(thread_safe); +void 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; + } +} + +Hash::Val *Hash::get(const Key& key) const { uint code=key.hash_code(); uint index=code%allocated; for(Pair *pair=refs[index]; pair; pair=pair->link) @@ -111,7 +131,7 @@ Hash::Value *Hash::get(const Key& key) c return 0; } -bool Hash::put_replace(const Key& key, Value *value) { SYNCHRONIZED(thread_safe); +bool Hash::put_replace(const Key& key, Val *value) { uint code=key.hash_code(); uint index=code%allocated; for(Pair *pair=refs[index]; pair; pair=pair->link) @@ -125,7 +145,7 @@ bool Hash::put_replace(const Key& key, V return false; } -bool Hash::put_dont_replace(const Key& key, Value *value) { SYNCHRONIZED(thread_safe); +bool Hash::put_dont_replace(const Key& key, Val *value) { if(full()) expand(); @@ -139,27 +159,44 @@ 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; } -void Hash::merge_dont_replace(const Hash& src) { SYNCHRONIZED(thread_safe); +void Hash::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 } -void Hash::foreach(Foreach_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) (*func)(pair->key, pair->value, info); } -void Hash::clear() { SYNCHRONIZED(thread_safe); +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; }