Skip to content

Commit

Permalink
chore: trying to make vle encoded database work
Browse files Browse the repository at this point in the history
  • Loading branch information
sectasy0 committed Nov 5, 2024
1 parent ebd1c4c commit 3f59025
Show file tree
Hide file tree
Showing 8 changed files with 309 additions and 267 deletions.
16 changes: 12 additions & 4 deletions src/protocol/binary.zig
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub const ZWriter = struct {

pub fn write(zw: ZWriter, value: ZType) anyerror!usize {
return switch (value) {
.str => |val| try zw.write_str(val),
.str, .sstr => |val| try zw.write_str(val),
.bool => |val| try zw.write_bool(val),
.int => |val| try zw.write_int(val),
.float => |val| try zw.write_float(val),
Expand Down Expand Up @@ -157,6 +157,8 @@ pub const ZWriter = struct {

fn write_int(zw: ZWriter, value: i64) !usize {
const needed = bytes_needed(i64, value);

std.debug.print("bytes needed: {d}/n", .{needed});
const as_bytes = std.mem.asBytes(&value);

_ = try zw.writer.writeByte(
Expand Down Expand Up @@ -223,6 +225,7 @@ pub const ZReader = struct {
.null => out.* = .{ .null = {} },
.int => {
const bytes_len = @as(usize, byte >> 4);
std.debug.print("len: {d}\n", .{bytes_len});
const value = try zr.reader.readVarInt(i64, .little, bytes_len);

size += bytes_len;
Expand Down Expand Up @@ -333,9 +336,14 @@ fn bytes_needed(comptime T: type, value: T) u8 {
return @intCast(@sizeOf(i64));
}

const U = std.meta.Int(.unsigned, info.bits);
const x = @as(U, @intCast(value));
const bits = std.math.log2_int_ceil(U, x);
if (info.signedness == .signed and value == 1) {
return 1;
}

const UType = std.meta.Int(.unsigned, info.bits);
const u_val = @as(UType, @intCast(value));
const bits = std.math.log2_int_ceil(UType, u_val);

return @intCast((bits + 7) / 8);
},
.Float => return @sizeOf(f64),
Expand Down
198 changes: 100 additions & 98 deletions src/server/processing/commands.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");

const ZType = @import("../../protocol/types.zig").ZType;
const ztypes = @import("../../protocol/types.zig");
const ZType = ztypes.ZType;

const Memory = @import("../storage/memory.zig");

Expand Down Expand Up @@ -65,37 +66,37 @@ pub const Handler = struct {
if (command_set.items.len < 3) return .{ .err = error.InvalidCommand };
return self.set(command_set.items[1], command_set.items[2]);
},
// .DELETE => {
// if (command_set.items.len < 2) return .{ .err = error.InvalidCommand };
// return self.delete(command_set.items[1]);
// },
// .SIZEOF => {
// if (command_set.items.len < 2) return .{ .err = error.InvalidCommand };
// return self.sizeof(command_set.items[1]);
// },
.DELETE => {
if (command_set.items.len < 2) return .{ .err = error.InvalidCommand };
return self.delete(command_set.items[1]);
},
.SIZEOF => {
if (command_set.items.len < 2) return .{ .err = error.InvalidCommand };
return self.sizeof(command_set.items[1]);
},
// .RENAME => {
// if (command_set.items.len < 3) return .{ .err = error.InvalidCommand };
// return self.rename(command_set.items[1], command_set.items[2]);
// },
// .ECHO => {
// if (command_set.items.len < 2) return .{ .err = error.InvalidCommand };
// switch (command_set.items[1]) {
// .str, .sstr => |text| return .{ .ok = .{ .str = text } },
// else => return .{ .err = error.KeyNotString }, // Maybe rename it to FieldNotString or ValueNotString?
// }
// },
// .COPY => {
// if (command_set.items.len < 3) return .{ .err = error.InvalidCommand };
// return self.copy(command_set.items[1..command_set.items.len]);
// },
// .MGET => return self.mget(command_set.items[1..command_set.items.len]),
// .MSET => return self.mset(command_set.items[1..command_set.items.len]),
.ECHO => {
if (command_set.items.len < 2) return .{ .err = error.InvalidCommand };
switch (command_set.items[1]) {
.str, .sstr => |text| return .{ .ok = .{ .str = text } },
else => return .{ .err = error.ValueNotString }, // Maybe rename it to FieldNotString or ValueNotString?
}
},
.COPY => {
if (command_set.items.len < 3) return .{ .err = error.InvalidCommand };
return self.copy(command_set.items[1..command_set.items.len]);
},
.MGET => return self.mget(command_set.items[1..command_set.items.len]),
.MSET => return self.mset(command_set.items[1..command_set.items.len]),
.PING => return .{ .ok = .{ .sstr = @constCast("PONG") } },
// .DBSIZE => return .{ .ok = .{ .int = self.memory.size() } },
// .LASTSAVE => return .{ .ok = .{ .int = self.memory.last_save } },
.DBSIZE => return .{ .ok = .{ .int = self.memory.size() } },
.LASTSAVE => return .{ .ok = .{ .int = self.memory.last_save } },
// .SAVE => return self.save(),
// .KEYS => return self.zkeys(),
// .FLUSH => return self.flush(),
.KEYS => return self.zkeys(),
.FLUSH => return self.flush(),
else => unreachable,
};
}
Expand All @@ -119,20 +120,20 @@ pub const Handler = struct {
return .{ .ok = .{ .sstr = @constCast("OK") } };
}

// fn delete(self: *Handler, key: ZType) Result {
// const result = self.memory.delete(key.str);
fn delete(self: *Handler, key: ZType) Result {
const result = self.memory.delete(key.str);

// if (result) {
// return .{ .ok = .{ .sstr = @constCast("OK") } };
// } else {
// return .{ .err = error.NotFound };
// }
// }
if (result) {
return .{ .ok = .{ .sstr = @constCast("OK") } };
} else {
return .{ .err = error.NotFound };
}
}

// fn flush(self: *Handler) Result {
// self.memory.flush();
// return .{ .ok = .{ .sstr = @constCast("OK") } };
// }
fn flush(self: *Handler) Result {
self.memory.flush();
return .{ .ok = .{ .sstr = @constCast("OK") } };
}

// fn save(self: *Handler) Result {
// if (self.memory.size() == 0) return .{ .err = error.SaveFailure };
Expand All @@ -150,61 +151,62 @@ pub const Handler = struct {
// return .{ .err = error.SaveFailure };
// }

// fn mget(self: *Handler, keys: []ZType) Result {
// var result = std.StringHashMap(ZType).init(self.allocator);
fn mget(self: *Handler, keys: []ZType) Result {
var result = std.StringHashMap(ZType).init(self.allocator);

// for (keys) |key| {
// if (key != .str) return .{ .err = error.KeyNotString };
for (keys) |key| {
if (key != .str) return .{ .err = error.KeyNotString };

// const value: ZType = self.memory.get(key.str) catch .{ .null = void{} };
const value: ZType = self.memory.get(key.str) catch .{ .null = void{} };

// result.put(key.str, value) catch |err| {
// return .{ .err = err };
// };
// }

// return .{ .ok = .{ .map = result } };
// }
result.put(key.str, value) catch |err| {
return .{ .err = err };
};
}

// fn mset(self: *Handler, entries: []ZType) Result {
// if (entries.len == 0 or entries.len & 1 == 1) return .{ .err = error.InvalidArgs };
return .{ .ok = .{ .map = result } };
}

// for (entries, 0..) |entry, index| {
// // cause its an array so i have to assume every even element is a value.
// if (index & 1 == 1 or index + 1 == entries.len) continue;
// if (entry != .str) return .{ .err = error.KeyNotString };
fn mset(self: *Handler, entries: []ZType) Result {
if (entries.len == 0 or entries.len & 1 == 1) return .{ .err = error.InvalidArgs };

// const value = entries[index + 1];
for (entries, 0..) |entry, index| {
// cause its an array so i have to assume every even element is a value.
if (index & 1 == 1 or index + 1 == entries.len) continue;
if (entry != .str) return .{ .err = error.KeyNotString };

// self.memory.put(entry.str, value) catch |err| {
// return .{ .err = err };
// };
// }
// return .{ .ok = .{ .sstr = @constCast("OK") } };
// }
const value = entries[index + 1];

// fn zkeys(self: *Handler) Result {
// const result = self.memory.keys() catch |err| {
// return .{ .err = err };
// };
// return .{ .ok = .{ .array = result } };
// }
self.memory.put(entry.str, value) catch |err| {
return .{ .err = err };
};
}
return .{ .ok = .{ .sstr = @constCast("OK") } };
}

// fn sizeof(self: *Handler, key: ZType) Result {
// const value: ZType = self.memory.get(key.str) catch |err| {
// return .{ .err = err };
// };
fn zkeys(self: *Handler) Result {
const result = self.memory.keys() catch |err| {
return .{ .err = err };
};
return .{ .ok = .{ .array = result } };
}

// const value_size: usize = switch (value) {
// .str, .sstr => |str| str.len,
// .array => value.array.items.len,
// inline .map, .set, .uset => |v| v.count(),
// inline .int, .float, .bool => |x| @sizeOf(@TypeOf(x)),
// else => 0,
// };
fn sizeof(self: *Handler, key: ZType) Result {
var value: ZType = self.memory.get(key.str) catch |err| {
return .{ .err = err };
};
defer ztypes.ztype_free(&value, self.allocator);

const value_size: usize = switch (value) {
.str, .sstr => |str| str.len,
.array => value.array.items.len,
inline .map, .set, .uset => |v| v.count(),
inline .int, .float, .bool => |x| @sizeOf(@TypeOf(x)),
else => 0,
};

// return .{ .ok = .{ .int = @intCast(value_size) } };
// }
return .{ .ok = .{ .int = @intCast(value_size) } };
}

// fn rename(self: *Handler, key: ZType, value: ZType) Result {
// if (key != .str or value != .str) return .{ .err = error.KeyNotString };
Expand All @@ -216,25 +218,25 @@ pub const Handler = struct {
// return .{ .ok = .{ .str = @constCast("OK") } };
// }

// fn copy(self: *Handler, entries: []ZType) Result {
// const CopyArgs = enum { REPLACE };
fn copy(self: *Handler, entries: []ZType) Result {
const CopyArgs = enum { REPLACE };

// var replace: bool = false;
// if (entries[0] != .str or entries[1] != .str) return .{ .err = error.KeyNotString };
var replace: bool = false;
if (entries[0] != .str or entries[1] != .str) return .{ .err = error.KeyNotString };

// if (entries.len > 2) {
// if (entries[2] != .str) return .{ .err = error.KeyNotString };
if (entries.len > 2) {
if (entries[2] != .str) return .{ .err = error.KeyNotString };

// // To check if entries[2] is "REPLACE" string.
// // If not, return error.BadRequest.
// _ = utils.enum_type_from_str(CopyArgs, entries[2].str) orelse return .{ .err = error.BadRequest };
// replace = true;
// }
// self.memory.copy(entries[0].str, entries[1].str, replace) catch |err| {
// return .{ .err = err };
// };
// return .{ .ok = .{ .str = @constCast("OK") } };
// }
// To check if entries[2] is "REPLACE" string.
// If not, return error.BadRequest.
_ = utils.enum_type_from_str(CopyArgs, entries[2].str) orelse return .{ .err = error.BadRequest };
replace = true;
}
self.memory.copy(entries[0].str, entries[1].str, replace) catch |err| {
return .{ .err = err };
};
return .{ .ok = .{ .str = @constCast("OK") } };
}

// method to free data needs to be freeded, for example keys command
// is creating std.ArrayList so it have to be freed after
Expand Down
Loading

0 comments on commit 3f59025

Please sign in to comment.