diff options
Diffstat (limited to 'examples/redis-unstable/src/adlist.c')
| -rw-r--r-- | examples/redis-unstable/src/adlist.c | 395 |
1 files changed, 0 insertions, 395 deletions
diff --git a/examples/redis-unstable/src/adlist.c b/examples/redis-unstable/src/adlist.c deleted file mode 100644 index d7ca5fb..0000000 --- a/examples/redis-unstable/src/adlist.c +++ /dev/null @@ -1,395 +0,0 @@ -/* adlist.c - A generic doubly linked list implementation - * - * Copyright (c) 2006-Present, Redis Ltd. - * All rights reserved. - * - * Licensed under your choice of (a) the Redis Source Available License 2.0 - * (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the - * GNU Affero General Public License v3 (AGPLv3). - */ - - -#include <stdlib.h> -#include "adlist.h" -#include "zmalloc.h" - -/* Create a new list. The created list can be freed with - * listRelease(), but private value of every node need to be freed - * by the user before to call listRelease(), or by setting a free method using - * listSetFreeMethod. - * - * On error, NULL is returned. Otherwise the pointer to the new list. */ -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; -} - -/* Remove all the elements from the list without destroying the list itself. */ -void listEmpty(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); - zfree(current); - current = next; - } - list->head = list->tail = NULL; - list->len = 0; -} - -/* Free the whole list. - * - * This function can't fail. */ -void listRelease(list *list) -{ - if (!list) - return; - listEmpty(list); - zfree(list); -} - -/* Generic version of listRelease. */ -void listReleaseGeneric(void *list) { - listRelease((struct list*)list); -} - -/* Add a new node to the list, to head, containing the specified 'value' - * pointer as value. - * - * On error, NULL is returned and no operation is performed (i.e. the - * list remains unaltered). - * On success the 'list' pointer you pass to the function is returned. */ -list *listAddNodeHead(list *list, void *value) -{ - listNode *node; - - if ((node = zmalloc(sizeof(*node))) == NULL) - return NULL; - node->value = value; - listLinkNodeHead(list, node); - return list; -} - -/* - * Add a node that has already been allocated to the head of list - */ -void listLinkNodeHead(list* list, listNode *node) { - 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++; -} - -/* Add a new node to the list, to tail, containing the specified 'value' - * pointer as value. - * - * On error, NULL is returned and no operation is performed (i.e. the - * list remains unaltered). - * On success the 'list' pointer you pass to the function is returned. */ -list *listAddNodeTail(list *list, void *value) -{ - listNode *node; - - if ((node = zmalloc(sizeof(*node))) == NULL) - return NULL; - node->value = value; - listLinkNodeTail(list, node); - return list; -} - -/* - * Add a node that has already been allocated to the tail of list - */ -void listLinkNodeTail(list *list, listNode *node) { - 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++; -} - -list *listInsertNode(list *list, listNode *old_node, void *value, int after) { - listNode *node; - - if ((node = zmalloc(sizeof(*node))) == NULL) - return NULL; - node->value = value; - if (after) { - node->prev = old_node; - node->next = old_node->next; - if (list->tail == old_node) { - list->tail = node; - } - } else { - node->next = old_node; - node->prev = old_node->prev; - if (list->head == old_node) { - list->head = node; - } - } - if (node->prev != NULL) { - node->prev->next = node; - } - if (node->next != NULL) { - node->next->prev = node; - } - list->len++; - return list; -} - -/* Remove the specified node from the specified list. - * The node is freed. If free callback is provided the value is freed as well. - * - * This function can't fail. */ -void listDelNode(list *list, listNode *node) -{ - listUnlinkNode(list, node); - if (list->free) list->free(node->value); - zfree(node); -} - -/* - * Remove the specified node from the list without freeing it. - */ -void listUnlinkNode(list *list, listNode *node) { - if (node->prev) - node->prev->next = node->next; - else - list->head = node->next; - if (node->next) - node->next->prev = node->prev; - else - list->tail = node->prev; - - node->next = NULL; - node->prev = NULL; - - list->len--; -} - -/* 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. */ -void listInitIterator(listIter *iter, list *list, int direction) -{ - if (direction == AL_START_HEAD) - iter->next = list->head; - else - iter->next = list->tail; - iter->direction = direction; -} - -/* Create an iterator in the list private iterator structure */ -void listRewind(list *list, listIter *li) { - li->next = list->head; - li->direction = AL_START_HEAD; -} - -void listRewindTail(list *list, listIter *li) { - li->next = list->tail; - li->direction = AL_START_TAIL; -} - -/* Return the next element of an iterator. - * It's valid to remove the currently returned element using - * listDelNode(), but not to remove other elements. - * - * The function returns a pointer to the next element of the list, - * or NULL if there are no more elements, so the classical usage - * pattern is: - * - * iter = listGetIterator(list,<direction>); - * while ((node = listNext(iter)) != NULL) { - * doSomethingWith(listNodeValue(node)); - * } - * - * */ -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; -} - -/* Duplicate the whole list. On out of memory NULL is returned. - * On success a copy of the original list is returned. - * - * The 'Dup' method set with listSetDupMethod() function is used - * to copy the node value. Otherwise the same pointer value of - * the original node is used as value of the copied node. - * - * The original list both on success or error is never modified. */ -list *listDup(list *orig) -{ - list *copy; - listIter iter; - listNode *node; - - if ((copy = listCreate()) == NULL) - return NULL; - copy->dup = orig->dup; - copy->free = orig->free; - copy->match = orig->match; - listRewind(orig, &iter); - while((node = listNext(&iter)) != NULL) { - void *value; - - if (copy->dup) { - value = copy->dup(node->value); - if (value == NULL) { - listRelease(copy); - return NULL; - } - } else { - value = node->value; - } - - if (listAddNodeTail(copy, value) == NULL) { - /* Free value if dup succeed but listAddNodeTail failed. */ - if (copy->free) copy->free(value); - - listRelease(copy); - return NULL; - } - } - return copy; -} - -/* Search the list for a node matching a given key. - * The match is performed using the 'match' method - * set with listSetMatchMethod(). If no 'match' method - * is set, the 'value' pointer of every node is directly - * compared with the 'key' pointer. - * - * On success the first matching node pointer is returned - * (search starts from head). If no matching node exists - * NULL is returned. */ -listNode *listSearchKey(list *list, void *key) -{ - listIter iter; - listNode *node; - - listRewind(list, &iter); - while((node = listNext(&iter)) != NULL) { - if (list->match) { - if (list->match(node->value, key)) { - return node; - } - } else { - if (key == node->value) { - return node; - } - } - } - return NULL; -} - -/* Return the element at the specified zero-based index - * where 0 is the head, 1 is the element next to head - * and so on. Negative integers are used in order to count - * from the tail, -1 is the last element, -2 the penultimate - * and so on. If the index is out of range NULL is returned. */ -listNode *listIndex(list *list, long index) { - listNode *n; - - if (index < 0) { - index = (-index)-1; - n = list->tail; - while(index-- && n) n = n->prev; - } else { - n = list->head; - while(index-- && n) n = n->next; - } - return n; -} - -/* Rotate the list removing the tail node and inserting it to the head. */ -void listRotateTailToHead(list *list) { - if (listLength(list) <= 1) return; - - /* Detach current tail */ - listNode *tail = list->tail; - list->tail = tail->prev; - list->tail->next = NULL; - /* Move it as head */ - list->head->prev = tail; - tail->prev = NULL; - tail->next = list->head; - list->head = tail; -} - -/* Rotate the list removing the head node and inserting it to the tail. */ -void listRotateHeadToTail(list *list) { - if (listLength(list) <= 1) return; - - listNode *head = list->head; - /* Detach current head */ - list->head = head->next; - list->head->prev = NULL; - /* Move it as tail */ - list->tail->next = head; - head->next = NULL; - head->prev = list->tail; - list->tail = head; -} - -/* Add all the elements of the list 'o' at the end of the - * list 'l'. The list 'other' remains empty but otherwise valid. */ -void listJoin(list *l, list *o) { - if (o->len == 0) return; - - o->head->prev = l->tail; - - if (l->tail) - l->tail->next = o->head; - else - l->head = o->head; - - l->tail = o->tail; - l->len += o->len; - - /* Setup other as an empty list. */ - o->head = o->tail = NULL; - o->len = 0; -} - -/* Initializes the node's value and sets its pointers - * so that it is initially not a member of any list. - */ -void listInitNode(listNode *node, void *value) { - node->prev = NULL; - node->next = NULL; - node->value = value; -} |
