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 {
for (self.root) |node| {
if (node == null) continue;
for (self.root) |maybe_node| {
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.*) {
.kv => allocator.destroy(node),
else => {},
.kv => |_| return, // will be deallocated by caller
.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");
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();
try trie.insert("and", {});