Data structure of redis study notes ----- skiplist (skip list)

Overview

Composition structure

operating

Inquire

insert

Distribution layer

delete

Update

Rank

Recommended reading


Overview

Redis ordered collection may need to obtain the value list in order according to the provided score, and also need a hash structure to store the correspondence between value and score. In order to achieve these two functions, redis uses a jump table for the bottom layer of the ordered collection. to realise. If you don't know the jump table, I suggest you go to see Xiao Hui's explanation of the jump table first .

Composition structure

struct zslnode{

    string value;

    double score;

    //多层连接指针
    zslnode*[] forwards;

    //回溯指针
    zslnode*[] backward;
}

struct zsl{
    //头指针
    zslnode* header;

    //跳跃表最高层
    int maxlevel;
    
    //所有键值对
    map<string, zslnode*> ht;
}

operating

Inquire

As shown in the figure above, suppose we want to search for 17, we start from the leftmost header, from the highest level (l3) we first encounter a node 21, we are looking for a lower level (l2) that is smaller than it It is found that the node 2 on the left and the node 37 on the right do not meet the conditions, we then go to the next layer (l1) and find that the node on the left is our data, take it out and return

insert

For insertion, we must first find a suitable location, and then start to create a new node. When creating, we need to randomly assign a layer number (if the number of layers allocated is higher than the highest number, then the highest height of the jump table needs to be updated), the new node To string together the two nodes before and after

Distribution layer

Without inserting a new node, you need to allocate a number of layers. In theory, the probability of going up one layer is 50%, and the maximum number of layers is limited to 64 layers, so the probability of reaching the 64 layer is 2^-63. Let's look at the random function

//本代码来自redis深度历险
//新节点随机层数

int zslRandomLevel(void){

    int level = 1;
    //ZSKIPLIST_P在redis源码中晋升率为25%
    while (random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
        level+= 1;
    return (level < ZSKIPLIST_MAXLEVEL) ? level :ZSKIPLIST_MAXLEVEL;
}

delete

When deleting, we need to find the position of the deleted node. After deleting, the nodes before and after the deleted node need to be rearranged (the two nodes are connected). If the highest level is affected, the maxLevel needs to be modified.

Update

When we call zadd, if the data does not exist, insert the operation, if it exists, we need to modify the score of this node. The modification operation requires two queries. In the first query, we need to find the corresponding node for deletion, and the second query is suitable for inserting. There is a special case in the update. All the scores in the ordered set are the same, so you need to compare the value (string comparison)

Rank

//代码来自redis深度历险
struct zslforward{

    zslnode* item;
    
    //跨度
    long span;
}

In our normal use of an ordered set, it is sorted, then this sorting is achieved? In the forward pointer summary, there is a span field that records how many nodes the current node of the current layer needs to go through to jump to the next node along the forward pointer

 

Recommended reading

Why does redis use skiplist instead of red-black?

 

This article comes from the Redis In-Depth Adventure, Redis Design and Implementation , and the official redis documents are waiting to be summarized. Please understand if there are any shortcomings. In the end, everyone has time to read Qian Wenpin's Redis In-Depth Adventures book, which is very powerful.

Guess you like

Origin blog.csdn.net/lin_keys/article/details/105891687