I'm trying to create a Trie structure in Zig using Zigs StringHashMap. I am able to get it to work a bit, but only by using a "inline" for loop which is not really usable as this requires the paths to be known at compile time :-(
Any help/explanation would be much appreciated :-)
The code:
const std = @import("std");
const Allocator = std.mem.Allocator;
const print = std.debug.print;
const expect = std.testing.expect;
const HashMap = struct {
value: u8,
children: std.StringHashMap(*HashMap),
};
fn newHashMap(allocator: Allocator, value: u8) HashMap {
return HashMap{
.value = value,
.children = std.StringHashMap(*HashMap).init(allocator),
};
}
fn showTree(root: *std.StringHashMap(*HashMap), keys:[3][]const u8 ) void {
var hashMap = root;
for (keys) |key| {
print("get key {s}\n", .{key});
var value = hashMap.get(key);
if (value) |node| {
print("we got a value for {s}:{}\n", .{key,node.value});
hashMap = &node.children;
} else {
print("no value for {s}\n", .{key});
break;
}
}
}
test "HashMap" {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const gpaAllocator = gpa.allocator();
var arena = std.heap.ArenaAllocator.init(gpaAllocator);
defer {
arena.deinit();
const leaked = gpa.deinit();
if (leaked) expect(false) catch @panic("TEST FAIL"); //fail test; can't try in defer as defer is executed after we return
}
const allocator = arena.allocator();
var root = &std.StringHashMap(*HashMap).init(allocator);
var hashMap = root;
const keys = [_][]const u8{ "a", "b", "c" };
const values: [3]u8 = .{ 1, 2, 3 };
// create tree
inline for (keys) |key, i| {
print("put key {s}:{}\n", .{ key, values[i] });
var newNode = newHashMap(allocator, values[i]);
try hashMap.put(key, &newNode);
showTree(root,keys);
hashMap = &newNode.children;
}
showTree(root,keys);
}
This prints:
Test [1/1] test "HashMap"...
put key a:1
put key b:2
put key c:3
get key a
we got a value for a:1
get key b
we got a value for b:2
get key c
we got a value for c:3
All 1 tests passed.
as expected.
Removing the 'inline' results in:
Test [1/1] test "HashMap"...
put key a:1
put key b:2
put key c:3
get key a
we got a value for a:3
get key b
no value for b
All 1 tests passed.