From 06443ecb437eebcf3373b1034ca5ff84ebe212df Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 10 Sep 2021 20:11:40 -0400 Subject: Add a user handle to destroy callback --- benchmark/tree_bench.c | 4 ++-- include/zix/btree.h | 8 ++++++-- include/zix/common.h | 2 +- include/zix/tree.h | 3 ++- src/btree.c | 26 ++++++++++++++++---------- src/tree.c | 25 ++++++++++++++----------- test/btree_test.c | 24 +++++++++++++----------- test/tree_test.c | 2 +- 8 files changed, 55 insertions(+), 39 deletions(-) diff --git a/benchmark/tree_bench.c b/benchmark/tree_bench.c index d27c506..1be6767 100644 --- a/benchmark/tree_bench.c +++ b/benchmark/tree_bench.c @@ -89,7 +89,7 @@ bench_zix_tree(size_t n_elems, uintptr_t r = 0; ZixTreeIter* ti = NULL; - ZixTree* t = zix_tree_new(false, int_cmp, NULL, NULL); + ZixTree* t = zix_tree_new(false, int_cmp, NULL, NULL, NULL); // Insert n_elems elements struct timespec insert_start = bench_start(); @@ -204,7 +204,7 @@ bench_zix_btree(size_t n_elems, } fprintf(del_dat, "\t%lf", bench_end(&del_start)); - zix_btree_free(t, NULL); + zix_btree_free(t, NULL, NULL); return EXIT_SUCCESS; } diff --git a/include/zix/btree.h b/include/zix/btree.h index d19da3c..07de8c3 100644 --- a/include/zix/btree.h +++ b/include/zix/btree.h @@ -95,7 +95,9 @@ zix_btree_new(ZixComparator cmp, const void* cmp_data); */ ZIX_API void -zix_btree_free(ZixBTree* t, ZixDestroyFunc destroy); +zix_btree_free(ZixBTree* t, + ZixDestroyFunc destroy, + const void* destroy_user_data); /** Clear everything from `t`, leaving it empty. @@ -105,7 +107,9 @@ zix_btree_free(ZixBTree* t, ZixDestroyFunc destroy); */ ZIX_API void -zix_btree_clear(ZixBTree* t, ZixDestroyFunc destroy); +zix_btree_clear(ZixBTree* t, + ZixDestroyFunc destroy, + const void* destroy_user_data); /// Return the number of elements in `t` ZIX_PURE_API diff --git a/include/zix/common.h b/include/zix/common.h index 02f00b4..f43fcde 100644 --- a/include/zix/common.h +++ b/include/zix/common.h @@ -124,7 +124,7 @@ typedef int (*ZixComparator)(const void* a, typedef bool (*ZixEqualFunc)(const void* a, const void* b); /// Function to destroy an element -typedef void (*ZixDestroyFunc)(void* ptr); +typedef void (*ZixDestroyFunc)(void* ptr, const void* user_data); /** @} diff --git a/include/zix/tree.h b/include/zix/tree.h index d7d2cce..e0daa80 100644 --- a/include/zix/tree.h +++ b/include/zix/tree.h @@ -45,7 +45,8 @@ ZixTree* zix_tree_new(bool allow_duplicates, ZixComparator cmp, void* cmp_data, - ZixDestroyFunc destroy); + ZixDestroyFunc destroy, + const void* destroy_user_data); /// Free `t` ZIX_API diff --git a/src/btree.c b/src/btree.c index 21db8d6..4a8c4f6 100644 --- a/src/btree.c +++ b/src/btree.c @@ -115,13 +115,15 @@ zix_btree_new(const ZixComparator cmp, const void* const cmp_data) } static void -zix_btree_free_children(ZixBTree* const t, - ZixBTreeNode* const n, - ZixDestroyFunc destroy) +zix_btree_free_children(ZixBTree* const t, + ZixBTreeNode* const n, + const ZixDestroyFunc destroy, + const void* const destroy_user_data) { if (!n->is_leaf) { for (ZixShort i = 0; i < n->n_vals + 1u; ++i) { - zix_btree_free_children(t, zix_btree_child(n, i), destroy); + zix_btree_free_children( + t, zix_btree_child(n, i), destroy, destroy_user_data); free(zix_btree_child(n, i)); } } @@ -129,30 +131,34 @@ zix_btree_free_children(ZixBTree* const t, if (destroy) { if (n->is_leaf) { for (ZixShort i = 0u; i < n->n_vals; ++i) { - destroy(n->data.leaf.vals[i]); + destroy(n->data.leaf.vals[i], destroy_user_data); } } else { for (ZixShort i = 0u; i < n->n_vals; ++i) { - destroy(n->data.inode.vals[i]); + destroy(n->data.inode.vals[i], destroy_user_data); } } } } void -zix_btree_free(ZixBTree* const t, ZixDestroyFunc destroy) +zix_btree_free(ZixBTree* const t, + const ZixDestroyFunc destroy, + const void* const destroy_user_data) { if (t) { - zix_btree_clear(t, destroy); + zix_btree_clear(t, destroy, destroy_user_data); free(t->root); free(t); } } void -zix_btree_clear(ZixBTree* const t, ZixDestroyFunc destroy) +zix_btree_clear(ZixBTree* const t, + ZixDestroyFunc destroy, + const void* destroy_user_data) { - zix_btree_free_children(t, t->root, destroy); + zix_btree_free_children(t, t->root, destroy, destroy_user_data); memset(t->root, 0, sizeof(ZixBTreeNode)); t->root->is_leaf = true; diff --git a/src/tree.c b/src/tree.c index 9faf13c..f26ff90 100644 --- a/src/tree.c +++ b/src/tree.c @@ -27,6 +27,7 @@ typedef struct ZixTreeNodeImpl ZixTreeNode; struct ZixTreeImpl { ZixTreeNode* root; ZixDestroyFunc destroy; + const void* destroy_user_data; ZixComparator cmp; void* cmp_data; size_t size; @@ -69,15 +70,17 @@ ZixTree* zix_tree_new(bool allow_duplicates, ZixComparator cmp, void* cmp_data, - ZixDestroyFunc destroy) + ZixDestroyFunc destroy, + const void* destroy_user_data) { - ZixTree* t = (ZixTree*)malloc(sizeof(ZixTree)); - t->root = NULL; - t->destroy = destroy; - t->cmp = cmp; - t->cmp_data = cmp_data; - t->size = 0; - t->allow_duplicates = allow_duplicates; + ZixTree* t = (ZixTree*)malloc(sizeof(ZixTree)); + t->root = NULL; + t->destroy = destroy; + t->destroy_user_data = destroy_user_data; + t->cmp = cmp; + t->cmp_data = cmp_data; + t->size = 0; + t->allow_duplicates = allow_duplicates; return t; } @@ -88,7 +91,7 @@ zix_tree_free_rec(ZixTree* t, ZixTreeNode* n) zix_tree_free_rec(t, n->left); zix_tree_free_rec(t, n->right); if (t->destroy) { - t->destroy(n->data); + t->destroy(n->data, t->destroy_user_data); } free(n); } @@ -451,7 +454,7 @@ zix_tree_remove(ZixTree* t, ZixTreeIter* ti) if ((n == t->root) && !n->left && !n->right) { t->root = NULL; if (t->destroy) { - t->destroy(n->data); + t->destroy(n->data, t->destroy_user_data); } free(n); --t->size; @@ -583,7 +586,7 @@ zix_tree_remove(ZixTree* t, ZixTreeIter* ti) DUMP(t); if (t->destroy) { - t->destroy(n->data); + t->destroy(n->data, t->destroy_user_data); } free(n); diff --git a/test/btree_test.c b/test/btree_test.c index b187d20..a890f0f 100644 --- a/test/btree_test.c +++ b/test/btree_test.c @@ -103,7 +103,7 @@ ZIX_LOG_FUNC(2, 3) static int test_fail(ZixBTree* t, const char* fmt, ...) { - zix_btree_free(t, NULL); + zix_btree_free(t, NULL, NULL); if (expect_failure) { return EXIT_SUCCESS; } @@ -119,15 +119,17 @@ test_fail(ZixBTree* t, const char* fmt, ...) static const size_t n_clear_insertions = 1024u; static void -destroy(void* const ptr) +destroy(void* const ptr, const void* const user_data) { + (void)user_data; assert(ptr); assert((uintptr_t)ptr <= n_clear_insertions); } static void -no_destroy(void* const ptr) +no_destroy(void* const ptr, const void* const user_data) { + (void)user_data; assert(!ptr); } @@ -140,10 +142,10 @@ test_clear(void) assert(!zix_btree_insert(t, (void*)(r + 1u))); } - zix_btree_clear(t, destroy); + zix_btree_clear(t, destroy, NULL); assert(zix_btree_size(t) == 0); - zix_btree_free(t, no_destroy); + zix_btree_free(t, no_destroy, NULL); } static void @@ -157,7 +159,7 @@ test_free(void) assert(zix_btree_size(t) == n_clear_insertions); - zix_btree_free(t, destroy); + zix_btree_free(t, destroy, NULL); } static void @@ -200,7 +202,7 @@ test_iter_comparison(void) assert(zix_btree_iter_equals(end, j)); assert(zix_btree_iter_equals(j, end)); - zix_btree_free(t, NULL); + zix_btree_free(t, NULL, NULL); } static void @@ -219,7 +221,7 @@ test_insert_split_value(void) // Insert the element that will be chosen as the split pivot assert(zix_btree_insert(t, (void*)split_value) == ZIX_STATUS_EXISTS); - zix_btree_free(t, NULL); + zix_btree_free(t, NULL, NULL); } static void @@ -257,7 +259,7 @@ test_remove_cases(void) } assert(!zix_btree_size(t)); - zix_btree_free(t, NULL); + zix_btree_free(t, NULL, NULL); } static int @@ -547,7 +549,7 @@ stress(const unsigned test_num, const size_t n_elems) } assert(zix_btree_size(t) == 0); - zix_btree_free(t, NULL); + zix_btree_free(t, NULL, NULL); // Test lower_bound with wildcard comparator @@ -598,7 +600,7 @@ stress(const unsigned test_num, const size_t n_elems) return test_fail(t, "Lower bound of maximum value is not end\n"); } - zix_btree_free(t, NULL); + zix_btree_free(t, NULL, NULL); return EXIT_SUCCESS; } diff --git a/test/tree_test.c b/test/tree_test.c index 7368e10..434d4d7 100644 --- a/test/tree_test.c +++ b/test/tree_test.c @@ -62,7 +62,7 @@ stress(unsigned test_num, size_t n_elems) { uintptr_t r = 0u; ZixTreeIter* ti = NULL; - ZixTree* t = zix_tree_new(true, int_cmp, NULL, NULL); + ZixTree* t = zix_tree_new(true, int_cmp, NULL, NULL, NULL); // Insert n_elems elements for (size_t i = 0; i < n_elems; ++i) { -- cgit v1.2.1