bucket裡的h欄位:雜湊函式拆分成hash1和hash2,hash1將key對映為h值,hash2將h值對映為slot的索引值。h值為數字key,當key為數字時,hash1函式沒有做任何事情,當key為字串時,會通過hash1函式將字串key計算出乙個數字h值,加快字串key之間的比較速度,如果要比較兩個字串的key是否相等,會先比較h值是否相等,如果相等再去比較字串的長度和內容,畢竟在大部分情況下,不同字串的h值一般是不相同的,引入h欄位大大提高了hashtable的插入、查詢的速度。
php的每個陣列維護了兩個雙向鍊錶,全域性鍊錶,保證整個陣列元素有序,連線slot的鍊錶,每個slot維護著乙個鍊錶,將所有雜湊衝突的bucket串聯起來,也就是說每乙個bucket都處在全域性鍊錶和所在slot鍊錶兩個雙向鍊錶上。在php5中,鍊錶是物理上的鍊錶,而php7中的鍊錶是一種邏輯上的鍊錶,所有的bucket都分配在連續的陣列記憶體中,不再通過指標維護上下游關係,每乙個bucket只維護下乙個bucket在陣列中的索引。也就是說不管是slot還是bucket,都儲存在連續的記憶體中,都是陣列。
typedef struct _bucketbucket;
未使用bucket:最初所有的bucket都是未使用狀態
有效bucket:儲存有效資料的buckeet
無效bucket:bucket上的資料被刪除
擴容和rehash操作:當容量不夠時會有以下兩種情況
第一種情況:檢查已刪除元素所佔的比例,說到比例,如果nnumused - nnumofelements > nnumofelements >> 5(無效的數量大於有效數量的2的5次方分之1)時,則進行 rehash,移除已刪除元素,重建索引。相應的zend_array結構體中的2個字段如下:
nnumused:指所有已使用的bucket的數量,包括有效bucket和無效bucket
nnumofelements:有效bucket的數量,bucket的zval.u1.v.type中對應的type欄位不為is_undef
第二種情況:當第一種情況不滿足時,則進行擴容,大小為原來的2倍
packed array有以下約束和特性:
key全是數字key
key按插入順序排列,並且是遞增的
每乙個key-value對應的儲存位置都是確定的,都儲存在buclet陣列的第key個元素上
packed array不需要索引陣列(空間優化,並且訪問也是直接操作bucekt陣列,不需要借助索引陣列,效能也有提公升)
hash array
依賴索引陣列來維護每乙個slot鍊錶中首元素在bucket陣列中的下標,例如:key為x時,x經過hash1處理後的h值為9223372036854953501,與ntablemask(-8)做位或運算後結果是-3,然後去索引陣列查-3這個slot的值,slot值對應的陣列儲存了多個bucket元素,該slot的鍊錶首元素在bucket陣列的下標為0,因此從這個下標向下挨個對比bucket桶的key值,直到zval.u2.next為空為止,一定可以找到key為x的元素。
注意:php7會在packed array的空間效率以及時間效率優化與空間浪費之間做乙個平衡,當空間浪費過多時(比如下標為,1,8, 中間浪費7個bucket空間),則會將packed array轉化為hash array。
Fabric 原始碼解析 原始碼目錄解析
這裡對重要的一些目錄進行說明 bccsp 與密碼學 加密 簽名 證書等等 相關的加密服務 將fabric中用到的密碼學相關的函式抽象成了一組介面,便於拓展。bddtests 一種新型的軟體開發模式 行為驅動開 需求 開發 common 一些公共庫 錯誤處理 日誌處理 賬本儲存 策略以及各種工具等等 ...
Spring原始碼解析之 Aop原始碼解析(2)
spring aop 更多的是oop開發模式的乙個補充,幫助oop以更好的方式來解決對於需要解決業務功能模組之上統一管理 的功能 以一副圖來做為aop功能的說明更直觀些。對於類似系統的安全檢查,系統日誌,事務管理等相關功能,物件導向的開發方法並沒有更好的解決方法 aop引入了一些概念。更多的是spr...
Integer原始碼解析
public class test else integer i3 200 integer i4 200 if i3 i4 else 結果為 原因integer 類會快取 128 到 127 之間的整數 但是如果new interger的話就是不同的物件了 源 分析 如果是在 128到正的127之間...