Zend 雜湊表的內部實現

2021-06-28 15:23:54 字數 2869 閱讀 9516

chapter: php中的hash演算法

1. 從php的hash(雜湊)演算法開始

2. zend 雜湊表的內部實現

3. php雜湊表結構的深入剖析

資料結構

php中使用乙個叫bucket的結構體表示桶(桶的相關參考linux核心中的hash與bucket

01typedefstructbucket bucket;

16

17typedefstruct_hashtable hashtable;

重點明確下面幾個字段:

雜湊演算法

php雜湊表最小容量是8(2^3),最大容量是0x80000000(2^31),並向2的整數次冪圓整(即長度會自動擴充套件為2的整數次冪,如13個元素的雜湊表長度為16;100個元素的雜湊表長度為128)。ntablemask被初始化為雜湊表長度(圓整後)減1。具體**在zend/zend_hash.c的_zend_hash_init函式中,這裡擷取與本文相關的部分並加上少量注釋。

01zend_apiint_zend_hash_init(hashtable *ht, uint nsize, hash_func_t phashfunction, dtor_func_t pdestructor, zend_bool persistent zend_file_line_dc)

02else

16ht->ntablesize = 1 << i;

17}

18

19ht->ntablemask = ht->ntablesize - 1;

20

21/*此處省略若干**…*/

22

23returnsuccess;

24}

值得一提的是php向2的整數次冪取圓整方法非常巧妙,可以背下來在需要的時候使用。

zend hashtable的雜湊演算法比較簡單:

1hash(key)=key & ntablemask

即簡單將資料的原始key與hashtable的ntablemask進行按位與即可。

如果原始key為字串,則首先使用times33演算法將字串轉為整形再與ntablemask按位與。

1hash(strkey)=time33(strkey) & ntablemask

下面是zend原始碼中查詢雜湊表的**:

01zend_apiintzend_hash_index_find(consthashtable *ht, ulong h,void**pdata)

02

16p = p->pnext;

17}

18returnfailure;

19}

20

21zend_apiintzend_hash_find(consthashtable *ht,constchar*arkey, uint nkeylength,void**pdata)

22

39}

40p = p->pnext;

41}

42returnfailure;

43}

其中zend_hash_index_find用於查詢整數key的情況,zend_hash_find用於查詢字串key。邏輯基本一致,只是字串key會通過zend_inline_hash_func轉為整數key,zend_inline_hash_func封裝了times33演算法,具體**就不貼出了。

雜湊表(雜湊表)的實現

雜湊函式直接用key size的形式,size為雜湊表的大小。衝突處理採用平方探測法,為保證可以探測到整個雜湊表空間,雜湊表大小設定為4k 3形式的素數。當雜湊表中的元素過多時會造成效能下降,這時應該倍增雜湊表的大小,重新計算原來雜湊表中每個元素在新的雜湊表中的位置。雜湊表的實現 hashtable...

雜湊表 雜湊表 的實現原理

雜湊表可以表述為,是一種可以根據關鍵字快速查詢資料的資料結構。通常情況下,不論雜湊表中資料有多少,增加,刪除,改寫資料的複雜度平均都是o 1 效率非常高。如果說每乙個資料它都對應著乙個固定的位置,那我們查詢特定乙個資料時,就可以直接檢視這個資料對應的位置是否存在資料。乙個形象的例子就是學生在教室中的...

雜湊表(雜湊表) C 實現

雜湊函式就是 關鍵字key 到 值value 的對映 value f key value反映的是關鍵字key的儲存位址。直接定址法 f key a key b 例如存放不同出生年份的人口數量,出生年份是關鍵字,那麼可以用直接定址法。直接定址法的優點是簡單均勻,也不會產生衝突 缺點是該方法適合表比較小...