Back to index

php5  5.3.10
Classes | Defines | Typedefs | Functions
zend_hash.h File Reference
#include <sys/types.h>
#include "zend.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  bucket
struct  _hashtable
struct  _zend_hash_key
struct  _HashPointer

Defines

#define HASH_KEY_IS_STRING   1
#define HASH_KEY_IS_LONG   2
#define HASH_KEY_NON_EXISTANT   3
#define HASH_UPDATE   (1<<0)
#define HASH_ADD   (1<<1)
#define HASH_NEXT_INSERT   (1<<2)
#define HASH_DEL_KEY   0
#define HASH_DEL_INDEX   1
#define HASH_DEL_KEY_QUICK   2
#define HASH_UPDATE_KEY_IF_NONE   0
#define HASH_UPDATE_KEY_IF_BEFORE   1
#define HASH_UPDATE_KEY_IF_AFTER   2
#define HASH_UPDATE_KEY_ANYWAY   3
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)   _zend_hash_init((ht), (nSize), (pHashFunction), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
#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)
#define zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest)   _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest)   _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
#define zend_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest)   _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest)   _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
#define zend_hash_index_update(ht, h, pData, nDataSize, pDest)   _zend_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_next_index_insert(ht, pData, nDataSize, pDest)   _zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
#define ZEND_HASH_APPLY_KEEP   0
#define ZEND_HASH_APPLY_REMOVE   1<<0
#define ZEND_HASH_APPLY_STOP   1<<1
#define zend_hash_del(ht, arKey, nKeyLength)   zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
#define zend_hash_quick_del(ht, arKey, nKeyLength, h)   zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)
#define zend_hash_index_del(ht, h)   zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
#define zend_hash_has_more_elements_ex(ht, pos)   (zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTANT ? FAILURE : SUCCESS)
#define zend_hash_has_more_elements(ht)   zend_hash_has_more_elements_ex(ht, NULL)
#define zend_hash_move_forward(ht)   zend_hash_move_forward_ex(ht, NULL)
#define zend_hash_move_backwards(ht)   zend_hash_move_backwards_ex(ht, NULL)
#define zend_hash_get_current_key(ht, str_index, num_index, duplicate)   zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
#define zend_hash_get_current_key_type(ht)   zend_hash_get_current_key_type_ex(ht, NULL)
#define zend_hash_get_current_data(ht, pData)   zend_hash_get_current_data_ex(ht, pData, NULL)
#define zend_hash_internal_pointer_reset(ht)   zend_hash_internal_pointer_reset_ex(ht, NULL)
#define zend_hash_internal_pointer_end(ht)   zend_hash_internal_pointer_end_ex(ht, NULL)
#define zend_hash_update_current_key(ht, key_type, str_index, str_length, num_index)   zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, HASH_UPDATE_KEY_ANYWAY, NULL)
#define zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite)   _zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite ZEND_FILE_LINE_CC)
#define ZEND_INIT_SYMTABLE(ht)   ZEND_INIT_SYMTABLE_EX(ht, 2, 0)
#define ZEND_INIT_SYMTABLE_EX(ht, n, persistent)   zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
#define ZEND_HANDLE_NUMERIC(key, length, func)
#define zend_symtable_update_current_key(ht, arKey, nKeyLength, mode)   zend_symtable_update_current_key_ex(ht, arKey, nKeyLength, mode, NULL)

Typedefs

typedef ulong(* hash_func_t )(const char *arKey, uint nKeyLength)
typedef int(* compare_func_t )(const void *, const void *TSRMLS_DC)
typedef void(* sort_func_t )(void *, size_t, register size_t, compare_func_t TSRMLS_DC)
typedef void(* dtor_func_t )(void *pDest)
typedef void(* copy_ctor_func_t )(void *pElement)
typedef void(* copy_ctor_param_func_t )(void *pElement, void *pParam)
typedef struct bucket Bucket
typedef struct _hashtable HashTable
typedef struct _zend_hash_key zend_hash_key
typedef zend_bool(* merge_checker_func_t )(HashTable *target_ht, void *source_data, zend_hash_key *hash_key, void *pParam)
typedef BucketHashPosition
typedef int(* apply_func_t )(void *pDest TSRMLS_DC)
typedef int(* apply_func_arg_t )(void *pDest, void *argument TSRMLS_DC)
typedef int(* apply_func_args_t )(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
typedef struct _HashPointer HashPointer

Functions

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)
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)
ZEND_API void zend_hash_destroy (HashTable *ht)
ZEND_API void zend_hash_clean (HashTable *ht)
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)
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)
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)
ZEND_API int zend_hash_add_empty_element (HashTable *ht, const char *arKey, uint nKeyLength)
ZEND_API void zend_hash_graceful_destroy (HashTable *ht)
ZEND_API void zend_hash_graceful_reverse_destroy (HashTable *ht)
ZEND_API void zend_hash_apply (HashTable *ht, apply_func_t apply_func TSRMLS_DC)
ZEND_API void zend_hash_apply_with_argument (HashTable *ht, apply_func_arg_t apply_func, void *TSRMLS_DC)
ZEND_API void zend_hash_apply_with_arguments (HashTable *ht TSRMLS_DC, apply_func_args_t apply_func, int,...)
ZEND_API void zend_hash_reverse_apply (HashTable *ht, apply_func_t apply_func TSRMLS_DC)
ZEND_API int zend_hash_del_key_or_index (HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag)
ZEND_API ulong zend_get_hash_value (const char *arKey, uint nKeyLength)
ZEND_API int zend_hash_find (const HashTable *ht, const char *arKey, uint nKeyLength, void **pData)
ZEND_API int zend_hash_quick_find (const HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void **pData)
ZEND_API int zend_hash_index_find (const HashTable *ht, ulong h, void **pData)
ZEND_API int zend_hash_exists (const HashTable *ht, const char *arKey, uint nKeyLength)
ZEND_API int zend_hash_quick_exists (const HashTable *ht, const char *arKey, uint nKeyLength, ulong h)
ZEND_API int zend_hash_index_exists (const HashTable *ht, ulong h)
ZEND_API ulong zend_hash_next_free_element (const HashTable *ht)
ZEND_API int zend_hash_move_forward_ex (HashTable *ht, HashPosition *pos)
ZEND_API int zend_hash_move_backwards_ex (HashTable *ht, HashPosition *pos)
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)
ZEND_API int zend_hash_get_current_key_type_ex (HashTable *ht, HashPosition *pos)
ZEND_API int zend_hash_get_current_data_ex (HashTable *ht, void **pData, HashPosition *pos)
ZEND_API void zend_hash_internal_pointer_reset_ex (HashTable *ht, HashPosition *pos)
ZEND_API void zend_hash_internal_pointer_end_ex (HashTable *ht, HashPosition *pos)
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)
ZEND_API int zend_hash_get_pointer (const HashTable *ht, HashPointer *ptr)
ZEND_API int zend_hash_set_pointer (HashTable *ht, const HashPointer *ptr)
ZEND_API void zend_hash_copy (HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size)
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)
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)
ZEND_API int zend_hash_sort (HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC)
ZEND_API int zend_hash_compare (HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC)
ZEND_API int zend_hash_minmax (const HashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC)
ZEND_API int zend_hash_num_elements (const HashTable *ht)
ZEND_API int zend_hash_rehash (HashTable *ht)
static ulong zend_inline_hash_func (const char *arKey, uint nKeyLength)
ZEND_API ulong zend_hash_func (const char *arKey, uint nKeyLength)
static int zend_symtable_update (HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest)
static int zend_symtable_del (HashTable *ht, const char *arKey, uint nKeyLength)
static int zend_symtable_find (HashTable *ht, const char *arKey, uint nKeyLength, void **pData)
static int zend_symtable_exists (HashTable *ht, const char *arKey, uint nKeyLength)
static int zend_symtable_update_current_key_ex (HashTable *ht, const char *arKey, uint nKeyLength, int mode, HashPosition *pos)

Class Documentation

struct bucket

Definition at line 54 of file zend_hash.h.

Collaboration diagram for bucket:
Class Members
char arKey
ulong h
uint nKeyLength
void * pData
void * pDataPtr
struct bucket * pLast
struct bucket * pListLast
struct bucket * pListNext
struct bucket * pNext
struct _hashtable

Definition at line 66 of file zend_hash.h.

Collaboration diagram for _hashtable:
Class Members
Bucket ** arBuckets
zend_bool bApplyProtection
unsigned char nApplyCount
ulong nNextFreeElement
uint nNumOfElements
uint nTableMask
uint nTableSize
dtor_func_t pDestructor
zend_bool persistent
Bucket * pInternalPointer
Bucket * pListHead
Bucket * pListTail
struct _zend_hash_key

Definition at line 85 of file zend_hash.h.

Class Members
char * arKey
ulong h
uint nKeyLength
struct _HashPointer

Definition at line 186 of file zend_hash.h.

Collaboration diagram for _HashPointer:
Class Members
ulong h
HashPosition pos

Define Documentation

#define HASH_ADD   (1<<1)

Definition at line 33 of file zend_hash.h.

#define HASH_DEL_INDEX   1

Definition at line 37 of file zend_hash.h.

#define HASH_DEL_KEY   0

Definition at line 36 of file zend_hash.h.

#define HASH_DEL_KEY_QUICK   2

Definition at line 38 of file zend_hash.h.

#define HASH_KEY_IS_LONG   2

Definition at line 29 of file zend_hash.h.

#define HASH_KEY_IS_STRING   1

Definition at line 28 of file zend_hash.h.

#define HASH_KEY_NON_EXISTANT   3

Definition at line 30 of file zend_hash.h.

#define HASH_NEXT_INSERT   (1<<2)

Definition at line 34 of file zend_hash.h.

#define HASH_UPDATE   (1<<0)

Definition at line 32 of file zend_hash.h.

#define HASH_UPDATE_KEY_ANYWAY   3

Definition at line 43 of file zend_hash.h.

#define HASH_UPDATE_KEY_IF_AFTER   2

Definition at line 42 of file zend_hash.h.

#define HASH_UPDATE_KEY_IF_BEFORE   1

Definition at line 41 of file zend_hash.h.

#define HASH_UPDATE_KEY_IF_NONE   0

Definition at line 40 of file zend_hash.h.

#define ZEND_HANDLE_NUMERIC (   key,
  length,
  func 
)

Definition at line 307 of file zend_hash.h.

#define zend_hash_add (   ht,
  arKey,
  nKeyLength,
  pData,
  nDataSize,
  pDest 
)    _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)

Definition at line 110 of file zend_hash.h.

#define ZEND_HASH_APPLY_KEEP   0

Definition at line 128 of file zend_hash.h.

#define ZEND_HASH_APPLY_REMOVE   1<<0

Definition at line 129 of file zend_hash.h.

#define ZEND_HASH_APPLY_STOP   1<<1

Definition at line 130 of file zend_hash.h.

#define zend_hash_del (   ht,
  arKey,
  nKeyLength 
)    zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)

Definition at line 153 of file zend_hash.h.

#define zend_hash_get_current_data (   ht,
  pData 
)    zend_hash_get_current_data_ex(ht, pData, NULL)

Definition at line 204 of file zend_hash.h.

#define zend_hash_get_current_key (   ht,
  str_index,
  num_index,
  duplicate 
)    zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)

Definition at line 200 of file zend_hash.h.

Definition at line 202 of file zend_hash.h.

Definition at line 194 of file zend_hash.h.

Definition at line 175 of file zend_hash.h.

#define zend_hash_index_del (   ht,
 
)    zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)

Definition at line 157 of file zend_hash.h.

#define zend_hash_index_update (   ht,
  h,
  pData,
  nDataSize,
  pDest 
)    _zend_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)

Definition at line 120 of file zend_hash.h.

#define zend_hash_init (   ht,
  nSize,
  pHashFunction,
  pDestructor,
  persistent 
)    _zend_hash_init((ht), (nSize), (pHashFunction), (pDestructor), (persistent) ZEND_FILE_LINE_CC)

Definition at line 103 of file zend_hash.h.

#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)

Definition at line 104 of file zend_hash.h.

Definition at line 208 of file zend_hash.h.

Definition at line 206 of file zend_hash.h.

#define zend_hash_merge (   target,
  source,
  pCopyConstructor,
  tmp,
  size,
  overwrite 
)    _zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite ZEND_FILE_LINE_CC)

Definition at line 221 of file zend_hash.h.

Definition at line 198 of file zend_hash.h.

Definition at line 196 of file zend_hash.h.

#define zend_hash_next_index_insert (   ht,
  pData,
  nDataSize,
  pDest 
)    _zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)

Definition at line 122 of file zend_hash.h.

#define zend_hash_quick_add (   ht,
  arKey,
  nKeyLength,
  h,
  pData,
  nDataSize,
  pDest 
)    _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)

Definition at line 116 of file zend_hash.h.

#define zend_hash_quick_del (   ht,
  arKey,
  nKeyLength,
 
)    zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)

Definition at line 155 of file zend_hash.h.

#define zend_hash_quick_update (   ht,
  arKey,
  nKeyLength,
  h,
  pData,
  nDataSize,
  pDest 
)    _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)

Definition at line 114 of file zend_hash.h.

#define zend_hash_update (   ht,
  arKey,
  nKeyLength,
  pData,
  nDataSize,
  pDest 
)    _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)

Definition at line 108 of file zend_hash.h.

#define zend_hash_update_current_key (   ht,
  key_type,
  str_index,
  str_length,
  num_index 
)    zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, HASH_UPDATE_KEY_ANYWAY, NULL)

Definition at line 210 of file zend_hash.h.

#define ZEND_INIT_SYMTABLE (   ht)    ZEND_INIT_SYMTABLE_EX(ht, 2, 0)

Definition at line 301 of file zend_hash.h.

#define ZEND_INIT_SYMTABLE_EX (   ht,
  n,
  persistent 
)    zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)

Definition at line 304 of file zend_hash.h.

#define zend_symtable_update_current_key (   ht,
  arKey,
  nKeyLength,
  mode 
)    zend_symtable_update_current_key_ex(ht, arKey, nKeyLength, mode, NULL)

Definition at line 375 of file zend_hash.h.


Typedef Documentation

typedef int(* apply_func_arg_t)(void *pDest, void *argument TSRMLS_DC)

Definition at line 133 of file zend_hash.h.

typedef int(* apply_func_args_t)(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)

Definition at line 134 of file zend_hash.h.

typedef int(* apply_func_t)(void *pDest TSRMLS_DC)

Definition at line 132 of file zend_hash.h.

typedef struct bucket Bucket
typedef int(* compare_func_t)(const void *, const void *TSRMLS_DC)

Definition at line 46 of file zend_hash.h.

typedef void(* copy_ctor_func_t)(void *pElement)

Definition at line 49 of file zend_hash.h.

typedef void(* copy_ctor_param_func_t)(void *pElement, void *pParam)

Definition at line 50 of file zend_hash.h.

typedef void(* dtor_func_t)(void *pDest)

Definition at line 48 of file zend_hash.h.

typedef ulong(* hash_func_t)(const char *arKey, uint nKeyLength)

Definition at line 45 of file zend_hash.h.

typedef struct _HashPointer HashPointer
typedef Bucket* HashPosition

Definition at line 94 of file zend_hash.h.

typedef struct _hashtable HashTable
typedef zend_bool(* merge_checker_func_t)(HashTable *target_ht, void *source_data, zend_hash_key *hash_key, void *pParam)

Definition at line 92 of file zend_hash.h.

typedef void(* sort_func_t)(void *, size_t, register size_t, compare_func_t TSRMLS_DC)

Definition at line 47 of file zend_hash.h.

typedef struct _zend_hash_key zend_hash_key

Function Documentation

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 
)

Definition at line 203 of file zend_hash.c.

{
       ulong h;
       uint nIndex;
       Bucket *p;

       IS_CONSISTENT(ht);

       if (nKeyLength <= 0) {
#if ZEND_DEBUG
              ZEND_PUTS("zend_hash_update: Can't put in empty key\n");
#endif
              return FAILURE;
       }

       h = zend_inline_hash_func(arKey, nKeyLength);
       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
                     if (!memcmp(p->arKey, arKey, nKeyLength)) {
                            if (flag & HASH_ADD) {
                                   return FAILURE;
                            }
                            HANDLE_BLOCK_INTERRUPTIONS();
#if ZEND_DEBUG
                            if (p->pData == pData) {
                                   ZEND_PUTS("Fatal error in zend_hash_update: p->pData == pData\n");
                                   HANDLE_UNBLOCK_INTERRUPTIONS();
                                   return FAILURE;
                            }
#endif
                            if (ht->pDestructor) {
                                   ht->pDestructor(p->pData);
                            }
                            UPDATE_DATA(ht, p, pData, nDataSize);
                            if (pDest) {
                                   *pDest = p->pData;
                            }
                            HANDLE_UNBLOCK_INTERRUPTIONS();
                            return SUCCESS;
                     }
              }
              p = p->pNext;
       }
       
       p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent);
       if (!p) {
              return FAILURE;
       }
       memcpy(p->arKey, arKey, nKeyLength);
       p->nKeyLength = nKeyLength;
       INIT_DATA(ht, p, pData, nDataSize);
       p->h = h;
       CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]);
       if (pDest) {
              *pDest = p->pData;
       }

       HANDLE_BLOCK_INTERRUPTIONS();
       CONNECT_TO_GLOBAL_DLLIST(p, ht);
       ht->arBuckets[nIndex] = p;
       HANDLE_UNBLOCK_INTERRUPTIONS();

       ht->nNumOfElements++;
       ZEND_HASH_IF_FULL_DO_RESIZE(ht);          /* If the Hash table is full, resize it */
       return SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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 
)

Definition at line 350 of file zend_hash.c.

{
       uint nIndex;
       Bucket *p;

       IS_CONSISTENT(ht);

       if (flag & HASH_NEXT_INSERT) {
              h = ht->nNextFreeElement;
       }
       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->nKeyLength == 0) && (p->h == h)) {
                     if (flag & HASH_NEXT_INSERT || flag & HASH_ADD) {
                            return FAILURE;
                     }
                     HANDLE_BLOCK_INTERRUPTIONS();
#if ZEND_DEBUG
                     if (p->pData == pData) {
                            ZEND_PUTS("Fatal error in zend_hash_index_update: p->pData == pData\n");
                            HANDLE_UNBLOCK_INTERRUPTIONS();
                            return FAILURE;
                     }
#endif
                     if (ht->pDestructor) {
                            ht->pDestructor(p->pData);
                     }
                     UPDATE_DATA(ht, p, pData, nDataSize);
                     HANDLE_UNBLOCK_INTERRUPTIONS();
                     if ((long)h >= (long)ht->nNextFreeElement) {
                            ht->nNextFreeElement = h < LONG_MAX ? h + 1 : LONG_MAX;
                     }
                     if (pDest) {
                            *pDest = p->pData;
                     }
                     return SUCCESS;
              }
              p = p->pNext;
       }
       p = (Bucket *) pemalloc_rel(sizeof(Bucket) - 1, ht->persistent);
       if (!p) {
              return FAILURE;
       }
       p->nKeyLength = 0; /* Numeric indices are marked by making the nKeyLength == 0 */
       p->h = h;
       INIT_DATA(ht, p, pData, nDataSize);
       if (pDest) {
              *pDest = p->pData;
       }

       CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]);

       HANDLE_BLOCK_INTERRUPTIONS();
       ht->arBuckets[nIndex] = p;
       CONNECT_TO_GLOBAL_DLLIST(p, ht);
       HANDLE_UNBLOCK_INTERRUPTIONS();

       if ((long)h >= (long)ht->nNextFreeElement) {
              ht->nNextFreeElement = h < LONG_MAX ? h + 1 : LONG_MAX;
       }
       ht->nNumOfElements++;
       ZEND_HASH_IF_FULL_DO_RESIZE(ht);
       return SUCCESS;
}

Here is the caller graph for this function:

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 
)

Definition at line 140 of file zend_hash.c.

{
       uint i = 3;
       Bucket **tmp;

       SET_INCONSISTENT(HT_OK);

       if (nSize >= 0x80000000) {
              /* prevent overflow */
              ht->nTableSize = 0x80000000;
       } else {
              while ((1U << i) < nSize) {
                     i++;
              }
              ht->nTableSize = 1 << i;
       }

       ht->nTableMask = ht->nTableSize - 1;
       ht->pDestructor = pDestructor;
       ht->arBuckets = NULL;
       ht->pListHead = NULL;
       ht->pListTail = NULL;
       ht->nNumOfElements = 0;
       ht->nNextFreeElement = 0;
       ht->pInternalPointer = NULL;
       ht->persistent = persistent;
       ht->nApplyCount = 0;
       ht->bApplyProtection = 1;
       
       /* Uses ecalloc() so that Bucket* == NULL */
       if (persistent) {
              tmp = (Bucket **) calloc(ht->nTableSize, sizeof(Bucket *));
              if (!tmp) {
                     return FAILURE;
              }
              ht->arBuckets = tmp;
       } else {
              tmp = (Bucket **) ecalloc_rel(ht->nTableSize, sizeof(Bucket *));
              if (tmp) {
                     ht->arBuckets = tmp;
              }
       }
       
       return SUCCESS;
}

Here is the caller graph for this function:

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 
)

Definition at line 187 of file zend_hash.c.

{
       int retval = _zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent ZEND_FILE_LINE_CC);

       ht->bApplyProtection = bApplyProtection;
       return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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 
)

Definition at line 803 of file zend_hash.c.

{
       Bucket *p;
       void *t;
       int mode = (overwrite?HASH_UPDATE:HASH_ADD);

       IS_CONSISTENT(source);
       IS_CONSISTENT(target);

       p = source->pListHead;
       while (p) {
              if (p->nKeyLength>0) {
                     if (_zend_hash_quick_add_or_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t, mode ZEND_FILE_LINE_RELAY_CC)==SUCCESS && pCopyConstructor) {
                            pCopyConstructor(t);
                     }
              } else {
                     if ((mode==HASH_UPDATE || !zend_hash_index_exists(target, p->h)) && zend_hash_index_update(target, p->h, p->pData, size, &t)==SUCCESS && pCopyConstructor) {
                            pCopyConstructor(t);
                     }
              }
              p = p->pListNext;
       }
       target->pInternalPointer = target->pListHead;
}

Here is the call graph for this function:

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 
)

Definition at line 273 of file zend_hash.c.

{
       uint nIndex;
       Bucket *p;

       IS_CONSISTENT(ht);

       if (nKeyLength == 0) {
              return zend_hash_index_update(ht, h, pData, nDataSize, pDest);
       }

       nIndex = h & ht->nTableMask;
       
       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
                     if (!memcmp(p->arKey, arKey, nKeyLength)) {
                            if (flag & HASH_ADD) {
                                   return FAILURE;
                            }
                            HANDLE_BLOCK_INTERRUPTIONS();
#if ZEND_DEBUG
                            if (p->pData == pData) {
                                   ZEND_PUTS("Fatal error in zend_hash_update: p->pData == pData\n");
                                   HANDLE_UNBLOCK_INTERRUPTIONS();
                                   return FAILURE;
                            }
#endif
                            if (ht->pDestructor) {
                                   ht->pDestructor(p->pData);
                            }
                            UPDATE_DATA(ht, p, pData, nDataSize);
                            if (pDest) {
                                   *pDest = p->pData;
                            }
                            HANDLE_UNBLOCK_INTERRUPTIONS();
                            return SUCCESS;
                     }
              }
              p = p->pNext;
       }
       
       p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent);
       if (!p) {
              return FAILURE;
       }

       memcpy(p->arKey, arKey, nKeyLength);
       p->nKeyLength = nKeyLength;
       INIT_DATA(ht, p, pData, nDataSize);
       p->h = h;
       
       CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]);

       if (pDest) {
              *pDest = p->pData;
       }

       HANDLE_BLOCK_INTERRUPTIONS();
       ht->arBuckets[nIndex] = p;
       CONNECT_TO_GLOBAL_DLLIST(p, ht);
       HANDLE_UNBLOCK_INTERRUPTIONS();

       ht->nNumOfElements++;
       ZEND_HASH_IF_FULL_DO_RESIZE(ht);          /* If the Hash table is full, resize it */
       return SUCCESS;
}

Here is the caller graph for this function:

ZEND_API ulong zend_get_hash_value ( const char *  arKey,
uint  nKeyLength 
)

Definition at line 861 of file zend_hash.c.

{
       return zend_inline_hash_func(arKey, nKeyLength);
}

Here is the call graph for this function:

Here is the caller graph for this function:

ZEND_API int zend_hash_add_empty_element ( HashTable ht,
const char *  arKey,
uint  nKeyLength 
)

Definition at line 342 of file zend_hash.c.

{
       void *dummy = (void *) 1;

       return zend_hash_add(ht, arKey, nKeyLength, &dummy, sizeof(void *), NULL);
}

Here is the caller graph for this function:

ZEND_API void zend_hash_apply ( HashTable ht,
apply_func_t apply_func  TSRMLS_DC 
)

Definition at line 665 of file zend_hash.c.

{
       Bucket *p;

       IS_CONSISTENT(ht);

       HASH_PROTECT_RECURSION(ht);
       p = ht->pListHead;
       while (p != NULL) {
              int result = apply_func(p->pData TSRMLS_CC);
              
              if (result & ZEND_HASH_APPLY_REMOVE) {
                     p = zend_hash_apply_deleter(ht, p);
              } else {
                     p = p->pListNext;
              }
              if (result & ZEND_HASH_APPLY_STOP) {
                     break;
              }
       }
       HASH_UNPROTECT_RECURSION(ht);
}

Here is the call graph for this function:

Here is the caller graph for this function:

ZEND_API void zend_hash_apply_with_argument ( HashTable ht,
apply_func_arg_t  apply_func,
void *  TSRMLS_DC 
)
ZEND_API void zend_hash_apply_with_arguments ( HashTable *ht  TSRMLS_DC,
apply_func_args_t  apply_func,
int  ,
  ... 
)

Definition at line 713 of file zend_hash.c.

{
       Bucket *p;
       va_list args;
       zend_hash_key hash_key;

       IS_CONSISTENT(ht);

       HASH_PROTECT_RECURSION(ht);

       p = ht->pListHead;
       while (p != NULL) {
              int result;
              va_start(args, num_args);
              hash_key.arKey = p->arKey;
              hash_key.nKeyLength = p->nKeyLength;
              hash_key.h = p->h;
              result = apply_func(p->pData TSRMLS_CC, num_args, args, &hash_key);

              if (result & ZEND_HASH_APPLY_REMOVE) {
                     p = zend_hash_apply_deleter(ht, p);
              } else {
                     p = p->pListNext;
              }
              if (result & ZEND_HASH_APPLY_STOP) {
                     va_end(args);
                     break;
              }
              va_end(args);
       }

       HASH_UNPROTECT_RECURSION(ht);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 542 of file zend_hash.c.

{
       Bucket *p, *q;

       IS_CONSISTENT(ht);

       p = ht->pListHead;

       memset(ht->arBuckets, 0, ht->nTableSize*sizeof(Bucket *));
       ht->pListHead = NULL;
       ht->pListTail = NULL;
       ht->nNumOfElements = 0;
       ht->nNextFreeElement = 0;
       ht->pInternalPointer = NULL;

       while (p != NULL) {
              q = p;
              p = p->pListNext;
              if (ht->pDestructor) {
                     ht->pDestructor(q->pData);
              }
              if (q->pData != &q->pDataPtr) {
                     pefree(q->pData, ht->persistent);
              }
              pefree(q, ht->persistent);
       }
}

Here is the caller graph for this function:

ZEND_API int zend_hash_compare ( HashTable ht1,
HashTable ht2,
compare_func_t  compar,
zend_bool ordered  TSRMLS_DC 
)

Definition at line 1423 of file zend_hash.c.

{
       Bucket *p1, *p2 = NULL;
       int result;
       void *pData2;

       IS_CONSISTENT(ht1);
       IS_CONSISTENT(ht2);

       HASH_PROTECT_RECURSION(ht1); 
       HASH_PROTECT_RECURSION(ht2); 

       result = ht1->nNumOfElements - ht2->nNumOfElements;
       if (result!=0) {
              HASH_UNPROTECT_RECURSION(ht1); 
              HASH_UNPROTECT_RECURSION(ht2); 
              return result;
       }

       p1 = ht1->pListHead;
       if (ordered) {
              p2 = ht2->pListHead;
       }

       while (p1) {
              if (ordered && !p2) {
                     HASH_UNPROTECT_RECURSION(ht1); 
                     HASH_UNPROTECT_RECURSION(ht2); 
                     return 1; /* That's not supposed to happen */
              }
              if (ordered) {
                     if (p1->nKeyLength==0 && p2->nKeyLength==0) { /* numeric indices */
                            result = p1->h - p2->h;
                            if (result!=0) {
                                   HASH_UNPROTECT_RECURSION(ht1); 
                                   HASH_UNPROTECT_RECURSION(ht2); 
                                   return result;
                            }
                     } else { /* string indices */
                            result = p1->nKeyLength - p2->nKeyLength;
                            if (result!=0) {
                                   HASH_UNPROTECT_RECURSION(ht1); 
                                   HASH_UNPROTECT_RECURSION(ht2); 
                                   return result;
                            }
                            result = memcmp(p1->arKey, p2->arKey, p1->nKeyLength);
                            if (result!=0) {
                                   HASH_UNPROTECT_RECURSION(ht1); 
                                   HASH_UNPROTECT_RECURSION(ht2); 
                                   return result;
                            }
                     }
                     pData2 = p2->pData;
              } else {
                     if (p1->nKeyLength==0) { /* numeric index */
                            if (zend_hash_index_find(ht2, p1->h, &pData2)==FAILURE) {
                                   HASH_UNPROTECT_RECURSION(ht1); 
                                   HASH_UNPROTECT_RECURSION(ht2); 
                                   return 1;
                            }
                     } else { /* string index */
                            if (zend_hash_quick_find(ht2, p1->arKey, p1->nKeyLength, p1->h, &pData2)==FAILURE) {
                                   HASH_UNPROTECT_RECURSION(ht1); 
                                   HASH_UNPROTECT_RECURSION(ht2); 
                                   return 1;
                            }
                     }
              }
              result = compar(p1->pData, pData2 TSRMLS_CC);
              if (result!=0) {
                     HASH_UNPROTECT_RECURSION(ht1); 
                     HASH_UNPROTECT_RECURSION(ht2); 
                     return result;
              }
              p1 = p1->pListNext;
              if (ordered) {
                     p2 = p2->pListNext;
              }
       }
       
       HASH_UNPROTECT_RECURSION(ht1); 
       HASH_UNPROTECT_RECURSION(ht2); 
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ZEND_API void zend_hash_copy ( HashTable target,
HashTable source,
copy_ctor_func_t  pCopyConstructor,
void *  tmp,
uint  size 
)

Definition at line 772 of file zend_hash.c.

{
       Bucket *p;
       void *new_entry;
       zend_bool setTargetPointer;

       IS_CONSISTENT(source);
       IS_CONSISTENT(target);

       setTargetPointer = !target->pInternalPointer;
       p = source->pListHead;
       while (p) {
              if (setTargetPointer && source->pInternalPointer == p) {
                     target->pInternalPointer = NULL;
              }
              if (p->nKeyLength) {
                     zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &new_entry);
              } else {
                     zend_hash_index_update(target, p->h, p->pData, size, &new_entry);
              }
              if (pCopyConstructor) {
                     pCopyConstructor(new_entry);
              }
              p = p->pListNext;
       }
       if (!target->pInternalPointer) {
              target->pInternalPointer = target->pListHead;
       }
}
ZEND_API int zend_hash_del_key_or_index ( HashTable ht,
const char *  arKey,
uint  nKeyLength,
ulong  h,
int  flag 
)

Definition at line 458 of file zend_hash.c.

{
       uint nIndex;
       Bucket *p;

       IS_CONSISTENT(ht);

       if (flag == HASH_DEL_KEY) {
              h = zend_inline_hash_func(arKey, nKeyLength);
       }
       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) 
                      && (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;
                     }
                     if (ht->pDestructor) {
                            ht->pDestructor(p->pData);
                     }
                     if (p->pData != &p->pDataPtr) {
                            pefree(p->pData, ht->persistent);
                     }
                     pefree(p, ht->persistent);
                     HANDLE_UNBLOCK_INTERRUPTIONS();
                     ht->nNumOfElements--;
                     return SUCCESS;
              }
              p = p->pNext;
       }
       return FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 516 of file zend_hash.c.

{
       Bucket *p, *q;

       IS_CONSISTENT(ht);

       SET_INCONSISTENT(HT_IS_DESTROYING);

       p = ht->pListHead;
       while (p != NULL) {
              q = p;
              p = p->pListNext;
              if (ht->pDestructor) {
                     ht->pDestructor(q->pData);
              }
              if (q->pData != &q->pDataPtr) {
                     pefree(q->pData, ht->persistent);
              }
              pefree(q, ht->persistent);
       }
       pefree(ht->arBuckets, ht->persistent);

       SET_INCONSISTENT(HT_DESTROYED);
}
ZEND_API int zend_hash_exists ( const HashTable ht,
const char *  arKey,
uint  nKeyLength 
)

Definition at line 923 of file zend_hash.c.

{
       ulong h;
       uint nIndex;
       Bucket *p;

       IS_CONSISTENT(ht);

       h = zend_inline_hash_func(arKey, nKeyLength);
       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
                     if (!memcmp(p->arKey, arKey, nKeyLength)) {
                            return 1;
                     }
              }
              p = p->pNext;
       }
       return 0;
}

Here is the call graph for this function:

ZEND_API int zend_hash_find ( const HashTable ht,
const char *  arKey,
uint  nKeyLength,
void **  pData 
)

Definition at line 871 of file zend_hash.c.

{
       ulong h;
       uint nIndex;
       Bucket *p;

       IS_CONSISTENT(ht);

       h = zend_inline_hash_func(arKey, nKeyLength);
       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
                     if (!memcmp(p->arKey, arKey, nKeyLength)) {
                            *pData = p->pData;
                            return SUCCESS;
                     }
              }
              p = p->pNext;
       }
       return FAILURE;
}

Here is the call graph for this function:

ZEND_API ulong zend_hash_func ( const char *  arKey,
uint  nKeyLength 
)

Definition at line 100 of file zend_hash.c.

{
       return zend_inline_hash_func(arKey, nKeyLength);
}

Here is the call graph for this function:

Here is the caller graph for this function:

ZEND_API int zend_hash_get_current_data_ex ( HashTable ht,
void **  pData,
HashPosition pos 
)

Definition at line 1156 of file zend_hash.c.

{
       Bucket *p;

       p = pos ? (*pos) : ht->pInternalPointer;

       IS_CONSISTENT(ht);

       if (p) {
              *pData = p->pData;
              return SUCCESS;
       } else {
              return FAILURE;
       }
}
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 
)

Definition at line 1109 of file zend_hash.c.

{
       Bucket *p;

       p = pos ? (*pos) : ht->pInternalPointer;

       IS_CONSISTENT(ht);

       if (p) {
              if (p->nKeyLength) {
                     if (duplicate) {
                            *str_index = estrndup(p->arKey, p->nKeyLength - 1);
                     } else {
                            *str_index = p->arKey;
                     }
                     if (str_length) {
                            *str_length = p->nKeyLength;
                     }
                     return HASH_KEY_IS_STRING;
              } else {
                     *num_index = p->h;
                     return HASH_KEY_IS_LONG;
              }
       }
       return HASH_KEY_NON_EXISTANT;
}

Definition at line 1137 of file zend_hash.c.

{
       Bucket *p;

       p = pos ? (*pos) : ht->pInternalPointer;

       IS_CONSISTENT(ht);

       if (p) {
              if (p->nKeyLength) {
                     return HASH_KEY_IS_STRING;
              } else {
                     return HASH_KEY_IS_LONG;
              }
       }
       return HASH_KEY_NON_EXISTANT;
}

Definition at line 1023 of file zend_hash.c.

{
       ptr->pos = ht->pInternalPointer;
       if (ht->pInternalPointer) {
              ptr->h = ht->pInternalPointer->h;
              return 1;
       } else {
              ptr->h = 0;
              return 0;
       }
}

Here is the caller graph for this function:

Definition at line 624 of file zend_hash.c.

{
       Bucket *p;

       IS_CONSISTENT(ht);

       p = ht->pListHead;
       while (p != NULL) {
              p = zend_hash_apply_deleter(ht, p);
       }
       pefree(ht->arBuckets, ht->persistent);

       SET_INCONSISTENT(HT_DESTROYED);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 639 of file zend_hash.c.

{
       Bucket *p;

       IS_CONSISTENT(ht);

       p = ht->pListTail;
       while (p != NULL) {
              zend_hash_apply_deleter(ht, p);
              p = ht->pListTail;
       }

       pefree(ht->arBuckets, ht->persistent);

       SET_INCONSISTENT(HT_DESTROYED);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 995 of file zend_hash.c.

{
       uint nIndex;
       Bucket *p;

       IS_CONSISTENT(ht);

       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) && (p->nKeyLength == 0)) {
                     return 1;
              }
              p = p->pNext;
       }
       return 0;
}

Here is the caller graph for this function:

ZEND_API int zend_hash_index_find ( const HashTable ht,
ulong  h,
void **  pData 
)

Definition at line 974 of file zend_hash.c.

{
       uint nIndex;
       Bucket *p;

       IS_CONSISTENT(ht);

       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) && (p->nKeyLength == 0)) {
                     *pData = p->pData;
                     return SUCCESS;
              }
              p = p->pNext;
       }
       return FAILURE;
}

Definition at line 1070 of file zend_hash.c.

{
       IS_CONSISTENT(ht);

       if (pos)
              *pos = ht->pListTail;
       else
              ht->pInternalPointer = ht->pListTail;
}

Here is the caller graph for this function:

Definition at line 1056 of file zend_hash.c.

{
       IS_CONSISTENT(ht);

       if (pos)
              *pos = ht->pListHead;
       else
              ht->pInternalPointer = ht->pListHead;
}
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 
)

Definition at line 840 of file zend_hash.c.

{
       Bucket *p;
       void *t;

       IS_CONSISTENT(source);
       IS_CONSISTENT(target);

       p = source->pListHead;
       while (p) {
              if (zend_hash_replace_checker_wrapper(target, p->pData, p, pParam, pMergeSource)) {
                     if (zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t)==SUCCESS && pCopyConstructor) {
                            pCopyConstructor(t);
                     }
              }
              p = p->pListNext;
       }
       target->pInternalPointer = target->pListHead;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ZEND_API int zend_hash_minmax ( const HashTable ht,
compare_func_t  compar,
int  flag,
void **pData  TSRMLS_DC 
)

Definition at line 1509 of file zend_hash.c.

{
       Bucket *p, *res;

       IS_CONSISTENT(ht);

       if (ht->nNumOfElements == 0 ) {
              *pData=NULL;
              return FAILURE;
       }

       res = p = ht->pListHead;
       while ((p = p->pListNext)) {
              if (flag) {
                     if (compar(&res, &p TSRMLS_CC) < 0) { /* max */
                            res = p;
                     }
              } else {
                     if (compar(&res, &p TSRMLS_CC) > 0) { /* min */
                            res = p;
                     }
              }
       }
       *pData = res->pData;
       return SUCCESS;
}

Here is the caller graph for this function:

Definition at line 1094 of file zend_hash.c.

{
       HashPosition *current = pos ? pos : &ht->pInternalPointer;

       IS_CONSISTENT(ht);

       if (*current) {
              *current = (*current)->pListLast;
              return SUCCESS;
       } else
              return FAILURE;
}

Here is the caller graph for this function:

Definition at line 1081 of file zend_hash.c.

{
       HashPosition *current = pos ? pos : &ht->pInternalPointer;

       IS_CONSISTENT(ht);

       if (*current) {
              *current = (*current)->pListNext;
              return SUCCESS;
       } else
              return FAILURE;
}

Definition at line 1536 of file zend_hash.c.

{
       IS_CONSISTENT(ht);

       return ht->nNextFreeElement;

}

Here is the caller graph for this function:

Definition at line 1015 of file zend_hash.c.

{
       IS_CONSISTENT(ht);

       return ht->nNumOfElements;
}
ZEND_API int zend_hash_quick_exists ( const HashTable ht,
const char *  arKey,
uint  nKeyLength,
ulong  h 
)

Definition at line 947 of file zend_hash.c.

{
       uint nIndex;
       Bucket *p;

       if (nKeyLength==0) {
              return zend_hash_index_exists(ht, h);
       }

       IS_CONSISTENT(ht);

       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
                     if (!memcmp(p->arKey, arKey, nKeyLength)) {
                            return 1;
                     }
              }
              p = p->pNext;
       }
       return 0;

}

Here is the call graph for this function:

Here is the caller graph for this function:

ZEND_API int zend_hash_quick_find ( const HashTable ht,
const char *  arKey,
uint  nKeyLength,
ulong  h,
void **  pData 
)

Definition at line 896 of file zend_hash.c.

{
       uint nIndex;
       Bucket *p;

       if (nKeyLength==0) {
              return zend_hash_index_find(ht, h, pData);
       }

       IS_CONSISTENT(ht);

       nIndex = h & ht->nTableMask;

       p = ht->arBuckets[nIndex];
       while (p != NULL) {
              if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
                     if (!memcmp(p->arKey, arKey, nKeyLength)) {
                            *pData = p->pData;
                            return SUCCESS;
                     }
              }
              p = p->pNext;
       }
       return FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 440 of file zend_hash.c.

{
       Bucket *p;
       uint nIndex;

       IS_CONSISTENT(ht);

       memset(ht->arBuckets, 0, ht->nTableSize * sizeof(Bucket *));
       p = ht->pListHead;
       while (p != NULL) {
              nIndex = p->h & ht->nTableMask;
              CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]);
              ht->arBuckets[nIndex] = p;
              p = p->pListNext;
       }
       return SUCCESS;
}

Here is the caller graph for this function:

ZEND_API void zend_hash_reverse_apply ( HashTable ht,
apply_func_t apply_func  TSRMLS_DC 
)

Definition at line 748 of file zend_hash.c.

{
       Bucket *p, *q;

       IS_CONSISTENT(ht);

       HASH_PROTECT_RECURSION(ht);
       p = ht->pListTail;
       while (p != NULL) {
              int result = apply_func(p->pData TSRMLS_CC);

              q = p;
              p = p->pListLast;
              if (result & ZEND_HASH_APPLY_REMOVE) {
                     zend_hash_apply_deleter(ht, q);
              }
              if (result & ZEND_HASH_APPLY_STOP) {
                     break;
              }
       }
       HASH_UNPROTECT_RECURSION(ht);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1035 of file zend_hash.c.

{
       if (ptr->pos == NULL) {
              ht->pInternalPointer = NULL;
       } else if (ht->pInternalPointer != ptr->pos) {
              Bucket *p;

              IS_CONSISTENT(ht);
              p = ht->arBuckets[ptr->h & ht->nTableMask];
              while (p != NULL) {
                     if (p == ptr->pos) {
                            ht->pInternalPointer = p;
                            return 1;
                     }
                     p = p->pNext;
              }
              return 0;
       }
       return 1;
}

Here is the caller graph for this function:

ZEND_API int zend_hash_sort ( HashTable ht,
sort_func_t  sort_func,
compare_func_t  compare_func,
int renumber  TSRMLS_DC 
)

Definition at line 1360 of file zend_hash.c.

{
       Bucket **arTmp;
       Bucket *p;
       int i, j;

       IS_CONSISTENT(ht);

       if (!(ht->nNumOfElements>1) && !(renumber && ht->nNumOfElements>0)) { /* Doesn't require sorting */
              return SUCCESS;
       }
       arTmp = (Bucket **) pemalloc(ht->nNumOfElements * sizeof(Bucket *), ht->persistent);
       if (!arTmp) {
              return FAILURE;
       }
       p = ht->pListHead;
       i = 0;
       while (p) {
              arTmp[i] = p;
              p = p->pListNext;
              i++;
       }

       (*sort_func)((void *) arTmp, i, sizeof(Bucket *), compar TSRMLS_CC);

       HANDLE_BLOCK_INTERRUPTIONS();
       ht->pListHead = arTmp[0];
       ht->pListTail = NULL;
       ht->pInternalPointer = ht->pListHead;

       arTmp[0]->pListLast = NULL;
       if (i > 1) {
              arTmp[0]->pListNext = arTmp[1];
              for (j = 1; j < i-1; j++) {
                     arTmp[j]->pListLast = arTmp[j-1];
                     arTmp[j]->pListNext = arTmp[j+1];
              }
              arTmp[j]->pListLast = arTmp[j-1];
              arTmp[j]->pListNext = NULL;
       } else {
              arTmp[0]->pListNext = NULL;
       }
       ht->pListTail = arTmp[i-1];

       pefree(arTmp, ht->persistent);
       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);
       }
       return SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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 
)

Definition at line 1175 of file zend_hash.c.

{
       Bucket *p, *q;

       p = pos ? (*pos) : ht->pInternalPointer;

       IS_CONSISTENT(ht);

       if (p) {
              if (key_type == HASH_KEY_IS_LONG) {
                     str_length = 0;
                     if (!p->nKeyLength && p->h == num_index) {
                            return SUCCESS;
                     }

                     q = ht->arBuckets[num_index & ht->nTableMask];
                     while (q != NULL) {
                            if (!q->nKeyLength && q->h == num_index) {
                                   break;
                            }
                            q = q->pNext;
                     }
              } else if (key_type == HASH_KEY_IS_STRING) {
                     ulong h;

                     if (p->nKeyLength == str_length &&
                         memcmp(p->arKey, str_index, str_length) == 0) {
                            return SUCCESS;
                     }

                     h = zend_inline_hash_func(str_index, str_length);
                     q = ht->arBuckets[h & ht->nTableMask];

                     while (q != NULL) {
                            if (q->h == h && q->nKeyLength == str_length && 
                                       memcmp(q->arKey, str_index, str_length) == 0) {
                                   break;
                            }
                            q = q->pNext;
                     }
              } else {
                     return FAILURE;
              }

              HANDLE_BLOCK_INTERRUPTIONS();

              if (q) {
                     if (mode != HASH_UPDATE_KEY_ANYWAY) {
                            Bucket *r = p->pListLast;
                            int found = HASH_UPDATE_KEY_IF_BEFORE;
                                          
                            while (r) {
                                   if (r == q) {
                                          found = HASH_UPDATE_KEY_IF_AFTER;
                                          break;
                                   }
                                   r = r->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;
                                   }
                                   if (ht->pDestructor) {
                                          ht->pDestructor(p->pData);
                                   }
                                   if (p->pData != &p->pDataPtr) {
                                          pefree(p->pData, ht->persistent);
                                   }
                                   pefree(p, ht->persistent);
                                   ht->nNumOfElements--;
                                   HANDLE_UNBLOCK_INTERRUPTIONS();
                                   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;
                     }
                     if (ht->pDestructor) {
                            ht->pDestructor(q->pData);
                     }
                     if (q->pData != &q->pDataPtr) {
                            pefree(q->pData, ht->persistent);
                     }
                     pefree(q, ht->persistent);
                     ht->nNumOfElements--;
              }

              if (p->pNext) {
                     p->pNext->pLast = p->pLast;
              }
              if (p->pLast) {
                     p->pLast->pNext = p->pNext;
              } else {
                     ht->arBuckets[p->h & ht->nTableMask] = p->pNext;
              }

              if (p->nKeyLength != str_length) {
                     Bucket *q = (Bucket *) pemalloc(sizeof(Bucket) - 1 + str_length, ht->persistent);

                     q->nKeyLength = str_length;
                     if (p->pData == &p->pDataPtr) {
                            q->pData = &q->pDataPtr;
                     } else {
                            q->pData = p->pData;
                     }
                     q->pDataPtr = p->pDataPtr;
                     q->pListNext = p->pListNext;
                     q->pListLast = p->pListLast;
                     if (q->pListNext) {
                            p->pListNext->pListLast = q;
                     } else {
                            ht->pListTail = q;
                     }
                     if (q->pListLast) {
                            p->pListLast->pListNext = q;
                     } else {
                            ht->pListHead = q;
                     }
                     if (ht->pInternalPointer == p) {
                            ht->pInternalPointer = q;
                     }
                     if (pos) {
                            *pos = q;
                     }
                     pefree(p, ht->persistent);
                     p = q;
              }

              if (key_type == HASH_KEY_IS_LONG) {
                     p->h = num_index;
              } else {
                     memcpy(p->arKey, str_index, str_length);
                     p->h = zend_inline_hash_func(str_index, str_length);
              }

              CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[p->h & ht->nTableMask]);
              ht->arBuckets[p->h & ht->nTableMask] = p;
              HANDLE_UNBLOCK_INTERRUPTIONS();

              return SUCCESS;
       } else {
              return FAILURE;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static ulong zend_inline_hash_func ( const char *  arKey,
uint  nKeyLength 
) [inline, static]

Definition at line 261 of file zend_hash.h.

{
       register ulong hash = 5381;

       /* variant with the hash unrolled eight times */
       for (; nKeyLength >= 8; nKeyLength -= 8) {
              hash = ((hash << 5) + hash) + *arKey++;
              hash = ((hash << 5) + hash) + *arKey++;
              hash = ((hash << 5) + hash) + *arKey++;
              hash = ((hash << 5) + hash) + *arKey++;
              hash = ((hash << 5) + hash) + *arKey++;
              hash = ((hash << 5) + hash) + *arKey++;
              hash = ((hash << 5) + hash) + *arKey++;
              hash = ((hash << 5) + hash) + *arKey++;
       }
       switch (nKeyLength) {
              case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
              case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
              case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
              case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
              case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
              case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
              case 1: hash = ((hash << 5) + hash) + *arKey++; break;
              case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
       }
       return hash;
}

Here is the caller graph for this function:

static int zend_symtable_del ( HashTable ht,
const char *  arKey,
uint  nKeyLength 
) [inline, static]

Definition at line 350 of file zend_hash.h.

{
       ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_del(ht, idx));
       return zend_hash_del(ht, arKey, nKeyLength);
}

Here is the caller graph for this function:

static int zend_symtable_exists ( HashTable ht,
const char *  arKey,
uint  nKeyLength 
) [inline, static]

Definition at line 364 of file zend_hash.h.

{
       ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx));
       return zend_hash_exists(ht, arKey, nKeyLength);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int zend_symtable_find ( HashTable ht,
const char *  arKey,
uint  nKeyLength,
void **  pData 
) [inline, static]

Definition at line 357 of file zend_hash.h.

{
       ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_find(ht, idx, pData));
       return zend_hash_find(ht, arKey, nKeyLength, pData);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int zend_symtable_update ( HashTable ht,
const char *  arKey,
uint  nKeyLength,
void *  pData,
uint  nDataSize,
void **  pDest 
) [inline, static]

Definition at line 343 of file zend_hash.h.

{
       ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update(ht, idx, pData, nDataSize, pDest));
       return zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest);
}
static int zend_symtable_update_current_key_ex ( HashTable ht,
const char *  arKey,
uint  nKeyLength,
int  mode,
HashPosition pos 
) [inline, static]

Definition at line 370 of file zend_hash.h.

{
       ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL, 0, idx, mode, pos));
       return zend_hash_update_current_key_ex(ht, HASH_KEY_IS_STRING, arKey, nKeyLength, 0, mode, pos);
}

Here is the call graph for this function: