summaryrefslogtreecommitdiff
path: root/Zend/zend_hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_hash.c')
-rw-r--r--Zend/zend_hash.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index f419e8a571..d41ad43969 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -466,16 +466,37 @@ ZEND_API int zend_hash_rehash(HashTable *ht)
}
memset(ht->arBuckets, 0, ht->nTableSize * sizeof(Bucket *));
- p = ht->pListHead;
- while (p != NULL) {
+ for (p = ht->pListHead; p != NULL; p = p->pListNext) {
nIndex = p->h & ht->nTableMask;
CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]);
ht->arBuckets[nIndex] = p;
- p = p->pListNext;
}
return SUCCESS;
}
+ZEND_API void zend_hash_reindex(HashTable *ht) {
+ Bucket *p;
+ uint nIndex;
+ ulong offset = 0;
+
+ IS_CONSISTENT(ht);
+ if (UNEXPECTED(ht->nNumOfElements == 0)) {
+ return;
+ }
+
+ memset(ht->arBuckets, 0, ht->nTableSize * sizeof(Bucket *));
+ for (p = ht->pListHead; p != NULL; p = p->pListNext) {
+ if (p->nKeyLength == 0) {
+ p->h = offset++;
+ }
+
+ nIndex = p->h & ht->nTableMask;
+ CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]);
+ ht->arBuckets[nIndex] = p;
+ }
+ ht->nNextFreeElement = offset;
+}
+
ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag)
{
uint nIndex;