Redis source code – jump table

Time:2021-10-21

preface

A skip list is an ordered data structureOrdered linked listIt solves the efficiency problem of finding a value in the ordered linked list. Jump table supports averageO(logn)In most cases, the efficiency of node search with the worst o (n) complexity is comparable to that of balanced tree, and the implementation is simpler. Redis uses the jump table as theOrdered set keyOne of the underlying implementations of.

Basic introduction

As one of the underlying implementations of an ordered set, we will first look at the simple usage of an ordered set.

> zadd fruit 10 banana
(integer) 1
> zadd fruit 12 apple
(integer) 1
> zadd fruit 8 cherry
(integer) 1
>Zrange fruit 0 - 1 # by score
1) "cherry"
2) "banana"
3) "apple"

principle

Search of ordered linked list

Such as the following ordered linked list
Redis source code - jump table
Search for elements < 5, 23 and 40 > from this ordered table. The number of comparisons is < 2, 4 and 6 respectively. The total number of comparisons is 2 + 4 + 6 = 12.
Is there an optimized algorithm?

Consider that the linked list is ordered, but binary search cannot be used. Similar to binary search tree, we extract some nodes as indexes. The following structure is obtained:

Redis source code - jump table

Here, we extract < 4, 8, 34, 45 > as the primary index, so that the number of comparisons can be reduced during search.

We can also extract some elements from the primary index and use them as secondary indexes to form the following structure:

Redis source code - jump table

Due to the similar binary search, the efficiency is improved, and the average search complexity can reach o (logn)

Skip table implementation

The structure diagram is as follows:
Redis source code - jump table

On the far left of the picture is the zskiplist structure, which contains the following attributes:
1) Header: points to the header node of the jump table
2) Tail: refers to the footer node of the jump table
3) Level: records the number of layers of the node with the largest number of layers in the current jump table (the number of layers of the header node is not included)
4) Length: records the length of the jump table, that is, the number of nodes contained in the jump table (header nodes are not included)

Level: in the figure, L1 and L2 are the layers of nodes, and each layer is equivalent to an ordered linked list. Each layer has two attributes: forward pointer and span.
Forward pointer: used to access other nodes at the end of the table.
Span: it records the distance between the node pointed by the forward pointer and the current node, that is, how many nodes are separated in the middle.
Backward pointer: the BW marked in the node is the backward pointer, which points to the previous node of the current node. Used when the program traverses from the end of the table to the header.
Score: 1.0, 2.0 and 3.0 in each node are the scores saved by the node. In the jump table, nodes are sorted from small to large according to their scores.
Member object (obj): O1, O2 and O3 in each node are the member objects saved by the node.

lookup

As shown in the figure above
Find node O3
After one search from L5 layer, O3 can be found
Redis source code - jump table
Find node O2
Redis source code - jump table