feat: add README.md
This commit is contained in:
		
							
								
								
									
										46
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -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"));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user