Annotation of parser3/src/main/pa_hash.C, revision 1.18

1.1       paf         1: /*
1.18    ! paf         2:   $Id: pa_hash.C,v 1.17 2001/02/25 13:23:02 paf Exp $
1.1       paf         3: */
                      4: 
                      5: /*
                      6:        The prime numbers used from zend_hash.c,
                      7:        the part of Zend scripting engine library,
                      8:        Copyrighted (C) 1999-2000    Zend Technologies Ltd.
                      9:        http://www.zend.com/license/0_92.txt
                     10:        For more information about Zend please visit http://www.zend.com/
                     11: */
                     12: 
1.11      paf        13: #include "pa_hash.h"
1.4       paf        14: #include "pa_threads.h"
1.2       paf        15: 
1.8       paf        16: void *Hash::Pair::operator new(size_t size, Pool& apool) {
                     17:        return apool.malloc(size);
1.2       paf        18: }
                     19: 
1.1       paf        20: /* Zend comment: Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster */
1.18    ! paf        21: uint Hash::allocates[]={
1.1       paf        22:        5, 11, 19, 53, 107, 223, 463, 983, 1979, 3907, 7963, 
                     23:        16229, 32531, 65407, 130987, 262237, 524521, 1048793, 
                     24:        2097397, 4194103, 8388857, 16777447, 33554201, 67108961, 
                     25:        134217487, 268435697, 536870683, 1073741621, 2147483399};
1.18    ! paf        26: int Hash::allocates_count=
        !            27:        sizeof(allocates)/sizeof(uint);
1.1       paf        28: 
                     29: 
1.13      paf        30: void Hash::construct(Pool& apool, bool athread_safe) {
                     31:        thread_safe=athread_safe;
1.1       paf        32:        
1.18    ! paf        33:        allocated=allocates[allocates_index=0];
        !            34:        threshold=allocated*THRESHOLD_PERCENT/100;
1.1       paf        35:        used=0;
1.18    ! paf        36:        refs=static_cast<Pair **>(calloc(sizeof(Pair *)*allocated));
1.1       paf        37: }
                     38: 
                     39: void Hash::expand() {
1.18    ! paf        40:        int old_size=allocated;
1.2       paf        41:        Pair **old_refs=refs;
1.4       paf        42: 
1.2       paf        43:        // allocated bigger refs array
1.18    ! paf        44:        allocates_index=allocates_index+1<allocates_count?allocates_index+1:allocates_count-1;
        !            45:        allocated=allocates[allocates_index];
        !            46:        refs=static_cast<Pair **>(calloc(sizeof(Pair *)*allocated));
1.1       paf        47: 
                     48:        // rehash
1.2       paf        49:        Pair **old_ref=old_refs;
                     50:        for(int old_index=0; old_index<old_size; old_index++)
                     51:                for(Pair *pair=*old_ref++; pair; ) {
                     52:                        Pair *linked_pair=pair->link;
                     53: 
1.18    ! paf        54:                        uint new_index=pair->code%allocated;
1.2       paf        55:                        Pair **new_ref=&refs[new_index];
                     56:                        pair->link=*new_ref;
                     57:                        *new_ref=pair;
1.1       paf        58: 
1.2       paf        59:                        pair=linked_pair;
                     60:                }
1.1       paf        61: }
                     62: 
1.18    ! paf        63: uint Hash::generic_code(uint aresult, const char *start, uint allocated) {
1.1       paf        64:        uint result=aresult, g;
1.18    ! paf        65:        const char *end=start+allocated;
1.1       paf        66: 
                     67:        while (start<end) {
                     68:                result=(result<<4)+*start++;
                     69:                if ((g=(result&0xF0000000))) {
                     70:                        result=result^(g>>24);
                     71:                        result=result^g;
                     72:                }
                     73:        }
                     74:        return result;
                     75: }
                     76: 
1.17      paf        77: bool Hash::put(const Key& key, Value *value) {  SYNCHRONIZED(thread_safe);
1.1       paf        78:        if(full()) 
                     79:                expand();
                     80: 
1.2       paf        81:        uint code=key.hash_code();
1.18    ! paf        82:        uint index=code%allocated;
1.2       paf        83:        Pair **ref=&refs[index];
                     84:        for(Pair *pair=*ref; pair; pair=pair->link)
                     85:                if(pair->code==code && pair->key==key) {
                     86:                        // found a pair with the same key
                     87:                        pair->value=value;
1.17      paf        88:                        return true;
1.1       paf        89:                }
1.2       paf        90:        
1.7       paf        91:        // proper pair not found -- create&link_in new pair
1.17      paf        92:        if(!*ref) // root cell were used?
                     93:                used++; // not, we'll use it and record the fact
1.15      paf        94:        *ref=NEW Pair(code, key, value, *ref);
1.17      paf        95:        return false;
1.1       paf        96: }
                     97: 
1.13      paf        98: Hash::Value *Hash::get(const Key& key) const {  SYNCHRONIZED(thread_safe);
1.2       paf        99:        uint code=key.hash_code();
1.18    ! paf       100:        uint index=code%allocated;
1.2       paf       101:        for(Pair *pair=refs[index]; pair; pair=pair->link)
1.1       paf       102:                if(pair->code==code && pair->key==key)
                    103:                        return pair->value;
                    104:        
                    105:        return 0;
                    106: }
1.16      paf       107: 
1.17      paf       108: bool Hash::put_replace(const Key& key, Value *value) {  SYNCHRONIZED(thread_safe);
1.16      paf       109:        uint code=key.hash_code();
1.18    ! paf       110:        uint index=code%allocated;
1.16      paf       111:        for(Pair *pair=refs[index]; pair; pair=pair->link)
                    112:                if(pair->code==code && pair->key==key) {
                    113:                        // found a pair with the same key, replacing
                    114:                        pair->value=value;
                    115:                        return true;
                    116:                }
                    117: 
                    118:        // proper pair not found 
                    119:        return false;
                    120: }
                    121: 
1.17      paf       122: bool Hash::put_dont_replace(const Key& key, Value *value) {  SYNCHRONIZED(thread_safe);
                    123:        if(full()) 
                    124:                expand();
                    125: 
                    126:        uint code=key.hash_code();
1.18    ! paf       127:        uint index=code%allocated;
1.17      paf       128:        Pair **ref=&refs[index];
                    129:        for(Pair *pair=*ref; pair; pair=pair->link)
                    130:                if(pair->code==code && pair->key==key) {
                    131:                        // found a pair with the same key, NOT replacing
                    132:                        return true;
                    133:                }
                    134: 
                    135:        // proper pair not found -- create&link_in new pair
                    136:        *ref=NEW Pair(code, key, value, *ref);
                    137:        if(!*ref) // root cell were used?
                    138:                used++; // not, we'll use it and record the fact
                    139:        return false;
                    140: }
                    141: 
                    142: void Hash::merge_dont_replace(const Hash& src) {  SYNCHRONIZED(thread_safe);
1.18    ! paf       143:        for(int i=0; i<src.allocated; i++)
1.17      paf       144:                for(Pair *pair=src.refs[i]; pair; pair=pair->link)
                    145:                        put_dont_replace(pair->key, pair->value);
1.18    ! paf       146:        // MAY:optimize this.allocated==src.allocated case
1.17      paf       147: }

E-mail: