Skip to content

Commit 8d66c25

Browse files
chore(rax_tree): Introduce raxFreeWithCallback call in RaxTreeMap destructor (#4255)
Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>
1 parent 612d50d commit 8d66c25

File tree

3 files changed

+32
-12
lines changed

3 files changed

+32
-12
lines changed

src/core/search/rax_tree.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,16 @@ template <typename V> struct RaxTreeMap {
109109
}
110110

111111
~RaxTreeMap() {
112-
for (auto it = begin(); it != end(); ++it) {
113-
V* ptr = &(*it).second;
114-
std::allocator_traits<decltype(alloc_)>::destroy(alloc_, ptr);
115-
alloc_.deallocate(ptr, 1);
116-
}
117-
raxFree(tree_);
112+
using Allocator = decltype(alloc_);
113+
114+
auto free_callback = [](void* data, void* context) {
115+
Allocator* allocator = static_cast<Allocator*>(context);
116+
V* ptr = static_cast<V*>(data);
117+
std::allocator_traits<Allocator>::destroy(*allocator, ptr);
118+
allocator->deallocate(ptr, 1);
119+
};
120+
121+
raxFreeWithCallbackAndArgument(tree_, free_callback, &alloc_);
118122
}
119123

120124
size_t size() const {

src/redis/rax.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,29 +1221,44 @@ int raxRemove(rax *rax, unsigned char *s, size_t len, void **old) {
12211221

12221222
/* This is the core of raxFree(): performs a depth-first scan of the
12231223
* tree and releases all the nodes found. */
1224-
void raxRecursiveFree(rax *rax, raxNode *n, void (*free_callback)(void*)) {
1224+
void raxRecursiveFree(rax *rax, raxNode *n, void (*free_callback)(void*, void*), void* argument) {
12251225
debugnode("free traversing",n);
12261226
int numchildren = n->iscompr ? 1 : n->size;
12271227
raxNode **cp = raxNodeLastChildPtr(n);
12281228
while(numchildren--) {
12291229
raxNode *child;
12301230
memcpy(&child,cp,sizeof(child));
1231-
raxRecursiveFree(rax,child,free_callback);
1231+
raxRecursiveFree(rax,child,free_callback,argument);
12321232
cp--;
12331233
}
12341234
debugnode("free depth-first",n);
12351235
if (free_callback && n->iskey && !n->isnull)
1236-
free_callback(raxGetData(n));
1236+
free_callback(raxGetData(n),argument);
12371237
rax_free(n);
12381238
rax->numnodes--;
12391239
}
12401240

1241+
/* Free the entire radix tree, invoking a free_callback function for each key's data.
1242+
* An additional argument is passed to the free_callback function.*/
1243+
void raxFreeWithCallbackAndArgument(rax *rax, void (*free_callback)(void*, void*), void* argument) {
1244+
raxRecursiveFree(rax,rax->head,free_callback,argument);
1245+
assert(rax->numnodes == 0);
1246+
rax_free(rax);
1247+
}
1248+
1249+
/* Wrapper for the callback to adapt it for the context */
1250+
void freeCallbackWrapper(void* data, void* argument) {
1251+
if (!argument) {
1252+
return;
1253+
}
1254+
void (*free_callback)(void*) = (void (*)(void*))argument;
1255+
free_callback(data);
1256+
}
1257+
12411258
/* Free a whole radix tree, calling the specified callback in order to
12421259
* free the auxiliary data. */
12431260
void raxFreeWithCallback(rax *rax, void (*free_callback)(void*)) {
1244-
raxRecursiveFree(rax,rax->head,free_callback);
1245-
assert(rax->numnodes == 0);
1246-
rax_free(rax);
1261+
raxFreeWithCallbackAndArgument(rax, freeCallbackWrapper, (void*)free_callback);
12471262
}
12481263

12491264
/* Free a whole radix tree. */

src/redis/rax.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ int raxRemove(rax *rax, unsigned char *s, size_t len, void **old);
195195
void *raxFind(rax *rax, unsigned char *s, size_t len);
196196
void raxFree(rax *rax);
197197
void raxFreeWithCallback(rax *rax, void (*free_callback)(void*));
198+
void raxFreeWithCallbackAndArgument(rax *rax, void (*free_callback)(void*, void*), void* argument);
198199
void raxStart(raxIterator *it, rax *rt);
199200
int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len);
200201
int raxNext(raxIterator *it);

0 commit comments

Comments
 (0)