Analysis of internal implementation principle of Redis ordered set (II.)

Source: Internet
Author: User

Redis:https://github.com/zwjlpeng/redis_deep_read

This blog post closely follows the internal implementation of the Redis ordered set of principles analysis, in this Bovenrivan the source code is in the following src/version.h defined in the redis version of the main

#define Redis_version "2.9.11"

In the analysis of the internal implementation of the Redis ordered set, I analyzed when Redis started to support the sequential set, the principle of jumping table, the structure of the jumping table, the Find/insert/delete implementation of the jump table, understand the basic structure of the jumping table, understand the Redis The implementation of the ordered set is not difficult, because the implementation of the Redis ordered set is also based on the jumping table as the underlying data structure, choose this data structure, not only because of simple, more because of performance.

The basic data structure of a jump table in Redis is defined as follows, and the hop table implemented in Redis is characterized by a forward pointer, a back pointer, and a span in the structure of the forward pointer, as compared to the basic hop table data structures. span fields, where the presence of this span field helps to quickly calculate the ranking of elements throughout the collection

//define a basic data node for a skip tabletypedef struct ZSKIPLISTNODE {robj*obj;//Zset Value    DoubleScore;//Zset scorestruct Zskiplistnode *backward;//the back pointerstruct Zskiplistlevel {//forward Pointerstruct Zskiplistnode *forward; unsignedintspan; } level[];} zskiplistnode;typedef struct Zskiplist {struct Zskiplistnode*header, *tail; unsignedLonglength; intLevel ;} Zskiplist;//ordered set data structuretypedef struct ZSET {dict*dict;//dictionary holds value, with value as keyZskiplist *ZSL;} Zset;

Convert the above data structure into a more formalized graphical representation, as shown in

In, you can see that the header pointer is pointing to a table header node with a fixed level (32 layer ), why it is defined as a, because it is defined as a layer in theory for 2^32-1 an element of the query is optimal, and 2^32=4294967296 elements, for the vast majority of applications, is enough, so it is defined as a layer, to why the query is optimal, you can think of it as a a complete binary sorting tree of layers that calculates the number of nodes in the tree

Another notable point in Redis 's ordered set is how it is stored when the score is the same, and when the score of the two values in the collection is the same, the store in the Skip table compares the two values. The two values are sorted by dictionary stored in the Skip table structure

With the above-mentioned data structure related to the basic knowledge, to see the Redis on zskiplist/zskiplistnode related operations, the source code is as follows (source code is from t_zset.c)

Create the source of the skip table structure

//#define ZSKIPLIST_MAXLEVEL */should be enough for 2^32 elements * /Zskiplist *zslcreate (void) {    intJ; Zskiplist*ZSL; //Allocating MemoryZSL = Zmalloc (sizeof(*ZSL)); ZSL->level =1;//The default level is 1Zsl->length =0;//Jump table length is set to 0Zsl->header = Zslcreatenode (Zskiplist_maxlevel,0, NULL);  for(j =0; J < Zskiplist_maxlevel; J + +) {        //because there are no elements, the forward pointer of the header node is set to 0Zsl->header->level[j].forward =NULL; //set the Span field in the forward pointer structure of the header node to 0Zsl->header->level[j].span =0; }    //table header back pointer set to 0Zsl->header->backward =NULL; //footer node set to nullZsl->tail =NULL; returnZSL;}

In the above code called the zslcreatenode function, the source code of the function is as follows =

Zskiplistnode *zslcreatenode (intdouble score, RobJ *obj) {    *zn = zmalloc (sizeof (*ZN) +level*sizeof(struct  zskiplistlevel));    Zn->score = score;    Zn->obj = obj;     return Zn;}

After executing the above code, you will create a skip table structure as shown

The basic structure of the jump table is created, the following is the insert operation, the source code inRedis is as follows

Zskiplistnode *zslinsert (Zskiplist *ZSL,DoubleScore, RobJ *obj) {Zskiplistnode*update[zskiplist_maxlevel], *x;//Update[32]UnsignedintRank[zskiplist_maxlevel];//Rank[32]    intI, level; Redisassert (!isNaN (score)); X= zsl->header; //find where an element is inserted     for(i = zsl->level-1; I >=0; i--) {        /*store rank that's crossed to reach the insert position*/Rank[i]= i = = (zsl->level-1) ?0: rank[i+1];  while(X->level[i].forward &&(x->level[i].forward->score < score | |//The following is the case of scoring the same, comparing the dictionary sort of value(X->level[i].forward->score = = Score &&comparestringobjects (x->level[i].forward->obj,obj) <0)) {Rank[i]+ = X->Level[i].span; X= x->Level[i].forward; } Update[i]=x; }    //generate a random number of layersLevel =Zslrandomlevel (); if(Level > Zsl->Level ) {         for(i = zsl->level; i < level; i++) {Rank[i]=0; Update[i]= zsl->header; Update[i]->level[i].span = zsl->length; }        //record maximum number of layersZsl->level =Level ; }    //Generating a skip table nodex =Zslcreatenode (level,score,obj);  for(i =0; I < level; i++) {x->level[i].forward = update[i]->Level[i].forward; Update[i]->level[i].forward =x; //Update spanX->level[i].span = Update[i]->level[i].span-(rank[0] -Rank[i]); Update[i]->level[i].span = (rank[0]-rank[i]) +1; }//This situation only occurs when the number of layers that are randomly out is less than the maximum number of layers     for(i = level; I < zsl->level; i++) {Update[i]->level[i].span++; } x->backward = (update[0] = = Zsl->header)? null:update[0]; if(x->level[0].forward) x->level[0].forward->backward =x; ElseZSL->tail =x; ZSL->length++; returnx;}

In the source code above, there is a function to generate a random number of layers, as follows:

 int  zslrandomlevel (void   int  level = 1  ;  //  #define ZSKIPLIST_P 0.25  while  ((Random () &0xffff ) < (zskiplist_p * 0XFFFF   + = 1  ;  //  #ZSKIPLIST_MAXLEVEL  return  (level<zskiplist_maxlevel)?  Level:zskiplist_maxlevel;}  

The graphical form description is as follows:

Understand the insert operation, the other query, delete, the scope operation is basically similar, ignored here ...

Analysis of internal implementation principle of Redis ordered set (II.)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.