From 9b3173f9be364dadb6f97ca53f97a6a371fc26cb Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 24 Apr 2019 13:15:43 -0400 Subject: [PATCH] Adding key and search to list --- src/util/list.c | 55 +++++++++++++++++++++++++++++++++++----- src/util/list.h | 21 ++++++++++----- tests/util/test_list.cpp | 34 ++++++++++++++++--------- 3 files changed, 85 insertions(+), 25 deletions(-) diff --git a/src/util/list.c b/src/util/list.c index 0b568d9..1bd6970 100644 --- a/src/util/list.c +++ b/src/util/list.c @@ -22,6 +22,7 @@ #endif #include +#include #include #include "list.h" @@ -29,6 +30,7 @@ typedef struct list_node_s { void *data; + int key; struct list_node_s *next; } list_node_t; @@ -42,6 +44,9 @@ typedef struct list_s { } list_t; +// local declarations +int gen_key(); + list_t *create_list(size_t elementSize, freeFunction freeFn) { list_t *list; @@ -67,12 +72,14 @@ void delete_list(list_t *list) free(list); } -void prepend_list(list_t *list, void *element) +int prepend_list(list_t *list, void *element) { list_node_t *node = malloc(sizeof(list_node_t)); node->data = malloc(list->elementSize); memcpy(node->data, element, list->elementSize); + node->key = gen_key(); + node->next = list->head; list->head = node; @@ -82,14 +89,18 @@ void prepend_list(list_t *list, void *element) } list->logicalLength++; + + return node->key; } -void append_list(list_t *list, void *element) +int append_list(list_t *list, void *element) { list_node_t *node = malloc(sizeof(list_node_t)); node->data = malloc(list->elementSize); node->next = NULL; + node->key = gen_key(); + memcpy(node->data, element, list->elementSize); if(list->logicalLength == 0) { @@ -100,8 +111,11 @@ void append_list(list_t *list, void *element) } list->logicalLength++; + + return node->key; } + void for_each_list(list_t *list, listIterator iterator) { assert(iterator != NULL); @@ -110,18 +124,16 @@ void for_each_list(list_t *list, listIterator iterator) bool result = true; while(node != NULL && result) { - result = (iterator); + result = iterator(node); node = node->next; } } list_node_t *head_list(list_t *list, bool removeFromList) -// // Warning: When node is removed caller is responsible for freeing it. -// { // assert(list->head != NULL); - + if (list) { list_node_t *node = list->head; if (removeFromList) { @@ -141,7 +153,7 @@ list_node_t *tail_list(list_t *list) } list_node_t *get_nth_list(list_t *list, int index) -{ +{ int n; list_node_t *lnode; @@ -152,11 +164,31 @@ list_node_t *get_nth_list(list_t *list, int index) return lnode; } +list_node_t *search_list(list_t *list, int key) +// Naive list search. Will not perform for large lists. +{ + list_node_t *lnode = first_list(list); + + while (done_list(lnode)) { + + if (get_key(lnode) == key) + return lnode; + + lnode = next_list(lnode); + } + return NULL; +} + int size_list(list_t *list) { return list->logicalLength; } +int get_key(list_node_t *lnode) +{ + return lnode->key; +} + void *get_data(list_node_t *lnode) { return lnode->data; @@ -175,3 +207,12 @@ void delete_node(list_t *list, list_node_t *lnode) free(lnode->data); free(lnode); } + + +// local functions + +int gen_key() +// Naive key generator. No guarentee of uniqueness +{ + return rand(); +} diff --git a/src/util/list.h b/src/util/list.h index e2e9185..b3583b3 100644 --- a/src/util/list.h +++ b/src/util/list.h @@ -46,14 +46,14 @@ with each node’s data pointer. void delete_list(list_t *list); /** -@brief Adds a node to the head of the list. +@brief Adds a node to the head of the list and returns its key. */ -void prepend_list(list_t *list, void *element); +int prepend_list(list_t *list, void *element); /** -@brief Adds a node to the tail of the list. +@brief Adds a node to the tail of the list and returns its key. */ -void append_list(list_t *list, void *element); +int append_list(list_t *list, void *element); /** @brief Returns the number of items in the list. @@ -67,7 +67,12 @@ int size_list(list_t *list); void *get_data(list_node_t *lnode); /** -@brief Returns next list node. +@brief Returns list node's key value. +*/ +int get_key(list_node_t *lnode); + +/** +@brief Returns next list node. */ list_node_t *get_next(list_node_t *lnode); @@ -94,10 +99,14 @@ list_node_t *head_list(list_t *list, bool removeFromList); list_node_t *tail_list(list_t *list); /** -@brief Returns nth node of the list or NULL. +@brief Returns nth node of the list or NULL. */ list_node_t *get_nth_list(list_t *list, int index); +/** +@brief Returns the list node with the given key or NULL. +*/ +list_node_t *search_list(list_t *list, int key); // // Iterator first/done/next operations diff --git a/tests/util/test_list.cpp b/tests/util/test_list.cpp index 787c1ed..7c592a5 100644 --- a/tests/util/test_list.cpp +++ b/tests/util/test_list.cpp @@ -13,7 +13,9 @@ ****************************************************************************** */ +#include #include +#include #define BOOST_TEST_MODULE list #include @@ -35,7 +37,7 @@ int *get_int_data(list_node_t *lnode) { bool iterate_int(list_node_t *lnode) { - printf("Found value: %d\n", *get_int_data(lnode)); + printf("At Key: %d Found value: %d\n", get_key(lnode), *get_int_data(lnode)); return true; } @@ -57,16 +59,23 @@ BOOST_AUTO_TEST_CASE(test_int_list){ int i, numbers = 10; list_t *list = NULL; + int key[10 + 1]; + + srand((unsigned int)time(0)); + list = create_list(sizeof(int), NULL); for(i = 1; i <= numbers; i++) { - append_list(list, &i); + key[i] = append_list(list, &i); } BOOST_CHECK(size_list(list) == 10); - + listIterator iterator = (listIterator)iterate_int; for_each_list(list, iterator); + list_node_t *lnode = search_list(list, key[5]); + BOOST_CHECK(get_key(lnode) == key[5]); + delete_list(list); } @@ -179,9 +188,15 @@ bool iterate_test_data(list_node_t *lnode) } +char *get_name(list_node_t *lnode) +{ + return get_test_data(lnode)->name; +} BOOST_AUTO_TEST_CASE(test_struct_list){ + int key; + list_t *list = NULL; list = create_list(sizeof(test_data_t *), delete_test_data); @@ -190,7 +205,7 @@ BOOST_AUTO_TEST_CASE(test_struct_list){ append_list(list, &data); data = create_test_data(2, "Kevin"); - append_list(list, &data); + key = append_list(list, &data); data = create_test_data(3, "Michael"); append_list(list, &data); @@ -202,16 +217,11 @@ BOOST_AUTO_TEST_CASE(test_struct_list){ for_each_list(list, iterator); - list_node_t *lnode; - // Iterate over list while maintaining containment of list abstraction - for (lnode = first_list(list); done_list(lnode); lnode = next_list(lnode)) { - test_data_t *test_data = get_test_data(lnode); + // locate a list node by a key + printf("Found %s!\n", get_name(search_list(list, key))); - if (test_data->num == 2) - printf("Found %s!\n", test_data->name); - } - lnode = head_list(list, true); + list_node_t *lnode = head_list(list, true); delete_node(list, lnode); delete_list(list);