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

1.1       paf         1: /*
1.5     ! paf         2:   $Id: pa_hash.C,v 1.4 2001/01/29 11:53:42 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: 
                     13: #include "pa_pool.h"
1.4       paf        14: #include "pa_threads.h"
1.2       paf        15: 
                     16: void *Hash::Pair::operator new(size_t size, Pool *apool) {
                     17:        return apool->malloc(size);
                     18: }
                     19: 
1.1       paf        20: /* Zend comment: Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster */
                     21: uint Hash::sizes[]={
                     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};
                     26: int Hash::sizes_count=
                     27:        sizeof(sizes)/sizeof(uint);
                     28: 
                     29: void *Hash::operator new(size_t size, Pool *apool) {
                     30:        return apool->malloc(size);
                     31: }
                     32: 
1.5     ! paf        33: Hash::Hash(Pool *apool, bool athread_safe) :
        !            34:        pool(apool),
        !            35:        thread_safe(athread_safe) {
1.1       paf        36:        
                     37:        size=sizes[size_index=0];
1.2       paf        38:        threshold=size*THRESHOLD_PERCENT/100;
1.1       paf        39:        used=0;
1.2       paf        40:        refs=static_cast<Pair **>(pool->calloc(sizeof(Pair *)*size));
1.1       paf        41: }
                     42: 
                     43: void Hash::expand() {
1.2       paf        44:        int old_size=size;
                     45:        Pair **old_refs=refs;
1.4       paf        46: 
1.2       paf        47:        // allocated bigger refs array
                     48:        size_index=size_index+1<sizes_count?size_index+1:sizes_count-1;
                     49:        size=sizes[size_index];
1.4       paf        50:        refs=static_cast<Pair **>(pool->calloc(sizeof(Pair *)*size));
1.1       paf        51: 
                     52:        // rehash
1.2       paf        53:        Pair **old_ref=old_refs;
                     54:        for(int old_index=0; old_index<old_size; old_index++)
                     55:                for(Pair *pair=*old_ref++; pair; ) {
                     56:                        Pair *linked_pair=pair->link;
                     57: 
                     58:                        uint new_index=pair->code%size;
                     59:                        Pair **new_ref=&refs[new_index];
                     60:                        pair->link=*new_ref;
                     61:                        *new_ref=pair;
1.1       paf        62: 
1.2       paf        63:                        pair=linked_pair;
                     64:                }
1.1       paf        65: }
                     66: 
                     67: uint Hash::generic_code(uint aresult, char *start, uint size) {
                     68:        uint result=aresult, g;
                     69:        char *end=start+size;
                     70: 
                     71:        while (start<end) {
                     72:                result=(result<<4)+*start++;
                     73:                if ((g=(result&0xF0000000))) {
                     74:                        result=result^(g>>24);
                     75:                        result=result^g;
                     76:                }
                     77:        }
                     78:        return result;
                     79: }
                     80: 
1.2       paf        81: void Hash::put(Key& key, Value *value) {
1.5     ! paf        82:        SYNCHRONIZED(thread_safe);
1.4       paf        83: 
1.1       paf        84:        if(full()) 
                     85:                expand();
                     86: 
1.2       paf        87:        uint code=key.hash_code();
                     88:        uint index=code%size;
                     89:        Pair **ref=&refs[index];
                     90:        for(Pair *pair=*ref; pair; pair=pair->link)
                     91:                if(pair->code==code && pair->key==key) {
                     92:                        // found a pair with the same key
                     93:                        pair->value=value;
                     94:                        return;
1.1       paf        95:                }
1.2       paf        96:        
                     97:        // not found proper pair -- create&link_in new pair
                     98:        *ref=new(pool) Pair(code, key, value, *ref);
1.1       paf        99: }
                    100: 
1.3       paf       101: Hash::Value* Hash::get(Key& key) {
1.5     ! paf       102:        SYNCHRONIZED(thread_safe);
1.4       paf       103: 
1.2       paf       104:        uint code=key.hash_code();
1.1       paf       105:        uint index=code%size;
1.2       paf       106:        for(Pair *pair=refs[index]; pair; pair=pair->link)
1.1       paf       107:                if(pair->code==code && pair->key==key)
                    108:                        return pair->value;
                    109:        
                    110:        return 0;
                    111: }

E-mail: