fix(hamt): properly cleanup allocations on deinit

This commit is contained in:
Rekai Nyangadzayi Musuka 2023-04-14 00:46:29 -05:00
parent 5f9126ec32
commit 6f6b1d8889
2 changed files with 23 additions and 7 deletions

View File

@ -24,17 +24,28 @@ pub fn init(allocator: Allocator) !HashArrayMappedTrie {
} }
pub fn deinit(self: *HashArrayMappedTrie) void { pub fn deinit(self: *HashArrayMappedTrie) void {
for (self.root) |node| { for (self.root) |maybe_node| {
if (node == null) continue; const node = maybe_node orelse continue;
deinitRecurse(self.allocator, node.?); deinitInner(self.allocator, node);
self.allocator.destroy(node);
} }
} }
fn deinitRecurse(allocator: Allocator, node: *Node) void { fn deinitInner(allocator: Allocator, node: *Node) void {
switch (node.*) { switch (node.*) {
.kv => allocator.destroy(node), .kv => |_| return, // will be deallocated by caller
else => {}, .table => |table| {
const amt_ptr = table.base[0..@popCount(table.map)]; // Array Mapped Table
for (amt_ptr) |*sub_node| {
if (sub_node.* == .table) {
deinitInner(allocator, sub_node);
}
}
allocator.free(amt_ptr);
},
} }
} }

View File

@ -2,7 +2,12 @@ const std = @import("std");
const HashArrayMappedTrie = @import("HashArrayMappedTrie.zig"); const HashArrayMappedTrie = @import("HashArrayMappedTrie.zig");
pub fn main() !void { pub fn main() !void {
var trie = try HashArrayMappedTrie.init(std.heap.page_allocator); var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(!gpa.deinit());
const allocator = gpa.allocator();
var trie = try HashArrayMappedTrie.init(allocator);
defer trie.deinit(); defer trie.deinit();
try trie.insert("and", {}); try trie.insert("and", {});