Annotation of parser3/src/main/pa_hash.C, revision 1.12
1.1 paf 1: /*
1.12 ! paf 2: $Id: pa_hash.C,v 1.11 2001/02/11 11:27:25 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 */
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:
1.8 paf 30: Hash::Hash(Pool& apool, bool athread_safe) :
1.11 paf 31: Pooled(apool),
1.5 paf 32: thread_safe(athread_safe) {
1.1 paf 33:
34: size=sizes[size_index=0];
1.2 paf 35: threshold=size*THRESHOLD_PERCENT/100;
1.1 paf 36: used=0;
1.12 ! paf 37: refs=static_cast<Pair **>(pool().calloc(sizeof(Pair *)*size));
1.1 paf 38: }
39:
40: void Hash::expand() {
1.2 paf 41: int old_size=size;
42: Pair **old_refs=refs;
1.4 paf 43:
1.2 paf 44: // allocated bigger refs array
45: size_index=size_index+1<sizes_count?size_index+1:sizes_count-1;
46: size=sizes[size_index];
1.12 ! paf 47: refs=static_cast<Pair **>(pool().calloc(sizeof(Pair *)*size));
1.1 paf 48:
49: // rehash
1.2 paf 50: Pair **old_ref=old_refs;
51: for(int old_index=0; old_index<old_size; old_index++)
52: for(Pair *pair=*old_ref++; pair; ) {
53: Pair *linked_pair=pair->link;
54:
55: uint new_index=pair->code%size;
56: Pair **new_ref=&refs[new_index];
57: pair->link=*new_ref;
58: *new_ref=pair;
1.1 paf 59:
1.2 paf 60: pair=linked_pair;
61: }
1.1 paf 62: }
63:
1.9 paf 64: uint Hash::generic_code(uint aresult, const char *start, uint size) {
1.1 paf 65: uint result=aresult, g;
1.9 paf 66: const char *end=start+size;
1.1 paf 67:
68: while (start<end) {
69: result=(result<<4)+*start++;
70: if ((g=(result&0xF0000000))) {
71: result=result^(g>>24);
72: result=result^g;
73: }
74: }
75: return result;
76: }
77:
1.10 paf 78: void Hash::put(const Key& key, Value *value) { SYNCHRONIZED(thread_safe);
1.1 paf 79: if(full())
80: expand();
81:
1.2 paf 82: uint code=key.hash_code();
83: uint index=code%size;
84: Pair **ref=&refs[index];
85: for(Pair *pair=*ref; pair; pair=pair->link)
86: if(pair->code==code && pair->key==key) {
87: // found a pair with the same key
88: pair->value=value;
89: return;
1.1 paf 90: }
1.2 paf 91:
1.7 paf 92: // proper pair not found -- create&link_in new pair
1.12 ! paf 93: *ref=new(pool()) Pair(code, key, value, *ref);
1.1 paf 94: }
95:
1.10 paf 96: Hash::Value *Hash::get(const Key& key) { SYNCHRONIZED(thread_safe);
1.2 paf 97: uint code=key.hash_code();
1.1 paf 98: uint index=code%size;
1.2 paf 99: for(Pair *pair=refs[index]; pair; pair=pair->link)
1.1 paf 100: if(pair->code==code && pair->key==key)
101: return pair->value;
102:
103: return 0;
104: }
E-mail: