The apsaradb for redis adlist implements a double-ended linked list in the data structure. The entire structure is as follows:
Linked List node definition:
typedef struct listNode { struct listNode *prev; struct listNode *next; void *value;} listNode;
Linked list definition:
typedef struct list { listNode *head; listNode *tail; void *(*dup)(void *ptr); void (*free)(void *ptr); int (*match)(void *ptr, void *key); unsigned long len;} list;
The three function pointers are ignored first, and then we will see what we are doing later. In addition, we have implemented an iterator that features a bit of C ++ in it.
typedef struct listIter { listNode *next; int direction;} listIter;
Three elements of a linked list: Create, insert, and delete
list *listCreate(void){ struct list *list; if ((list = malloc(sizeof(*list))) == NULL) return NULL; list->head = list->tail = NULL; list->len = 0; list->dup = NULL; list->free = NULL; list->match = NULL; return list;}
Insert is divided into header insertion and tail insertion. The source code implementation header has a very clear comment, telling this function some details, the author is very careful:
list *listAddNodeHead(list *list, void *value){ listNode *node; if ((node = malloc(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;}
Release memory
void listRelease(list *list){ unsigned long len; listNode *current, *next; current = list->head; len = list->len; while(len--) { next = current->next; if (list->free) list->free(current->value); free(current); current = next; } free(list);}
The method of creating an iterator can be followed in the future. The iterator is divided into different directions:
/* Returns a list iterator 'iter'. After the initialization every * call to listNext() will return the next element of the list. * * This function can't fail. */listIter *listGetIterator(list *list, int direction){ listIter *iter; if ((iter = malloc(sizeof(*iter))) == NULL) return NULL; if (direction == AL_START_HEAD) iter->next = list->head; else iter->next = list->tail; iter->direction = direction; return iter;}
Redis source code-Data Structure-adlist double-ended linked list