Redis的跳躍表底層實現

2021-09-07 02:58:47 字數 1228 閱讀 4719

跳躍表是一種有序的資料結構,主要用在zset(有序集合)和集群節點的內部資料結構。在大部分情況下,跳躍表的效率可以和平衡樹相媲美,並且因為跳躍表的實現比平衡樹要來得更為簡單,所以有不少程式都使用跳躍表來代替平衡樹。注意mysql的底層採用的是b+樹實現。

跳躍表的實現

redis的跳躍表由redis.h/zskiplistnode和redis.h/zskiplist兩個結構定義,其中zskiplistnode結構用於表示跳躍表節點,而zskiplist結構則用於儲存跳躍表節點的相關資訊,比如節點的數量,以及指向表頭節點和表尾節點的指標等等。

header:指向跳躍表的表頭節點

tail:指向跳躍表的表尾節點

level:記錄目前跳躍表內,層數最大的那個節點的層數(表頭節點的層數不計算在內)

length:記錄跳躍表的長度,也即是,跳躍表目前包含節點的數量(表頭節點不計算在內)

位於zskiplist結構右方的是四個zskiplistnode結構,該結構包含以下屬性:

層(level):節點中用l1、l2、l3等字樣標記節點的各個層,l1代表第一層,l2代表第二層,依次類推。每個層都帶有兩個屬性:前進指標和跨度。前進指標用於訪問位於表尾方向的其他節點,而跨度則記錄了前進指標所指向節點和當前節點的距離。在上面的中,連線上帶有數字的箭頭就代表前進指標,而那個數字就是跨度。當程式從表頭向表尾進行遍歷時,訪問會沿著層的前進指標進行。

後退(backward)指標:節點中用bw字樣標記節點的後退指標,它指向位於當前節點的前乙個節點。後退指標在程式從表尾向表頭遍歷時使用。

分值(score):各個節點中的1.0、2.0和3.0是節點所儲存的分值。在跳躍表中,節點按各自所儲存的分值從小到大排列。

成員物件(obj):各個節點中的o1、o2和o3是節點所儲存的成員物件。

注意表頭節點和其他節點的構造是一樣的:表頭節點也有後退指標、分值和成員物件,不過表頭節點的這些屬性都不會被用到,所以圖中省略了這些部分,只顯示了表頭節點的各個層。

實質上僅靠多個跳躍表節點就可以組成乙個跳躍表,但通過使用乙個zskiplist結構來持有這些節點,程式可以更方便地對整個跳躍表進行處理,比如快速訪問跳躍表的表頭節點和表尾節點,或者快速地獲取跳躍表節點的數量(也即是跳躍表的長度)等資訊,這樣獲取表頭、表尾節點,表長,以及表中最高層數的複雜度均為o(1)。

Redis06 底層 跳躍鍊錶skiplist

每次初始化時初始化最初的節點,也就是最左邊的節點,它的高度就是跳表最大高度,初始每個位置指標指向null。插入元素時首先判斷該元素在集合中是否存在,從最初節點的最高位置開始尋找,向前的指標鍵值比要找的值大就向下移動,小就向前移動。如果不存在就插入,首先用隨機函式每次隨機乙個數0或1,出現一次1就停止...

Redis的跳躍表

typedef struct zskiplistnode level 層 層高1 32隨機,一般層數量越多,訪問其他節點速度越快 struct zskiplistnode backward 後退指標 只能退至前乙個節點 double score 分值 所有節點按分值從小到大排序 robj obj 成...

Redis底層資料結構(6)跳躍表

當乙個有序集合包含的元素數量多,又或者有序集合中的元素的成員是比較長的字串時,redis就會使用跳躍表作為有序集合鍵的底層實現。簡介如果我們要實現按照成績對學生進行排名,可以選擇陣列 鍊錶 平衡樹或紅黑樹來實現,陣列的插入和刪除效率低,鍊錶查詢的效率低,平衡樹或紅黑樹雖然效率高但是實現複雜。跳躍表 ...