实现在adlist.c中
redis中对双链表的实现没有特别之处,链表应该是redis数据结构最简单的一种了。一样地,除了数据阈,额外维护前驱和后继指针。
1 内存布局
2 创建实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
list *listCreate(void) { struct list *list;
if ((list = zmalloc(sizeof(*list))) == NULL) return NULL; list->head = list->tail = NULL; list->len = 0; list->dup = NULL; list->free = NULL; list->match = NULL; return list; }
|
3 新增
3.1 头插
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
list *listAddNodeHead(list *list, void *value) { listNode *node; if ((node = zmalloc(sizeof(*node))) == NULL) return NULL; node->value = value; if (list->len == 0) {
list->head = list->tail = node; node->prev = node->next = NULL; } else {
node->prev = NULL; node->next = list->head; list->head->prev = node; list->head = node; } list->len++; return list; }
|
3.2 尾插
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
list *listAddNodeTail(list *list, void *value) { listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL) return NULL; node->value = value; if (list->len == 0) { list->head = list->tail = node; node->prev = node->next = NULL; } else { node->prev = list->tail; node->next = NULL; list->tail->next = node; list->tail = node; } list->len++; return list; }
|
4 读取数据
一般的数据集合或者容器的实现都会配套迭代器来进行数据的遍历读取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
listNode *listNext(listIter *iter) { listNode *current = iter->next;
if (current != NULL) {
if (iter->direction == AL_START_HEAD) iter->next = current->next; else iter->next = current->prev; } return current; }
|