Diff for /parser3/src/main/Attic/pa_hash.C between versions 1.8 and 1.43

version 1.8, 2001/01/29 20:10:32 version 1.43, 2001/10/29 13:04:46
Line 1 Line 1
 /*  /** @file
   $Id$          Parser: hash class.
   
           Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
           Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
   
           $Id$
 */  */
   
 /*  /*
Line 10 Line 15
         For more information about Zend please visit http://www.zend.com/          For more information about Zend please visit http://www.zend.com/
 */  */
   
 #include "pa_pool.h"  #include "pa_hash.h"
 #include "pa_threads.h"  
   
 void *Hash::Pair::operator new(size_t size, Pool& apool) {  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 */  /* Zend comment: Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster */
 uint Hash::sizes[]={  uint Hash::allocates[]={
         5, 11, 19, 53, 107, 223, 463, 983, 1979, 3907, 7963,           5, 11, 19, 53, 107, 223, 463, 983, 1979, 3907, 7963, 
         16229, 32531, 65407, 130987, 262237, 524521, 1048793,           16229, 32531, 65407, 130987, 262237, 524521, 1048793, 
         2097397, 4194103, 8388857, 16777447, 33554201, 67108961,           2097397, 4194103, 8388857, 16777447, 33554201, 67108961, 
         134217487, 268435697, 536870683, 1073741621, 2147483399};          134217487, 268435697, 536870683, 1073741621, 2147483399};
 int Hash::sizes_count=  int Hash::allocates_count=
         sizeof(sizes)/sizeof(uint);          sizeof(allocates)/sizeof(uint);
   
 void *Hash::operator new(size_t size, Pool& apool) {  
         return apool.malloc(size);  
 }  
   
 Hash::Hash(Pool& apool, bool athread_safe) :  void Hash::construct_new() {
         pool(apool),          allocated=allocates[allocates_index=0];
         thread_safe(athread_safe) {          threshold=allocated*THRESHOLD_PERCENT/100;
                   count=used=0;
         size=sizes[size_index=0];          refs=static_cast<Pair **>(calloc(sizeof(Pair *)*allocated));
         threshold=size*THRESHOLD_PERCENT/100;  }
         used=0;  
         refs=static_cast<Pair **>(pool.calloc(sizeof(Pair *)*size));  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<Pair **>(malloc(size, 7));  memcpy(refs, source.refs, size);
 }  }
   
 void Hash::expand() {  void Hash::expand() {
         int old_size=size;          int old_size=allocated;
         Pair **old_refs=refs;          Pair **old_refs=refs;
   
         // allocated bigger refs array          // allocated bigger refs array
         size_index=size_index+1<sizes_count?size_index+1:sizes_count-1;          allocates_index=allocates_index+1<allocates_count?allocates_index+1:allocates_count-1;
         size=sizes[size_index];          allocated=allocates[allocates_index];
         refs=static_cast<Pair **>(pool.calloc(sizeof(Pair *)*size));          threshold=allocated*THRESHOLD_PERCENT/100;
           refs=static_cast<Pair **>(calloc(sizeof(Pair *)*allocated));
   
         // rehash          // rehash
         Pair **old_ref=old_refs;          Pair **old_ref=old_refs;
Line 55  void Hash::expand() { Line 64  void Hash::expand() {
                 for(Pair *pair=*old_ref++; pair; ) {                  for(Pair *pair=*old_ref++; pair; ) {
                         Pair *linked_pair=pair->link;                          Pair *linked_pair=pair->link;
   
                         uint new_index=pair->code%size;                          uint new_index=pair->code%allocated;
                         Pair **new_ref=&refs[new_index];                          Pair **new_ref=&refs[new_index];
                         pair->link=*new_ref;                          pair->link=*new_ref;
                         *new_ref=pair;                          *new_ref=pair;
Line 64  void Hash::expand() { Line 73  void Hash::expand() {
                 }                  }
 }  }
   
 uint Hash::generic_code(uint aresult, char *start, uint size) {  uint Hash::generic_code(uint aresult, const char *start, uint allocated) {
         uint result=aresult, g;          uint result=aresult, g;
         char *end=start+size;          const char *end=start+allocated;
   
         while (start<end) {          while (start<end) {
                 result=(result<<4)+*start++;                  result=(result<<4)+*start++;
Line 78  uint Hash::generic_code(uint aresult, ch Line 87  uint Hash::generic_code(uint aresult, ch
         return result;          return result;
 }  }
   
 void Hash::put(Key& key, Value *value) {  SYNCHRONIZED(thread_safe);  bool Hash::put(const Key& key, Val *value) {
         if(full())           if(full()) 
                 expand();                  expand();
   
         uint code=key.hash_code();          uint code=key.hash_code();
         uint index=code%size;          uint index=code%allocated;
         Pair **ref=&refs[index];          Pair **ref=&refs[index];
         for(Pair *pair=*ref; pair; pair=pair->link)          for(Pair *pair=*ref; pair; pair=pair->link)
                 if(pair->code==code && pair->key==key) {                  if(pair->code==code && pair->key==key) {
                         // found a pair with the same key                          // found a pair with the same key
                         pair->value=value;                          pair->value=value;
                         return;                          return true;
                 }                  }
                   
         // proper pair not found -- create&link_in new pair          // proper pair not found -- create&link_in new pair
         *ref=new(pool) 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;
 }  }
   
 Hash::Value *Hash::get(Key& key) {  SYNCHRONIZED(thread_safe);  Hash::Val *Hash::get(const Key& key) const {
         uint code=key.hash_code();          uint code=key.hash_code();
         uint index=code%size;          uint index=code%allocated;
         for(Pair *pair=refs[index]; pair; pair=pair->link)          for(Pair *pair=refs[index]; pair; pair=pair->link)
                 if(pair->code==code && pair->key==key)                  if(pair->code==code && pair->key==key)
                         return pair->value;                          return pair->value;
                   
         return 0;          return 0;
 }  }
   
   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)
                   if(pair->code==code && pair->key==key) {
                           // found a pair with the same key, replacing
                           pair->value=value;
                           return true;
                   }
   
           // proper pair not found 
           return false;
   }
   
   bool Hash::put_dont_replace(const Key& key, Val *value) {
           if(full()) 
                   expand();
   
           uint code=key.hash_code();
           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, NOT replacing
                           return true;
                   }
   
           // proper pair not found -- create&link_in new pair
           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) {
           for(int i=0; i<src.allocated; i++)
                   for(Pair *pair=src.refs[i]; pair; pair=pair->link)
                           put_dont_replace(pair->key, pair->value);
           // MAY:optimize this.allocated==src.allocated case
   }
   
   void Hash::for_each(For_each_func func, void *info) const {
           Pair **ref=refs;
           for(int index=0; index<allocated; index++)
                   for(Pair *pair=*ref++; pair; pair=pair->link)
                           if(pair->value)
                                   (*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; index<allocated; index++)
                   for(Pair *pair=*ref++; pair; pair=pair->link)
                           if(pair->value)
                                   (*func)(pair->key, pair->value, info);
   }
   
   void* Hash::first_that(First_that_func func, void *info) const {
           Pair **ref=refs;
           for(int index=0; index<allocated; index++)
                   for(Pair *pair=*ref++; pair; pair=pair->link)
                           if(pair->value)
                                   if(void *result=(*func)(pair->key, pair->value, info))
                                           return result;
           return 0;
   }
   
   void Hash::clear() {
           memset(refs, 0, sizeof(*refs)*allocated);
           count=used=0;   
   }

Removed from v.1.8  
changed lines
  Added in v.1.43


E-mail: