博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php Hash Table(三) Hash Table初始化
阅读量:6191 次
发布时间:2019-06-21

本文共 2018 字,大约阅读时间需要 6 分钟。

HashTable初始化,在使用HashTable之前要先执行初始化,下边就看看初始化时都做了什么,

Zend/zend_hash.c

 
static const Bucket *uninitialized_bucket = NULL; //声明一个全局Bucket * ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC){    uint i = 3;   /* 初始化HashTable大小时,是按照2的整数次幂来初始化,最小为2的3次幂 */    SET_INCONSISTENT(HT_OK);  /* 调试用,初始化当前HashTable的状态 */    if (nSize >= 0x80000000) {        /* HashTable的最大值,防止溢出 */        ht->nTableSize = 0x80000000;    } else {        while ((1U << i) < nSize) {            i++;        }        ht->nTableSize = 1 << i;    }    ht->nTableMask = 0;    /* 0 表示 ht->arBuckets 还没有初始化 */    ht->pDestructor = pDestructor;  /* 设置析构函数为传入的函数指针 */    ht->arBuckets = (Bucket**)&uninitialized_bucket;    ht->pListHead = NULL;    ht->pListTail = NULL;    ht->nNumOfElements = 0;    ht->nNextFreeElement = 0;    ht->pInternalPointer = NULL;    ht->persistent = persistent;    ht->nApplyCount = 0;    ht->bApplyProtection = 1;    return SUCCESS;}
 

ht  是一个指向HashTable变量的指针, 它可以定义为直接值形式, 也可以通过emalloc()/pemalloc()动态分配, 或者更常见的是使用ALLOC_HASHTABLE(ht). ALLOC_HASHTABLE()宏使用了一个特定内存池的预分配块来降低内存分配所需的时间, 相比于ht = emalloc(sizeof(HashTable));它通常是首选.

nSize  应该被设置为HashTable期望存储的最大元素个数. 如果向这个HashTable中尝试增加多于这个数的元素, 它将会自动增长, 不过有一点需要注意的是, 这里Zend重建整个新扩展的HashTable的索引的过程需要耗费不少的处理时间. 如果nSize不是2的幂, 它将被按照下面公式扩展为下一个2的幂:

nSize = pow(2, ceil(log(nSize, 2)));

pHashFunction  是旧版本Zend引擎的遗留参数, 它不在使用, 因此这个值应该被设置为NULL. 在早期的Zend引擎中, 这个值指向一个用以替换标准的DJBX33A(一种常见的抗碰撞哈希算法, 用来将任意字符串key转换到可重演的整型值)的可选哈希算法.

pDestructor  指向当从HashTable删除元素时应该被调用的函数, 比如当使用zend_hash_del()删除或使用zend_hash_update()替换. 析构器函数的原型如下:

void method_name(void *pElement);

pElement指向指向要从HashTable中删除的元素.

persistent  它只是一个简单的标记, 引擎会直接传递给pemalloc()函数. 所有需要保持跨请求可用的HashTable都必须设置这个标记, 并且必须调用pemalloc()分配.

可见,zend_hash_init并没有为存放buckets申请内存空间,只是设置了初始化的size,并且设置了nTableMask为0,表示 ht->arBuckets还未初始化。整个HashTable的size是按照2的整数次幂申请的,最小为2的3次幂,若空间不够则尝试2的4次 幂、2的5次幂……直到大于传入的size。

那么buckets的空间是什么时候申请的呢?答案就是在操作HashTable的时候,看下一篇。~..~

 
 

转载地址:http://lfrda.baihongyu.com/

你可能感兴趣的文章
npm包版本
查看>>
勤劳,还是懒惰?
查看>>
android 设计模式
查看>>
安卓精品源码,android日历在线选座微博主页抽屉菜单原生指纹源码
查看>>
Python 爬虫之模拟登陆CSND
查看>>
《 Kotlin + Spring Boot : 下一代 Java 服务端开发 》
查看>>
three.js中文文档 2.通过模块导入
查看>>
iOS-Autolayout自动计算itemSize的UICollectionViewLayout瀑布流布局
查看>>
基于AspectJ的Spring AOP Advice执行顺序
查看>>
【ios】关于[self.tableView reloadData]使用技巧
查看>>
MySQL 日志(错误日志、二进制日志、查询日志、慢查询日志)
查看>>
聊聊spring kafka的retry
查看>>
解决移动端iOS下上传图片被旋转问题。
查看>>
gitlab备份与恢复
查看>>
Nginx在服务器上的配置
查看>>
关于javascript中的原型和原型链
查看>>
Git各种错误操作撤销的方法
查看>>
laravel较优雅的分表关联查询(性能较好,SQL的数量=表的数量,涵盖了较多laravel手册推荐的方法)...
查看>>
针对app测试的重点关注内容
查看>>
Redis Lua 脚本
查看>>