}
}
+static zend_always_inline void i_zend_hash_bucket_delete(HashTable *ht, Bucket *p)
+{
+#ifdef ZEND_SIGNALS
+ TSRMLS_FETCH();
+#endif
+
+ HANDLE_BLOCK_INTERRUPTIONS();
+ if (p->pLast) {
+ p->pLast->pNext = p->pNext;
+ } else {
+ ht->arBuckets[p->h & ht->nTableMask] = p->pNext;
+ }
+ if (p->pNext) {
+ p->pNext->pLast = p->pLast;
+ }
+ if (p->pListLast != NULL) {
+ p->pListLast->pListNext = p->pListNext;
+ } else {
+ /* Deleting the head of the list */
+ ht->pListHead = p->pListNext;
+ }
+ if (p->pListNext != NULL) {
+ p->pListNext->pListLast = p->pListLast;
+ } else {
+ /* Deleting the tail of the list */
+ ht->pListTail = p->pListLast;
+ }
+ if (ht->pInternalPointer == p) {
+ ht->pInternalPointer = p->pListNext;
+ }
+ ht->nNumOfElements--;
+ if (ht->pDestructor) {
+ ht->pDestructor(p->pData);
+ }
+ if (p->pData != &p->pDataPtr) {
+ pefree(p->pData, ht->persistent);
+ }
+ pefree(p, ht->persistent);
+ HANDLE_UNBLOCK_INTERRUPTIONS();
+}
+
+static void zend_hash_bucket_delete(HashTable *ht, Bucket *p) {
+ i_zend_hash_bucket_delete(ht, p);
+}
+
ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
{
uint i = 3;
{
uint nIndex;
Bucket *p;
-#ifdef ZEND_SIGNALS
- TSRMLS_FETCH();
-#endif
IS_CONSISTENT(ht);
&& (p->nKeyLength == nKeyLength)
&& ((p->nKeyLength == 0) /* Numeric index (short circuits the memcmp() check) */
|| !memcmp(p->arKey, arKey, nKeyLength))) { /* String index */
- HANDLE_BLOCK_INTERRUPTIONS();
- if (p == ht->arBuckets[nIndex]) {
- ht->arBuckets[nIndex] = p->pNext;
- } else {
- p->pLast->pNext = p->pNext;
- }
- if (p->pNext) {
- p->pNext->pLast = p->pLast;
- }
- if (p->pListLast != NULL) {
- p->pListLast->pListNext = p->pListNext;
- } else {
- /* Deleting the head of the list */
- ht->pListHead = p->pListNext;
- }
- if (p->pListNext != NULL) {
- p->pListNext->pListLast = p->pListLast;
- } else {
- ht->pListTail = p->pListLast;
- }
- if (ht->pInternalPointer == p) {
- ht->pInternalPointer = p->pListNext;
- }
- ht->nNumOfElements--;
- if (ht->pDestructor) {
- ht->pDestructor(p->pData);
- }
- if (p->pData != &p->pDataPtr) {
- pefree(p->pData, ht->persistent);
- }
- pefree(p, ht->persistent);
- HANDLE_UNBLOCK_INTERRUPTIONS();
+ i_zend_hash_bucket_delete(ht, p);
return SUCCESS;
}
p = p->pNext;
}
}
-/* This function is used by the various apply() functions.
- * It deletes the passed bucket.
- */
-static void zend_hash_apply_deleter(HashTable *ht, Bucket *p)
-{
-#ifdef ZEND_SIGNALS
- TSRMLS_FETCH();
-#endif
-
- HANDLE_BLOCK_INTERRUPTIONS();
- if (p->pLast) {
- p->pLast->pNext = p->pNext;
- } else {
- uint nIndex;
-
- nIndex = p->h & ht->nTableMask;
- 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;
- } else {
- /* Deleting the head of the list */
- ht->pListHead = p->pListNext;
- }
- if (p->pListNext != NULL) {
- p->pListNext->pListLast = p->pListLast;
- } else {
- ht->pListTail = p->pListLast;
- }
- if (ht->pInternalPointer == p) {
- ht->pInternalPointer = p->pListNext;
- }
- ht->nNumOfElements--;
- HANDLE_UNBLOCK_INTERRUPTIONS();
-
- if (ht->pDestructor) {
- ht->pDestructor(p->pData);
- }
- if (p->pData != &p->pDataPtr) {
- pefree(p->pData, ht->persistent);
- }
- pefree(p, ht->persistent);
-}
-
-
ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
{
IS_CONSISTENT(ht);
while (ht->pListHead != NULL) {
- zend_hash_apply_deleter(ht, ht->pListHead);
+ zend_hash_bucket_delete(ht, ht->pListHead);
}
if (ht->nTableMask) {
IS_CONSISTENT(ht);
while (ht->pListTail != NULL) {
- zend_hash_apply_deleter(ht, ht->pListTail);
+ zend_hash_bucket_delete(ht, ht->pListTail);
}
if (ht->nTableMask) {
Bucket *p_next = p->pListNext;
if (result & ZEND_HASH_APPLY_REMOVE) {
- zend_hash_apply_deleter(ht, p);
+ zend_hash_bucket_delete(ht, p);
}
p = p_next;
Bucket *p_next = p->pListNext;
if (result & ZEND_HASH_APPLY_REMOVE) {
- zend_hash_apply_deleter(ht, p);
+ zend_hash_bucket_delete(ht, p);
}
p = p_next;
Bucket *p_next = p->pListNext;
if (result & ZEND_HASH_APPLY_REMOVE) {
- zend_hash_apply_deleter(ht, p);
+ zend_hash_bucket_delete(ht, p);
}
p = p_next;
Bucket *p_last = p->pListLast;
if (result & ZEND_HASH_APPLY_REMOVE) {
- zend_hash_apply_deleter(ht, p);
+ zend_hash_bucket_delete(ht, p);
}
p = p_last;
return FAILURE;
}
- HANDLE_BLOCK_INTERRUPTIONS();
-
if (q) {
if (mode != HASH_UPDATE_KEY_ANYWAY) {
Bucket *r = p->pListLast;
}
if (mode & found) {
/* delete current bucket */
- if (p == ht->arBuckets[p->h & ht->nTableMask]) {
- ht->arBuckets[p->h & ht->nTableMask] = p->pNext;
- } else {
- p->pLast->pNext = p->pNext;
- }
- if (p->pNext) {
- p->pNext->pLast = p->pLast;
- }
- if (p->pListLast != NULL) {
- p->pListLast->pListNext = p->pListNext;
- } else {
- /* Deleting the head of the list */
- ht->pListHead = p->pListNext;
- }
- if (p->pListNext != NULL) {
- p->pListNext->pListLast = p->pListLast;
- } else {
- ht->pListTail = p->pListLast;
- }
- if (ht->pInternalPointer == p) {
- ht->pInternalPointer = p->pListNext;
- }
- ht->nNumOfElements--;
- if (ht->pDestructor) {
- ht->pDestructor(p->pData);
- }
- if (p->pData != &p->pDataPtr) {
- pefree(p->pData, ht->persistent);
- }
- pefree(p, ht->persistent);
- HANDLE_UNBLOCK_INTERRUPTIONS();
+ zend_hash_bucket_delete(ht, p);
return FAILURE;
}
}
+
/* delete another bucket with the same key */
- if (q == ht->arBuckets[q->h & ht->nTableMask]) {
- ht->arBuckets[q->h & ht->nTableMask] = q->pNext;
- } else {
- q->pLast->pNext = q->pNext;
- }
- if (q->pNext) {
- q->pNext->pLast = q->pLast;
- }
- if (q->pListLast != NULL) {
- q->pListLast->pListNext = q->pListNext;
- } else {
- /* Deleting the head of the list */
- ht->pListHead = q->pListNext;
- }
- if (q->pListNext != NULL) {
- q->pListNext->pListLast = q->pListLast;
- } else {
- ht->pListTail = q->pListLast;
- }
- if (ht->pInternalPointer == q) {
- ht->pInternalPointer = q->pListNext;
- }
- ht->nNumOfElements--;
- if (ht->pDestructor) {
- ht->pDestructor(q->pData);
- }
- if (q->pData != &q->pDataPtr) {
- pefree(q->pData, ht->persistent);
- }
- pefree(q, ht->persistent);
+ zend_hash_bucket_delete(ht, q);
}
+ HANDLE_BLOCK_INTERRUPTIONS();
+
if (p->pNext) {
p->pNext->pLast = p->pLast;
}