PHP7源码学习笔记(二) HashTable

源码版本:php-7.1.0
PHP的数组结构是一种非常灵活的结构,其存储的数据同时包括Java语言中的List和HashMap结构。PHP数组的底层是一个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;        //hashTable中已有的元素个数,包括UNDEF类型的元素
    uint32_t          nNumOfElements;  //hashTable中真是存在的元素个数
    uint32_t          nTableSize;      //hashTable的大小,默认是8,每次扩容增加一倍。
    uint32_t          nInternalPointer;
    zend_long         nNextFreeElement;
    dtor_func_t       pDestructor;
};
typedef struct _Bucket {
    zval              val;
    zend_ulong        h;                //packedArray中的数值索引或者是 hashArray中的哈希值
    zend_string      *key;              //key的具体内容,例如 $arr['a']=2;这个位置存储的就是‘a’
} Bucket;

hashTable中包含两种数据结构,即packed array 和 hash array。
如果存储的数据是List结构,那么在数组存储过程中,并不会进行hash运算,而是直接存储当前数据的key值。
如果存储的数据是HashMap结构,那么在数据存储过程中,首先要获取当前key的哈希值,而后根据哈希值将数据塞入到对应的bucket中。
如果出现哈希值碰撞的问题,

假如a与b在进行哈希计算之后,得到了同样的一个值,那么在哈希索引会指向b的bucket,在b的bucket中存入a数据bucket的编号,通过链表的方式,可以取到a的值。

你可能感兴趣的:(PHP7源码学习笔记(二) HashTable)