feat: add README.md
This commit is contained in:
parent
49a5d1b72a
commit
b353458d68
|
@ -0,0 +1,46 @@
|
||||||
|
# Hash Array Mapped Trie
|
||||||
|
|
||||||
|
A barebones implementation of [this paper](https://infoscience.epfl.ch/record/64398) by Phil Bagwell.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
As an example:
|
||||||
|
```zig
|
||||||
|
const std = @import("std");
|
||||||
|
const expectEqual = std.testing.expectEqual;
|
||||||
|
const HashArrayMappedTrie = @import("hamt").HashArrayMappedTrie;
|
||||||
|
|
||||||
|
const StringTrie = HashArrayMappedTrie([]const u8, void, StringContext);
|
||||||
|
|
||||||
|
const StringContext = struct {
|
||||||
|
// Note: This definition is *required*
|
||||||
|
// TODO: I could just grab the @typeInfo(HashFn).Fn.return_type right?
|
||||||
|
pub const Digest = u64;
|
||||||
|
|
||||||
|
pub inline fn hash(key: []const u8) Digest {
|
||||||
|
return std.hash.Wyhash.hash(0, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn eql(left: []const u8, right: []const u8) bool {
|
||||||
|
return std.mem.eql(u8, left, right);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test {
|
||||||
|
const Pair = StringTrie.Pair;
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
|
var trie = StringTrie.init();
|
||||||
|
defer trie.deinit(allocator);
|
||||||
|
|
||||||
|
try trie.insert(allocator, "hello", {});
|
||||||
|
|
||||||
|
try expectEqual(@as(?Pair, .{ .key = "hello", .value = {} }), trie.search("hello"));
|
||||||
|
try expectEqual(@as(?Pair, null), trie.search("world"));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
Build in release mode with `zig build -Doptimzie=ReleaseSafe`;
|
||||||
|
|
|
@ -15,6 +15,9 @@ pub fn build(b: *std.Build) void {
|
||||||
// set a preferred release mode, allowing the user to decide how to optimize.
|
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const module = b.addModule("hamt", .{ .source_file = .{ .path = "src/lib.zig" } });
|
||||||
|
_ = module;
|
||||||
|
|
||||||
const lib = b.addStaticLibrary(.{
|
const lib = b.addStaticLibrary(.{
|
||||||
.name = "hamt",
|
.name = "hamt",
|
||||||
// In this case the main source file is merely a path, however, in more
|
// In this case the main source file is merely a path, however, in more
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.{
|
.{
|
||||||
.name = "SDL",
|
.name = "hamt",
|
||||||
.version = "0.0.1",
|
.version = "0.1.0",
|
||||||
.dependencies = .{},
|
.dependencies = .{},
|
||||||
}
|
}
|
||||||
|
|
27
src/trie.zig
27
src/trie.zig
|
@ -21,7 +21,7 @@ pub fn HashArrayMappedTrie(comptime K: type, comptime V: type, comptime Context:
|
||||||
|
|
||||||
const Node = union(enum) { kv: Pair, table: Table };
|
const Node = union(enum) { kv: Pair, table: Table };
|
||||||
const Table = struct { map: Digest = 0, base: [*]Node };
|
const Table = struct { map: Digest = 0, base: [*]Node };
|
||||||
const Pair = struct { key: K, value: V };
|
pub const Pair = struct { key: K, value: V };
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init() Self {
|
||||||
return Self{ .root = [_]?*Node{null} ** table_size };
|
return Self{ .root = [_]?*Node{null} ** table_size };
|
||||||
|
@ -291,23 +291,23 @@ const StringContext = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const TestHamt = HashArrayMappedTrie([]const u8, void, StringContext);
|
const StringTrie = HashArrayMappedTrie([]const u8, void, StringContext);
|
||||||
|
|
||||||
test "trie init" {
|
test "trie init" {
|
||||||
_ = TestHamt.init();
|
_ = StringTrie.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
test "init and deinit" {
|
test "init and deinit" {
|
||||||
const allocator = std.testing.allocator;
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
var trie = TestHamt.init();
|
var trie = StringTrie.init();
|
||||||
defer trie.deinit(allocator);
|
defer trie.deinit(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "trie insert" {
|
test "trie insert" {
|
||||||
const allocator = std.testing.allocator;
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
var trie = TestHamt.init();
|
var trie = StringTrie.init();
|
||||||
defer trie.deinit(allocator);
|
defer trie.deinit(allocator);
|
||||||
|
|
||||||
try trie.insert(allocator, "hello", {});
|
try trie.insert(allocator, "hello", {});
|
||||||
|
@ -315,10 +315,10 @@ test "trie insert" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "trie search" {
|
test "trie search" {
|
||||||
const Pair = TestHamt.Pair;
|
const Pair = StringTrie.Pair;
|
||||||
const allocator = std.testing.allocator;
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
var trie = TestHamt.init();
|
var trie = StringTrie.init();
|
||||||
defer trie.deinit(allocator);
|
defer trie.deinit(allocator);
|
||||||
|
|
||||||
try std.testing.expectEqual(@as(?Pair, null), trie.search("sdvx"));
|
try std.testing.expectEqual(@as(?Pair, null), trie.search("sdvx"));
|
||||||
|
@ -331,3 +331,16 @@ test "trie search" {
|
||||||
try trie.insert(allocator, "", {});
|
try trie.insert(allocator, "", {});
|
||||||
try std.testing.expectEqual(@as(?Pair, .{ .key = "", .value = {} }), trie.search(""));
|
try std.testing.expectEqual(@as(?Pair, .{ .key = "", .value = {} }), trie.search(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "README.md example" {
|
||||||
|
const Pair = StringTrie.Pair;
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
|
var trie = StringTrie.init();
|
||||||
|
defer trie.deinit(allocator);
|
||||||
|
|
||||||
|
try trie.insert(allocator, "hello", {});
|
||||||
|
|
||||||
|
try std.testing.expectEqual(@as(?Pair, .{ .key = "hello", .value = {} }), trie.search("hello"));
|
||||||
|
try std.testing.expectEqual(@as(?Pair, null), trie.search("world"));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue