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