hashtable
hashtable 包括 :
- 一個
gc結(jié)構(gòu) ,是幫助垃圾回收而使用的 - 一個聯(lián)合體
- 掩碼
- 桶指針
arData - 析構(gòu)函數(shù)
pDestructor - 桶的數(shù)目
nTableSize
...
// src\Zend\zend_types.h
typedef struct _zend_array HashTable;
struct _zend_array {
zend_refcounted_h gc;
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar flags,
zend_uchar nApplyCount,
zend_uchar nIteratorsCount,
zend_uchar consistency)
} v;
uint32_t flags;
} u;
uint32_t nTableMask;
Bucket *arData;
uint32_t nNumUsed;
uint32_t nNumOfElements;
uint32_t nTableSize;
uint32_t nInternalPointer;
zend_long nNextFreeElement;
dtor_func_t pDestructor;
};
然后是Bucket 結(jié)構(gòu)
typedef struct _Bucket {
zval val;
zend_ulong h; /* hash value (or numeric index) */
zend_string *key; /* string key or NULL for numerics */
} Bucket;
然后是zval
typedef struct _zval_struct zval;
struct _zval_struct {
zend_value value; /* value */
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar type, /* active type */
zend_uchar type_flags,
zend_uchar const_flags,
zend_uchar reserved) /* call info for EX(This) */
} v;
uint32_t type_info;
} u1;
union {
uint32_t next; /* hash collision chain */
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t num_args; /* arguments number for EX(This) */
uint32_t fe_pos; /* foreach position */
uint32_t fe_iter_idx; /* foreach iterator index */
uint32_t access_flags; /* class constant access flags */
uint32_t property_guard; /* single property guard */
uint32_t extra; /* not further specified */
} u2;
};
繼續(xù)上面的結(jié)構(gòu) _zval_struct , 我的代碼的版本是php 7.1.8, 然后看到 ·_zval_struct 由以下幾個部分組成
zend_val- 聯(lián)合體
u1 - 聯(lián)合體
u2
u2 有一個next 的值可以實(shí)現(xiàn)關(guān)聯(lián)數(shù)組相關(guān)的操作
zend_value; 然后到了zend_value
zend_value 是一個聯(lián)合體,7.18 繼續(xù)對zend_value 進(jìn)行優(yōu)化,縮小了zend_value的大小,可以節(jié)省非常多的內(nèi)存
typedef union _zend_value {
zend_long lval; /* long value */
double dval; /* double value */
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zend_ast_ref *ast;
zval *zv;
void *ptr;
zend_class_entry *ce;
zend_function *func;
struct {
uint32_t w1;
uint32_t w2;
} ww;
} zend_value;