@@ -120,6 +120,8 @@ struct critnib_leaf {
120
120
121
121
struct critnib {
122
122
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
123
125
124
126
/* pool of freed nodes: singly linked list, next at child[0] */
125
127
struct critnib_node * deleted_node ;
@@ -161,8 +163,12 @@ static inline unsigned slice_index(word key, sh_t shift) {
161
163
162
164
/*
163
165
* 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)
164
170
*/
165
- struct critnib * critnib_new (void ) {
171
+ struct critnib * critnib_new (free_leaf_t cb_free_leaf , void * leaf_allocator ) {
166
172
struct critnib * c = umf_ba_global_alloc (sizeof (struct critnib ));
167
173
if (!c ) {
168
174
return NULL ;
@@ -175,6 +181,8 @@ struct critnib *critnib_new(void) {
175
181
goto err_free_critnib ;
176
182
}
177
183
184
+ c -> leaf_allocator = leaf_allocator ;
185
+ c -> cb_free_leaf = cb_free_leaf ;
178
186
utils_annotate_memory_no_check (& c -> root , sizeof (c -> root ));
179
187
utils_annotate_memory_no_check (& c -> remove_count , sizeof (c -> remove_count ));
180
188
@@ -189,6 +197,10 @@ struct critnib *critnib_new(void) {
189
197
*/
190
198
static void delete_node (struct critnib * c , struct critnib_node * __restrict n ) {
191
199
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
+ }
192
204
umf_ba_global_free (to_leaf (n ));
193
205
} else {
194
206
for (int i = 0 ; i < SLNODES ; i ++ ) {
@@ -225,6 +237,10 @@ void critnib_delete(struct critnib *c) {
225
237
226
238
for (int i = 0 ; i < DELETED_LIFE ; i ++ ) {
227
239
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
+ }
228
244
umf_ba_global_free (c -> pending_del_leaves [i ]);
229
245
}
230
246
@@ -277,6 +293,10 @@ static void free_leaf(struct critnib *__restrict c,
277
293
return ;
278
294
}
279
295
296
+ if (c -> cb_free_leaf && k ) {
297
+ c -> cb_free_leaf (c -> leaf_allocator , (void * )k -> value );
298
+ }
299
+
280
300
utils_atomic_store_release_ptr ((void * * )& k -> value , c -> deleted_leaf );
281
301
utils_atomic_store_release_ptr ((void * * )& c -> deleted_leaf , k );
282
302
}
0 commit comments