最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PHP 源代碼分析 Zend HashTable詳解第1/3頁(yè)

 更新時(shí)間:2009年08月10日 10:51:09   作者:  
在PHP的Zend引擎中,有一個(gè)數(shù)據(jù)結(jié)構(gòu)非常重要,它無(wú)處不在,是PHP數(shù)據(jù)存儲(chǔ)的核心,各種常量、變量、函數(shù)、類、對(duì)象等都用它來(lái)組織,這個(gè)數(shù)據(jù)結(jié)構(gòu)就是HashTable。
HashTable在通常的數(shù)據(jù)結(jié)構(gòu)教材中也稱作散列表,哈希表。其基本原理比較簡(jiǎn)單(如果你對(duì)其不熟悉,請(qǐng)查閱隨便一本數(shù)據(jù)結(jié)構(gòu)教材或在網(wǎng)上搜索),但PHP的實(shí)現(xiàn)有其獨(dú)特的地方。理解了HashTable的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),對(duì)我們分析PHP的源代碼,特別是Zend Engine中的虛擬機(jī)的實(shí)現(xiàn)時(shí),有很重要的幫助。它可以幫助我們?cè)诖竽X中模擬一個(gè)完整的虛擬機(jī)的形象。它也是PHP中其它一些數(shù)據(jù)結(jié)構(gòu)如數(shù)組實(shí)現(xiàn)的基礎(chǔ)。
Zend HashTable的實(shí)現(xiàn)結(jié)合了雙向鏈表和向量(數(shù)組)兩種數(shù)據(jù)結(jié)構(gòu)的優(yōu)點(diǎn),為PHP提供了非常高效的數(shù)據(jù)存儲(chǔ)和查詢機(jī)制。
Let's begin!
一、 HashTable的數(shù)據(jù)結(jié)構(gòu)
在Zend Engine中的HashTable的實(shí)現(xiàn)代碼主要包括zend_hash.h, zend_hash.c這兩個(gè)文件中。Zend HashTable包括兩個(gè)主要的數(shù)據(jù)結(jié)構(gòu),其一是Bucket(桶)結(jié)構(gòu),另一個(gè)是HashTable結(jié)構(gòu)。Bucket結(jié)構(gòu)是用于保存數(shù)據(jù)的容器,而HashTable結(jié)構(gòu)則提供了對(duì)所有這些Bucket(或桶列)進(jìn)行管理的機(jī)制。
復(fù)制代碼 代碼如下:

typedef struct bucket {
ulong h; /* Used for numeric indexing */
uint nKeyLength; /* key 長(zhǎng)度 */
void *pData; /* 指向Bucket中保存的數(shù)據(jù)的指針 */
void *pDataPtr; /* 指針數(shù)據(jù) */
struct bucket *pListNext; /* 指向HashTable桶列中下一個(gè)元素 */
struct bucket *pListLast; /* 指向HashTable桶列中前一個(gè)元素 */
struct bucket *pNext; /* 指向具有同一個(gè)hash值的桶列的后一個(gè)元素 */
struct bucket *pLast; /* 指向具有同一個(gè)hash值的桶列的前一個(gè)元素 */
char arKey[1]; /* 必須是最后一個(gè)成員,key名稱*/
} Bucket;

在Zend HashTable中,每個(gè)數(shù)據(jù)元素(Bucket)有一個(gè)鍵名(key),它在整個(gè)HashTable中是唯一的,不能重復(fù)。根據(jù)鍵名可以唯一確定HashTable中的數(shù)據(jù)元素。鍵名有兩種表示方式。第一種方式使用字符串a(chǎn)rKey作為鍵名,該字符串的長(zhǎng)度為nKeyLength。注意到在上面的數(shù)據(jù)結(jié)構(gòu)中arKey雖然只是一個(gè)長(zhǎng)度為1的字符數(shù)組,但它并不意味著key只能是一個(gè)字符。實(shí)際上Bucket是一個(gè)可變長(zhǎng)的結(jié)構(gòu)體,由于arKey是Bucket的最后一個(gè)成員變量,通過(guò)arKey與nKeyLength結(jié)合可確定一個(gè)長(zhǎng)度為nKeyLength的key。這是C語(yǔ)言編程中的一個(gè)比較常用的技巧。另一種鍵名的表示方式是索引方式,這時(shí)nKeyLength總是0,長(zhǎng)整型字段h就表示該數(shù)據(jù)元素的鍵名。簡(jiǎn)單的來(lái)說(shuō),即如果nKeyLength=0,則鍵名為h;否則鍵名為arKey, 鍵名的長(zhǎng)度為nKeyLength。
當(dāng)nKeyLength > 0時(shí),并不表示這時(shí)的h值就沒(méi)有意義。事實(shí)上,此時(shí)它保存的是arKey對(duì)應(yīng)的hash值。不管hash函數(shù)怎么設(shè)計(jì),沖突都是不可避免的,也就是說(shuō)不同的arKey可能有相同的hash值。具有相同hash值的Bucket保存在HashTable的arBuckets數(shù)組(參考下面的解釋)的同一個(gè)索引對(duì)應(yīng)的桶列中。這個(gè)桶列是一個(gè)雙向鏈表,其前向元素,后向元素分別用pLast, pNext來(lái)表示。新插入的Bucket放在該桶列的最前面。
在Bucket中,實(shí)際的數(shù)據(jù)是保存在pData指針指向的內(nèi)存塊中,通常這個(gè)內(nèi)存塊是系統(tǒng)另外分配的。但有一種情況例外,就是當(dāng)Bucket保存的數(shù)據(jù)是一個(gè)指針時(shí),HashTable將不會(huì)另外請(qǐng)求系統(tǒng)分配空間來(lái)保存這個(gè)指針,而是直接將該指針保存到pDataPtr中,然后再將pData指向本結(jié)構(gòu)成員的地址。這樣可以提高效率,減少內(nèi)存碎片。由此我們可以看到PHP HashTable設(shè)計(jì)的精妙之處。如果Bucket中的數(shù)據(jù)不是一個(gè)指針,pDataPtr為NULL。
HashTable中所有的Bucket通過(guò)pListNext, pListLast構(gòu)成了一個(gè)雙向鏈表。最新插入的Bucket放在這個(gè)雙向鏈表的最后。
注意在一般情況下,Bucket并不能提供它所存儲(chǔ)的數(shù)據(jù)大小的信息。所以在PHP的實(shí)現(xiàn)中,Bucket中保存的數(shù)據(jù)必須具有管理自身大小的能力。
復(fù)制代碼 代碼如下:

typedef struct _hashtable {
uint nTableSize;
uint nTableMask;
uint nNumOfElements;
ulong nNextFreeElement;
Bucket *pInternalPointer;
Bucket *pListHead;
Bucket *pListTail;
Bucket **arBuckets;
dtor_func_t pDestructor;
zend_bool persistent;
unsigned char nApplyCount;
zend_bool bApplyProtection;
#if ZEND_DEBUG
int inconsistent;
#endif
} HashTable;


相關(guān)文章

  • 淺談PHP的排列組合(如輸入a,b,c 輸出他們的全部組合)

    淺談PHP的排列組合(如輸入a,b,c 輸出他們的全部組合)

    下面小編就為大家?guī)?lái)一篇淺談PHP的排列組合(如輸入a,b,c 輸出他們的全部組合)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • PHP源碼之explode使用說(shuō)明

    PHP源碼之explode使用說(shuō)明

    最近一直在想有關(guān)字符串操作的一些效率上的事情,截取字串的問(wèn)題,都會(huì)避免不了重新分配空間的消耗,也順帶看了explode這個(gè)函數(shù)的源碼,理解下,拿出自己的分析共享下
    2011-08-08
  • PHP filesize函數(shù)用法淺析

    PHP filesize函數(shù)用法淺析

    在本篇文章中我們給大家整理了關(guān)于PHP中filesize函數(shù)的用法和相關(guān)知識(shí)點(diǎn),有需要的朋友們學(xué)習(xí)下。
    2019-02-02
  • PHP寫(xiě)入WRITE編碼為UTF8的文件的實(shí)現(xiàn)代碼

    PHP寫(xiě)入WRITE編碼為UTF8的文件的實(shí)現(xiàn)代碼

    可以把uft-8格式的文件,寫(xiě)到文本中的實(shí)現(xiàn)代碼
    2008-07-07
  • PHP 線程安全與非線程安全版本的區(qū)別深入解析

    PHP 線程安全與非線程安全版本的區(qū)別深入解析

    Windows版的PHP從版本5.2.1開(kāi)始有Thread Safe(線程安全)和None Thread Safe(NTS,非線程安全)之分,這兩者不同在于何處?到底應(yīng)該用哪種?這里做一個(gè)簡(jiǎn)單的介紹
    2013-08-08
  • PHP實(shí)現(xiàn)的字符串匹配算法示例【sunday算法】

    PHP實(shí)現(xiàn)的字符串匹配算法示例【sunday算法】

    這篇文章主要介紹了PHP實(shí)現(xiàn)的字符串匹配算法,簡(jiǎn)單描述了sunday算法的概念與原理,并結(jié)合實(shí)例形式分析了php基于sunday算法實(shí)現(xiàn)字符串匹配操作相關(guān)技巧,需要的朋友可以參考下
    2017-12-12
  • php繪制一個(gè)矩形的方法

    php繪制一個(gè)矩形的方法

    這篇文章主要介紹了php繪制一個(gè)矩形的方法,主要涉及GD庫(kù)中imagerectangle方法的使用技巧,需要的朋友可以參考下
    2015-01-01
  • 訪問(wèn)編碼后的中文URL返回404錯(cuò)誤的解決方法

    訪問(wèn)編碼后的中文URL返回404錯(cuò)誤的解決方法

    這篇文章主要介紹了訪問(wèn)編碼后的中文URL返回404錯(cuò)誤的解決方法,本文使用的是替換方法,當(dāng)然也可以使用加密方法來(lái)解決,最后附妹子圖一張,需要的朋友可以參考下
    2014-08-08
  • php設(shè)置靜態(tài)內(nèi)容緩存時(shí)間的方法

    php設(shè)置靜態(tài)內(nèi)容緩存時(shí)間的方法

    這篇文章主要介紹了php設(shè)置靜態(tài)內(nèi)容緩存時(shí)間的方法,涉及針對(duì)header函數(shù)中參數(shù)的應(yīng)用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-12-12
  • php開(kāi)發(fā)微信支付獲取用戶地址

    php開(kāi)發(fā)微信支付獲取用戶地址

    微信支付的收貨地址共享功能,主要是統(tǒng)一的管理微信用戶個(gè)人的收貨地址,其收貨地址可以被應(yīng)用于所有可以調(diào)用的開(kāi)發(fā)者。用戶的收貨地址包含了很多個(gè)人信息,因此該接口必須要通過(guò)申請(qǐng),申請(qǐng)的方式可以在mp平臺(tái)上查看到。
    2015-10-10

最新評(píng)論

株洲市| 二手房| 上蔡县| 博湖县| 宁远县| 安丘市| 孝昌县| 菏泽市| 宁津县| 大洼县| 渑池县| 启东市| 黄龙县| 荔波县| 巴林左旗| 钦州市| 南川市| 麟游县| 宁安市| 大化| 陇川县| 库伦旗| 连平县| 曲松县| 邓州市| 靖江市| 鱼台县| 贡觉县| 额敏县| 维西| 久治县| 中宁县| 金昌市| 黎川县| 枞阳县| 长泰县| 文安县| 武邑县| 兴山县| 潢川县| 文化|