Ver Fonte

split files

Danilo Fragoso há 10 meses atrás
pai
commit
761e696023
4 ficheiros alterados com 166 adições e 89 exclusões
  1. 76 0
      command.zig
  2. 14 89
      main.zig
  3. 41 0
      socket.zig
  4. 35 0
      storage.zig

+ 76 - 0
command.zig

@@ -0,0 +1,76 @@
+const std = @import("std");
+const storage = @import("storage.zig");
+
+const Command = enum {
+    read,
+    write,
+    delete,
+    status,
+};
+
+fn parseKeyValue(buf: []const u8) ?[2][]const u8 {
+    var kvIterator = std.mem.splitAny(u8, buf, "|");
+    const key = kvIterator.first();
+    const value = kvIterator.next() orelse {
+        std.debug.print("No value found for key: {s}\n", .{key});
+        return null;
+    };
+
+    return [2][]const u8{ key, value };
+}
+
+pub fn parse(msg: []const u8) ?[]const u8 {
+    const trimSet = [_]u8{ '\n', ' ' };
+    const cleanMsg = std.mem.trim(u8, msg, &trimSet);
+    var messageIterator = std.mem.splitAny(u8, cleanMsg, " ");
+
+    const cmdString = messageIterator.first();
+    const command = std.meta.stringToEnum(Command, cmdString) orelse {
+        std.debug.print("Failed to parse command\n", .{});
+        return null;
+    };
+
+    switch (command) {
+        .read => {
+            const key = messageIterator.next() orelse {
+                std.debug.print("No key provided for read command\n", .{});
+                return null;
+            };
+
+            const value = storage.read(key) orelse {
+                std.debug.print("Key not found in storage: {s}\n", .{key});
+                return "false";
+            };
+
+            return value;
+        },
+        .write => {
+            const kvPair = messageIterator.next() orelse {
+                std.debug.print("No key-value pair provided for read command\n", .{});
+                return null;
+            };
+
+            const kv = parseKeyValue(kvPair) orelse {
+                std.debug.print("Failed to parse key-value pair\n", .{});
+                return null;
+            };
+
+            if (storage.write(kv[0], kv[1])) {
+                return "true";
+            }
+
+            std.debug.print("Failed to write to storage\n", .{});
+            return "false";
+        },
+        .delete => {
+            std.debug.print("Delete command received\n", .{});
+            return null;
+        },
+        .status => {
+            std.debug.print("Status command received\n", .{});
+            return "well going our operation";
+        },
+    }
+
+    return null;
+}

+ 14 - 89
main.zig

@@ -2,112 +2,37 @@ const std = @import("std");
 const net = std.net;
 const posix = std.posix;
 
-pub fn main() !void {
-    const address = try std.net.Address.parseIp("127.0.0.1", 6000);
+const socket = @import("socket.zig");
+const command = @import("command.zig");
+const storage = @import("storage.zig");
 
-    const tpe: u32 = posix.SOCK.STREAM;
-    const protocol = posix.IPPROTO.TCP;
-    const listener = try posix.socket(address.any.family, tpe, protocol);
+pub fn main() !void {
+    const listener = try socket.init(8080);
     defer posix.close(listener);
-
-    try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
-    try posix.bind(listener, &address.any, address.getOsSockLen());
-    try posix.listen(listener, 128);
+    std.debug.print("pizzakv!\n", .{});
 
     while (true) {
         var client_address: net.Address = undefined;
         var client_address_len: posix.socklen_t = @sizeOf(net.Address);
 
-        const socket = posix.accept(listener, &client_address.any, &client_address_len, 0) catch |err| {
+        const conn = posix.accept(listener, &client_address.any, &client_address_len, 0) catch |err| {
             std.debug.print("error accept: {any}\n", .{err});
             continue;
         };
-        defer posix.close(socket);
+        defer posix.close(conn);
 
         std.debug.print("Connection received\n", .{});
         var buf: [128]u8 = undefined;
-        const n = try read(socket, &buf);
-        std.debug.print("Read {d} bytes: {s}\n", .{ n, buf[0..n] });
+        const n = try socket.read(conn, &buf);
 
-        try parseMessage(buf[0..n]);
+        const response = command.parse(buf[0..n]) orelse {
+            std.debug.print("Failed to parse message\n", .{});
+            continue;
+        };
 
-        write(socket, "congratulations") catch |err| {
+        socket.write(conn, response) catch |err| {
             // This can easily happen, say if the client disconnects.
             std.debug.print("error writing: {any}\n", .{err});
         };
     }
 }
-
-const Command = enum {
-    read,
-    write,
-    delete,
-    status,
-};
-
-fn parseKeyValue(buf: []const u8) ?[2][]const u8 {
-    var kvIterator = std.mem.splitAny(u8, buf, "|");
-    const key = kvIterator.first();
-    const value = kvIterator.next() orelse {
-        std.debug.print("No value found for key: {s}\n", .{key});
-        return null;
-    };
-
-    std.debug.print("Parsed key: {s}, value: {s}\n", .{ key, value });
-    return [2][]const u8{ key, value };
-}
-
-fn parseMessage(buf: []const u8) !void {
-    var messageIterator = std.mem.splitAny(u8, buf, " ");
-
-    const command = std.meta.stringToEnum(Command, messageIterator.first()) orelse {
-        std.debug.print("Failed to parse command\n", .{});
-        return;
-    };
-
-    switch (command) {
-        .read => {
-            std.debug.print("Read command received\n", .{});
-        },
-        .write => {
-            std.debug.print("Write command received\n", .{});
-
-            const kvPair = messageIterator.next() orelse {
-                std.debug.print("No key-value pair provided for read command\n", .{});
-                return;
-            };
-
-            const kv = parseKeyValue(kvPair) orelse {
-                std.debug.print("Failed to parse key-value pair\n", .{});
-                return;
-            };
-
-            std.debug.print("Key: {s}, Value: {s}\n", .{ kv[0], kv[1] });
-        },
-        .delete => std.debug.print("Delete command received\n", .{}),
-        .status => std.debug.print("Status command received\n", .{}),
-    }
-}
-
-fn read(socket: posix.socket_t, buf: []u8) !usize {
-    var pos: usize = 0;
-    while (pos < buf.len) {
-        const n = try posix.read(socket, buf[pos..]);
-        if (n == 0) {
-            return pos; // connection closed
-        }
-        pos += n;
-    }
-    return pos;
-}
-
-fn write(socket: posix.socket_t, msg: []const u8) !void {
-    var pos: usize = 0;
-    while (pos < msg.len) {
-        const written = try posix.write(socket, msg[pos..]);
-        if (written == 0) {
-            return error.Closed;
-        }
-        pos += written;
-    }
-}

+ 41 - 0
socket.zig

@@ -0,0 +1,41 @@
+const std = @import("std");
+const net = std.net;
+const posix = std.posix;
+
+pub fn init(port: u16) !posix.socket_t {
+    const address = try std.net.Address.parseIp("127.0.0.1", port);
+
+    const tpe: u32 = posix.SOCK.STREAM;
+    const protocol = posix.IPPROTO.TCP;
+
+    const listener = try posix.socket(address.any.family, tpe, protocol);
+
+    try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
+    try posix.bind(listener, &address.any, address.getOsSockLen());
+    try posix.listen(listener, 128);
+
+    return listener;
+}
+
+pub fn read(conn: posix.socket_t, buf: []u8) !usize {
+    var pos: usize = 0;
+    while (pos < buf.len) {
+        const n = try posix.read(conn, buf[pos..]);
+        if (n == 0) {
+            return pos;
+        }
+        pos += n;
+    }
+    return pos;
+}
+
+pub fn write(conn: posix.socket_t, msg: []const u8) !void {
+    var pos: usize = 0;
+    while (pos < msg.len) {
+        const written = try posix.write(conn, msg[pos..]);
+        if (written == 0) {
+            return error.Closed;
+        }
+        pos += written;
+    }
+}

+ 35 - 0
storage.zig

@@ -0,0 +1,35 @@
+const std = @import("std");
+
+var buf: [1024 * 1024 * 100][]const u8 = undefined;
+
+pub fn hashKey(k: []const u8) u32 {
+    var hash: u32 = 17 * 22;
+    const xoramasrosas = "xoramasrosas";
+
+    for (k, 0..) |char, i| {
+        hash = hash +% (char ^ xoramasrosas[i % xoramasrosas.len]);
+    }
+
+    return hash;
+}
+
+pub fn write(key: []const u8, value: []const u8) bool {
+    std.debug.print("Writing key: {s}, value: {s}\n", .{ key, value });
+    const hash = hashKey(key);
+
+    const valueCopy = std.heap.page_allocator.dupe(u8, value) catch {
+        std.debug.print("Failed to duplicate value for key: {s}\n", .{key});
+        return false;
+    };
+
+    buf[hash % buf.len] = valueCopy;
+    return true;
+}
+
+pub fn read(key: []const u8) ?[]const u8 {
+    std.debug.print("Reading key: {s}\n", .{key});
+    const hash = hashKey(key);
+    const value = buf[hash % buf.len];
+
+    return value;
+}