Redis's Adlist implements a double-ended list of data structures, such as the following:
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
Of the three function pointers in the first without the tube, followed by the look at the details of what to do, also implemented an iterator, a little C + + taste in the inside
typedef struct LISTITER { listnode *next; int direction;} Listiter;
Linked list three elements. 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;}
Inserts are divided into from the head insert and the end insert, the source implementation of the head has a very clear gaze, tell the function of some details, the author is very attentively:
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;}
Freeing 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);}
Iterators are created and can be emulated in the future, with the iterator in the direction of:
/* Returns A list iterator ' iter '. After the initialization every * call to Listnext () would 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;}
Copyright notice: This article blog original article. Blogs, without consent, may not be reproduced.
Redis source code-data structure Adlist double-ended list