1. 程式人生 > >redis原始碼之跳躍表skiplist

redis原始碼之跳躍表skiplist

未完待續…

跳躍表skiplist

1.簡介:

離散,有序的資料結構。和連結串列、字典等資料結構被廣泛地應用在Redis 內部不同, Redis 只在兩個地方用到了跳躍表,一個是實現有序集合鍵,另一個是在叢集節點中用作內部資料結構。

2.定義:

/*
 * 跳躍表節點
 */
typedef struct zskiplistNode {

    robj *obj;// 成員物件,它指向一個字串物件,而宇符串物件則儲存著一個SDS值

    double score;// 分值,按此排序

    struct zskiplistNode *backward;// 後退指標

    struct
zskiplistLevel {// 層 struct zskiplistNode *forward;// 前進指標 unsigned int span;// 跨度 } level[]; } zskiplistNode; /* * 跳躍表 */ typedef struct zskiplist { struct zskiplistNode *header, *tail;// 表頭節點和表尾節點 unsigned long length;// 表中節點的數量,表頭節點不計算在內 int level;// 表中層數最大的節點的層數,表頭節點的層數不計算在內
} zskiplist;

注意:
1.初看上去,很容易以為跨度和遍歷操作有關,但實際上並不是這樣,遍歷操作只使用前進指標就可以完成了,跨度實際上是用來計算排位( rank )的:在查詢某個節點的過程中,將沿途訪問過的所有層的跨度累計起來,得到的結果就是目標節點在跳躍表中的排位。
舉個例子,圖5-4 用虛線標記了在跳躍表中查詢分值為3.0 、成員物件為o3 的節點時,沿途經歷的層z 查詢的過程只經過了一個層,並且層的跨度為3 ,所以目標節點在跳躍表中的排位為3。類似的,跨度為1可以累加。
這裡寫圖片描述
2.住意表頭節點和其他節點的構造是一樣的:表頭節點也有後退指標、分值和成員物件,不過表頭節點的這些屬性都不會被用到


3.在同一個跳躍表中,各個節點儲存的成員物件必須是唯一的,但是多個節點儲存的分值卻可以是相同的:分值相同的節點將按照成員物件在字典序中的大小來進行排序。
4.跳躍表節點的level 陣列可以包含多個元素,每個元素都包含一個指向其他節點的指標,程式可以通過這些層來加快訪問其他節點的速度,一般來說,層的數量越多,訪問其他節點的速度就越快。每個跳躍表節點的層高都是1 至32 之間的隨機數。