Diff for /parser3/src/main/Attic/pa_hash.C between versions 1.20 and 1.47

version 1.20, 2001/03/11 08:16:35 version 1.47, 2001/11/05 11:46:28
Line 1 Line 1
 /*  /** @file
         Parser          Parser: hash class.
   
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)          Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)
   
         $Id$          $Id$
 */  */
Line 15 Line 16
 */  */
   
 #include "pa_hash.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 */
Line 31  int Hash::allocates_count= Line 31  int Hash::allocates_count=
         sizeof(allocates)/sizeof(uint);          sizeof(allocates)/sizeof(uint);
   
   
 void Hash::construct(Pool& apool, bool athread_safe) {  void Hash::construct_new() {
         thread_safe=athread_safe;  
           
         allocated=allocates[allocates_index=0];          allocated=allocates[allocates_index=0];
         threshold=allocated*THRESHOLD_PERCENT/100;          threshold=allocated*THRESHOLD_PERCENT/100;
         used=0;          count=used=0;
         refs=static_cast<Pair **>(calloc(sizeof(Pair *)*allocated));          refs=static_cast<Pair **>(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<Pair **>(malloc(size, 7));  memcpy(refs, source.refs, size);
   }
   
 void Hash::expand() {  void Hash::expand() {
         int old_size=allocated;          int old_size=allocated;
         Pair **old_refs=refs;          Pair **old_refs=refs;
Line 47  void Hash::expand() { Line 55  void Hash::expand() {
         // allocated bigger refs array          // allocated bigger refs array
         allocates_index=allocates_index+1<allocates_count?allocates_index+1:allocates_count-1;          allocates_index=allocates_index+1<allocates_count?allocates_index+1:allocates_count-1;
         allocated=allocates[allocates_index];          allocated=allocates[allocates_index];
           threshold=allocated*THRESHOLD_PERCENT/100;
         refs=static_cast<Pair **>(calloc(sizeof(Pair *)*allocated));          refs=static_cast<Pair **>(calloc(sizeof(Pair *)*allocated));
   
         // rehash          // rehash
Line 78  uint Hash::generic_code(uint aresult, co Line 87  uint Hash::generic_code(uint aresult, co
         return result;          return result;
 }  }
   
 bool Hash::put(const Key& key, Value *value) {  SYNCHRONIZED(thread_safe);  bool Hash::put(const Key& key, Val *value) {
         if(full())           if(full()) 
                 expand();                  expand();
   
Line 96  bool Hash::put(const Key& key, Value *va Line 105  bool Hash::put(const Key& key, Value *va
         if(!*ref) // root cell were used?          if(!*ref) // root cell were used?
                 used++; // not, we'll use it and record the fact                  used++; // not, we'll use it and record the fact
         *ref=NEW Pair(code, key, value, *ref);          *ref=NEW Pair(code, key, value, *ref);
           count++;
         return false;          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 code=key.hash_code();
         uint index=code%allocated;          uint index=code%allocated;
         for(Pair *pair=refs[index]; pair; pair=pair->link)          for(Pair *pair=refs[index]; pair; pair=pair->link)
Line 109  Hash::Value *Hash::get(const Key& key) c Line 131  Hash::Value *Hash::get(const Key& key) c
         return 0;          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 code=key.hash_code();
         uint index=code%allocated;          uint index=code%allocated;
         for(Pair *pair=refs[index]; pair; pair=pair->link)          for(Pair *pair=refs[index]; pair; pair=pair->link)
Line 123  bool Hash::put_replace(const Key& key, V Line 145  bool Hash::put_replace(const Key& key, V
         return false;          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())           if(full()) 
                 expand();                  expand();
   
Line 137  bool Hash::put_dont_replace(const Key& k Line 159  bool Hash::put_dont_replace(const Key& k
                 }                  }
   
         // proper pair not found -- create&link_in new pair          // proper pair not found -- create&link_in new pair
         *ref=NEW Pair(code, key, value, *ref);  
         if(!*ref) // root cell were used?          if(!*ref) // root cell were used?
                 used++; // not, we'll use it and record the fact                  used++; // not, we'll use it and record the fact
           *ref=NEW Pair(code, key, value, *ref);
           count++;
         return false;          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; i<src.allocated; i++)          for(int i=0; i<src.allocated; i++)
                 for(Pair *pair=src.refs[i]; pair; pair=pair->link)                  for(Pair *pair=src.refs[i]; pair; pair=pair->link)
                         put_dont_replace(pair->key, pair->value);                          put_dont_replace(pair->key, pair->value);
         // MAY:optimize this.allocated==src.allocated case          // 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)
                           (*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)
                           (*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(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.20  
changed lines
  Added in v.1.47


E-mail: