redis基礎資料結構(五) 跳躍表

2021-08-20 20:37:14 字數 2039 閱讀 7745

跳躍表是一種對順序鍊錶的改進,將查詢順序鍊錶的o(n)時間優化為o(logn)時間,空間增加約兩倍,有兩種常見變體,一種是隨機跳躍表,使用隨機演算法決定每個節點的高度,缺陷有產生隨機數的開銷;另一種是123確定性跳躍表,除了頭和尾,第n層相鄰的兩個節點之間只有1個,2個或者3個第n-1層的節點,當插入或刪除時調整結構;另一種對順序鍊錶的o(logn)優化是,使用乙個指標陣列,陣列中每個指標指向乙個鍊錶節點,從而變成二分查詢,得到乙個o(logn)的時間界,這種方法需要的空間少,缺陷是在鍊錶增刪節點時需要對指標陣列進行大量的記憶體搬移,底層呼叫c庫函式memmove可以防止重疊記憶體拷貝造成踩記憶體,但是效能堪憂。

redis的跳躍表使用的是隨機跳躍表,**在server.h和t_zset.c中,server.h提供了跳躍表節點和頭的定義,如下

typedef struct zskiplistnode  level;

} zskiplistnode;

typedef struct zskiplist zskiplist;

zskiplistnode是跳躍表節點,包括乙個可變長字串,乙個後向指標backward用於指向本節點在level[0]的上乙個節點,level結構中每一層都有乙個前向指標,以及乙個scan表示跨過幾個level[0]元素可以達到本層下乙個節點。zskiplist是頭,包括頭尾指標,長度和層數

t_zsets中提供的api:

zslcreatenode:建立乙個跳躍表節點,呼叫者需要提供明確的level

zslcreate:建立乙個zskiplist,其結構中有頭尾指標,頭指標指向乙個32層的節點,32層就是支援的最高層數

zslfreenode:釋放乙個跳躍表節點的記憶體,包含其中的sds

zslfree:銷毀乙個zskiplist,包含所有節點和頭的記憶體釋放,方法是順序遍歷level[0]節點

zslinsert:向zskiplist中插入乙個節點

zsldeletenode:在乙個zskiplist中刪除乙個節點,內部函式,呼叫者需要提供每個level的刪除位置

zsldelete:在乙個zskiplist中刪除乙個節點,外部函式,呼叫者提供score和sds供查詢節點,可選擇是否保留節點記憶體

zslvaluegtemin:判斷value是否比最小值大

zslvalueltemax:判斷value是否比最大值小

zslisinrange:用score判斷zskiplist中是否有一部分在range中

zslfirstinrange:找到乙個zskiplist中第乙個出現在range中的節點

zsllastinrange:找到乙個zskiplist中最後乙個出現在range中的節點

zsldeleterangebyscore:刪除zskiplist在score範圍中的節點

zsldeleterangebylex:刪除zskiplist在sds範圍中的節點

zsldeleterangebyrank:刪除一段索引範圍的節點,索引是level[0]中出現的位置

zslgetrank:查詢乙個節點對應的索引

zslgetelementbyrank:通過節點查詢乙個對應的索引

zslparserange:將給定的min和max物件解析到range中,關於物件在物件系統中總結

zslparselexrangeitem:從給定物件中解析出乙個sds,並作為range中的乙個邊界使用

zslfreelexrange:銷毀乙個sds的range

zslparselexrange:讀取sds型別的range

sdscmplex:比較兩個sds的大小

zsllexvaluegtemin:根據提供的值判斷是否要更新range中的min

zsllexvalueltemax:根據提供的值判斷是否要更新range中的max

zslisinlexrange:判斷zskiplist中是否有一部分在sds的range中

zslfirstinlexrange:查詢乙個zskiplist中第乙個出現在sds的range中的節點

zsllastinlexrange:查詢乙個zskiplist中最後乙個出現在sds的range中的節點

redis資料結構 跳躍表

跳躍表 skiplist 是一種有序資料鏈表結構,它通過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的。查詢平均效能為o logn 最壞的情況會出現o n 情況,而redis中的zset在資料較多的時候底層就是採用跳躍表去實現的,元素較少的時候會進行小物件壓縮採用壓縮列表實現。小...

Redis資料結構 跳躍表

跳躍表是一種有序資料結構,它通過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的。redis使用跳躍表作為有序集合鍵的底層實現之一,如果乙個有序集合包含的元素數量比較多,又或者有序集合中的元素的成員是比較長的字串時,redis就會使用跳躍表作為有序集合鍵的底層實現。redis的跳躍...

Redis資料結構 skiplist(跳躍表)

跳躍表在redis中主要用於有序集合鍵的實現,其他地方沒怎麼用到,但是這種資料結構在面試的時候經常會問到,因為它作為一種查詢時間複雜度為o logn 的特殊的鍊錶,效率堪比紅黑樹或平衡樹,而實現難度卻遠小於它們。下面分3個模組講解redis的跳躍表實現 一 跳躍表的應用場景 在redis中,當有序集...