1.7.1.3 SkipList(跳跃表)操作

1) An empty SkipList

redis相关知识(六)_elements

2) Finding an element with key x

redis相关知识(六)_explained_02

1
2
3
4
5
6
7
8
9
10
11
12
13
p=top
While(1)
{
while (p->next->key < x ) p=p->next;
If (p->down == NULL ) return p->next
p=p->down ;
}

Observe that we return x, if exists, or succ(x) if x is not in the SkipList

3) Inserting new element X

Determine k the number of levels in which x participates (explained later)

Do find(x), and insert x to the appropriate places in the lowest k levels. (after the elements at which the search path turns down or terminates)

Example – inserting 119. k=2

If k is larger than the current number of levels, add new levels (and update top)

Example – inser(119) when k=4

redis相关知识(六)_explained_03

Determining k

k – the number of levels at which an element x participate.

Use a random function OurRnd() — returns 1 or 0 (True/False) with equal probability.

k=1 ;

While( OurRnd() ) k++ ;

Deleteing a key x

Find x in all the levels it participates, and delete it using the standard ‘delete from a linked list’ method.

If one or more of the upper levels are empty, remove them (and update top)

redis相关知识(六)_explained_04

Facts about SkipList

The expected number of levels is O( log n )

(here n is the numer of elements)

The expected time for insert/delete/find is O( log n )

The expected size (number of cells) is O(n )

1.7.2 redis SkipList 实现

/* ZSETs use a specialized version of Skiplists */

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
typedef struct zskiplistNode
{
robj *obj;
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;
typedef struct zset
{
dict *dict;
zskiplist *zsl;
} zset;