background image

>nTableSize = 0x80000000;    } else {        while ((1U << i) < nSize) {            i++;        }        ht-
>nTableSize = 1 << i;    }

    ht->nTableMask = ht->nTableSize - 1;

    /*此处省略若干代码…*/

    return SUCCESS;}

值得一提的是

PHP 向 2 的整数次幂取圆整方法非常巧妙,可以背下来在需要的时候使用。

Zend HashTable 的哈希算法异常简单:

hash(key)=key & nTableMask

即简单将数据的原始

key 与 HashTable 的 nTableMask 进行按位与即可。

如果原始

key 为字符串,则首先使用

Times33  

算法将字符串转为整形再与

nTableMask 按位

与。

hash(strkey)=time33(strkey) & nTableMask

下面是

Zend 源码中查找哈希表的代码:

ZEND_API int zend_hash_index_find(const HashTable *ht, ulong h, void **pData){    uint 
nIndex;    Bucket *p;

    IS_CONSISTENT(ht);

    nIndex = h & ht->nTableMask;

    p = ht->arBuckets[nIndex];    while (p != NULL) {        if ((p->h == h) && (p->nKeyLength == 
0)) {            *pData = p->pData;            return SUCCESS;        }        p = p->pNext;    }    return 
FAILURE;}

ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void 
**pData){    ulong h;    uint nIndex;    Bucket *p;

    IS_CONSISTENT(ht);

    h = zend_inline_hash_func(arKey, nKeyLength);    nIndex = h & ht->nTableMask;

    p = ht->arBuckets[nIndex];    while (p != NULL) {        if ((p->h == h) && (p->nKeyLength == 
nKeyLength)) {            if (!memcmp(p->arKey, arKey, nKeyLength)) {                *pData = p-
>pData;                return SUCCESS;            }        }        p = p->pNext;    }    return FAILURE;}