@@ -117,7 +117,6 @@ static void _zend_is_inconsistent(HashTable *ht, char *file, int line)
117
117
(ht)->nApplyCount--;
118
118
119
119
120
- /* Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster */
121
120
static uint PrimeNumbers [] =
122
121
{5 , 11 , 19 , 53 , 107 , 223 , 463 , 983 , 1979 , 3907 , 7963 , 16229 , 32531 , 65407 , 130987 , 262237 , 524521 , 1048793 , 2097397 , 4194103 , 8388857 , 16777447 , 33554201 , 67108961 , 134217487 , 268435697 , 536870683 , 1073741621 , 2147483399 };
123
122
static uint nNumPrimeNumbers = sizeof (PrimeNumbers ) / sizeof (uint );
@@ -129,22 +128,23 @@ static uint nNumPrimeNumbers = sizeof(PrimeNumbers) / sizeof(uint);
129
128
130
129
static int zend_hash_do_resize (HashTable * ht );
131
130
132
-
133
- ZEND_API ulong hashpjw (char * arKey , uint nKeyLength )
131
+ static inline ulong zend_inline_hash_func (char * arKey , uint nKeyLength )
134
132
{
135
- ulong h = 0 , g ;
136
- char * arEnd = arKey + nKeyLength ;
133
+ ulong h = 5381 ;
134
+ char * arEnd = arKey + nKeyLength ;
137
135
138
136
while (arKey < arEnd ) {
139
- h = (h << 4 ) + * arKey ++ ;
140
- if ((g = (h & 0xF0000000 ))) {
141
- h = h ^ (g >> 24 );
142
- h = h ^ g ;
143
- }
137
+ h += (h << 5 );
138
+ h ^= (ulong ) * arKey ++ ;
144
139
}
145
140
return h ;
146
141
}
147
142
143
+ ZEND_API ulong zend_hash_func (char * arKey , uint nKeyLength )
144
+ {
145
+ return zend_inline_hash_func (arKey , nKeyLength );
146
+ }
147
+
148
148
149
149
#define UPDATE_DATA (ht , p , pData , nDataSize ) \
150
150
if (nDataSize == sizeof(void*)) { \
@@ -178,35 +178,25 @@ ZEND_API ulong hashpjw(char *arKey, uint nKeyLength)
178
178
179
179
ZEND_API int zend_hash_init (HashTable * ht , uint nSize , hash_func_t pHashFunction , dtor_func_t pDestructor , int persistent )
180
180
{
181
- uint i ;
181
+ uint i = 3 ;
182
182
183
183
SET_INCONSISTENT (HT_OK );
184
-
185
- for (i = 0 ; i < nNumPrimeNumbers ; i ++ ) {
186
- if (nSize <= PrimeNumbers [i ]) {
187
- nSize = PrimeNumbers [i ];
188
- ht -> nHashSizeIndex = i ;
189
- break ;
190
- }
191
- }
192
- if (i == nNumPrimeNumbers ) { /* This shouldn't really happen unless the ask for a ridiculous size */
193
- nSize = PrimeNumbers [i - 1 ];
194
- ht -> nHashSizeIndex = i - 1 ;
184
+
185
+ while ((1 << i ) < nSize ) {
186
+ i ++ ;
195
187
}
188
+
189
+ ht -> nTableSize = 1 << i ;
190
+ ht -> nTableMask = ht -> nTableSize - 1 ;
196
191
197
192
/* Uses ecalloc() so that Bucket* == NULL */
198
- ht -> arBuckets = (Bucket * * ) pecalloc (nSize , sizeof (Bucket * ), persistent );
193
+ ht -> arBuckets = (Bucket * * ) pecalloc (ht -> nTableSize , sizeof (Bucket * ), persistent );
199
194
200
195
if (!ht -> arBuckets ) {
201
196
return FAILURE ;
202
197
}
203
- if (pHashFunction == NULL ) {
204
- ht -> pHashFunction = hashpjw ;
205
- } else {
206
- ht -> pHashFunction = pHashFunction ;
207
- }
198
+
208
199
ht -> pDestructor = pDestructor ;
209
- ht -> nTableSize = nSize ;
210
200
ht -> pListHead = NULL ;
211
201
ht -> pListTail = NULL ;
212
202
ht -> nNumOfElements = 0 ;
@@ -252,8 +242,8 @@ ZEND_API int zend_hash_add_or_update(HashTable *ht, char *arKey, uint nKeyLength
252
242
253
243
HANDLE_NUMERIC (arKey , nKeyLength , zend_hash_index_update_or_next_insert (ht , idx , pData , nDataSize , pDest , flag ));
254
244
255
- h = ht -> pHashFunction (arKey , nKeyLength );
256
- nIndex = h % ht -> nTableSize ;
245
+ h = zend_inline_hash_func (arKey , nKeyLength );
246
+ nIndex = h & ht -> nTableMask ;
257
247
258
248
p = ht -> arBuckets [nIndex ];
259
249
while (p != NULL ) {
@@ -321,7 +311,7 @@ ZEND_API int zend_hash_quick_add_or_update(HashTable *ht, char *arKey, uint nKey
321
311
return FAILURE ;
322
312
}
323
313
324
- nIndex = h % ht -> nTableSize ;
314
+ nIndex = h & ht -> nTableMask ;
325
315
326
316
p = ht -> arBuckets [nIndex ];
327
317
while (p != NULL ) {
@@ -397,7 +387,7 @@ ZEND_API int zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void
397
387
if (flag & HASH_NEXT_INSERT ) {
398
388
h = ht -> nNextFreeElement ;
399
389
}
400
- nIndex = h % ht -> nTableSize ;
390
+ nIndex = h & ht -> nTableMask ;
401
391
402
392
p = ht -> arBuckets [nIndex ];
403
393
while (p != NULL ) {
@@ -461,13 +451,13 @@ static int zend_hash_do_resize(HashTable *ht)
461
451
462
452
IS_CONSISTENT (ht );
463
453
464
- if ((ht -> nHashSizeIndex < nNumPrimeNumbers - 1 )) { /* Let's double the table size */
465
- t = (Bucket * * ) perealloc_recoverable (ht -> arBuckets , PrimeNumbers [ ht -> nHashSizeIndex + 1 ] * sizeof (Bucket * ), ht -> persistent );
454
+ if ((ht -> nTableSize << 1 ) > 0 ) { /* Let's double the table size */
455
+ t = (Bucket * * ) perealloc_recoverable (ht -> arBuckets , ( ht -> nTableSize << 1 ) * sizeof (Bucket * ), ht -> persistent );
466
456
if (t ) {
467
457
HANDLE_BLOCK_INTERRUPTIONS ();
468
458
ht -> arBuckets = t ;
469
- ht -> nTableSize = PrimeNumbers [ ht -> nHashSizeIndex + 1 ] ;
470
- ht -> nHashSizeIndex ++ ;
459
+ ht -> nTableSize = ( ht -> nTableSize << 1 ) ;
460
+ ht -> nTableMask = ht -> nTableSize - 1 ;
471
461
zend_hash_rehash (ht );
472
462
HANDLE_UNBLOCK_INTERRUPTIONS ();
473
463
return SUCCESS ;
@@ -484,10 +474,10 @@ ZEND_API int zend_hash_rehash(HashTable *ht)
484
474
485
475
IS_CONSISTENT (ht );
486
476
487
- memset (ht -> arBuckets , 0 , PrimeNumbers [ ht -> nHashSizeIndex ] * sizeof (Bucket * ));
477
+ memset (ht -> arBuckets , 0 , ht -> nTableSize * sizeof (Bucket * ));
488
478
p = ht -> pListHead ;
489
479
while (p != NULL ) {
490
- nIndex = p -> h % ht -> nTableSize ;
480
+ nIndex = p -> h & ht -> nTableMask ;
491
481
CONNECT_TO_BUCKET_DLLIST (p , ht -> arBuckets [nIndex ]);
492
482
ht -> arBuckets [nIndex ] = p ;
493
483
p = p -> pListNext ;
@@ -504,9 +494,9 @@ ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint nKeyLen
504
494
505
495
if (flag == HASH_DEL_KEY ) {
506
496
HANDLE_NUMERIC (arKey , nKeyLength , zend_hash_del_key_or_index (ht , arKey , nKeyLength , idx , HASH_DEL_INDEX ));
507
- h = ht -> pHashFunction (arKey , nKeyLength );
497
+ h = zend_inline_hash_func (arKey , nKeyLength );
508
498
}
509
- nIndex = h % ht -> nTableSize ;
499
+ nIndex = h & ht -> nTableMask ;
510
500
511
501
p = ht -> arBuckets [nIndex ];
512
502
while (p != NULL ) {
@@ -632,7 +622,7 @@ static Bucket *zend_hash_apply_deleter(HashTable *ht, Bucket *p)
632
622
} else {
633
623
uint nIndex ;
634
624
635
- nIndex = p -> h % ht -> nTableSize ;
625
+ nIndex = p -> h & ht -> nTableMask ;
636
626
ht -> arBuckets [nIndex ] = p -> pNext ;
637
627
}
638
628
if (p -> pNext ) {
@@ -837,7 +827,7 @@ ZEND_API ulong zend_get_hash_value(HashTable *ht, char *arKey, uint nKeyLength)
837
827
{
838
828
IS_CONSISTENT (ht );
839
829
840
- return ht -> pHashFunction (arKey , nKeyLength );
830
+ return zend_inline_hash_func (arKey , nKeyLength );
841
831
}
842
832
843
833
@@ -855,8 +845,8 @@ ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **
855
845
856
846
HANDLE_NUMERIC (arKey , nKeyLength , zend_hash_index_find (ht , idx , pData ));
857
847
858
- h = ht -> pHashFunction (arKey , nKeyLength );
859
- nIndex = h % ht -> nTableSize ;
848
+ h = zend_inline_hash_func (arKey , nKeyLength );
849
+ nIndex = h & ht -> nTableMask ;
860
850
861
851
p = ht -> arBuckets [nIndex ];
862
852
while (p != NULL ) {
@@ -879,7 +869,7 @@ ZEND_API int zend_hash_quick_find(HashTable *ht, char *arKey, uint nKeyLength, u
879
869
880
870
IS_CONSISTENT (ht );
881
871
882
- nIndex = h % ht -> nTableSize ;
872
+ nIndex = h & ht -> nTableMask ;
883
873
884
874
p = ht -> arBuckets [nIndex ];
885
875
while (p != NULL ) {
@@ -905,8 +895,8 @@ ZEND_API int zend_hash_exists(HashTable *ht, char *arKey, uint nKeyLength)
905
895
906
896
HANDLE_NUMERIC (arKey , nKeyLength , zend_hash_index_exists (ht , idx ));
907
897
908
- h = ht -> pHashFunction (arKey , nKeyLength );
909
- nIndex = h % ht -> nTableSize ;
898
+ h = zend_inline_hash_func (arKey , nKeyLength );
899
+ nIndex = h & ht -> nTableMask ;
910
900
911
901
p = ht -> arBuckets [nIndex ];
912
902
while (p != NULL ) {
@@ -928,7 +918,7 @@ ZEND_API int zend_hash_index_find(HashTable *ht, ulong h, void **pData)
928
918
929
919
IS_CONSISTENT (ht );
930
920
931
- nIndex = h % ht -> nTableSize ;
921
+ nIndex = h & ht -> nTableMask ;
932
922
933
923
p = ht -> arBuckets [nIndex ];
934
924
while (p != NULL ) {
@@ -949,7 +939,7 @@ ZEND_API int zend_hash_index_exists(HashTable *ht, ulong h)
949
939
950
940
IS_CONSISTENT (ht );
951
941
952
- nIndex = h % ht -> nTableSize ;
942
+ nIndex = h & ht -> nTableMask ;
953
943
954
944
p = ht -> arBuckets [nIndex ];
955
945
while (p != NULL ) {
0 commit comments