summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2024-09-18 07:57:02 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2024-09-18 07:57:02 +0200
commitf07957d7e4a67792af5356ea3f8c09b318283cce (patch)
treec3d1011b1c021170588647cddf976c1ae2e88d6e
parentfadbf136de03215a9bfaca04ee336b4085589de4 (diff)
downloadprobe-f07957d7e4a67792af5356ea3f8c09b318283cce.tar.gz
Simple KV store testing HashMap in Zig
-rw-r--r--README.md4
-rw-r--r--zig-kv-store/Makefile2
-rw-r--r--zig-kv-store/main.zig94
3 files changed, 100 insertions, 0 deletions
diff --git a/README.md b/README.md
index fa00a94..8fad2cc 100644
--- a/README.md
+++ b/README.md
@@ -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});
+ }
+ }
+}