summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-09-10 20:11:40 -0400
committerDavid Robillard <d@drobilla.net>2021-09-10 20:54:28 -0400
commit06443ecb437eebcf3373b1034ca5ff84ebe212df (patch)
tree89c4c0d72eac6b10d88bf1042584d84cf9fc607f
parent6d4cb50fa2f2cdd092e9459a6da59eb3cdda7434 (diff)
downloadzix-06443ecb437eebcf3373b1034ca5ff84ebe212df.tar.gz
zix-06443ecb437eebcf3373b1034ca5ff84ebe212df.tar.bz2
zix-06443ecb437eebcf3373b1034ca5ff84ebe212df.zip
Add a user handle to destroy callback
-rw-r--r--benchmark/tree_bench.c4
-rw-r--r--include/zix/btree.h8
-rw-r--r--include/zix/common.h2
-rw-r--r--include/zix/tree.h3
-rw-r--r--src/btree.c26
-rw-r--r--src/tree.c25
-rw-r--r--test/btree_test.c24
-rw-r--r--test/tree_test.c2
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) {