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 }