|
|
|
@ -228,6 +228,10 @@ ZEND_API int zend_hash_add_or_update(HashTable *ht, char *arKey, uint nKeyLength |
|
|
|
} |
|
|
|
p->h = h; |
|
|
|
p->pNext = ht->arBuckets[nIndex]; |
|
|
|
p->pLast = NULL; |
|
|
|
if (p->pNext) { |
|
|
|
p->pNext->pLast = p; |
|
|
|
} |
|
|
|
if (pDest) { |
|
|
|
*pDest = p->pData; |
|
|
|
} |
|
|
|
@ -334,6 +338,10 @@ ZEND_API int zend_hash_quick_add_or_update(HashTable *ht, char *arKey, uint nKey |
|
|
|
} |
|
|
|
p->h = h; |
|
|
|
p->pNext = ht->arBuckets[nIndex]; |
|
|
|
p->pLast = NULL; |
|
|
|
if (p->pNext) { |
|
|
|
p->pNext->pLast = p; |
|
|
|
} |
|
|
|
if (pDest) { |
|
|
|
*pDest = p->pData; |
|
|
|
} |
|
|
|
@ -438,6 +446,10 @@ ZEND_API int zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void |
|
|
|
} |
|
|
|
|
|
|
|
p->pNext = ht->arBuckets[nIndex]; |
|
|
|
p->pLast = NULL; |
|
|
|
if (p->pNext) { |
|
|
|
p->pNext->pLast = p; |
|
|
|
} |
|
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
|
|
if (ht->pInternalPointer == NULL) { |
|
|
|
ht->pInternalPointer = p; |
|
|
|
@ -513,6 +525,10 @@ ZEND_API int zend_hash_rehash(HashTable *ht) |
|
|
|
while (p != NULL) { |
|
|
|
nIndex = p->h % ht->nTableSize; |
|
|
|
p->pNext = ht->arBuckets[nIndex]; |
|
|
|
p->pLast = NULL; |
|
|
|
if (p->pNext) { |
|
|
|
p->pNext->pLast = p; |
|
|
|
} |
|
|
|
ht->arBuckets[nIndex] = p; |
|
|
|
p = p->pListNext; |
|
|
|
} |
|
|
|
@ -542,6 +558,9 @@ ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint nKeyLen |
|
|
|
} else { |
|
|
|
t->pNext = p->pNext; |
|
|
|
} |
|
|
|
if (p->pNext) { |
|
|
|
p->pNext->pLast = p->pLast; |
|
|
|
} |
|
|
|
if (p->pListLast != NULL) { |
|
|
|
p->pListLast->pListNext = p->pListNext; |
|
|
|
} else { |
|
|
|
@ -630,7 +649,6 @@ ZEND_API void zend_hash_clean(HashTable *ht) |
|
|
|
SET_INCONSISTENT(HT_OK); |
|
|
|
} |
|
|
|
|
|
|
|
#if 0 |
|
|
|
/* This function is used by the various apply() functions. |
|
|
|
* It deletes the passed bucket, and returns the address of the |
|
|
|
* next bucket. The hash *may* be altered during that time, the |
|
|
|
@ -639,12 +657,9 @@ ZEND_API void zend_hash_clean(HashTable *ht) |
|
|
|
static Bucket *zend_hash_apply_deleter(HashTable *ht, Bucket *p) |
|
|
|
{ |
|
|
|
Bucket *retval; |
|
|
|
uint nIndex; |
|
|
|
|
|
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
|
|
|
|
|
|
nIndex = p->h % ht->nTableSize; |
|
|
|
|
|
|
|
if (ht->pDestructor) { |
|
|
|
ht->pDestructor(p->pData); |
|
|
|
} |
|
|
|
@ -653,9 +668,19 @@ static Bucket *zend_hash_apply_deleter(HashTable *ht, Bucket *p) |
|
|
|
} |
|
|
|
retval = p->pListNext; |
|
|
|
|
|
|
|
if (ht->arBuckets[nIndex] == p) { |
|
|
|
if (p->pLast) { |
|
|
|
p->pLast->pNext = p->pNext; |
|
|
|
} else { |
|
|
|
uint nIndex; |
|
|
|
|
|
|
|
nIndex = p->h % ht->nTableSize; |
|
|
|
ht->arBuckets[nIndex] = p->pNext; |
|
|
|
} |
|
|
|
if (p->pNext) { |
|
|
|
p->pNext->pLast = p->pLast; |
|
|
|
} else { |
|
|
|
/* Nothing to do as this list doesn't have a tail */ |
|
|
|
} |
|
|
|
|
|
|
|
if (p->pListLast != NULL) { |
|
|
|
p->pListLast->pListNext = p->pListNext; |
|
|
|
@ -678,24 +703,16 @@ static Bucket *zend_hash_apply_deleter(HashTable *ht, Bucket *p) |
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
ZEND_API void zend_hash_graceful_destroy(HashTable *ht) |
|
|
|
{ |
|
|
|
Bucket *p, *q; |
|
|
|
Bucket *p; |
|
|
|
|
|
|
|
IS_CONSISTENT(ht); |
|
|
|
|
|
|
|
p = ht->pListHead; |
|
|
|
while (p != NULL) { |
|
|
|
q = p; |
|
|
|
p = p->pListNext; |
|
|
|
if (q->nKeyLength==0) { |
|
|
|
zend_hash_index_del(ht, q->h); |
|
|
|
} else { |
|
|
|
zend_hash_del(ht, q->arKey, q->nKeyLength); |
|
|
|
} |
|
|
|
p = zend_hash_apply_deleter(ht,p); |
|
|
|
} |
|
|
|
pefree(ht->arBuckets,ht->persistent); |
|
|
|
|
|
|
|
@ -710,41 +727,33 @@ ZEND_API void zend_hash_graceful_destroy(HashTable *ht) |
|
|
|
|
|
|
|
ZEND_API void zend_hash_apply(HashTable *ht,int (*destruct) (void *)) |
|
|
|
{ |
|
|
|
Bucket *p, *q; |
|
|
|
Bucket *p; |
|
|
|
|
|
|
|
IS_CONSISTENT(ht); |
|
|
|
|
|
|
|
p = ht->pListHead; |
|
|
|
while (p != NULL) { |
|
|
|
q = p; |
|
|
|
p = p->pListNext; |
|
|
|
if (destruct(q->pData)) { |
|
|
|
if (q->nKeyLength==0) { |
|
|
|
zend_hash_index_del(ht, q->h); |
|
|
|
} else { |
|
|
|
zend_hash_del(ht, q->arKey, q->nKeyLength); |
|
|
|
} |
|
|
|
} |
|
|
|
if (destruct(p->pData)) { |
|
|
|
p = zend_hash_apply_deleter(ht,p); |
|
|
|
} else { |
|
|
|
p = p->pListNext; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ZEND_API void zend_hash_apply_with_argument(HashTable *ht,int (*destruct) (void *, void *), void *argument) |
|
|
|
{ |
|
|
|
Bucket *p, *q; |
|
|
|
Bucket *p; |
|
|
|
|
|
|
|
IS_CONSISTENT(ht); |
|
|
|
|
|
|
|
p = ht->pListHead; |
|
|
|
while (p != NULL) { |
|
|
|
q = p; |
|
|
|
p = p->pListNext; |
|
|
|
if (destruct(q->pData, argument)) { |
|
|
|
if (q->nKeyLength==0) { |
|
|
|
zend_hash_index_del(ht, q->h); |
|
|
|
} else { |
|
|
|
zend_hash_del(ht, q->arKey, q->nKeyLength); |
|
|
|
} |
|
|
|
if (destruct(p->pData, argument)) { |
|
|
|
p = zend_hash_apply_deleter(ht,p); |
|
|
|
} else { |
|
|
|
p = p->pListNext; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -752,7 +761,7 @@ ZEND_API void zend_hash_apply_with_argument(HashTable *ht,int (*destruct) (void |
|
|
|
|
|
|
|
ZEND_API void zend_hash_apply_with_arguments(HashTable *ht,int (*destruct)(void *, int, va_list, zend_hash_key *), int num_args, ...) |
|
|
|
{ |
|
|
|
Bucket *p, *q; |
|
|
|
Bucket *p; |
|
|
|
va_list args; |
|
|
|
zend_hash_key hash_key; |
|
|
|
|
|
|
|
@ -762,17 +771,13 @@ ZEND_API void zend_hash_apply_with_arguments(HashTable *ht,int (*destruct)(void |
|
|
|
|
|
|
|
p = ht->pListHead; |
|
|
|
while (p != NULL) { |
|
|
|
q = p; |
|
|
|
p = p->pListNext; |
|
|
|
hash_key.arKey = q->arKey; |
|
|
|
hash_key.nKeyLength = q->nKeyLength; |
|
|
|
hash_key.h = q->h; |
|
|
|
if (destruct(q->pData, num_args, args, &hash_key)) { |
|
|
|
if (q->nKeyLength==0) { |
|
|
|
zend_hash_index_del(ht, q->h); |
|
|
|
} else { |
|
|
|
zend_hash_del(ht, q->arKey, q->nKeyLength); |
|
|
|
} |
|
|
|
hash_key.arKey = p->arKey; |
|
|
|
hash_key.nKeyLength = p->nKeyLength; |
|
|
|
hash_key.h = p->h; |
|
|
|
if (destruct(p->pData, num_args, args, &hash_key)) { |
|
|
|
p = zend_hash_apply_deleter(ht,p); |
|
|
|
} else { |
|
|
|
p = p->pListNext; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -788,7 +793,7 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, void (*pCopyC |
|
|
|
IS_CONSISTENT(source); |
|
|
|
IS_CONSISTENT(target); |
|
|
|
|
|
|
|
p = source->pListHead; |
|
|
|
p = source->pListHead; |
|
|
|
while (p) { |
|
|
|
memcpy(tmp, p->pData, size); |
|
|
|
if (pCopyConstructor) { |
|
|
|
|