Redis的底層資料結構-跳錶
阿新 • • 發佈:2021-11-11
跳躍表(skiplist)是一種有序資料結構,它通過在每個節點中維持多個指向其它節點的指標,從而達到快速訪問節點的目的。具有如下性質:
1、由很多層結構組成;
2、每一層都是一個有序的連結串列,排列順序為由高層到底層,都至少包含兩個連結串列節點,分別是前面的head節點和後面的nil節點;
3、最底層的連結串列包含了所有的元素;
4、如果一個元素出現在某一層的連結串列中,那麼在該層之下的連結串列也全都會出現(上一層的元素是當前層的元素的子集);
5、連結串列中的每個節點都包含兩個指標,一個指向同一層的下一個連結串列節點,另一個指向下一層的同一個連結串列節點;
Redis中跳躍表節點定義如下:
typedef struct zskiplistNode { //層 struct zskiplistLevel{ //前進指標 struct zskiplistNode *forward; //跨度 unsigned int span; }level[]; //後退指標 struct zskiplistNode *backward; //分值 double score; //成員物件 robj *obj; } zskiplistNode
多個跳躍表節點構成一個跳躍表:
typedef struct zskiplist{ //表頭節點和表尾節點 structz skiplistNode *header, *tail; //表中節點的數量 unsigned long length; //表中層數最大的節點的層數 int level; }zskiplist;
①、搜尋:從最高層的連結串列節點開始,如果比當前節點要大和比當前層的下一個節點要小,那麼則往下找,也就是和當前層的下一層的節點的下一個節點進行比較,以此類推,一直找到最底層的最後一個節點,如果找到則返回,反之則返回空。
②、插入:首先確定插入的層數,有一種方法是假設拋一枚硬幣,如果是正面就累加,直到遇見反面為止,最後記錄正面的次數作為插入的層數。當確定插入的層數k後,則需要將新元素插入到從底層到k層。
③、刪除:在各個層中找到包含指定值的節點,然後將節點從連結串列中刪除即可,如果刪除以後只剩下頭尾兩個節點,則刪除這一層。