Skip to content

Commit

Permalink
Allow keys and values over 4096 bytes long
Browse files Browse the repository at this point in the history
  • Loading branch information
devraymondsh committed Sep 18, 2023
1 parent 83389fc commit 7c2e891
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 77 deletions.
81 changes: 53 additions & 28 deletions core/src/Kivi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ fn upper_power_of_two(n_arg: u64) u64 {
fn key_to_possible_index(self: *const Kivi, key: []const u8) usize {
return std.hash.Wyhash.hash(0, key) & (self.entries.len - 1);
}
fn stringcpy(dest: []u8, src: []const u8) void {
@memcpy(dest.ptr[0..src.len], src.ptr[0..src.len]);
}

pub fn init_default_allocator(self: *Kivi, config: *const Config) !usize {
var gpa = GPA{};
Expand Down Expand Up @@ -69,27 +72,34 @@ pub fn init(allocator: std.mem.Allocator, config: *const Config) !Kivi {
return Kivi{ .allocator = allocator, .entries = entries, .table_size = maximum_elements, .keys_mmap = keys_mmap, .values_mmap = values_mmap };
}

pub fn set(self: *Kivi, key: []const u8, value: []const u8) !usize {
pub fn undo_key_reserve(self: *Kivi, slice: []u8) void {
self.keys_mmap.cursor -= slice.len;
}
pub fn reserve_key(self: *Kivi, size: usize) ![]u8 {
const key_cursor = self.keys_mmap.cursor;
errdefer self.keys_mmap.cursor = key_cursor;

return try self.keys_mmap.reserve(size);
}
pub fn reserve(self: *Kivi, key_slice: []u8, size: usize) ![]u8 {
var retrying = false;
var rehashing = false;
var index = self.key_to_possible_index(key);
var index = self.key_to_possible_index(key_slice);
while (true) {
if (self.entries[index].key == null) {
const value_slice = try self.values_mmap.reserve(size);
self.entries[index] = Entry{
.key = try self.keys_mmap.push(key),
.value = try self.values_mmap.push(value),
.key = key_slice,
.value = value_slice,
};

return value.len;
return value_slice;
}

index += 1;
if (index >= self.entries.len) {
if (!rehashing) {
index = self.key_to_possible_index(key);
index = self.key_to_possible_index(key_slice);
rehashing = true;
} else {
if (!retrying) {
Expand All @@ -104,23 +114,27 @@ pub fn set(self: *Kivi, key: []const u8, value: []const u8) !usize {

return error.NoFreeSlot;
}
pub fn set(self: *Kivi, key: []const u8, value: []const u8) !usize {
const key_slice = try self.reserve_key(key.len);
errdefer self.undo_key_reserve(key_slice);

const value_slice = try self.reserve(key_slice, value.len);

stringcpy(key_slice, key);
stringcpy(value_slice, value);

return value_slice.len;
}

pub fn get(self: *const Kivi, key: []const u8, value: ?[]u8) !usize {
pub fn get_slice(self: *const Kivi, key: []const u8) ![]u8 {
var retrying = false;
var rehashing = false;
var index = self.key_to_possible_index(key);
while (true) {
const entry = self.entries[index];
if (entry.key != null) {
if (std.mem.eql(u8, key, entry.key.?)) {
if (value != null) {
@memcpy(value.?[0..entry.value.len], entry.value.ptr[0..entry.value.len]);
}

return entry.value.len;
if (self.entries[index].key != null) {
if (std.mem.eql(u8, key, self.entries[index].key.?)) {
return self.entries[index].value;
}
} else {
return error.NotFound;
}

index += 1;
Expand All @@ -141,25 +155,27 @@ pub fn get(self: *const Kivi, key: []const u8, value: ?[]u8) !usize {

return error.NotFound;
}
pub fn get(self: *const Kivi, key: []const u8, value: ?[]u8) !usize {
const value_slice = try self.get_slice(key);

pub fn del(self: *const Kivi, key: []const u8, value: ?[]u8) !usize {
if (value != null) {
stringcpy(value.?, value_slice);
}

return value_slice.len;
}

pub fn del_slice(self: *const Kivi, key: []const u8) ![]u8 {
var retrying = false;
var rehashing = false;
var index = self.key_to_possible_index(key);
while (true) {
var entry = self.entries[index];
if (entry.key != null) {
if (std.mem.eql(u8, key, entry.key.?)) {
if (value != null) {
@memcpy(value.?[0..entry.value.len], entry.value.ptr[0..entry.value.len]);
}

if (self.entries[index].key != null) {
if (std.mem.eql(u8, key, self.entries[index].key.?)) {
self.entries[index].key = null;

return entry.value.len;
return self.entries[index].value;
}
} else {
return error.NotFound;
}

index += 1;
Expand All @@ -180,6 +196,15 @@ pub fn del(self: *const Kivi, key: []const u8, value: ?[]u8) !usize {

return error.NotFound;
}
pub fn del(self: *const Kivi, key: []const u8, value: ?[]u8) !usize {
const value_slice = try self.del_slice(key);

if (value != null) {
stringcpy(value.?, value_slice);
}

return value_slice.len;
}

pub fn deinit(self: *Kivi) void {
self.keys_mmap.deinit();
Expand Down
13 changes: 13 additions & 0 deletions core/src/Mmap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ pub fn push(self: *Mmap, data: []const u8) ![]u8 {
return slice;
}

pub fn reserve(self: *Mmap, size: usize) ![]u8 {
const starting_pos = self.cursor;
const ending_pos = starting_pos + size;

if (ending_pos > self.protected_mem_cursor) {
try self.mprotect();
}

self.cursor = ending_pos;

return self.mem[starting_pos..ending_pos];
}

pub fn deinit(self: *Mmap) void {
if (!is_windows) {
std.os.munmap(self.mem);
Expand Down
1 change: 0 additions & 1 deletion core/src/codegen/generate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ fn generate_C_headers(comptime Type: type, writer: anytype) !void {
\\
\\
, .{ @alignOf(Type), @sizeOf(Type) });
// std.debug.panic("Thing: {any}", .{.{ Type, @alignOf(Type), @sizeOf(Type) }});
}
inline for (@typeInfo(Type).Struct.decls) |decl| {
if (std.mem.startsWith(u8, decl.name, "kivi_") or std.mem.eql(u8, decl.name, "setup_debug_handlers") or std.mem.eql(u8, decl.name, "dump_stack_trace") or std.mem.eql(u8, decl.name, "Config")) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/include/kivi.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <stddef.h>

struct __attribute__((aligned(8))) Kivi {
char __opaque[128];
char __opaque[120];
};

struct Config {
Expand Down
2 changes: 1 addition & 1 deletion drivers/js/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
interface KiviConfig {
forceUseRuntimeFFI: ?boolean,
forceUseRuntimeFFI: boolean | undefined,
}

export class Kivi {
Expand Down
11 changes: 0 additions & 11 deletions drivers/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ export class Kivi {
* @returns {(string|null)}
*/
get(key) {
if (key.length > 4096) {
throw new Error("Key is too long!");
}

return this.#InnerKivi.get(key);
}
/**
Expand All @@ -67,13 +63,6 @@ export class Kivi {
* @returns {void}
*/
set(key, value) {
if (key.length > 4096) {
throw new Error("Key is too long!");
}
if (value.length > 4096) {
throw new Error("Value is too long!");
}

if (!this.#InnerKivi.set(key, value)) {
throw new Error("Failed to insert!");
}
Expand Down
5 changes: 0 additions & 5 deletions drivers/js/nodejs/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ fn formatTarget(target: std.Target, allocator: std.mem.Allocator, suffix: []cons
}

pub fn build(b: *std.build.Builder) !void {
const x = b.addModule("core-build", .{ .source_file = std.Build.LazyPath.relative("../../../core/build.zig") });

const target = b.standardTargetOptions(.{});
optimize = b.standardOptimizeOption(.{});
const target_info = try std.zig.system.NativeTargetInfo.detect(target);
Expand All @@ -43,13 +41,10 @@ pub fn build(b: *std.build.Builder) !void {
});
const shared = b.addSharedLibrary(.{ .name = "kivi-node-addon", .root_source_file = std.Build.LazyPath.relative("src/main.zig"), .target = target, .optimize = optimize });
shared.force_pic = true;
shared.bundle_compiler_rt = true;
shared.linker_allow_shlib_undefined = true;
shared.addModule("Kivi", kivi_mod);
shared.addIncludePath(std.build.LazyPath.relative("src/napi-headers"));

shared.addModule("core-build", x);

if (optimize == .ReleaseFast) {
shared.strip = true;
shared.single_threaded = true;
Expand Down
Loading

0 comments on commit 7c2e891

Please sign in to comment.