PHP底层之HashTable的实现

这是一篇关于PHP中大量使用的数据结构HashTable的介绍,通过了解HashTable的存储原理,可以搞清楚一些问题,如数组的存储及一些操作原理、count()函数是如何得出数组元素个数的、foreach比for快的原因等等。HashTable是PHP的灵魂,因为在Zend引擎中大量地使用了HashTable,如变量表,常量表,函数表等,这些都是使用HashTable保存的,另外,PHP的数组也是通过使用HashTble实现的。

首先对Hashtable做个简单介绍,Hashtable的概念实际上非常简单:字符串的键首先会被传递给一个hash函数,然后这个函数会返回一个整数(我们把它叫做hash值),而这个整数就是“通常”的数组的索引。问题是对于两个不同的字符串,调用hash函数会得到同一个hash值,而现实情况是任意字符串都可以作为键,所以键会有无数个,而数组的大小必须是提前设定好的,因为hash值必须小于数组索引的最大值,所以可以生成的hash值必须是有限的。这样用有限的hash值表示无限的键,必然会导致冲突。我们把两个不同的键的hash值是一样的情况称为冲突,任何Hashtable算法都必须提供某种机制解决这种冲突。有两种主要的处理冲突的方法。开放定址法,当冲突发生的时候,冲突的元素会被保存到一个不同的索引中;链接法,所有拥有相同的hash值的元素,它们都会被保存到一个链表中。PHP使用的就是第二种方法。

 

PHP中的HashTable的实现代码保存在Zend/zend_hash.h和Zend/zend_hash.c这两个文件中,PHP使用如下两个数据结构来实现哈希表,HashTable结构体用于保存整个哈希表需要的基本信息:

typedef struct _hashtable { 
    uint nTableSize;        // hash Bucket的大小,最小为8,以2x增长。
    uint nTableMask;        // nTableSize-1 , 索引取值的优化
    uint nNumOfElements;    // hash Bucket中当前存在的元素个数,count()函数会直接返回此值 
    ulong nNextFreeElement; // 下一个数字索引的位置
    Bucket *pInternalPointer;   // 当前遍历的指针(foreach比for快的原因之一)
    Bucket *pListHead;          // 存储数组头元素指针
    Bucket *pListTail;          // 存储数组尾元素指针
    Bucket **arBuckets;         // 存储hash数组
    dtor_func_t p

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值