redis源码笔记-adlist

系统 1570 0

adlist是redis自己是实现的一个通用的双向链表。

------------------------------------------------adlist.h---------------------------------------------------

      
        #ifndef __ADLIST_H__


      
      
        #define
      
       __ADLIST_H__




      
        /*
      
      
         Node, List, and Iterator are the only data structures used currently. 
      
      
        */
      
      
        



typedef 
      
      
        struct
      
      
         listNode {


      
      
        struct
      
       listNode *
      
        prev;


      
      
        struct
      
       listNode *
      
        next;


      
      
        void
      
       *
      
        value;

} listNode;        双向链表,存的结构是一个指针void
      
      *
      
        



typedef 
      
      
        struct
      
      
         listIter {

listNode 
      
      *
      
        next;


      
      
        int
      
      
         direction;

} listIter;          迭代器,可以向前遍历,也可以向后遍历;



typedef 
      
      
        struct
      
      
         list {

listNode 
      
      *
      
        head;

listNode 
      
      *
      
        tail;


      
      
        void
      
       *(*dup)(
      
        void
      
       *
      
        ptr);


      
      
        void
      
       (*free)(
      
        void
      
       *
      
        ptr);


      
      
        int
      
       (*match)(
      
        void
      
       *ptr, 
      
        void
      
       *
      
        key);

unsigned 
      
      
        int
      
      
         len;

} list;                链表本身的结构,头、尾指针,同时一个函数指针dup用于在复制链表(list or listNode
      
      ?
      
        )调用,一个函数指针free在释放链表时调用,一个函数指针match用来作匹配时调用,以及一个记录链表长度的字段;注意三个函数指针是list的成员,也就是被所有list node共用,因此listNode应该具有共性。




      
      
        /*
      
      
         Functions implemented as macros 
      
      
        */
      
      
        #define
      
       listLength(l) ((l)->len)     链表长度


      
        #define
      
       listFirst(l) ((l)->head)      链表的第一个结点


      
        #define
      
       listLast(l) ((l)->tail)         链表的最后一个结点


      
        #define
      
       listPrevNode(n) ((n)->prev)        当前结点的前一个结点


      
        #define
      
       listNextNode(n) ((n)->next)        当前结点的后一个结点


      
        #define
      
       listNodeValue(n) ((n)->value)     当前结点的值




      
        #define
      
       listSetDupMethod(l,m) ((l)->dup = (m))       


      
        #define
      
       listSetFreeMethod(l,m) ((l)->free = (m))


      
        #define
      
       listSetMatchMethod(l,m) ((l)->match = (m))   set三个函数指针的方法




      
        #define
      
       listGetDupMethod(l) ((l)->dup)


      
        #define
      
       listGetFree(l) ((l)->free)


      
        #define
      
       listGetMatchMethod(l) ((l)->match)       get三个函数指针的方法




      
        /*
      
      
         Prototypes 
      
      
        */
      
      
        

list 
      
      *listCreate(
      
        void
      
      
        );            创建链表


      
      
        void
      
       listRelease(list *
      
        list);      释放链表

list 
      
      *listAddNodeHead(list *list, 
      
        void
      
       *
      
        value);       在表头加一个结点

list 
      
      *listAddNodeTail(list *list, 
      
        void
      
       *
      
        value);         在表尾加一个结点

list 
      
      *listInsertNode(list *list, listNode *old_node, 
      
        void
      
       *value, 
      
        int
      
      
         after);


      
      
        void
      
       listDelNode(list *list, listNode *
      
        node);

listIter 
      
      *listGetIterator(list *list, 
      
        int
      
      
         direction);

listNode 
      
      *listNext(listIter *
      
        iter);


      
      
        void
      
       listReleaseIterator(listIter *
      
        iter);

list 
      
      *listDup(list *
      
        orig);

listNode 
      
      *listSearchKey(list *list, 
      
        void
      
       *
      
        key);

listNode 
      
      *listIndex(list *list, 
      
        int
      
      
         index);


      
      
        void
      
       listRewind(list *list, listIter *
      
        li);


      
      
        void
      
       listRewindTail(list *list, listIter *
      
        li);




      
      
        /*
      
      
         Directions for iterators 
      
      
        */
      
      
        #define
      
       AL_START_HEAD 0         


      
        #define
      
       AL_START_TAIL 1          定义迭代器方向




      
        #endif
      
       /* __ADLIST_H__ */
    

 

 

------------------------------------------------adlist.c---------------------------------------------------

      
          1
      
       #include <stdlib.h>


      
          2
      
       #include 
      
        "
      
      
        adlist.h
      
      
        "
      
      
          3
      
       #include 
      
        "
      
      
        zmalloc.h
      
      
        "     //redis对内存分配库函数的一个封装,用于stat目的
      
      
          4
      
      
          5
      
      
        /*
      
      
         Create a new list. The created list can be freed with


      
      
          6
      
      
         * AlFreeList(), but private value of every node need to be freed


      
      
          7
      
      
         * by the user before to call AlFreeList().


      
      
          8
      
      
         *


      
      
          9
      
      
         * On error, NULL is returned. Otherwise the pointer to the new list. 
      
      
        */
      
      
         10
      
       list *listCreate(
      
        void
      
      
        )


      
      
         11
      
      
        {


      
      
         12
      
      
        struct
      
       list *
      
        list;


      
      
         13
      
      
         14
      
      
        if
      
       ((list = zmalloc(
      
        sizeof
      
      (*list))) ==
      
         NULL)


      
      
         15
      
      
        return
      
      
         NULL;


      
      
         16
      
           list->head = list->tail =
      
         NULL;


      
      
         17
      
           list->len = 
      
        0
      
      
        ;


      
      
         18
      
           list->dup =
      
         NULL;


      
      
         19
      
           list->free =
      
         NULL;


      
      
         20
      
           list->match =
      
         NULL;


      
      
         21
      
      
        return
      
      
         list;


      
      
         22
      
      
        }    //这个函数创建的list是个裸的list,三个函数指针需要自行调用set赋值


      
      
         23
      
      
         24
      
      
        /*
      
      
         Free the whole list.


      
      
         25
      
      
         *


      
      
         26
      
      
         * This function can't fail. 
      
      
        */
      
      
         27
      
      
        void
      
       listRelease(list *
      
        list)


      
      
         28
      
      
        {


      
      
         29
      
           unsigned 
      
        int
      
      
         len;


      
      
         30
      
           listNode *current, *
      
        next;


      
      
         31
      
      
         32
      
           current = list->
      
        head;


      
      
         33
      
           len = list->
      
        len;


      
      
         34
      
      
        while
      
      (len--
      
        ) {


      
      
         35
      
               next = current->
      
        next;


      
      
         36
      
      
        if
      
       (list->free) list->free(current->
      
        value);      //


      
      
         37
      
      
                zfree(current);


      
      
         38
      
               current =
      
         next;


      
      
         39
      
      
            }


      
      
         40
      
      
            zfree(list);


      
      
         41
      
      
        }       //先用free释放listNode中保存的元素,然后释放结点,最后释放链表本身。在链表操作中,注意在释放当前结点时,需要保存后续结点的值


      
      
         42
      
      
         43
      
      
        /*
      
      
         Add a new node to the list, to head, contaning the specified 'value'


      
      
         44
      
      
         * pointer as value.


      
      
         45
      
      
         *


      
      
         46
      
      
         * On error, NULL is returned and no operation is performed (i.e. the


      
      
         47
      
      
         * list remains unaltered).


      
      
         48
      
      
         * On success the 'list' pointer you pass to the function is returned. 
      
      
        */
      
      
         49
      
       list *listAddNodeHead(list *list, 
      
        void
      
       *
      
        value)


      
      
         50
      
      
        {


      
      
         51
      
           listNode *
      
        node;


      
      
         52
      
      
         53
      
      
        if
      
       ((node = zmalloc(
      
        sizeof
      
      (*node))) ==
      
         NULL)


      
      
         54
      
      
        return
      
      
         NULL;


      
      
         55
      
           node->value =
      
         value;


      
      
         56
      
      
        if
      
       (list->len == 
      
        0
      
      
        ) {


      
      
         57
      
               list->head = list->tail =
      
         node;


      
      
         58
      
               node->prev = node->next =
      
         NULL;


      
      
         59
      
           } 
      
        else
      
      
         {


      
      
         60
      
               node->prev =
      
         NULL;


      
      
         61
      
               node->next = list->
      
        head;


      
      
         62
      
               list->head->prev =
      
         node;


      
      
         63
      
               list->head =
      
         node;


      
      
         64
      
      
            }


      
      
         65
      
           list->len++
      
        ;


      
      
         66
      
      
        return
      
      
         list;


      
      
         67
      
      
        }


      
      
         68
      
      
         69
      
      
        /*
      
      
         Add a new node to the list, to tail, contaning the specified 'value'


      
      
         70
      
      
         * pointer as value.


      
      
         71
      
      
         *


      
      
         72
      
      
         * On error, NULL is returned and no operation is performed (i.e. the


      
      
         73
      
      
         * list remains unaltered).


      
      
         74
      
      
         * On success the 'list' pointer you pass to the function is returned. 
      
      
        */
      
      
         75
      
       list *listAddNodeTail(list *list, 
      
        void
      
       *
      
        value)


      
      
         76
      
      
        {


      
      
         77
      
           listNode *
      
        node;


      
      
         78
      
      
         79
      
      
        if
      
       ((node = zmalloc(
      
        sizeof
      
      (*node))) ==
      
         NULL)


      
      
         80
      
      
        return
      
      
         NULL;


      
      
         81
      
           node->value =
      
         value;


      
      
         82
      
      
        if
      
       (list->len == 
      
        0
      
      
        ) {


      
      
         83
      
               list->head = list->tail =
      
         node;


      
      
         84
      
               node->prev = node->next =
      
         NULL;


      
      
         85
      
           } 
      
        else
      
      
         {


      
      
         86
      
               node->prev = list->
      
        tail;


      
      
         87
      
               node->next =
      
         NULL;


      
      
         88
      
               list->tail->next =
      
         node;


      
      
         89
      
               list->tail =
      
         node;


      
      
         90
      
      
            }


      
      
         91
      
           list->len++
      
        ;


      
      
         92
      
      
        return
      
      
         list;


      
      
         93
      
      
        }


      
      
         94
      
      
         95
      
       list *listInsertNode(list *list, listNode *old_node, 
      
        void
      
       *value, 
      
        int
      
      
         after) {


      
      
         96
      
           listNode *
      
        node;


      
      
         97
      
      
         98
      
      
        if
      
       ((node = zmalloc(
      
        sizeof
      
      (*node))) ==
      
         NULL)


      
      
         99
      
      
        return
      
      
         NULL;


      
      
        100
      
           node->value =
      
         value;


      
      
        101
      
      
        if
      
      
         (after) {


      
      
        102
      
               node->prev =
      
         old_node;


      
      
        103
      
               node->next = old_node->
      
        next;


      
      
        104
      
      
        if
      
       (list->tail ==
      
         old_node) {


      
      
        105
      
                   list->tail =
      
         node;


      
      
        106
      
      
                }


      
      
        107
      
           } 
      
        else
      
      
         {


      
      
        108
      
               node->next =
      
         old_node;


      
      
        109
      
               node->prev = old_node->
      
        prev;


      
      
        110
      
      
        if
      
       (list->head ==
      
         old_node) {


      
      
        111
      
                   list->head =
      
         node;


      
      
        112
      
      
                }


      
      
        113
      
      
            }


      
      
        114
      
      
        if
      
       (node->prev !=
      
         NULL) {


      
      
        115
      
               node->prev->next =
      
         node;


      
      
        116
      
      
            }


      
      
        117
      
      
        if
      
       (node->next !=
      
         NULL) {


      
      
        118
      
               node->next->prev =
      
         node;


      
      
        119
      
      
            }


      
      
        120
      
           list->len++
      
        ;


      
      
        121
      
      
        return
      
      
         list;


      
      
        122
      
      
        }


      
      
        123
      
      
        124
      
      
        /*
      
      
         Remove the specified node from the specified list.


      
      
        125
      
      
         * It's up to the caller to free the private value of the node.


      
      
        126
      
      
         *


      
      
        127
      
      
         * This function can't fail. 
      
      
        */
      
      
        128
      
      
        void
      
       listDelNode(list *list, listNode *
      
        node)


      
      
        129
      
      
        {


      
      
        130
      
      
        if
      
       (node->
      
        prev)


      
      
        131
      
               node->prev->next = node->
      
        next;


      
      
        132
      
      
        else
      
      
        133
      
               list->head = node->
      
        next;


      
      
        134
      
      
        if
      
       (node->
      
        next)


      
      
        135
      
               node->next->prev = node->
      
        prev;


      
      
        136
      
      
        else
      
      
        137
      
               list->tail = node->
      
        prev;


      
      
        138
      
      
        if
      
       (list->free) list->free(node->
      
        value);


      
      
        139
      
      
            zfree(node);


      
      
        140
      
           list->len--
      
        ;


      
      
        141
      
      
        }


      
      
        142
      
      
        143
      
      
        /*
      
      
         Returns a list iterator 'iter'. After the initialization every


      
      
        144
      
      
         * call to listNext() will return the next element of the list.


      
      
        145
      
      
         *


      
      
        146
      
      
         * This function can't fail. 
      
      
        */
      
      
        147
      
       listIter *listGetIterator(list *list, 
      
        int
      
      
         direction)


      
      
        148
      
      
        {


      
      
        149
      
           listIter *
      
        iter;


      
      
        150
      
      
        151
      
      
        if
      
       ((iter = zmalloc(
      
        sizeof
      
      (*iter))) == NULL) 
      
        return
      
      
         NULL;


      
      
        152
      
      
        if
      
       (direction ==
      
         AL_START_HEAD)


      
      
        153
      
               iter->next = list->
      
        head;


      
      
        154
      
      
        else
      
      
        155
      
               iter->next = list->
      
        tail;


      
      
        156
      
           iter->direction =
      
         direction;


      
      
        157
      
      
        return
      
      
         iter;


      
      
        158
      
      
        }


      
      
        159
      
      
        160
      
      
        /*
      
      
         Release the iterator memory 
      
      
        */
      
      
        161
      
      
        void
      
       listReleaseIterator(listIter *
      
        iter) {


      
      
        162
      
      
            zfree(iter);


      
      
        163
      
      
        }


      
      
        164
      
      
        165
      
      
        /*
      
      
         Create an iterator in the list private iterator structure 
      
      
        */
      
      
        166
      
      
        void
      
       listRewind(list *list, listIter *
      
        li) {


      
      
        167
      
           li->next = list->
      
        head;


      
      
        168
      
           li->direction =
      
         AL_START_HEAD;


      
      
        169
      
      
        }


      
      
        170
      
      
        171
      
      
        void
      
       listRewindTail(list *list, listIter *
      
        li) {


      
      
        172
      
           li->next = list->
      
        tail;


      
      
        173
      
           li->direction =
      
         AL_START_TAIL;


      
      
        174
      
      
        }


      
      
        175
      
      
        176
      
      
        /*
      
      
         Return the next element of an iterator.


      
      
        177
      
      
         * It's valid to remove the currently returned element using


      
      
        178
      
      
         * listDelNode(), but not to remove other elements.


      
      
        179
      
      
         *


      
      
        180
      
      
         * The function returns a pointer to the next element of the list,


      
      
        181
      
      
         * or NULL if there are no more elements, so the classical usage patter


      
      
        182
      
      
         * is:


      
      
        183
      
      
         *


      
      
        184
      
      
         * iter = listGetIterator(list,<direction>);


      
      
        185
      
      
         * while ((node = listNext(iter)) != NULL) {


      
      
        186
      
      
         *     doSomethingWith(listNodeValue(node));


      
      
        187
      
      
         * }


      
      
        188
      
      
         *


      
      
        189
      
      
         * 
      
      
        */
      
      
        190
      
       listNode *listNext(listIter *
      
        iter)


      
      
        191
      
      
        {


      
      
        192
      
           listNode *current = iter->
      
        next;


      
      
        193
      
      
        194
      
      
        if
      
       (current !=
      
         NULL) {


      
      
        195
      
      
        if
      
       (iter->direction ==
      
         AL_START_HEAD)


      
      
        196
      
                   iter->next = current->
      
        next;


      
      
        197
      
      
        else
      
      
        198
      
                   iter->next = current->
      
        prev;


      
      
        199
      
      
            }


      
      
        200
      
      
        return
      
      
         current;


      
      
        201
      
      
        }       //注意这个函数,如果对返回值作delete操作,iter并未失效


      
      
        202
      
      
        203
      
      
        /*
      
      
         Duplicate the whole list. On out of memory NULL is returned.


      
      
        204
      
      
         * On success a copy of the original list is returned.


      
      
        205
      
      
         *


      
      
        206
      
      
         * The 'Dup' method set with listSetDupMethod() function is used


      
      
        207
      
      
         * to copy the node value. Otherwise the same pointer value of


      
      
        208
      
      
         * the original node is used as value of the copied node.


      
      
        209
      
      
         *


      
      
        210
      
      
         * The original list both on success or error is never modified. 
      
      
        */
      
      
        211
      
       list *listDup(list *
      
        orig)


      
      
        212
      
      
        {


      
      
        213
      
           list *
      
        copy;


      
      
        214
      
           listIter *
      
        iter;


      
      
        215
      
           listNode *
      
        node;


      
      
        216
      
      
        217
      
      
        if
      
       ((copy = listCreate()) ==
      
         NULL)


      
      
        218
      
      
        return
      
      
         NULL;


      
      
        219
      
           copy->dup = orig->
      
        dup;


      
      
        220
      
           copy->free = orig->
      
        free;


      
      
        221
      
           copy->match = orig->
      
        match;


      
      
        222
      
           iter =
      
         listGetIterator(orig, AL_START_HEAD);


      
      
        223
      
      
        while
      
      ((node = listNext(iter)) !=
      
         NULL) {


      
      
        224
      
      
        void
      
       *
      
        value;


      
      
        225
      
      
        226
      
      
        if
      
       (copy->
      
        dup) {


      
      
        227
      
                   value = copy->dup(node->
      
        value);


      
      
        228
      
      
        if
      
       (value ==
      
         NULL) {


      
      
        229
      
      
                        listRelease(copy);


      
      
        230
      
      
                        listReleaseIterator(iter);


      
      
        231
      
      
        return
      
      
         NULL;


      
      
        232
      
      
                    }


      
      
        233
      
               } 
      
        else
      
      
        234
      
                   value = node->
      
        value;


      
      
        235
      
      
        if
      
       (listAddNodeTail(copy, value) ==
      
         NULL) {


      
      
        236
      
      
                    listRelease(copy);       
        
          //这里疑似有内存泄露,如果copy->dup被指定,并为value成功分配了内存,但addNodeTail的时候失败了,这块内存就没人管了。 
        
      
      
        237
      
      
                    listReleaseIterator(iter);


      
      
        238
      
      
        return
      
      
         NULL; 


      
      
        239
      
      
                }


      
      
        240
      
      
            }


      
      
        241
      
      
            listReleaseIterator(iter);


      
      
        242
      
      
        return
      
      
         copy;


      
      
        243
      
      
        }  //如果没有指定dup函数则是个浅拷贝,否则是个深拷贝。


      
      
        244
      
      
        245
      
      
        /*
      
      
         Search the list for a node matching a given key.


      
      
        246
      
      
         * The match is performed using the 'match' method


      
      
        247
      
      
         * set with listSetMatchMethod(). If no 'match' method


      
      
        248
      
      
         * is set, the 'value' pointer of every node is directly


      
      
        249
      
      
         * compared with the 'key' pointer.


      
      
        250
      
      
         *


      
      
        251
      
      
         * On success the first matching node pointer is returned


      
      
        252
      
      
         * (search starts from head). If no matching node exists


      
      
        253
      
      
         * NULL is returned. 
      
      
        */
      
      
        254
      
       listNode *listSearchKey(list *list, 
      
        void
      
       *
      
        key)


      
      
        255
      
      
        {


      
      
        256
      
           listIter *
      
        iter;


      
      
        257
      
           listNode *
      
        node;


      
      
        258
      
      
        259
      
           iter =
      
         listGetIterator(list, AL_START_HEAD);


      
      
        260
      
      
        while
      
      ((node = listNext(iter)) !=
      
         NULL) {


      
      
        261
      
      
        if
      
       (list->
      
        match) {


      
      
        262
      
      
        if
      
       (list->match(node->
      
        value, key)) {


      
      
        263
      
      
                        listReleaseIterator(iter);


      
      
        264
      
      
        return
      
      
         node;


      
      
        265
      
      
                    }


      
      
        266
      
               } 
      
        else
      
      
         {


      
      
        267
      
      
        if
      
       (key == node->
      
        value) {


      
      
        268
      
      
                        listReleaseIterator(iter);


      
      
        269
      
      
        return
      
      
         node;


      
      
        270
      
      
                    }


      
      
        271
      
      
                }


      
      
        272
      
      
            }


      
      
        273
      
      
            listReleaseIterator(iter);


      
      
        274
      
      
        return
      
      
         NULL;


      
      
        275
      
      
        } //O(n)的复杂度,n是链表长度


      
      
        276
      
      
        277
      
      
        /*
      
      
         Return the element at the specified zero-based index


      
      
        278
      
      
         * where 0 is the head, 1 is the element next to head


      
      
        279
      
      
         * and so on. Negative integers are used in order to count


      
      
        280
      
      
         * from the tail, -1 is the last element, -2 the penultimante


      
      
        281
      
      
         * and so on. If the index is out of range NULL is returned. 
      
      
        */
      
      
        282
      
       listNode *listIndex(list *list, 
      
        int
      
      
         index) {


      
      
        283
      
           listNode *
      
        n;


      
      
        284
      
      
        285
      
      
        if
      
       (index < 
      
        0
      
      
        ) {


      
      
        286
      
               index = (-index)-
      
        1
      
      
        ; //注意从后边往前数时index的处理


      
      
        287
      
               n = list->
      
        tail;


      
      
        288
      
      
        while
      
      (index-- && n) n = n->
      
        prev;


      
      
        289
      
           } 
      
        else
      
      
         {


      
      
        290
      
               n = list->
      
        head;


      
      
        291
      
      
        while
      
      (index-- && n) n = n->
      
        next;


      
      
        292
      
      
            }


      
      
        293
      
      
        return
      
      
         n;


      
      
        294
      
       }
    

redis源码笔记-adlist


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论