Keep collision list ordered from higher to lower buckets.

This commit is contained in:
Dmitry Stogov 2018-09-04 01:19:07 +03:00
parent 318b34da05
commit 437e91e194

View file

@ -339,6 +339,11 @@ ZEND_API void ZEND_FASTCALL zend_hash_discard(HashTable *ht, uint32_t nNumUsed)
if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
ht->nNumOfElements--;
/* Collision pointers always directed from higher to lower buckets */
#if 0
if (!(Z_NEXT(p->val) == HT_INVALID_IDX || HT_HASH_TO_BUCKET_EX(arData, Z_NEXT(p->val)) < p)) {
abort();
}
#endif
nIndex = p->h | ht->nTableMask;
HT_HASH_EX(arData, nIndex) = Z_NEXT(p->val);
}
@ -1069,9 +1074,20 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_set_bucket_key(HashTable *ht, Bucket *b,
b->key = key;
b->h = ZSTR_H(key);
nIndex = b->h | ht->nTableMask;
Z_NEXT(b->val) = HT_HASH_EX(arData, nIndex);
HT_HASH_EX(arData, nIndex) = HT_IDX_TO_HASH(idx);
idx = HT_IDX_TO_HASH(idx);
i = HT_HASH_EX(arData, nIndex);
if (i == HT_INVALID_IDX || i < idx) {
Z_NEXT(b->val) = i;
HT_HASH_EX(arData, nIndex) = idx;
} else {
p = HT_HASH_TO_BUCKET_EX(arData, i);
while (Z_NEXT(p->val) != HT_INVALID_IDX && Z_NEXT(p->val) > idx) {
i = Z_NEXT(p->val);
p = HT_HASH_TO_BUCKET_EX(arData, i);
}
Z_NEXT(b->val) = Z_NEXT(p->val);
Z_NEXT(p->val) = idx;
}
return &b->val;
}