php Hash Table(三) Hash Table初始化
2015-09-24 17:28
591 查看
HashTable初始化,在使用HashTable之前要先执行初始化,下边就看看初始化时都做了什么,
Zend/zend_hash.c
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()替换.析构器函数的原型如下:
voidmethod_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的时候,看下一篇。~..~
Zend/zend_hash.c
staticconstBucket*uninitialized_bucket=NULL;//声明一个全局Bucket* ZEND_APIint_zend_hash_init(HashTable*ht,uintnSize,hash_func_tpHashFunction,dtor_func_tpDestructor,zend_boolpersistentZEND_FILE_LINE_DC) { uinti=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; returnSUCCESS; }
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()替换.析构器函数的原型如下:
voidmethod_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的时候,看下一篇。~..~
相关文章推荐
- php模糊查询知识点
- PHP学习笔记(六):类与对象
- php分页代码
- windows下ftp上传下载和一些常用命令
- php模糊查询实例代码
- php数组操作小结
- 用PHP做服务器转发层,解决js的ajax跨域访问问题
- phpExcel中文帮助手册之常用功能指南
- zend studio自动添加文件注释和方法注释
- PHP中配置IIS7实现基本身份验证的方法
- FTP实现文件/文件夹的上传或下载
- 【Wordpress】以修改文章页面single.php下的评论栏说明一些Wordpress的函数与页面
- tp-from表单的验证
- 常见PHP数据库解决方案分析介绍
- PHP类的自动加载
- 又十个超级有用的PHP代码片段
- TP-登录
- phpcms v9模块操作列表
- PHP易混淆知识整理笔记
- php $_SERVER当前完整url的写法