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

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

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

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • HashMap和HashTable有什么不同?在面试和被面试的过程中,我问过也被问过这个问题,也见过了不少回答,今...
    程序员技术圈阅读 947评论 1赞 12
  • java.util.HashMap 本质是一个Entry[]数组(哈希桶数组),用Key的哈希值对桶数组size取...
    Ary_zz阅读 601评论 1赞 1
  • 一、HashMap概述 HashMap基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用nul...
    小陈阿飞阅读 714评论 0赞 2
  • 一、HashMap 的存储结构键值均可为 null JDK7 的 HashMap JDK7 的 HashMap 的...
    Djbfifjd阅读 16,457评论 2赞 21
  • 有了不如意的地方,怎么办?看情况,分类处理。引入一个二维四象限的表格,横坐标为发生频率,纵坐标为影响大小。这样,就...
    行走的LILY阅读 387评论 0赞 0

友情链接更多精彩内容