• php Hash Table(三) Hash Table初始化


    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的时候,看下一篇。~..~

     
     
  • 相关阅读:
    #Responsive# 响应式图片//www.w3cplus.com/blog/tags/509.html 整个系列完结。
    用js实现帧动画
    js判断对象是否存在
    canvas
    函数的四种调用模式
    递归真的好难啊!!! 看完之后好多了
    词法作用域
    变量名提升
    ajax调用后台Java
    左图又文字自适应
  • 原文地址:https://www.cnblogs.com/leezhxing/p/4835946.html
Copyright © 2020-2023  润新知