diff --git a/README.md b/README.md index 76ee9c0..e41de63 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ test { const Pair = StringTrie.Pair; const allocator = std.testing.allocator; - var trie = StringTrie.init(); + var trie = try StringTrie.init(allocator); defer trie.deinit(allocator); try trie.insert(allocator, "hello", {}); diff --git a/src/bench.zig b/src/bench.zig index 6b68fdf..164814d 100644 --- a/src/bench.zig +++ b/src/bench.zig @@ -18,24 +18,28 @@ pub fn main() !void { defer std.debug.assert(!gpa.deinit()); const allocator = gpa.allocator(); + const elem_count = 10; - const keys = try allocator.alloc([32]u8, 10); + const keys = try allocator.alloc([32]u8, elem_count); defer allocator.free(keys); var rand = std.rand.DefaultPrng.init(0); for (keys) |*key| rand.fill(key); - var trie = HashArrayMappedTrie([]const u8, void, StringContext).init(); + var trie = try HashArrayMappedTrie([]const u8, void, StringContext).init(allocator); defer trie.deinit(allocator); - for (keys) |*key| { - try trie.insert(allocator, key, {}); - } - var timer = try std.time.Timer.start(); + for (keys) |*key| { + try trie.insert(allocator, key, {}); + } + const insert_time = timer.lap(); + for (keys) |*key| { _ = trie.search(key); } + const search_time = timer.read(); - std.debug.print("{}ns\n", .{timer.read()}); + std.debug.print("Insert: {d:.2}ns\n", .{(@intToFloat(f32, insert_time) / elem_count) * 100.0}); + std.debug.print("Search: {d:.2}ns\n", .{(@intToFloat(f32, search_time) / elem_count) * 100.0}); } diff --git a/src/trie.zig b/src/trie.zig index 6a61f81..99707d3 100644 --- a/src/trie.zig +++ b/src/trie.zig @@ -17,14 +17,18 @@ pub fn HashArrayMappedTrie(comptime K: type, comptime V: type, comptime Context: const table_size = @typeInfo(Digest).Int.bits; const t = @intCast(Log2Int(Digest), @typeInfo(Log2Int(Digest)).Int.bits); - root: [table_size]?*Node, + root: []?*Node, const Node = union(enum) { kv: Pair, table: Table }; const Table = struct { map: Digest = 0, base: [*]Node }; pub const Pair = struct { key: K, value: V }; - pub fn init() Self { - return Self{ .root = [_]?*Node{null} ** table_size }; + pub fn init(allocator: Allocator) !Self { + // TODO: Add ability to have a larger root node (for quicker lookup times) + const root = try allocator.alloc(?*Node, table_size); + std.mem.set(?*Node, root, null); + + return Self{ .root = root }; } pub fn deinit(self: *Self, allocator: Allocator) void { @@ -34,6 +38,8 @@ pub fn HashArrayMappedTrie(comptime K: type, comptime V: type, comptime Context: _deinit(allocator, node); allocator.destroy(node); } + + allocator.free(self.root); } fn _deinit(allocator: Allocator, node: *Node) void { @@ -294,20 +300,22 @@ const StringContext = struct { const StringTrie = HashArrayMappedTrie([]const u8, void, StringContext); test "trie init" { - _ = StringTrie.init(); + const allocator = std.testing.allocator; + var trie = try StringTrie.init(allocator); + defer trie.deinit(allocator); } test "init and deinit" { const allocator = std.testing.allocator; - var trie = StringTrie.init(); + var trie = try StringTrie.init(allocator); defer trie.deinit(allocator); } test "trie insert" { const allocator = std.testing.allocator; - var trie = StringTrie.init(); + var trie = try StringTrie.init(allocator); defer trie.deinit(allocator); try trie.insert(allocator, "hello", {}); @@ -318,7 +326,7 @@ test "trie search" { const Pair = StringTrie.Pair; const allocator = std.testing.allocator; - var trie = StringTrie.init(); + var trie = try StringTrie.init(allocator); defer trie.deinit(allocator); try std.testing.expectEqual(@as(?Pair, null), trie.search("sdvx")); @@ -336,7 +344,7 @@ test "README.md example" { const Pair = StringTrie.Pair; const allocator = std.testing.allocator; - var trie = StringTrie.init(); + var trie = try StringTrie.init(allocator); defer trie.deinit(allocator); try trie.insert(allocator, "hello", {});