Diff for /parser3/src/include/pa_hash.h between versions 1.99 and 1.107

version 1.99, 2017/11/15 22:48:57 version 1.107, 2025/05/26 00:52:15
Line 1 Line 1
 /** @file  /** @file
         Parser: hash class decl.          Parser: hash class decl.
   
         Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com)          Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com)
   
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
 */  
   
 /*  
         The prime numbers used from zend_hash.c,  
         the part of Zend scripting engine library,  
         Copyrighted (C) 1999-2000    Zend Technologies Ltd.  
         http://www.zend.com/license/0_92.txt  
         For more information about Zend please visit http://www.zend.com/  
 */  */
   
 #ifndef PA_HASH_H  #ifndef PA_HASH_H
Line 25 Line 17
   
 const int HASH_ALLOCATES_COUNT=29;  const int HASH_ALLOCATES_COUNT=29;
   
 /** Zend comment: Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster   // nearest primes to 5 * 2^n
   
         paf: HPUX ld could not handle static member: unsatisfied symbols  
 */  
 static uint Hash_allocates[HASH_ALLOCATES_COUNT]={  static uint Hash_allocates[HASH_ALLOCATES_COUNT]={
         5, 11, 19, 53, 107, 223, 463, 983, 1979, 3907, 7963,           5, 11, 19, 41, 79, 163, 317, 641, 1279, 2557, 5119,
         16229, 32531, 65407, 130987, 262237, 524521, 1048793,           10243, 20479, 40961, 81919, 163841, 327673, 655357,
         2097397, 4194103, 8388857, 16777447, 33554201, 67108961,           1310719, 2621447, 5242883, 10485767, 20971529, 41943049,
         134217487, 268435697, 536870683, 1073741621, 2147483399};          83886091, 167772161, 335544323, 671088637, 1342177283};
   
 /// useful generic hash function  /// useful generic hash function
 inline void generic_hash_code(uint& result, char c) {  inline void generic_hash_code(uint& result, char c) {
Line 115  inline uint hash_code(int self) { Line 104  inline uint hash_code(int self) {
   
 #endif  #endif
   
   #define HASH_PUT_CSTR(h, cstr, v) \
           { static const String::Body body_##__LINE__(cstr); (h).put(body_##__LINE__, (v)); }
   
 template<typename K, typename V> class HASH: public PA_Object {  template<typename K, typename V> class HASH: public PA_Object {
 protected:  protected:
         class Pair;          class Pair;
Line 474  public: Line 466  public:
                 CORD key=str.get_cord();                  CORD key=str.get_cord();
   
                 uint code=str.get_hash_code();                  uint code=str.get_hash_code();
                 uint index=code%this->allocated;                  uint index=code % this->allocated;
                 Pair **ref=&this->refs[index];                  Pair **ref=&this->refs[index];
                 for(Pair *pair=*ref; pair; pair=pair->link)                  for(Pair *pair=*ref; pair; pair=pair->link)
                         if(pair->code==code && CORD_cmp(pair->key,key)==0) {                          if(pair->code==code && CORD_cmp(pair->key,key)==0) {
Line 491  public: Line 483  public:
                 return false;                  return false;
         }          }
   
           bool put(const char *str, V value) {
                   return put(String::Body(str), value);
           }
   
         /// remove the [key] @returns existed or not          /// remove the [key] @returns existed or not
         bool remove(K str) {          bool remove(K str) {
                 CORD key=str.get_cord();                  CORD key=str.get_cord();
                 uint code=str.get_hash_code();                  uint code=str.get_hash_code();
                 uint index=code%this->allocated;                  uint index=code % this->allocated;
                 for(Pair **ref=&this->refs[index]; *ref; ref=&(*ref)->link){                  for(Pair **ref=&this->refs[index]; *ref; ref=&(*ref)->link){
                         Pair *pair=*ref;                          Pair *pair=*ref;
                         if(pair->code==code && CORD_cmp(pair->key,key)==0) {                          if(pair->code==code && CORD_cmp(pair->key,key)==0) {
Line 521  public: Line 517  public:
         bool contains(K str){          bool contains(K str){
                 CORD key=str.get_cord();                  CORD key=str.get_cord();
                 uint code=str.get_hash_code();                  uint code=str.get_hash_code();
                 uint index=code%this->allocated;                  uint index=code % this->allocated;
                 for(Pair *pair=this->refs[index]; pair; pair=pair->link){                  for(Pair *pair=this->refs[index]; pair; pair=pair->link){
                         if(pair->code==code && CORD_cmp(pair->key,key)==0)                          if(pair->code==code && CORD_cmp(pair->key,key)==0)
                                 return true;                                  return true;
Line 534  public: Line 530  public:
         V get(K str) const {          V get(K str) const {
                 CORD key=str.get_cord();                  CORD key=str.get_cord();
                 uint code=str.get_hash_code();                  uint code=str.get_hash_code();
                 uint index=code%this->allocated;                  uint index=code % this->allocated;
                 for(Pair *pair=this->refs[index]; pair; pair=pair->link)                  for(Pair *pair=this->refs[index]; pair; pair=pair->link)
                         if(pair->code==code && CORD_cmp(pair->key,key)==0)                          if(pair->code==code && CORD_cmp(pair->key,key)==0)
                                 return pair->value;                                  return pair->value;
Line 550  public: Line 546  public:
                 } else {                  } else {
                         key=0;                          key=0;
                 }                  }
                 uint index=code%this->allocated;                  uint index=code % this->allocated;
                 for(Pair *pair=this->refs[index]; pair; pair=pair->link)                  for(Pair *pair=this->refs[index]; pair; pair=pair->link)
                         if(pair->code==code && CORD_cmp(pair->key,(CORD)key)==0)                          if(pair->code==code && CORD_cmp(pair->key,(CORD)key)==0)
                                 return pair->value;                                  return pair->value;
   
                 return V(0);                  return V((const char *)0);
         }          }
   
         /// put a [value] under the [key] if that [key] existed @returns existed or not          /// put a [value] under the [key] if that [key] existed @returns existed or not
Line 567  public: Line 563  public:
   
                 CORD key=str.get_cord();                  CORD key=str.get_cord();
                 uint code=str.get_hash_code();                  uint code=str.get_hash_code();
                 uint index=code%this->allocated;                  uint index=code % this->allocated;
                 for(Pair *pair=this->refs[index]; pair; pair=pair->link)                  for(Pair *pair=this->refs[index]; pair; pair=pair->link)
                         if(pair->code==code && CORD_cmp(pair->key,key)==0) {                          if(pair->code==code && CORD_cmp(pair->key,key)==0) {
                                 // found a pair with the same key, replacing                                  // found a pair with the same key, replacing
Line 590  public: Line 586  public:
   
                 CORD key=str.get_cord();                  CORD key=str.get_cord();
                 uint code=str.get_hash_code();                  uint code=str.get_hash_code();
                 uint index=code%this->allocated;                  uint index=code % this->allocated;
                 Pair **ref=&this->refs[index];                  Pair **ref=&this->refs[index];
                 for(Pair *pair=*ref; pair; pair=pair->link)                  for(Pair *pair=*ref; pair; pair=pair->link)
                         if(pair->code==code && CORD_cmp(pair->key,key)==0) {                          if(pair->code==code && CORD_cmp(pair->key,key)==0) {
Line 606  public: Line 602  public:
                 return false;                  return false;
         }          }
   
           /// rename $.from[] to $.to[]
           void rename(K from, K to) {
                   CORD key_from=from.get_cord();
                   uint code_from=from.get_hash_code();
                   uint index_from=code_from % this->allocated;
   
                   CORD key_to=to.get_cord();
                   uint code_to=to.get_hash_code();
                   uint index_to=code_to % this->allocated;
   
                   if(code_from == code_to && CORD_cmp(key_from, key_to)==0)
                           return;
   
                   for(Pair **ref=&this->refs[index_from]; *ref; ref=&(*ref)->link){
                           Pair *pair=*ref;
                           if(pair->code==code_from && CORD_cmp(pair->key,key_from)==0) {
                                   // found a pair with the required key
   
                                   // remove it from the from key first
                                   Pair *next=pair->link;
                                   *ref=next;
   
                                   // to simplify code
                                   remove(to);
   
                                   // change pair key
                                   pair->code=code_to;
                                   (CORD &)(pair->key)=key_to;
   
                                   // link to the to key, hash order left intact
                                   if(!(pair->link=this->refs[index_to])) // root was unused?
                                           this->fused_refs++; // we've used it and record the fact
                                   this->refs[index_to]=pair;
                                   return;
                           }
                   }
           }
   
         /// put all 'src' values if NO with same key existed          /// put all 'src' values if NO with same key existed
         void merge_dont_replace(const HASH_STRING& src) {          void merge_dont_replace(const HASH_STRING& src) {
 #ifdef HASH_ORDER  #ifdef HASH_ORDER

Removed from v.1.99  
changed lines
  Added in v.1.107


E-mail: