跳躍表 -《Redis設計與實現》讀書筆記
阿新 • • 發佈:2021-08-02
使用場景
- 當有序集合包含的元素數量比較多 或者 有序集合中元素的成員是比較長的字串時,使用跳躍表實現有序集合
- 叢集節點中用作內部資料結構
定義
// 跳躍表節點 typedef struct zskiplistNode { // 成員物件:一個SDS值 // 在同一個跳躍表中,各個節點儲存的成員物件必須是唯一的,但是多個節點儲存的分值卻可以是相同的 // 分值相同的節點將按照成員物件在字典序中的大小來進行排序,成員物件較小的節點會排在前面(靠近表頭的方向),而成員物件較大的節點則會排在後面(靠近表尾的方向) sds ele; // 分值 // 跳躍表中的所有節點都按分值從小到大排序 double score; // 後退指標:用於從表尾向表頭方向訪問節點 // 每次只能後退至前一個節點 struct zskiplistNode *backward; // 層陣列可以包含多個元素,每個元素都包含一個指向其他節點的指標 // 層可以加快訪問其他節點的速度,一般來說,層的數量越多,訪問其他節點的資料越快 // 每次建立一個新跳躍表節點的時候,根據冪次定律(越大的數出現的概率越小)隨機生成一個介於1和32之間的值作為level陣列的大小 struct zskiplistLevel { // 前進指標:用於從表頭向表尾方向訪問節點 struct zskiplistNode *forward; // 跨度:記錄前進指標所指向節點和當前節點的距離 // 兩個節點之間的跨度越大,相距得就越遠 // 由於指向null的所有前進指標沒有連向任何節點,所以跨度都為0 // 跨度用來計算排位(rank) unsigned long span; } level[]; } zskiplistNode; // 跳躍表 typedef struct zskiplist { // 指向跳躍表的表頭節點:表頭節點的後退指標、分值和成員物件屬性都不會被用到,僅用到層屬性 // 指向跳躍表的表尾節點 struct zskiplistNode *header, *tail; // 跳躍表內節點的數量 unsigned long length; // 跳躍表內層數最大的那個節點的層數(表頭節點的層數不算) int level; } zskiplist;
原始碼閱讀
- 檔案:src/server.h、src/t_zset.c、src/sort.c