LCOV - code coverage report
Current view: top level - Zend - zend_hash.h (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 12 12 100.0 %
Date: 2015-02-17 20:30:22 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2015 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        | 
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #ifndef ZEND_HASH_H
      23             : #define ZEND_HASH_H
      24             : 
      25             : #include <sys/types.h>
      26             : #include "zend.h"
      27             : 
      28             : #define HASH_KEY_IS_STRING 1
      29             : #define HASH_KEY_IS_LONG 2
      30             : #define HASH_KEY_NON_EXISTENT 3
      31             : #define HASH_KEY_NON_EXISTANT HASH_KEY_NON_EXISTENT /* Keeping old define (with typo) for backward compatibility */
      32             : 
      33             : #define HASH_UPDATE             (1<<0)
      34             : #define HASH_ADD                        (1<<1)
      35             : #define HASH_NEXT_INSERT        (1<<2)
      36             : 
      37             : #define HASH_DEL_KEY 0
      38             : #define HASH_DEL_INDEX 1
      39             : #define HASH_DEL_KEY_QUICK 2
      40             : 
      41             : #define HASH_UPDATE_KEY_IF_NONE    0
      42             : #define HASH_UPDATE_KEY_IF_BEFORE  1
      43             : #define HASH_UPDATE_KEY_IF_AFTER   2
      44             : #define HASH_UPDATE_KEY_ANYWAY     3
      45             : 
      46             : typedef ulong (*hash_func_t)(const char *arKey, uint nKeyLength);
      47             : typedef int  (*compare_func_t)(const void *, const void * TSRMLS_DC);
      48             : typedef void (*sort_func_t)(void *, size_t, register size_t, compare_func_t TSRMLS_DC);
      49             : typedef void (*dtor_func_t)(void *pDest);
      50             : typedef void (*copy_ctor_func_t)(void *pElement);
      51             : typedef void (*copy_ctor_param_func_t)(void *pElement, void *pParam);
      52             : 
      53             : struct _hashtable;
      54             : 
      55             : typedef struct bucket {
      56             :         ulong h;                                                /* Used for numeric indexing */
      57             :         uint nKeyLength;
      58             :         void *pData;
      59             :         void *pDataPtr;
      60             :         struct bucket *pListNext;
      61             :         struct bucket *pListLast;
      62             :         struct bucket *pNext;
      63             :         struct bucket *pLast;
      64             :         const char *arKey;
      65             : } Bucket;
      66             : 
      67             : typedef struct _hashtable {
      68             :         uint nTableSize;
      69             :         uint nTableMask;
      70             :         uint nNumOfElements;
      71             :         ulong nNextFreeElement;
      72             :         Bucket *pInternalPointer;       /* Used for element traversal */
      73             :         Bucket *pListHead;
      74             :         Bucket *pListTail;
      75             :         Bucket **arBuckets;
      76             :         dtor_func_t pDestructor;
      77             :         zend_bool persistent;
      78             :         unsigned char nApplyCount;
      79             :         zend_bool bApplyProtection;
      80             : #if ZEND_DEBUG
      81             :         int inconsistent;
      82             : #endif
      83             : } HashTable;
      84             : 
      85             : 
      86             : typedef struct _zend_hash_key {
      87             :         const char *arKey;
      88             :         uint nKeyLength;
      89             :         ulong h;
      90             : } zend_hash_key;
      91             : 
      92             : 
      93             : typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, void *source_data, zend_hash_key *hash_key, void *pParam);
      94             : 
      95             : typedef Bucket* HashPosition;
      96             : 
      97             : BEGIN_EXTERN_C()
      98             : 
      99             : /* startup/shutdown */
     100             : ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
     101             : ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
     102             : ZEND_API void zend_hash_destroy(HashTable *ht);
     103             : ZEND_API void zend_hash_clean(HashTable *ht);
     104             : #define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)                                               _zend_hash_init((ht), (nSize), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
     105             : #define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection)          _zend_hash_init_ex((ht), (nSize), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC)
     106             : 
     107             : /* additions/updates/changes */
     108             : ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
     109             : #define zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     110             :                 _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     111             : #define zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     112             :                 _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     113             : 
     114             : ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
     115             : #define zend_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
     116             :                 _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     117             : #define zend_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
     118             :                 _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     119             : 
     120             : ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
     121             : #define zend_hash_index_update(ht, h, pData, nDataSize, pDest) \
     122             :                 _zend_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     123             : #define zend_hash_next_index_insert(ht, pData, nDataSize, pDest) \
     124             :                 _zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
     125             : 
     126             : ZEND_API int zend_hash_add_empty_element(HashTable *ht, const char *arKey, uint nKeyLength);
     127             : 
     128             : 
     129             : #define ZEND_HASH_APPLY_KEEP                            0
     130             : #define ZEND_HASH_APPLY_REMOVE                          1<<0
     131             : #define ZEND_HASH_APPLY_STOP                            1<<1
     132             : 
     133             : typedef int (*apply_func_t)(void *pDest TSRMLS_DC);
     134             : typedef int (*apply_func_arg_t)(void *pDest, void *argument TSRMLS_DC);
     135             : typedef int (*apply_func_args_t)(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
     136             : 
     137             : ZEND_API void zend_hash_graceful_destroy(HashTable *ht);
     138             : ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht);
     139             : ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC);
     140             : ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void * TSRMLS_DC);
     141             : ZEND_API void zend_hash_apply_with_arguments(HashTable *ht TSRMLS_DC, apply_func_args_t apply_func, int, ...);
     142             : 
     143             : /* This function should be used with special care (in other words,
     144             :  * it should usually not be used).  When used with the ZEND_HASH_APPLY_STOP
     145             :  * return value, it assumes things about the order of the elements in the hash.
     146             :  * Also, it does not provide the same kind of reentrancy protection that
     147             :  * the standard apply functions do.
     148             :  */
     149             : ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC);
     150             : 
     151             : 
     152             : /* Deletes */
     153             : ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag);
     154             : #define zend_hash_del(ht, arKey, nKeyLength) \
     155             :                 zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
     156             : #define zend_hash_quick_del(ht, arKey, nKeyLength, h) \
     157             :                 zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)
     158             : #define zend_hash_index_del(ht, h) \
     159             :                 zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
     160             : #define zend_get_hash_value \
     161             :                 zend_hash_func
     162             : 
     163             : /* Data retreival */
     164             : ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     165             : ZEND_API int zend_hash_quick_find(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void **pData);
     166             : ZEND_API int zend_hash_index_find(const HashTable *ht, ulong h, void **pData);
     167             : 
     168             : /* Misc */
     169             : ZEND_API int zend_hash_exists(const HashTable *ht, const char *arKey, uint nKeyLength);
     170             : ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h);
     171             : ZEND_API int zend_hash_index_exists(const HashTable *ht, ulong h);
     172             : ZEND_API ulong zend_hash_next_free_element(const HashTable *ht);
     173             : 
     174             : /* traversing */
     175             : #define zend_hash_has_more_elements_ex(ht, pos) \
     176             :         (zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTENT ? FAILURE : SUCCESS)
     177             : ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
     178             : ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
     179             : ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
     180             : ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos);
     181             : ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
     182             : ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
     183             : ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
     184             : ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
     185             : ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, int mode, HashPosition *pos);
     186             : 
     187             : typedef struct _HashPointer {
     188             :         HashPosition pos;
     189             :         ulong h;
     190             : } HashPointer;
     191             : 
     192             : ZEND_API int zend_hash_get_pointer(const HashTable *ht, HashPointer *ptr);
     193             : ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
     194             : 
     195             : #define zend_hash_has_more_elements(ht) \
     196             :         zend_hash_has_more_elements_ex(ht, NULL)
     197             : #define zend_hash_move_forward(ht) \
     198             :         zend_hash_move_forward_ex(ht, NULL)
     199             : #define zend_hash_move_backwards(ht) \
     200             :         zend_hash_move_backwards_ex(ht, NULL)
     201             : #define zend_hash_get_current_key(ht, str_index, num_index, duplicate) \
     202             :         zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
     203             : #define zend_hash_get_current_key_zval(ht, key) \
     204             :         zend_hash_get_current_key_zval_ex(ht, key, NULL)
     205             : #define zend_hash_get_current_key_type(ht) \
     206             :         zend_hash_get_current_key_type_ex(ht, NULL)
     207             : #define zend_hash_get_current_data(ht, pData) \
     208             :         zend_hash_get_current_data_ex(ht, pData, NULL)
     209             : #define zend_hash_internal_pointer_reset(ht) \
     210             :         zend_hash_internal_pointer_reset_ex(ht, NULL)
     211             : #define zend_hash_internal_pointer_end(ht) \
     212             :         zend_hash_internal_pointer_end_ex(ht, NULL)
     213             : #define zend_hash_update_current_key(ht, key_type, str_index, str_length, num_index) \
     214             :         zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, HASH_UPDATE_KEY_ANYWAY, NULL)
     215             : 
     216             : /* Copying, merging and sorting */
     217             : ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
     218             : ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite ZEND_FILE_LINE_DC);
     219             : ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam);
     220             : ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);
     221             : ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC);
     222             : ZEND_API int zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC);
     223             : 
     224             : #define zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite)                                 \
     225             :         _zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite ZEND_FILE_LINE_CC)
     226             : 
     227             : ZEND_API int zend_hash_num_elements(const HashTable *ht);
     228             : 
     229             : ZEND_API int zend_hash_rehash(HashTable *ht);
     230             : ZEND_API void zend_hash_reindex(HashTable *ht, zend_bool only_integer_keys);
     231             : 
     232             : 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);
     233             : #define zend_hash_splice(ht, nDataSize, pCopyConstructor, offset, length, list, list_count, removed) \
     234             :         _zend_hash_splice(ht, nDataSize, pCopyConstructor, offset, length, list, list_count, removed ZEND_FILE_LINE_CC)
     235             : 
     236             : /*
     237             :  * DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
     238             :  *
     239             :  * This is Daniel J. Bernstein's popular `times 33' hash function as
     240             :  * posted by him years ago on comp.lang.c. It basically uses a function
     241             :  * like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
     242             :  * known hash functions for strings. Because it is both computed very
     243             :  * fast and distributes very well.
     244             :  *
     245             :  * The magic of number 33, i.e. why it works better than many other
     246             :  * constants, prime or not, has never been adequately explained by
     247             :  * anyone. So I try an explanation: if one experimentally tests all
     248             :  * multipliers between 1 and 256 (as RSE did now) one detects that even
     249             :  * numbers are not useable at all. The remaining 128 odd numbers
     250             :  * (except for the number 1) work more or less all equally well. They
     251             :  * all distribute in an acceptable way and this way fill a hash table
     252             :  * with an average percent of approx. 86%. 
     253             :  *
     254             :  * If one compares the Chi^2 values of the variants, the number 33 not
     255             :  * even has the best value. But the number 33 and a few other equally
     256             :  * good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
     257             :  * advantage to the remaining numbers in the large set of possible
     258             :  * multipliers: their multiply operation can be replaced by a faster
     259             :  * operation based on just one shift plus either a single addition
     260             :  * or subtraction operation. And because a hash function has to both
     261             :  * distribute good _and_ has to be very fast to compute, those few
     262             :  * numbers should be preferred and seems to be the reason why Daniel J.
     263             :  * Bernstein also preferred it.
     264             :  *
     265             :  *
     266             :  *                  -- Ralf S. Engelschall <rse@engelschall.com>
     267             :  */
     268             : 
     269             : static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
     270             : {
     271             :         register ulong hash = 5381;
     272             : 
     273             :         /* variant with the hash unrolled eight times */
     274             :         for (; nKeyLength >= 8; nKeyLength -= 8) {
     275             :                 hash = ((hash << 5) + hash) + *arKey++;
     276             :                 hash = ((hash << 5) + hash) + *arKey++;
     277             :                 hash = ((hash << 5) + hash) + *arKey++;
     278             :                 hash = ((hash << 5) + hash) + *arKey++;
     279             :                 hash = ((hash << 5) + hash) + *arKey++;
     280             :                 hash = ((hash << 5) + hash) + *arKey++;
     281             :                 hash = ((hash << 5) + hash) + *arKey++;
     282             :                 hash = ((hash << 5) + hash) + *arKey++;
     283             :         }
     284             :         switch (nKeyLength) {
     285             :                 case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     286             :                 case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     287             :                 case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     288             :                 case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     289             :                 case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     290             :                 case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     291             :                 case 1: hash = ((hash << 5) + hash) + *arKey++; break;
     292             :                 case 0: break;
     293             : EMPTY_SWITCH_DEFAULT_CASE()
     294             :         }
     295             :         return hash;
     296             : }
     297             : 
     298             : 
     299             : ZEND_API ulong zend_hash_func(const char *arKey, uint nKeyLength);
     300             : 
     301             : #if ZEND_DEBUG
     302             : /* debug */
     303             : void zend_hash_display_pListTail(const HashTable *ht);
     304             : void zend_hash_display(const HashTable *ht);
     305             : #endif
     306             : 
     307             : END_EXTERN_C()
     308             : 
     309             : #define ZEND_INIT_SYMTABLE(ht)                                                          \
     310             :         ZEND_INIT_SYMTABLE_EX(ht, 2, 0)
     311             : 
     312             : #define ZEND_INIT_SYMTABLE_EX(ht, n, persistent)                        \
     313             :         zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
     314             : 
     315             : #define ZEND_HANDLE_NUMERIC_EX(key, length, idx, func) do {                                     \
     316             :         register const char *tmp = key;                                                                                 \
     317             :                                                                                                                                                         \
     318             :         if (*tmp == '-') {                                                                                                              \
     319             :                 tmp++;                                                                                                                          \
     320             :         }                                                                                                                                               \
     321             :         if (*tmp >= '0' && *tmp <= '9') { /* possibly a numeric index */          \
     322             :                 const char *end = key + length - 1;                                                                     \
     323             :                                                                                                                                                         \
     324             :                 if ((*end != '\0') /* not a null terminated string */                           \
     325             :                  || (*tmp == '0' && length > 2) /* numbers with leading zeros */     \
     326             :                  || (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */               \
     327             :                  || (SIZEOF_LONG == 4 &&                                                                                        \
     328             :                      end - tmp == MAX_LENGTH_OF_LONG - 1 &&                                                     \
     329             :                      *tmp > '2')) { /* overflow */                                                                   \
     330             :                         break;                                                                                                                  \
     331             :                 }                                                                                                                                       \
     332             :                 idx = (*tmp - '0');                                                                                                     \
     333             :                 while (++tmp != end && *tmp >= '0' && *tmp <= '9') {                              \
     334             :                         idx = (idx * 10) + (*tmp - '0');                                                                \
     335             :                 }                                                                                                                                       \
     336             :                 if (tmp == end) {                                                                                                       \
     337             :                         if (*key == '-') {                                                                                              \
     338             :                                 if (idx-1 > LONG_MAX) { /* overflow */                                               \
     339             :                                         break;                                                                                                  \
     340             :                                 }                                                                                                                       \
     341             :                                 idx = 0 - idx;                                                                                  \
     342             :                         } else if (idx > LONG_MAX) { /* overflow */                                          \
     343             :                                 break;                                                                                                          \
     344             :                         }                                                                                                                               \
     345             :                         func;                                                                                                                   \
     346             :                 }                                                                                                                                       \
     347             :         }                                                                                                                                               \
     348             : } while (0)
     349             : 
     350             : #define ZEND_HANDLE_NUMERIC(key, length, func) do {                                                     \
     351             :         ulong idx;                                                                                                                              \
     352             :                                                                                                                                                         \
     353             :         ZEND_HANDLE_NUMERIC_EX(key, length, idx, return func);                                  \
     354             : } while (0)
     355             : 
     356        1500 : static inline int zend_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest)                                    \
     357             : {
     358        1500 :         ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update(ht, idx, pData, nDataSize, pDest));
     359        1478 :         return zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest);
     360             : }
     361             : 
     362             : 
     363           6 : static inline int zend_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength)
     364             : {
     365           6 :         ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_del(ht, idx));
     366           5 :         return zend_hash_del(ht, arKey, nKeyLength);
     367             : }
     368             : 
     369             : 
     370        2682 : static inline int zend_symtable_find(HashTable *ht, const char *arKey, uint nKeyLength, void **pData)
     371             : {
     372        2682 :         ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_find(ht, idx, pData));
     373        2677 :         return zend_hash_find(ht, arKey, nKeyLength, pData);
     374             : }
     375             : 
     376             : 
     377          17 : static inline int zend_symtable_exists(HashTable *ht, const char *arKey, uint nKeyLength)
     378             : {
     379          17 :         ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx));
     380          17 :         return zend_hash_exists(ht, arKey, nKeyLength);
     381             : }
     382             : 
     383             : static inline int zend_symtable_update_current_key_ex(HashTable *ht, const char *arKey, uint nKeyLength, int mode, HashPosition *pos)
     384             : {
     385             :         ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL, 0, idx, mode, pos));
     386             :         return zend_hash_update_current_key_ex(ht, HASH_KEY_IS_STRING, arKey, nKeyLength, 0, mode, pos);
     387             : }
     388             : #define zend_symtable_update_current_key(ht,arKey,nKeyLength,mode) \
     389             :         zend_symtable_update_current_key_ex(ht, arKey, nKeyLength, mode, NULL)
     390             : 
     391             : 
     392             : #endif                                                  /* ZEND_HASH_H */
     393             : 
     394             : /*
     395             :  * Local variables:
     396             :  * tab-width: 4
     397             :  * c-basic-offset: 4
     398             :  * indent-tabs-mode: t
     399             :  * End:
     400             :  */

Generated by: LCOV version 1.11