diff options
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | zig-kv-store/Makefile | 2 | ||||
| -rw-r--r-- | zig-kv-store/main.zig | 94 |
3 files changed, 100 insertions, 0 deletions
@@ -7,6 +7,9 @@ reference them later if I need to. > Check `shell.nix` to see the software and dependencies that are used > in these examples. If you use Nix just do `nix-shell shell.nix`. +Every test has it's own `Makefile` so please check that before you try +running it. + | Example | What does it do? | |----------------------------------|----------------------------------------------------------------| | [c-asm](./c-asm) | Calls a function written in ASM from C code. | @@ -20,3 +23,4 @@ reference them later if I need to. | [zig-x11](./zig-x11) | Uses X11 to create a basic window without any bindings needed. | | [zig-http](./zig-http) | Basic example of a HTTP 1.1 server without any routing etc. | | [zig-x11-box](./zig-x11-box) | Move a box around with arrow keys with Xlib and Zig. | +| [zig-kv-store](./zig-kv-store) | Simple Key-value store that mimics memcached written in Zig. | diff --git a/zig-kv-store/Makefile b/zig-kv-store/Makefile new file mode 100644 index 0000000..4e313d0 --- /dev/null +++ b/zig-kv-store/Makefile @@ -0,0 +1,2 @@ +default: + zig run main.zig -freference-trace diff --git a/zig-kv-store/main.zig b/zig-kv-store/main.zig new file mode 100644 index 0000000..8578009 --- /dev/null +++ b/zig-kv-store/main.zig @@ -0,0 +1,94 @@ +// https://github.com/memcached/memcached/wiki/Commands +// https://ziglang.org/documentation/master/std/#std.hash_map.HashMap + +const std = @import("std"); + +const Error = error{ + Failed, + KeyNotFound, +}; + +const Store = struct { + data: std.StringHashMap([]const u8), + + pub fn set(self: *Store, key: []const u8, value: []const u8) !void { + self.data.put(key, value) catch |err| { + std.log.err("Failed adding key `{s}` with error {}", .{ key, err }); + return error.Failed; + }; + } + + pub fn get(self: *Store, key: []const u8) ![]const u8 { + if (self.data.get(key)) |value| { + return value; + } + return error.KeyNotFound; + } + + pub fn del(self: *Store, key: []const u8) !void { + if (!self.data.remove(key)) { + std.log.err("Failed deleting key `{s}`", .{key}); + return error.KeyNotFound; + } + } +}; + +pub fn main() !void { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + var allocator = arena.allocator(); + + var store = Store{ .data = std.StringHashMap([]const u8).init(allocator) }; + defer store.data.deinit(); + + // Setting new key. + { + const key = "johhny"; + try store.set(key, "blaze"); + } + + // Retrieving back existing key if we know it will never return an error. + { + const key = "johhny"; + const result = store.get(key) catch unreachable; + std.log.info("Value: {s}", .{result}); + } + + // Retrieving back the value and handling errors. + { + const key = "unknown"; + if (store.get(key)) |val| { + std.log.info("Value: {s}", .{val}); + } else |err| { + std.log.err("Error: {any}", .{err}); + } + } + + // Retrieving back key that does not exist and handling specific errors. + { + const key = "unknown"; + if (store.get(key)) |val| { + std.log.info("Value: {s}", .{val}); + } else |err| switch (err) { + error.KeyNotFound => { + std.log.err("Key `{s}` was not found", .{key}); + }, + } + } + + // Deleting existing key. + { + const key = "johhny"; + try store.del(key); + } + + // Retrieving back the value and handling errors. + { + const key = "johnny"; + if (store.get(key)) |val| { + std.log.info("Value: {s}", .{val}); + } else |err| { + std.log.err("Error: {any}", .{err}); + } + } +} |
