diff --git a/include/nng/supplemental/nanolib/linkedlist.h b/include/nng/supplemental/nanolib/linkedlist.h new file mode 100644 index 000000000..18c14323a --- /dev/null +++ b/include/nng/supplemental/nanolib/linkedlist.h @@ -0,0 +1,33 @@ +#include +#include + +struct linkedListNode { + void *data; + unsigned long long expiredAt; + struct linkedListNode *next; + struct linkedListNode *prev; +}; + +struct linkedList { + unsigned int cap; + unsigned int size; + unsigned int overWrite; + unsigned long long expiredAt; + + struct linkedListNode *head; + struct linkedListNode *tail; +}; + +int linkedList_replace_head(struct linkedList *list, + void *data, + unsigned long long expiredAt); +int linkedList_init(struct linkedList **list, + unsigned int cap, + unsigned int overWrite, + unsigned long long expiredAt); +int linkedList_enqueue(struct linkedList *list, + void *data, + unsigned long long expiredAt); +int linkedList_dequeue(struct linkedList *list, + void **data); +int linkedList_release(struct linkedList *list); diff --git a/src/supplemental/nanolib/CMakeLists.txt b/src/supplemental/nanolib/CMakeLists.txt index 0ec6f99ec..1a1e815f4 100644 --- a/src/supplemental/nanolib/CMakeLists.txt +++ b/src/supplemental/nanolib/CMakeLists.txt @@ -40,4 +40,5 @@ if (SUPP_RULE_ENGINE) nng_test(rule_test) endif (SUPP_RULE_ENGINE) -add_subdirectory(ringbuffer) +add_subdirectory(linkedlist) +add_subdirectory(ringbuffer) \ No newline at end of file diff --git a/src/supplemental/nanolib/linkedlist/CMakeLists.txt b/src/supplemental/nanolib/linkedlist/CMakeLists.txt new file mode 100644 index 000000000..8a9a6db92 --- /dev/null +++ b/src/supplemental/nanolib/linkedlist/CMakeLists.txt @@ -0,0 +1,3 @@ +nng_sources( + linkedlist.c +) diff --git a/src/supplemental/nanolib/linkedlist/linkedlist.c b/src/supplemental/nanolib/linkedlist/linkedlist.c new file mode 100644 index 000000000..176f02ab1 --- /dev/null +++ b/src/supplemental/nanolib/linkedlist/linkedlist.c @@ -0,0 +1,138 @@ +#include "nng/supplemental/nanolib/linkedlist.h" + +int linkedList_replace_head(struct linkedList *list, + void *data, + unsigned long long expiredAt) +{ + if (list->size == 0) { + log_error("linkedList_replace_head failed list is empty!\n"); + return -1; + } + + free(list->head->data); + + list->head->data = data; + list->head = list->head->next; + list->tail = list->tail->next; + + return 0; +} + +int linkedList_init(struct linkedList **list, + unsigned int cap, + unsigned int overWrite, + unsigned long long expiredAt) +{ + struct linkedList *newList; + + newList = (struct linkedList *)nni_alloc(sizeof(struct linkedList)); + if (newList == NULL) { + log_error("alloc new linkedList failed\n"); + return -1; + } + + newList->cap = cap; + newList->size = 0; + newList->overWrite = overWrite; + newList->expiredAt = expiredAt; + newList->head = NULL; + newList->tail = NULL; + + *list = newList; + + return 0; +} + +int linkedList_enqueue(struct linkedList *list, + void *data, + unsigned long long expiredAt) +{ + if (list->size == list->cap) { + if (list->overWrite == 0) { + log_error("Linked list is full, and do not allow to overwrite!\n"); + return -1; + } else { + return linkedList_replace_head(list, data, expiredAt); + } + } + + struct linkedListNode *newNode = NULL; + newNode = (struct linkedListNode *)nni_alloc(sizeof(struct linkedListNode)); + if (newNode == NULL) { + log_error("Linked list alloc new node failed!\n"); + return -1; + } + newNode->data = data; + newNode->expiredAt = expiredAt; + + if (list->head == NULL) { + list->head = newNode; + list->tail = newNode; + } + + newNode->next = list->head; + newNode->prev = list->tail; + + list->tail->next = newNode; + list->head->prev = newNode; + list->tail = newNode; + list->size++; + + return 0; +} + +int linkedList_dequeue(struct linkedList *list, + void **data) +{ + if (list->size == 0) { + log_error("Linked list is empty, dequeue failed!\n"); + return -1; + } + struct linkedListNode *node = list->head; + + *data = node->data; + + struct linkedListNode *tmp; + if (list->size == 1) { + tmp = list->head; + free(tmp); + list->head = NULL; + list->tail = NULL; + list->size = 0; + return 0; + } + + tmp = list->head; + + list->tail->next = list->head->next; + list->head->next->prev = list->tail; + list->head = list->head->next; + + free(tmp); + + list->size--; + + return 0; +} + +int linkedList_release(struct linkedList *list) +{ + int ret = 0; + if (list == NULL) { + return -1; + } + + while (list->size != 0) { + void *data; + ret = linkedList_dequeue(list, &data); + if (ret != 0) { + log_error("linkedList_dequeue failed!\n"); + return -1; + } + free(data); + } + + free(list); + + return 0; +}