Redis源码笔记二: adlist

  1 /* adlist.h - A generic doubly linked list implementation
  2  *
  3  * Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
  4  * All rights reserved.
  5  *
  6  * Redistribution and use in source and binary forms, with or without
  7  * modification, are permitted provided that the following conditions are met:
  8  *
  9  *   * Redistributions of source code must retain the above copyright notice,
 10  *     this list of conditions and the following disclaimer.
 11  *   * Redistributions in binary form must reproduce the above copyright
 12  *     notice, this list of conditions and the following disclaimer in the
 13  *     documentation and/or other materials provided with the distribution.
 14  *   * Neither the name of Redis nor the names of its contributors may be used
 15  *     to endorse or promote products derived from this software without
 16  *     specific prior written permission.
 17  *
 18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 28  * POSSIBILITY OF SUCH DAMAGE.
 29  */
 30 
 31 #ifndef __ADLIST_H__
 32 #define __ADLIST_H__
 33 
 34 /* Node, List, and Iterator are the only data structures used currently. */
 35 
 36 typedef struct listNode {
 37     /* 前驱节点 */
 38     struct listNode *prev;    
 39 
 40     /* 后继节点 */
 41     struct listNode *next;
 42 
 43     /**/
 44     void *value;
 45 } listNode;/* 双链表节点 */
 46 
 47 typedef struct listIter {    
 48     /* 下一节点 */
 49     listNode *next;
 50 
 51     /* 迭代方向 */
 52     int direction;
 53 } listIter;/* 迭代器 */
 54 
 55 typedef struct list {
 56     /* 表头指针 */
 57     listNode *head;
 58 
 59     /* 表尾指针 */
 60     listNode *tail;
 61 
 62     /* 复制函数 */
 63     void *(*dup)(void *ptr);
 64 
 65     /* 释放函数 */
 66     void (*free)(void *ptr);
 67 
 68     /* 对比函数 */
 69     int (*match)(void *ptr, void *key);
 70 
 71     /* 节点数量 */
 72     unsigned long len;
 73 } list;/* 双链表 */
 74 
 75 /* Functions implemented as macros */
 76 #define listLength(l) ((l)->len)
 77 #define listFirst(l) ((l)->head)
 78 #define listLast(l) ((l)->tail)
 79 #define listPrevNode(n) ((n)->prev)
 80 #define listNextNode(n) ((n)->next)
 81 #define listNodeValue(n) ((n)->value)
 82 
 83 #define listSetDupMethod(l,m) ((l)->dup = (m))
 84 #define listSetFreeMethod(l,m) ((l)->free = (m))
 85 #define listSetMatchMethod(l,m) ((l)->match = (m))
 86 
 87 #define listGetDupMethod(l) ((l)->dup)
 88 #define listGetFree(l) ((l)->free)
 89 #define listGetMatchMethod(l) ((l)->match)
 90 
 91 /* Prototypes */
 92 
 93 /* 创建一个新链表 */
 94 list *listCreate(void);
 95 
 96 /* 释放一个新链表,以及该链表包含的节点 */
 97 void listRelease(list *list);
 98 
 99 /* 将一个包含给定值的节点添加到链表的表头  */
100 list *listAddNodeHead(list *list, void *value);
101 
102 /* 将一个包含给定值的节点添加到链表的表尾 */
103 list *listAddNodeTail(list *list, void *value);
104 
105 /* 将一个包含给定值的节点添加到某个节点的之前或之后 */
106 list *listInsertNode(list *list, listNode *old_node, void *value, int after);
107 
108 /* 删除给定节点 */
109 void listDelNode(list *list, listNode *node);
110 
111 
112 /* 创建一个列表迭代器 */
113 listIter *listGetIterator(list *list, int direction);
114 
115 /* 取出迭代器当前指向的节点 */
116 listNode *listNext(listIter *iter);
117 
118 /* 释放迭代器 */
119 void listReleaseIterator(listIter *iter);
120 
121 /* 创建一个给定链表的副本 */
122 list *listDup(list *orig);
123 
124 /* 在链表中查找和给定key匹配的节点 */
125 listNode *listSearchKey(list *list, void *key);
126 
127 /* 给据给定索引,返回列表中相应的节点 */
128 listNode *listIndex(list *list, long index);
129 
130 /* 将迭代器的指针指向表头 */
131 void listRewind(list *list, listIter *li);
132 
133 /* 将迭代器的指针指向表尾 */
134 void listRewindTail(list *list, listIter *li);
135 
136 /* 取出链表的表尾节点,将它插入到表头 */
137 void listRotate(list *list);
138 
139 /* Directions for iterators */
140 #define AL_START_HEAD 0
141 #define AL_START_TAIL 1
142 
143 #endif /* __ADLIST_H__ */
adlist.h
  1 /* adlist.c - A generic doubly linked list implementation
  2  *
  3  * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
  4  * All rights reserved.
  5  *
  6  * Redistribution and use in source and binary forms, with or without
  7  * modification, are permitted provided that the following conditions are met:
  8  *
  9  *   * Redistributions of source code must retain the above copyright notice,
 10  *     this list of conditions and the following disclaimer.
 11  *   * Redistributions in binary form must reproduce the above copyright
 12  *     notice, this list of conditions and the following disclaimer in the
 13  *     documentation and/or other materials provided with the distribution.
 14  *   * Neither the name of Redis nor the names of its contributors may be used
 15  *     to endorse or promote products derived from this software without
 16  *     specific prior written permission.
 17  *
 18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 28  * POSSIBILITY OF SUCH DAMAGE.
 29  */
 30 
 31 
 32 #include <stdlib.h>
 33 #include "adlist.h"
 34 #include "zmalloc.h"
 35 
 36 /* Create a new list. The created list can be freed with
 37  * AlFreeList(), but private value of every node need to be freed
 38  * by the user before to call AlFreeList().
 39  *
 40  * On error, NULL is returned. Otherwise the pointer to the new list. */
 41 list *listCreate(void)
 42 {
 43     struct list *list;
 44 
 45     if ((list = zmalloc(sizeof(*list))) == NULL)
 46         return NULL;
 47 
 48     /* 更新属性 */
 49     list->head = list->tail = NULL;
 50     list->len = 0;
 51     list->dup = NULL;
 52     list->free = NULL;
 53     list->match = NULL;
 54 
 55     return list;
 56 }
 57 
 58 /* Free the whole list.
 59  *
 60  * This function can't fail. */
 61 void listRelease(list *list)
 62 {
 63     unsigned long len;
 64     listNode *current, *next;
 65 
 66     current = list->head;
 67     len = list->len;
 68     while(len--) {
 69         next = current->next;
 70 
 71         /* 如果列表有自带的free方法,那么先对节点调用它 */
 72         if (list->free) list->free(current->value);
 73 
 74         /* 之后释放节点 */
 75         zfree(current);
 76         current = next;
 77     }
 78     zfree(list);
 79 }
 80 
 81 /* Add a new node to the list, to head, contaning the specified 'value'
 82  * pointer as value.
 83  *
 84  * On error, NULL is returned and no operation is performed (i.e. the
 85  * list remains unaltered).
 86  * On success the 'list' pointer you pass to the function is returned. */
 87 list *listAddNodeHead(list *list, void *value)
 88 {
 89     listNode *node;
 90 
 91     if ((node = zmalloc(sizeof(*node))) == NULL)
 92         return NULL;
 93     node->value = value;
 94 
 95     /* 节点为0时,更新属性 */
 96     if (list->len == 0) {
 97         list->head = list->tail = node;
 98         node->prev = node->next = NULL;
 99 
100     /* 节点不为0时,更新属性 */
101     } else {
102         node->prev = NULL;
103         node->next = list->head;
104         list->head->prev = node;
105         list->head = node;
106     }
107 
108     /* 更新节点数量 */
109     list->len++;
110 
111     return list;
112 }
113 
114 /* Add a new node to the list, to tail, containing the specified 'value'
115  * pointer as value.
116  *
117  * On error, NULL is returned and no operation is performed (i.e. the
118  * list remains unaltered).
119  * On success the 'list' pointer you pass to the function is returned. */
120 list *listAddNodeTail(list *list, void *value)
121 {
122     listNode *node;
123 
124     if ((node = zmalloc(sizeof(*node))) == NULL)
125         return NULL;
126     node->value = value;
127 
128     /* 节点为0时,更新属性 */
129     if (list->len == 0) {
130         list->head = list->tail = node;
131         node->prev = node->next = NULL;
132     }else {    /* 节点不为0时,更新属性 */
133         node->prev = list->tail;
134         node->next = NULL;
135         list->tail->next = node;
136         list->tail = node;
137     }
138 
139     /* 更新节点数量 */
140     list->len++;
141    
142        return list;
143 }
144 
145 /* 创建一个包含值value的节点,并根据after参数的指示,将新节点插入到old_node的之前或之后 */
146 list *listInsertNode(list *list, listNode *old_node, void *value, int after) {
147     listNode *node;
148 
149     if ((node = zmalloc(sizeof(*node))) == NULL)
150         return NULL;
151     node->value = value;
152     if (after) {
153         /* 将node插入到old_node之后 */
154         node->prev = old_node;            
155         node->next = old_node->next;    
156 
157         /* 处理表尾节点 */
158         if (list->tail == old_node) {    
159             list->tail = node;
160         }
161     } else {
162         /* 将node插入到old_node之前 */
163         node->next = old_node;            
164         node->prev = old_node->prev;    
165 
166         /* 处理表头节点 */
167         if (list->head == old_node) {    
168             list->head = node;            
169         }
170     }
171 
172     /* 更新前置节点和后继节点的指针 */
173     if (node->prev != NULL) {
174         node->prev->next = node;
175     }
176     if (node->next != NULL) {
177         node->next->prev = node;
178     }
179 
180     /* 更新列表节点 */
181     list->len++;
182 
183     return list;
184 }
185 
186 /* Remove the specified node from the specified list.
187  * It's up to the caller to free the private value of the node.
188  *
189  * This function can't fail. */
190 /* 释放列表中给定的节点 */
191 void listDelNode(list *list, listNode *node)
192 {
193     /* 处理前驱节点 */
194     if (node->prev)
195         node->prev->next = node->next;
196     else
197         list->head = node->next;
198 
199     /* 处理后继节点 */
200     if (node->next)
201         node->next->prev = node->prev;
202     else
203         list->tail = node->prev;
204 
205     /* 释放节点值 */
206     if (list->free) list->free(node->value);
207 
208     /* 释放节点 */
209     zfree(node);
210 
211     /* 更新列表节点数目  */
212     list->len--;
213 }
214 
215 /* Returns a list iterator 'iter'. After the initialization every
216  * call to listNext() will return the next element of the list.
217  *
218  * This function can't fail. */
219  /* 创建列表list的一个迭代器, 迭代方向由direction参数决定,每次对迭代listNext(),迭代器返回列表的下一个节点 */
220 listIter *listGetIterator(list *list, int direction)
221 {
222     listIter *iter;
223     
224     if ((iter = zmalloc(sizeof(*iter))) == NULL) return NULL;
225 
226     /* 根据迭代器方向,将迭代器的指针指向表头或表尾 */
227     if (direction == AL_START_HEAD)
228         iter->next = list->head;
229     else
230         iter->next = list->tail;
231 
232     /* 记录方向 */
233     iter->direction = direction;
234     return iter;
235 }
236 
237 /* Release the iterator memory */
238 /* 释放迭代器的内存 */
239 void listReleaseIterator(listIter *iter) {
240     zfree(iter);
241 }
242 
243 /* Create an iterator in the list private iterator structure */
244 /* 将迭代器iter的迭代指针倒回list的表头 */
245 void listRewind(list *list, listIter *li) {
246     li->next = list->head;
247     li->direction = AL_START_HEAD;
248 }
249 
250 /* 将迭代器iter的迭代指针倒回list的表尾 */
251 void listRewindTail(list *list, listIter *li) {
252     li->next = list->tail;
253     li->direction = AL_START_TAIL;
254 }
255 
256 /* Return the next element of an iterator.
257  * It's valid to remove the currently returned element using
258  * listDelNode(), but not to remove other elements.
259  *
260  * The function returns a pointer to the next element of the list,
261  * or NULL if there are no more elements, so the classical usage patter
262  * is:
263  *
264  * iter = listGetIterator(list,<direction>);
265  * while ((node = listNext(iter)) != NULL) {
266  *     doSomethingWith(listNodeValue(node));
267  * }
268  *
269  * */
270  /* 函数要么返回当前节点,要么返回NULL,因此,常见的用法为:
271   * iter = listGetIterator(list, <direction>);
272   * while((node = listNext(iter)) != NULL){
273   *        doSomethingWith(listNodeValue(node));      
274   *     }
275  */
276 listNode *listNext(listIter *iter)
277 {
278     listNode *current = iter->next;
279 
280     if (current != NULL) {
281         /* 根据迭代方向,选择节点 */
282         if (iter->direction == AL_START_HEAD)
283             iter->next = current->next;    //?
284         else
285             iter->next = current->prev;    //?
286     }
287     return current;
288 }
289 
290 /* Duplicate the whole list. On out of memory NULL is returned.
291  * On success a copy of the original list is returned.
292  *
293  * The 'Dup' method set with listSetDupMethod() function is used
294  * to copy the node value. Otherwise the same pointer value of
295  * the original node is used as value of the copied node.
296  *
297  * The original list both on success or error is never modified. */
298 /* 创建一个给定链表的副本 */
299 list *listDup(list *orig)
300 {
301     list *copy;
302     listIter *iter;
303     listNode *node;
304 
305     if ((copy = listCreate()) == NULL)
306         return NULL;
307 
308     /* 更新属性 */
309     copy->dup = orig->dup;
310     copy->free = orig->free;
311     copy->match = orig->match;
312     iter = listGetIterator(orig, AL_START_HEAD);
313 
314     while((node = listNext(iter)) != NULL) {
315         void *value;
316 
317         if (copy->dup) {
318             value = copy->dup(node->value);
319             if (value == NULL) {
320                 listRelease(copy);
321                 listReleaseIterator(iter);
322                 return NULL;
323             }
324         } else
325             value = node->value;
326         if (listAddNodeTail(copy, value) == NULL) {
327             listRelease(copy);
328             listReleaseIterator(iter);
329             return NULL;
330         }
331     }
332     listReleaseIterator(iter);
333     return copy;
334 }
335 
336 /* Search the list for a node matching a given key.
337  * The match is performed using the 'match' method
338  * set with listSetMatchMethod(). If no 'match' method
339  * is set, the 'value' pointer of every node is directly
340  * compared with the 'key' pointer.
341  *
342  * On success the first matching node pointer is returned
343  * (search starts from head). If no matching node exists
344  * NULL is returned. */
345  /* 在链表中查找和给定key匹配的节点 */
346 listNode *listSearchKey(list *list, void *key)
347 {
348     listIter *iter;
349     listNode *node;
350 
351     iter = listGetIterator(list, AL_START_HEAD);
352     while((node = listNext(iter)) != NULL) {
353         if (list->match) {
354             if (list->match(node->value, key)) {
355                 listReleaseIterator(iter);
356                 return node;
357             }
358         } else {
359             if (key == node->value) {
360                 listReleaseIterator(iter);
361                 return node;
362             }
363         }
364     }
365     listReleaseIterator(iter);
366     return NULL;
367 }
368 
369 /* Return the element at the specified zero-based index
370  * where 0 is the head, 1 is the element next to head
371  * and so on. Negative integers are used in order to count
372  * from the tail, -1 is the last element, -2 the penultimate
373  * and so on. If the index is out of range NULL is returned. */
374 /* 给据给定索引,返回列表中相应的节点 */
375 listNode *listIndex(list *list, long index) {
376     listNode *n;
377 
378     if (index < 0) {
379         index = (-index)-1;
380         n = list->tail;
381         while(index-- && n) n = n->prev;
382     } else {
383         n = list->head;
384         while(index-- && n) n = n->next;
385     }
386     return n;
387 }
388 
389 /* Rotate the list removing the tail node and inserting it to the head. */
390 /* 取出链表中的表尾节点,将它插入到表头 */
391 void listRotate(list *list) {
392     listNode *tail = list->tail;
393 
394     if (listLength(list) <= 1) return;
395 
396     /* Detach current tail */
397     list->tail = tail->prev;
398     list->tail->next = NULL;
399     /* Move it as head */
400     list->head->prev = tail;
401     tail->prev = NULL;
402     tail->next = list->head;
403     list->head = tail;
404 }
adlist.c

 

posted on 2014-03-31 19:47  __夏沫  阅读(332)  评论(0)    收藏  举报

导航