]> granicus.if.org Git - php/commitdiff
Add only_integer_keys option to zend_hash_reindex
authorNikita Popov <nikic@php.net>
Wed, 9 Apr 2014 09:20:55 +0000 (11:20 +0200)
committerNikita Popov <nikic@php.net>
Wed, 9 Apr 2014 10:31:21 +0000 (12:31 +0200)
This allows to either do a full reindex, or only reindex the integer
keys.

Zend/zend_hash.c
Zend/zend_hash.h
ext/standard/array.c

index a33e8726e28a102e50395b8a4b188641a5c342f0..309631338a49787ba0d148eca3698a489884283f 100644 (file)
@@ -480,7 +480,7 @@ ZEND_API int zend_hash_rehash(HashTable *ht)
        return SUCCESS;
 }
 
-ZEND_API void zend_hash_reindex(HashTable *ht) {
+ZEND_API void zend_hash_reindex(HashTable *ht, zend_bool only_integer_keys) {
        Bucket *p;
        uint nIndex;
        ulong offset = 0;
@@ -492,8 +492,9 @@ ZEND_API void zend_hash_reindex(HashTable *ht) {
 
        memset(ht->arBuckets, 0, ht->nTableSize * sizeof(Bucket *));
        for (p = ht->pListHead; p != NULL; p = p->pListNext) {
-               if (p->nKeyLength == 0) {
+               if (!only_integer_keys || p->nKeyLength == 0) {
                        p->h = offset++;
+                       p->nKeyLength = 0;
                }
 
                nIndex = p->h & ht->nTableMask;
@@ -1353,7 +1354,7 @@ ZEND_API void _zend_hash_splice(HashTable *ht, uint nDataSize, copy_ctor_func_t
                ZEND_HASH_IF_FULL_DO_RESIZE(ht);
        }
 
-       zend_hash_reindex(ht);
+       zend_hash_reindex(ht, 1);
 }
 /* }}} */
 
@@ -1403,15 +1404,7 @@ ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func,
        HANDLE_UNBLOCK_INTERRUPTIONS();
 
        if (renumber) {
-               p = ht->pListHead;
-               i=0;
-               while (p != NULL) {
-                       p->nKeyLength = 0;
-                       p->h = i++;
-                       p = p->pListNext;
-               }
-               ht->nNextFreeElement = i;
-               zend_hash_rehash(ht);
+               zend_hash_reindex(ht, 0);
        }
        return SUCCESS;
 }
index b07efc84ecb5f4381439f9005581bc051e725d4a..03f83dfb18061c2ddcdc431a4ea0a6011157f36e 100644 (file)
@@ -227,7 +227,7 @@ ZEND_API int zend_hash_minmax(const HashTable *ht, compare_func_t compar, int fl
 ZEND_API int zend_hash_num_elements(const HashTable *ht);
 
 ZEND_API int zend_hash_rehash(HashTable *ht);
-ZEND_API void zend_hash_reindex(HashTable *ht);
+ZEND_API void zend_hash_reindex(HashTable *ht, zend_bool only_integer_keys);
 
 ZEND_API void _zend_hash_splice(HashTable *ht, uint nDataSize, copy_ctor_func_t pCopyConstructor, uint offset, uint length, void **list, uint list_count, HashTable *removed ZEND_FILE_LINE_DC);
 #define zend_hash_splice(ht, nDataSize, pCopyConstructor, offset, length, list, list_count, removed) \
index 7b2b1c5589cb0ca722176eeb1d2b89df18ee23f9..6c3be814cb9a234b0afb81ebb4938eaaa939d2d3 100644 (file)
@@ -1786,13 +1786,7 @@ static void php_array_data_shuffle(zval *array TSRMLS_DC) /* {{{ */
        }
        temp = hash->pListHead;
        j = 0;
-       while (temp != NULL) {
-               temp->nKeyLength = 0;
-               temp->h = j++;
-               temp = temp->pListNext;
-       }
-       hash->nNextFreeElement = n_elems;
-       zend_hash_rehash(hash);
+       zend_hash_reindex(hash, 0);
        HANDLE_UNBLOCK_INTERRUPTIONS();
 
        efree(elems);
@@ -1897,7 +1891,7 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
 
        /* If we did a shift... re-index like it did before */
        if (!off_the_end) {
-               zend_hash_reindex(Z_ARRVAL_P(stack));
+               zend_hash_reindex(Z_ARRVAL_P(stack), 1);
        } else if (!key_len && index >= Z_ARRVAL_P(stack)->nNextFreeElement - 1) {
                Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1;
        }
@@ -3848,15 +3842,7 @@ PHP_FUNCTION(array_multisort)
                        hash->pListTail = indirect[k][i];
                }
 
-               p = hash->pListHead;
-               k = 0;
-               while (p != NULL) {
-                       if (p->nKeyLength == 0)
-                               p->h = k++;
-                       p = p->pListNext;
-               }
-               hash->nNextFreeElement = array_size;
-               zend_hash_rehash(hash);
+               zend_hash_reindex(hash, 1);
        }
        HANDLE_UNBLOCK_INTERRUPTIONS();