PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_HEAD/Zend - zend_hash.h
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 20
Code covered: 100.0 % Executed lines: 20
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2009 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: zend_hash.h 281221 2009-05-27 11:58:44Z dsp $ */
      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_NON_EXISTANT   IS_NULL
      29                 : #define HASH_KEY_IS_LONG                IS_LONG
      30                 : #define HASH_KEY_IS_STRING              IS_STRING
      31                 : #define HASH_KEY_IS_UNICODE             IS_UNICODE
      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 _key {
      56                 :         zend_uchar type;
      57                 :         union {
      58                 :                 char  s[1];   /* Must be last element */
      59                 :                 UChar u[1];   /* Must be last element */
      60                 :         } arKey;
      61                 : } HashKey;
      62                 : 
      63                 : typedef struct bucket {
      64                 :         ulong h;                                                /* Used for numeric indexing */
      65                 :         uint nKeyLength;
      66                 :         void *pData;
      67                 :         void *pDataPtr;
      68                 :         struct bucket *pListNext;
      69                 :         struct bucket *pListLast;
      70                 :         struct bucket *pNext;
      71                 :         struct bucket *pLast;
      72                 :         HashKey key; /* Must be last element */
      73                 : } Bucket;
      74                 : 
      75                 : typedef struct _hashtable {
      76                 :         uint nTableSize;
      77                 :         uint nTableMask;
      78                 :         uint nNumOfElements;
      79                 :         ulong nNextFreeElement;
      80                 :         Bucket *pInternalPointer;       /* Used for element traversal */
      81                 :         Bucket *pListHead;
      82                 :         Bucket *pListTail;
      83                 :         Bucket **arBuckets;
      84                 :         dtor_func_t pDestructor;
      85                 :         zend_bool persistent;
      86                 :         zend_bool unicode;
      87                 :         unsigned char nApplyCount;
      88                 :         zend_bool bApplyProtection;
      89                 : #if ZEND_DEBUG
      90                 :         int inconsistent;
      91                 : #endif
      92                 : } HashTable;
      93                 : 
      94                 : 
      95                 : typedef struct _zend_hash_key {
      96                 :         ulong h;
      97                 :         uint nKeyLength;
      98                 :         zend_uchar type;
      99                 :         zstr arKey;
     100                 : } zend_hash_key;
     101                 : 
     102                 : 
     103                 : typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, void *source_data, zend_hash_key *hash_key, void *pParam);
     104                 : 
     105                 : typedef Bucket* HashPosition;
     106                 : 
     107                 : BEGIN_EXTERN_C()
     108                 : 
     109                 : /* startup/shutdown */
     110                 : ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
     111                 : ZEND_API int _zend_u_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool unicode ZEND_FILE_LINE_DC);
     112                 : ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
     113                 : ZEND_API int _zend_u_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool unicode, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
     114                 : ZEND_API void zend_hash_destroy(HashTable *ht);
     115                 : ZEND_API void zend_hash_clean(HashTable *ht);
     116                 : #define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)                                               _zend_hash_init((ht), (nSize), (pHashFunction), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
     117                 : #define zend_u_hash_init(ht, nSize, pHashFunction, pDestructor, persistent, unicode)                                            _zend_u_hash_init((ht), (nSize), (pHashFunction), (pDestructor), (persistent), (unicode) ZEND_FILE_LINE_CC)
     118                 : #define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection)          _zend_hash_init_ex((ht), (nSize), (pHashFunction), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC)
     119                 : #define zend_u_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, unicode, bApplyProtection)               _zend_u_hash_init_ex((ht), (nSize), (pHashFunction), (pDestructor), (persistent), (unicode), (bApplyProtection) ZEND_FILE_LINE_CC)
     120                 : 
     121                 : /* additions/updates/changes */
     122                 : 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);
     123                 : ZEND_API int _zend_ascii_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
     124                 : ZEND_API int _zend_rt_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
     125                 : ZEND_API int _zend_utf8_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
     126                 : ZEND_API int _zend_u_hash_add_or_update(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
     127                 : #define zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     128                 :                 _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     129                 : #define zend_ascii_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     130                 :                 _zend_ascii_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     131                 : #define zend_rt_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     132                 :                 _zend_rt_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     133                 : #define zend_utf8_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     134                 :                 _zend_utf8_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     135                 : #define zend_u_hash_update(ht, type, arKey, nKeyLength, pData, nDataSize, pDest) \
     136                 :                 _zend_u_hash_add_or_update(ht, type, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     137                 : #define zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     138                 :                 _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     139                 : #define zend_ascii_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     140                 :                 _zend_ascii_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     141                 : #define zend_rt_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     142                 :                 _zend_rt_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     143                 : #define zend_utf8_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
     144                 :                 _zend_utf8_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     145                 : #define zend_u_hash_add(ht, type, arKey, nKeyLength, pData, nDataSize, pDest) \
     146                 :                 _zend_u_hash_add_or_update(ht, type, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     147                 : 
     148                 : 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);
     149                 : ZEND_API int _zend_u_hash_quick_add_or_update(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
     150                 : #define zend_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
     151                 :                 _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     152                 : #define zend_u_hash_quick_update(ht, type, arKey, nKeyLength, h, pData, nDataSize, pDest) \
     153                 :                 _zend_u_hash_quick_add_or_update(ht, type, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     154                 : #define zend_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
     155                 :                 _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     156                 : #define zend_u_hash_quick_add(ht, type, arKey, nKeyLength, h, pData, nDataSize, pDest) \
     157                 :                 _zend_u_hash_quick_add_or_update(ht, type, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
     158                 : 
     159                 : 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);
     160                 : #define zend_hash_index_update(ht, h, pData, nDataSize, pDest) \
     161                 :                 _zend_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
     162                 : #define zend_hash_next_index_insert(ht, pData, nDataSize, pDest) \
     163                 :                 _zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
     164                 : 
     165                 : ZEND_API int zend_hash_add_empty_element(HashTable *ht, const char *arKey, uint nKeyLength);
     166                 : ZEND_API int zend_u_hash_add_empty_element(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength);
     167                 : 
     168                 : 
     169                 : #define ZEND_HASH_APPLY_KEEP                            0
     170                 : #define ZEND_HASH_APPLY_REMOVE                          1<<0
     171                 : #define ZEND_HASH_APPLY_STOP                            1<<1
     172                 : 
     173                 : 
     174                 : typedef int (*apply_func_t)(void *pDest TSRMLS_DC);
     175                 : typedef int (*apply_func_arg_t)(void *pDest, void *argument TSRMLS_DC);
     176                 : typedef int (*apply_func_args_t)(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
     177                 : 
     178                 : ZEND_API void zend_hash_graceful_destroy(HashTable *ht);
     179                 : ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht);
     180                 : ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC);
     181                 : ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void * TSRMLS_DC);
     182                 : ZEND_API void zend_hash_apply_with_arguments(HashTable *ht TSRMLS_DC, apply_func_args_t apply_func, int, ...);
     183                 : 
     184                 : /* This function should be used with special care (in other words,
     185                 :  * it should usually not be used).  When used with the ZEND_HASH_APPLY_STOP
     186                 :  * return value, it assumes things about the order of the elements in the hash.
     187                 :  * Also, it does not provide the same kind of reentrancy protection that
     188                 :  * the standard apply functions do.
     189                 :  */
     190                 : ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC);
     191                 : 
     192                 : ZEND_API void zend_hash_to_unicode(HashTable *ht, apply_func_t apply_func TSRMLS_DC);
     193                 : 
     194                 : /* Deletes */
     195                 : ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag);
     196                 : ZEND_API int zend_ascii_hash_del(HashTable *ht, const char *arKey, uint nKeyLength);
     197                 : ZEND_API int zend_rt_hash_del(HashTable *ht, const char *arKey, uint nKeyLength);
     198                 : ZEND_API int zend_utf8_hash_del(HashTable *ht, const char *arKey, uint nKeyLength);
     199                 : ZEND_API int zend_u_hash_del_key_or_index(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, ulong h, int flag);
     200                 : #define zend_hash_del(ht, arKey, nKeyLength) \
     201                 :                 zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
     202                 : #define zend_hash_quick_del(ht, arKey, nKeyLength, h) \
     203                 :                 zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)
     204                 : #define zend_u_hash_del(ht, type, arKey, nKeyLength) \
     205                 :                 zend_u_hash_del_key_or_index(ht, type, arKey, nKeyLength, 0, HASH_DEL_KEY)
     206                 : #define zend_u_hash_quick_del(ht, type, arKey, nKeyLength, h) \
     207                 :                 zend_u_hash_del_key_or_index(ht, type, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)
     208                 : #define zend_hash_index_del(ht, h) \
     209                 :                 zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
     210                 : 
     211                 : ZEND_API ulong zend_get_hash_value(const char *arKey, uint nKeyLength);
     212                 : ZEND_API ulong zend_u_get_hash_value(zend_uchar type, zstr arKey, uint nKeyLength);
     213                 : 
     214                 : /* Data retreival */
     215                 : ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     216                 : ZEND_API int zend_ascii_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     217                 : ZEND_API int zend_rt_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     218                 : ZEND_API int zend_utf8_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     219                 : ZEND_API int zend_u_hash_find(const HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, void **pData);
     220                 : ZEND_API int zend_hash_quick_find(const HashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData);
     221                 : ZEND_API int zend_u_hash_quick_find(const HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, ulong h, void **pData);
     222                 : ZEND_API int zend_hash_index_find(const HashTable *ht, ulong h, void **pData);
     223                 : 
     224                 : /* Misc */
     225                 : ZEND_API int zend_hash_exists(const HashTable *ht, const char *arKey, uint nKeyLength);
     226                 : ZEND_API int zend_ascii_hash_exists(HashTable *ht, const char *arKey, uint nKeyLength);
     227                 : ZEND_API int zend_rt_hash_exists(HashTable *ht, const char *arKey, uint nKeyLength);
     228                 : ZEND_API int zend_utf8_hash_exists(HashTable *ht, const char *arKey, uint nKeyLength);
     229                 : ZEND_API int zend_u_hash_exists(const HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength);
     230                 : ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h);
     231                 : ZEND_API int zend_u_hash_quick_exists(const HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, ulong h);
     232                 : ZEND_API int zend_hash_index_exists(const HashTable *ht, ulong h);
     233                 : ZEND_API ulong zend_hash_next_free_element(const HashTable *ht);
     234                 : 
     235                 : 
     236                 : /* traversing */
     237                 : #define zend_hash_has_more_elements_ex(ht, pos) \
     238                 :         (zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTANT ? FAILURE : SUCCESS)
     239                 : ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
     240                 : ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
     241                 : ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, zstr *str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
     242                 : ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
     243                 : ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
     244                 : ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
     245                 : ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
     246                 : ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, zstr str_index, uint str_length, ulong num_index, int mode, HashPosition *pos);
     247                 : 
     248                 : typedef struct _HashPointer {
     249                 :         HashPosition pos;
     250                 :         ulong h;
     251                 : } HashPointer;
     252                 : 
     253                 : ZEND_API int zend_hash_get_pointer(const HashTable *ht, HashPointer *ptr);
     254                 : ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
     255                 : 
     256                 : #define zend_hash_has_more_elements(ht) \
     257                 :         zend_hash_has_more_elements_ex(ht, NULL)
     258                 : #define zend_hash_move_forward(ht) \
     259                 :         zend_hash_move_forward_ex(ht, NULL)
     260                 : #define zend_hash_move_backwards(ht) \
     261                 :         zend_hash_move_backwards_ex(ht, NULL)
     262                 : #define zend_hash_get_current_key(ht, str_index, num_index, duplicate) \
     263                 :         zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
     264                 : #define zend_hash_get_current_key_type(ht) \
     265                 :         zend_hash_get_current_key_type_ex(ht, NULL)
     266                 : #define zend_hash_get_current_data(ht, pData) \
     267                 :         zend_hash_get_current_data_ex(ht, pData, NULL)
     268                 : #define zend_hash_internal_pointer_reset(ht) \
     269                 :         zend_hash_internal_pointer_reset_ex(ht, NULL)
     270                 : #define zend_hash_internal_pointer_end(ht) \
     271                 :         zend_hash_internal_pointer_end_ex(ht, NULL)
     272                 : #define zend_hash_update_current_key(ht, key_type, str_index, str_length, num_index) \
     273                 :         zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, HASH_UPDATE_KEY_ANYWAY, NULL)
     274                 : 
     275                 : /* Copying, merging and sorting */
     276                 : ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
     277                 : 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);
     278                 : 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);
     279                 : ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);
     280                 : ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC);
     281                 : ZEND_API int zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC);
     282                 : 
     283                 : #define zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite)                                 \
     284                 :         _zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite ZEND_FILE_LINE_CC)
     285                 : 
     286                 : ZEND_API int zend_hash_num_elements(const HashTable *ht);
     287                 : 
     288                 : ZEND_API int zend_hash_rehash(HashTable *ht);
     289                 : 
     290                 : /*
     291                 :  * DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
     292                 :  *
     293                 :  * This is Daniel J. Bernstein's popular `times 33' hash function as
     294                 :  * posted by him years ago on comp.lang.c. It basically uses a function
     295                 :  * like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
     296                 :  * known hash functions for strings. Because it is both computed very
     297                 :  * fast and distributes very well.
     298                 :  *
     299                 :  * The magic of number 33, i.e. why it works better than many other
     300                 :  * constants, prime or not, has never been adequately explained by
     301                 :  * anyone. So I try an explanation: if one experimentally tests all
     302                 :  * multipliers between 1 and 256 (as RSE did now) one detects that even
     303                 :  * numbers are not useable at all. The remaining 128 odd numbers
     304                 :  * (except for the number 1) work more or less all equally well. They
     305                 :  * all distribute in an acceptable way and this way fill a hash table
     306                 :  * with an average percent of approx. 86%.
     307                 :  *
     308                 :  * If one compares the Chi^2 values of the variants, the number 33 not
     309                 :  * even has the best value. But the number 33 and a few other equally
     310                 :  * good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
     311                 :  * advantage to the remaining numbers in the large set of possible
     312                 :  * multipliers: their multiply operation can be replaced by a faster
     313                 :  * operation based on just one shift plus either a single addition
     314                 :  * or subtraction operation. And because a hash function has to both
     315                 :  * distribute good _and_ has to be very fast to compute, those few
     316                 :  * numbers should be preferred and seems to be the reason why Daniel J.
     317                 :  * Bernstein also preferred it.
     318                 :  *
     319                 :  *
     320                 :  *                  -- Ralf S. Engelschall <rse@engelschall.com>
     321                 :  */
     322                 : 
     323                 : static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
     324       185150627 : {
     325       185150627 :         register ulong hash = 5381;
     326                 : 
     327                 :         /* variant with the hash unrolled eight times */
     328       748230672 :         for (; nKeyLength >= 8; nKeyLength -= 8) {
     329       563080045 :                 hash = ((hash << 5) + hash) + *arKey++;
     330       563080045 :                 hash = ((hash << 5) + hash) + *arKey++;
     331       563080045 :                 hash = ((hash << 5) + hash) + *arKey++;
     332       563080045 :                 hash = ((hash << 5) + hash) + *arKey++;
     333       563080045 :                 hash = ((hash << 5) + hash) + *arKey++;
     334       563080045 :                 hash = ((hash << 5) + hash) + *arKey++;
     335       563080045 :                 hash = ((hash << 5) + hash) + *arKey++;
     336       563080045 :                 hash = ((hash << 5) + hash) + *arKey++;
     337                 :         }
     338       185150627 :         switch (nKeyLength) {
     339         2561275 :                 case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     340        42820891 :                 case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     341        49888057 :                 case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     342        92070429 :                 case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     343        94674812 :                 case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     344       134903593 :                 case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
     345       138134884 :                 case 1: hash = ((hash << 5) + hash) + *arKey++; break;
     346                 :                 case 0: break;
     347                 : EMPTY_SWITCH_DEFAULT_CASE()
     348                 :         }
     349       185150627 :         return hash;
     350                 : }
     351                 : 
     352                 : #define zend_u_inline_hash_func(type, arKey, nKeyLength) \
     353                 :         zend_inline_hash_func(arKey.s, USTR_BYTES(type, nKeyLength))
     354                 : 
     355                 : #define zend_hash_func(arKey, nKeyLength) zend_get_hash_value(arKey, nKeyLength)
     356                 : #define zend_u_hash_func(type, arKey, nKeyLength) zend_u_get_hash_value(type, arKey, nKeyLength)
     357                 : 
     358                 : #if ZEND_DEBUG
     359                 : /* debug */
     360                 : void zend_hash_display_pListTail(const HashTable *ht);
     361                 : void zend_hash_display(const HashTable *ht);
     362                 : #endif
     363                 : 
     364                 : END_EXTERN_C()
     365                 : 
     366                 : #define ZEND_INIT_SYMTABLE(ht)                                                          \
     367                 :         ZEND_INIT_SYMTABLE_EX(ht, 2, 0)
     368                 : 
     369                 : #define ZEND_INIT_SYMTABLE_EX(ht, n, persistent)                        \
     370                 :         zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
     371                 : 
     372                 : 
     373                 : ZEND_API int zend_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest);
     374                 : ZEND_API int zend_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength);
     375                 : ZEND_API int zend_symtable_find(HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     376                 : ZEND_API int zend_symtable_exists(HashTable *ht, const char *arKey, uint nKeyLength);
     377                 : ZEND_API int zend_symtable_update_current_key_ex(HashTable *ht, const char *arKey, uint nKeyLength, int mode, HashPosition *pos);
     378                 : #define zend_symtable_update_current_key(ht,arKey,nKeyLength,mode) \
     379                 :         zend_symtable_update_current_key_ex(ht, arKey, nKeyLength, mode, NULL)
     380                 : 
     381                 : ZEND_API int zend_ascii_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest);
     382                 : ZEND_API int zend_ascii_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength);
     383                 : ZEND_API int zend_ascii_symtable_find(HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     384                 : ZEND_API int zend_ascii_symtable_exists(HashTable *ht, const char *arKey, uint nKeyLength);
     385                 : 
     386                 : ZEND_API int zend_rt_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest);
     387                 : ZEND_API int zend_rt_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength);
     388                 : ZEND_API int zend_rt_symtable_find(HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     389                 : ZEND_API int zend_rt_symtable_exists(HashTable *ht, const char *arKey, uint nKeyLength);
     390                 : 
     391                 : ZEND_API int zend_utf8_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest);
     392                 : ZEND_API int zend_utf8_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength);
     393                 : ZEND_API int zend_utf8_symtable_find(HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
     394                 : ZEND_API int zend_utf8_symtable_exists(HashTable *ht, const char *arKey, uint nKeyLength);
     395                 : 
     396                 : ZEND_API int zend_u_symtable_update(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest);
     397                 : ZEND_API int zend_u_symtable_del(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength);
     398                 : ZEND_API int zend_u_symtable_find(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, void **pData);
     399                 : ZEND_API int zend_u_symtable_exists(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength);
     400                 : ZEND_API int zend_u_symtable_update_current_key_ex(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, int mode, HashPosition *pos);
     401                 : #define zend_u_symtable_update_current_key(ht,type,arKey,nKeyLength,mode) \
     402                 :         zend_u_symtable_update_current_key_ex(ht, type, arKey, nKeyLength, mode, NULL)
     403                 : 
     404                 : /* {{{ ZEND_HANDLE_*_NUMERIC macros */
     405                 : #define ZEND_HANDLE_NUMERIC(key, length, func) do {                                                     \
     406                 :         register const char *tmp = key;                                                                                 \
     407                 :                                                                                                                                                         \
     408                 :         if (*tmp == '-') {                                                                                                              \
     409                 :                 tmp++;                                                                                                                          \
     410                 :         }                                                                                                                                               \
     411                 :         if (*tmp >= '0' && *tmp <= '9') { /* possibly a numeric index */          \
     412                 :                 const char *end = key + length - 1;                                                                     \
     413                 :                 long idx;                                                                                                                       \
     414                 :                                                                                                                                                         \
     415                 :                 if ((*end != '\0') /* not a null terminated string */                           \
     416                 :                  || (*tmp == '0' && length > 2) /* numbers with leading zeros */     \
     417                 :                  || (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */               \
     418                 :                  || (SIZEOF_LONG == 4 &&                                                                                        \
     419                 :                      end - tmp == MAX_LENGTH_OF_LONG - 1 &&                                                     \
     420                 :                      *tmp > '2')) { /* overflow */                                                                   \
     421                 :                         break;                                                                                                                  \
     422                 :                 }                                                                                                                                       \
     423                 :                 idx = (*tmp - '0');                                                                                                     \
     424                 :                 while (++tmp != end && *tmp >= '0' && *tmp <= '9') {                              \
     425                 :                         idx = (idx * 10) + (*tmp - '0');                                                                \
     426                 :                 }                                                                                                                                       \
     427                 :                 if (tmp == end) {                                                                                                       \
     428                 :                         if (*key == '-') {                                                                                              \
     429                 :                                 idx = -idx;                                                                                                     \
     430                 :                                 if (idx > 0) { /* overflow */                                                                \
     431                 :                                         break;                                                                                                  \
     432                 :                                 }                                                                                                                       \
     433                 :                         } else if (idx < 0) { /* overflow */                                                 \
     434                 :                                 break;                                                                                                          \
     435                 :                         }                                                                                                                               \
     436                 :                         return func;                                                                                                    \
     437                 :                 }                                                                                                                                       \
     438                 :         }                                                                                                                                               \
     439                 : } while (0)
     440                 : 
     441                 : #define ZEND_HANDLE_U_NUMERIC(key, length, func) do {                                           \
     442                 :         register const UChar *tmp = key;                                                                                \
     443                 :                                                                                                                                                         \
     444                 :         if (*tmp == 0x2D /*'-'*/ ) {                                                                                    \
     445                 :                 tmp++;                                                                                                                          \
     446                 :         }                                                                                                                                               \
     447                 :         if (*tmp >= 0x30 /*'0'*/ && *tmp <= 0x39 /*'9'*/) {                                               \
     448                 :                 /* possibly a numeric index */                                                                          \
     449                 :                 const UChar *end = key + length - 1;                                                            \
     450                 :                 long idx;                                                                                                                       \
     451                 :                                                                                                                                                         \
     452                 :                 if ((*end != 0) /* not a null terminated string */                                      \
     453                 :                  || (*tmp == 0x30 && length > 2) /* numbers with leading zeros */    \
     454                 :                  || (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */               \
     455                 :                  || (SIZEOF_LONG == 4 &&                                                                                        \
     456                 :                      end - tmp == MAX_LENGTH_OF_LONG - 1 &&                                                     \
     457                 :                      *tmp > 0x32 /*'2'*/)) { /* overflow */                                                  \
     458                 :                         break;                                                                                                                  \
     459                 :                 }                                                                                                                                       \
     460                 :                 idx = (*tmp - '0');                                                                                                     \
     461                 :                 while (++tmp != end && *tmp >= 0x30 && *tmp <= 0x39) {                            \
     462                 :                         idx = (idx * 10) + (*tmp - 0x30);                                                               \
     463                 :                 }                                                                                                                                       \
     464                 :                 if (tmp == end) {                                                                                                       \
     465                 :                         if (*key == 0x2D) {                                                                                             \
     466                 :                                 idx = -idx;                                                                                                     \
     467                 :                                 if (idx > 0) { /* overflow */                                                                \
     468                 :                                         break;                                                                                                  \
     469                 :                                 }                                                                                                                       \
     470                 :                         } else if (idx < 0) { /* overflow */                                                 \
     471                 :                                 break;                                                                                                          \
     472                 :                         }                                                                                                                               \
     473                 :                         return func;                                                                                                    \
     474                 :                 }                                                                                                                                       \
     475                 :         }                                                                                                                                               \
     476                 : } while (0)
     477                 : /* }}} */
     478                 : 
     479                 : #endif                                                  /* ZEND_HASH_H */
     480                 : 
     481                 : /*
     482                 :  * Local variables:
     483                 :  * tab-width: 4
     484                 :  * c-basic-offset: 4
     485                 :  * indent-tabs-mode: t
     486                 :  * End:
     487                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:23 +0000 (36 hours ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.