Adlist of Redis underlying data structure

Source: Internet
Author: User

Recently, I wanted to learn Redis by using Redis's source code. Although the usual work is not used much, but the Redis is still more interested in, after all, its performance is good. Redis is an open source project that we can use to understand Redis through source code. I will later through their own study, write some about the Redis source code posts. The main content of the post is the analysis of the code design, and does not explain the source code in detail. If there is a wrong place, please correct me. Source code is Reids 3.0.3 version.


Adlist


One, adlist, double chain list


The data structure is defined as follows:

node typedef struct LISTNODE {struct ListNode *prev;    struct ListNode *next; void *value;}    listnode;//iterator typedef struct LISTITER {ListNode *next;    int direction;//iterator Direction} listiter;//linked list typedef struct List {ListNode *head;    ListNode *tail; void * (*dup) (void *ptr);//copy function void (*free) (void *ptr);//Destroy function int (*match) (void *ptr, void *key);//matching function unsigned Long Len;} List


With the general two-way linked list is not very different. Redis's doubly linked list is designed to be a more generic linked list, so value is a pointer, not limited to the actual type of value, in addition to the list provides a copy, destroy, matching function, so that the list of value can support different memory management methods, or some callbacks.


In addition, iterators are provided, and the iterator of a linked list is usually not a random iterator, but only one element can jump one element at a to. Since this is a doubly linked list, the iterator can jump forward or jump backwards, but redis only provides functions that jump backwards. Iterators also support forward, reverse, and need to specify the direction through the direction field. The combination of direction also enables the iterator to jump forward, presumably so that Adlist does not provide a function to jump forward.


Second, the related operation function of adlist


There are two main categories, one is a macro, a class is a function, see the code is relatively simple, here is not detailed code. Just simply enumerate the functions.

/* prototypes */list *listcreate (void);//Create linked list void listrelease (list *list);//Destroy List of lists  *listaddnodehead (List *list, void *value);//Insert element List *listaddnodetail into the table header (list * List, void *value);//Insert Element List *listinsertnode (List *list, listnode *old_node) toward the end of the table,  void *value, int after)  //insert to the specified position Void listdelnode (list *list,  Listnode *node);//Delete node listiter *listgetiterator (list *list, int direction);// Iterator Listnode *listnext (listiter *iter);//iterator jumps backward, next Void listreleaseiterator (Listiter *iter) ;//Destroy Iterator List *listdup (list *orig);//Copy list Listnode *listsearchkey (list *list, void  *key);//Query Listnode *listindex (LIST *LIST, LONG INDEX);//Gets the node at the specified location void  Listrewind (List *list, listiter *li);//The iterator returns the header, forward iterator Void listrewindtail (list *list,  LISTITER *LI);//iterator to footer, reverse iterator VoId listrotate (list *list);//rotate linked list, put the footer element to the table header 


Iii. Adlist provides memory management of objects


Let's talk about how Adlist manages memory through Dup,free.


There are three places to be aware of:

A. When inserting an element, value in node is directly assigned the value of the incoming parameter, and the DUP function is not called.

B. In listdup, if the DUP function exists, call the DUP function to copy value.

C. Listdelnode and Listrelease, if the free function exists, the value is destroyed by the free method.


Through the above three points, you can implement some simple memory management methods, mainly the application and destruction of object memory management. Here is a brief introduction to the usage.


1) Adlist is not responsible for application and destruction


such as the following code (code does not pass the compilation test, may be wrong)

Char s[] = "Hello world"; list *lst = Listcreate ();//list free,dup function is empty listaddnodetail (LST, &s[0]); Listaddnodetail ( LST, &s[1]); Listaddnodetail (LST, &s[2]); Listaddnodetail (LST, &s[3]);//do some thing with lstlist *lst2 = Listdup (LST);//do some thing with lst2listrelease (LST); Listrelease (LST2);


In the example above, Adlist is not responsible for the application and destruction of the value memory space, which is managed entirely by the caller. The element specified by value is required to have a longer life cycle than adlist, otherwise the value specified in Adlist may be invalidated.


2) adlist responsible for dynamic application and destruction


As the following code, (the code does not pass the compilation test, possibly wrong):

Void addstringtolisthead (list *lst, char *s) {    char *snew  =  (char*) malloc (strlen (s) +1);     assert (snew);     strcpy (snew,s);     listaddnodehead (list,snew);} Void *stringdup (void *s) {    char *sorg =  (char*) s;     char *snew =  (char*) malloc (strlen (sorg) +1);     assert (snew);     strcpy (snew,sorg);     return snew;    } Void *stringfree (void *s) {    if  (s)  free (s);} Int stringmatch (VOID *S1, VOID *S2) {    if  (s1 &&  S2)  return strcmp ((char*) s1, (char*) s2)  == 0 ? 1 : 0;     if  (!S1 && !S2)  RETURN 1;    RETURN&Nbsp;0;} List *lst = listcreate (); Listsetdupmethod (lst, stringdup); Listsetfreemethod (lst,  Stringfree); Listsetmatchmethod (Lst, stringmatch); Addstringtolisthead (LST, "Hello"); Addstringtolisthead (LST , "World");// do somethinglist *lst2 = listdup (LST);// do  Somethinglistrelease (LST); Listrelease (LST2);


In the example above, the dynamically generated space is inserted into adlist, which is managed entirely by Adlist, and the caller should not hold or delete the dynamic space pointer for a long time, otherwise it will cause management confusion. It is important to note that Adlist's DUP function needs to be deeply copied at copy time, otherwise a dynamic request space is saved by two pointers for a long time, as long as one of the pointers is free, another pointer is invalidated, the re-access or the free fail pointer will be faulted.


3) failed to support reference counting friendly


The reason why the reference counting was not friendly is that when inserting an element, no related function is called to increase the reference count. Use DUP to implement the reference count plus 1 when the list is copied, minus 1 when the node is deleted by the free reference count. However, when inserting an element, the pointer is held because no DUP is called or other functions are used to make the reference count 1,value, which makes adlist not friendly to support reference counting. However, this can be supported by other means, such as the reference counter plus 1 before inserting, and the reference count minus 1 if the insert fails.


Four, easy to produce memory fragmentation.


Do not consider value first, just look at node. As you can see, adlist is required to apply for node space when inserting elements or copying linked lists, and freeing up space when deleting nodes. For continuous insertion and deletion, if all zmalloc, zfree functions do not make a good memory management strategy, it is easy to create content fragmentation.


V. Summary


In addition to providing caller-defined methods in memory management, Adlist is not much different from the general two-way list, which is characterized as described above and is no longer described here.

This article is from the "Chhquan" blog, make sure to keep this source http://chhquan.blog.51cto.com/1346841/1771106

Adlist of Redis underlying data structure

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.