php内核-数据类型之数组

柔光的暖阳◎ 2022-02-05 12:57 728阅读 0赞

php数组的底层实现为散列表(HashTable)

散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。
了解更多:https://zh.wikipedia.org/wiki/哈希表

HashTable的数据结构:

  1. typedef struct _zend_array zend_array;
  2. typedef struct _zend_array HashTable;
  3. typedef struct _Bucket {
  4. zval val; /* 存储的具体的值 */
  5. zend_ulong h; /* key的hash code */
  6. zend_string *key; /* 存储元素的key */
  7. } Bucket;
  8. struct _zend_array {
  9. zend_refcounted_h gc;
  10. union {
  11. struct {
  12. ZEND_ENDIAN_LOHI_4(
  13. zend_uchar flags,
  14. zend_uchar _unused,
  15. zend_uchar nIteratorsCount,
  16. zend_uchar _unused2)
  17. } v;
  18. uint32_t flags;
  19. } u;
  20. uint32_t nTableMask; /* 用于散列函数映射存储元素在arData数组中的下标 */
  21. Bucket *arData; /* 存储元素数组,每个元素结构统一为Bucket, arData指向第一个Bucket */
  22. uint32_t nNumUsed; /* 已用的Bucket个数 */
  23. uint32_t nNumOfElements; /* 数组中实际存储的元素个数*/
  24. uint32_t nTableSize; /* 数组总容量*/
  25. uint32_t nInternalPointer;/* 内部指针 */
  26. zend_long nNextFreeElement;/* 下一个可用的数值索引,注意是数值索引,即无key时的索引 */
  27. dtor_func_t pDestructor;
  28. };
  1. arData:散列表中保存存储元素的数组,内存联系,arData指向数组首地址
  2. nTableSize:数组的总容量,即可以容纳的元素数。它的大小始终是2的幂次方,最小为8,依次为8、16、32、64等等
  3. nTableMask:散列函数根据key的hash code映射元素的存储位置是用到,实际值是nTableSize的相反数,即nTableMask = -nTableSize,位运算表示则为nTableMask = ~nTableSize + 1
  4. nNumUsed & nNumOfElements: nNumUsed是指数组当前使用的Bucket数,但这些Bucket中存储的不一定都是有效的数据,因为当数组删除掉一个元舒适,并不会马上将其从数组中移除,而是先将其标记为IS_UNDEF,只有在数组容量超限扩容时,才会真正的删除。nNumOfElements则是数组中有效元素的数量。
  5. nNextFreeElement:这个是自动确定数值索引使用的,从0开始。一定是数值索引。
  6. pDestructor:当删除或覆盖数组中的某个元素是,如果提供了这个函数句柄,则删除或覆盖后调用次函数,对旧元素进行清理。
  7. u:这个结构主要用于一些辅助作用。

发表评论

表情:
评论列表 (有 0 条评论,728人围观)

还没有评论,来说两句吧...

相关阅读

    相关 PHP 基础数据类型Boolean

    前面我们试着构建了PHP的开发环境,以及创建了一个最简单的Hello World工程。今天我们来学习PHP的基础数据类型。 和其他的编程语言一样,PHP中Boolean(布尔