美文网首页PHPPHP经验分享
PHP7源码学习笔记(二) HashTable

PHP7源码学习笔记(二) HashTable

作者: 公式般欢笑 | 来源:发表于2020-02-27 14:18 被阅读0次

    源码版本: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中。
    如果出现哈希值碰撞的问题,

    <?php
      $arr=[];
      $arr['a']=1;
      $arr['b']=2;
    

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

    相关文章

      网友评论

        本文标题:PHP7源码学习笔记(二) HashTable

        本文链接:https://www.haomeiwen.com/subject/eebthhtx.html