@@ -120,6 +120,8 @@ struct critnib_leaf {
120120
121121struct critnib {
122122 struct critnib_node * root ;
123+ free_leaf_t cb_free_leaf ; // callback for freeing a leaf
124+ void * leaf_allocator ; // handle of allocator for leaves
123125
124126 /* pool of freed nodes: singly linked list, next at child[0] */
125127 struct critnib_node * deleted_node ;
@@ -161,8 +163,12 @@ static inline unsigned slice_index(word key, sh_t shift) {
161163
162164/*
163165 * critnib_new -- allocates a new critnib structure
166+ *
167+ * Arguments:
168+ * - cb_free_leaf - callback for freeing a leaf (can be NULL)
169+ * - leaf_allocator - handle of allocator for leaves (can be NULL)
164170 */
165- struct critnib * critnib_new (void ) {
171+ struct critnib * critnib_new (free_leaf_t cb_free_leaf , void * leaf_allocator ) {
166172 struct critnib * c = umf_ba_global_alloc (sizeof (struct critnib ));
167173 if (!c ) {
168174 return NULL ;
@@ -175,6 +181,8 @@ struct critnib *critnib_new(void) {
175181 goto err_free_critnib ;
176182 }
177183
184+ c -> leaf_allocator = leaf_allocator ;
185+ c -> cb_free_leaf = cb_free_leaf ;
178186 utils_annotate_memory_no_check (& c -> root , sizeof (c -> root ));
179187 utils_annotate_memory_no_check (& c -> remove_count , sizeof (c -> remove_count ));
180188
@@ -189,6 +197,10 @@ struct critnib *critnib_new(void) {
189197 */
190198static void delete_node (struct critnib * c , struct critnib_node * __restrict n ) {
191199 if (is_leaf (n )) {
200+ // call the callback freeing the leaf
201+ if (c -> cb_free_leaf && to_leaf (n )) {
202+ c -> cb_free_leaf (c -> leaf_allocator , (void * )to_leaf (n )-> value );
203+ }
192204 umf_ba_global_free (to_leaf (n ));
193205 } else {
194206 for (int i = 0 ; i < SLNODES ; i ++ ) {
@@ -225,6 +237,10 @@ void critnib_delete(struct critnib *c) {
225237
226238 for (int i = 0 ; i < DELETED_LIFE ; i ++ ) {
227239 umf_ba_global_free (c -> pending_del_nodes [i ]);
240+ if (c -> cb_free_leaf && c -> pending_del_leaves [i ]) {
241+ c -> cb_free_leaf (c -> leaf_allocator ,
242+ (void * )c -> pending_del_leaves [i ]-> value );
243+ }
228244 umf_ba_global_free (c -> pending_del_leaves [i ]);
229245 }
230246
@@ -277,6 +293,10 @@ static void free_leaf(struct critnib *__restrict c,
277293 return ;
278294 }
279295
296+ if (c -> cb_free_leaf && k ) {
297+ c -> cb_free_leaf (c -> leaf_allocator , (void * )k -> value );
298+ }
299+
280300 utils_atomic_store_release_ptr ((void * * )& k -> value , c -> deleted_leaf );
281301 utils_atomic_store_release_ptr ((void * * )& c -> deleted_leaf , k );
282302}
0 commit comments