Skip to content

Commit

Permalink
Add rm support
Browse files Browse the repository at this point in the history
  • Loading branch information
devraymondsh committed Jan 10, 2024
1 parent f7f2421 commit 04b458b
Show file tree
Hide file tree
Showing 16 changed files with 114 additions and 10 deletions.
31 changes: 30 additions & 1 deletion bench/bench-with-builtin.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ const assert = (name, left, right) => {
};
const roundToTwoDecimal = (num) => +(Math.round(num + "e+2") + "e-2");

const benchmarkRemove = (data, o, keyidx) => {
const startingTime = performance.now();
for (const item of data) {
o.rm(item[keyidx]);
}
return performance.now() - startingTime;
};
const benchmarkDeletion = (data, o, keyidx) => {
const startingTime = performance.now();
for (const item of data) {
Expand All @@ -23,7 +30,7 @@ const benchmarkDeletion = (data, o, keyidx) => {
const benchmarkLookup = (data, o, keyidx) => {
const startingTime = performance.now();
for (const item of data) {
assert(`${o.name} deletion`, o.get(item[keyidx]), item.value);
assert(`${o.name} lookup`, o.get(item[keyidx]), item.value);
}
return performance.now() - startingTime;
};
Expand All @@ -41,13 +48,15 @@ const wrapInHumanReadable = (value) => {
totalLookupTime: roundToTwoDecimal(value.totalLookupTime) + " ms",
totalInsertionTime: roundToTwoDecimal(value.totalInsertionTime) + " ms",
totalDeletionTime: roundToTwoDecimal(value.totalDeletionTime) + " ms",
totalRemoveTime: roundToTwoDecimal(value.totalRemoveTime) + " ms",
};
};
const formatLogResult = (value) => {
return {
totalLookupTime: value.lookupDuration,
totalInsertionTime: value.insertionDuration,
totalDeletionTime: value.deletionDuration,
totalRemoveTime: value.removeDuration,
};
};
const logResults = (name, durationArr, averageArg) => {
Expand All @@ -62,6 +71,7 @@ const logResults = (name, durationArr, averageArg) => {
totalLookupTime: average.totalLookupTime,
totalInsertionTime: average.totalInsertionTime,
totalDeletionTime: average.totalDeletionTime,
totalRemoveTime: average.totalRemoveTime,
});

console.log(`\n${name}:`);
Expand Down Expand Up @@ -91,6 +101,11 @@ const logRatio = () => {
averageLogResult[1].totalDeletionTime /
averageLogResult[0].totalDeletionTime
) + "x",
remove:
roundToTwoDecimal(
averageLogResult[1].totalRemoveTime /
averageLogResult[0].totalRemoveTime
) + "x",
});
};

Expand All @@ -111,6 +126,9 @@ const builtinMapBenchmark = () => {
set: function (k, v) {
return this.map.set(k, v);
},
rm: function (k) {
this.map.delete(k);
},
del: function (k) {
const v = this.map.get(k);
this.map.delete(k);
Expand All @@ -123,24 +141,28 @@ const builtinMapBenchmark = () => {
const insertionDuration = benchmarkInsertion(data, o, "key");
const lookupDuration = benchmarkLookup(data, o, "key");
const deletionDuration = benchmarkDeletion(data, o, "key");
const removeDuration = benchmarkRemove(data, o, "key");
o.destroy();
durationArr.push({
iteration: i,
insertionDuration,
lookupDuration,
deletionDuration,
removeDuration,
});
if (average.insertionDuration === 0) {
average = {
insertionDuration,
lookupDuration,
deletionDuration,
removeDuration,
};
} else {
average = {
insertionDuration: (average.insertionDuration + insertionDuration) / 2,
lookupDuration: (average.lookupDuration + lookupDuration) / 2,
deletionDuration: (average.deletionDuration + deletionDuration) / 2,
removeDuration: (average.removeDuration + removeDuration) / 2,
};
}
}
Expand All @@ -166,31 +188,38 @@ const kiviBenchmark = () => {
del: function (k) {
return this.map.del(k);
},
rm: function (k) {
this.map.rm(k);
},
destroy: function () {
return this.map.destroy();
},
};
const insertionDuration = benchmarkInsertion(data, o, "kyb");
const lookupDuration = benchmarkLookup(data, o, "kyb");
const deletionDuration = benchmarkDeletion(data, o, "kyb");
const removeDuration = benchmarkRemove(data, o, "kyb");
o.destroy();
durationArr.push({
iteration: i,
insertionDuration,
lookupDuration,
deletionDuration,
removeDuration,
});
if (average.insertionDuration === 0) {
average = {
insertionDuration,
lookupDuration,
deletionDuration,
removeDuration,
};
} else {
average = {
insertionDuration: (average.insertionDuration + insertionDuration) / 2,
lookupDuration: (average.lookupDuration + lookupDuration) / 2,
deletionDuration: (average.deletionDuration + deletionDuration) / 2,
removeDuration: (average.removeDuration + removeDuration) / 2,
};
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/core/Kivi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ pub fn del(self: *Kivi, key: []const u8, value: ?[]u8) !usize {
return value_slice_len;
}

pub fn rm(self: *Kivi, key: []const u8) !void {
const value_slice = try self.del_slice(key);
self.del_value(value_slice);
}

pub fn deinit(self: *Kivi) void {
self.mem.deinit();
}
2 changes: 2 additions & 0 deletions src/core/include/kivi.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ size_t kivi_get(const struct Kivi *const, const char *const key, const size_t ke
size_t kivi_set(struct Kivi *const, const char *const key, const size_t key_len, const char *const val, const size_t val_len);
// TODO: Behavior documented in these comments
size_t kivi_del(struct Kivi *const, const char *const key, const size_t key_len, char *const val, const size_t val_len);
// TODO: Behavior documented in these comments
void kivi_rm(struct Kivi *const, const char *const key, const size_t key_len);
3 changes: 3 additions & 0 deletions src/core/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ pub export fn kivi_set(self: *Kivi, key: [*]const u8, key_len: usize, val: [*]co
pub export fn kivi_del(self: *Kivi, key: [*]const u8, key_len: usize, val: ?[*]u8, val_len: usize) usize {
return self.del(key[0..key_len], if (val) |v| v[0..val_len] else null) catch 0;
}
pub export fn kivi_rm(self: *Kivi, key: [*]const u8, key_len: usize) void {
self.rm(key[0..key_len]) catch {};
}

comptime {
_ = Kivi;
Expand Down
4 changes: 4 additions & 0 deletions src/core/tests/ffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,9 @@ int main(void) {

assert(kivi_get(&kv, "foo", 3, NULL, 0) == 0);

assert(kivi_set(&kv, "foo", 3, "bar", 3) == 3);

kivi_rm(&kv, "foo", 3);

kivi_deinit(&kv);
}
3 changes: 3 additions & 0 deletions src/drivers/js/deno&bun/bun.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ export const dlopenLib = dlopen(dllPath, {
],
returns: FFIType.u32,
},
kivi_rm: {
args: [FFIType.ptr, FFIType.cstring, FFIType.usize],
},
});

export const bunUtils = {
Expand Down
4 changes: 4 additions & 0 deletions src/drivers/js/deno&bun/deno.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export const dlopenLib = Deno.dlopen(dllPath, {
parameters: ["pointer", "pointer", "usize", "pointer", "usize"],
result: "u32",
},
kivi_rm: {
parameters: ["pointer", "pointer", "usize"],
result: "void",
},
});

export const denoUtils = {
Expand Down
22 changes: 22 additions & 0 deletions src/drivers/js/deno&bun/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,26 @@ export class DenoAndBunKivi {

return null;
}

rm(key) {
const key_len = new TextEncoder().encodeInto(
key,
this.#key_scratch
).written;
const written_len = utils.symbols.kivi_del(
this.#buf,
this.#key_scratch_ptr,
key_len,
this.#value_scratch_ptr,
4096
);

if (written_len != 0) {
return new TextDecoder().decode(
this.#value_scratch.subarray(0, written_len)
);
}

return null;
}
}
9 changes: 9 additions & 0 deletions src/drivers/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,13 @@ export class Kivi {
del(key) {
return this.#InnerKivi.del(key);
}

/**
* Removes a key with its value.
* @param {string} key
* @returns {void}
*/
rm(key) {
return this.#InnerKivi.rm(key);
}
}
2 changes: 1 addition & 1 deletion src/drivers/js/nodejs/functions/del.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub export fn kivi_del_js(env: ntypes.napi_env, info: ntypes.napi_callback_info)
return common.exception_ret(env, "Invalid Kivi instance!");
};
const key = common.get_buffer_string(env, args[1]) catch {
return common.exception_ret(env, "Empty/invalid key buffer!");
return common.exception_ret(env, "Invalid/empty key buffer!");
};
const value = self.del_slice(key) catch return common.get_null(env);

Expand Down
2 changes: 1 addition & 1 deletion src/drivers/js/nodejs/functions/get.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub export fn kivi_get_js(env: ntypes.napi_env, info: ntypes.napi_callback_info)
return common.exception_ret(env, "Invalid Kivi instance!");
};
const key = common.get_buffer_string(env, args[1]) catch {
return common.exception_ret(env, "Empty/invalid key buffer!");
return common.exception_ret(env, "Invalid/empty key buffer!");
};
const value = self.get_slice(key) catch return common.get_null(env);

Expand Down
20 changes: 20 additions & 0 deletions src/drivers/js/nodejs/functions/rm.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const Kivi = @import("Kivi");
const common = @import("common.zig");
const ntypes = @import("../napi-bindings.zig");
const symbols = @import("../symbols.zig");

pub export fn kivi_rm_js(env: ntypes.napi_env, info: ntypes.napi_callback_info) ntypes.napi_value {
const args = common.parse_args(env, info, 2) catch {
return common.exception_ret(env, "Invalid Arguments!");
};

const self = common.get_kivi(env, args[0]) catch {
return common.exception_ret(env, "Invalid Kivi instance!");
};
const key = common.get_buffer_string(env, args[1]) catch {
return common.exception_ret(env, "Invalid/empty key buffer!");
};
self.rm(key) catch {};

return common.get_undefined(env);
}
4 changes: 2 additions & 2 deletions src/drivers/js/nodejs/functions/set.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ pub export fn kivi_set_js(env: ntypes.napi_env, info: ntypes.napi_callback_info)
return common.exception_ret(env, "Invalid Kivi instance!");
};
const key = common.get_buffer_string(env, args[1]) catch {
return common.exception_ret(env, "Empty/invalid key buffer!");
return common.exception_ret(env, "Invalid/empty key buffer!");
};
const value = common.get_buffer_string(env, args[2]) catch {
return common.exception_ret(env, "Empty/invalid value buffer!");
return common.exception_ret(env, "Invalid/empty value buffer!");
};
const reserved_key = self.reserve_key(key.len) catch {
return common.exception_ret(env, "Not enough memory to store the key!");
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/js/nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ export class NodeKivi {
del(key) {
return addon.kivi_del(this.#buf, key);
}
rm(key) {
return addon.kivi_rm(this.#buf, key);
}
}
4 changes: 4 additions & 0 deletions src/drivers/js/nodejs/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const common = @import("functions/common.zig");
pub const set = @import("functions/set.zig");
pub const get = @import("functions/get.zig");
pub const del = @import("functions/del.zig");
pub const rm = @import("functions/rm.zig");

pub export fn kivi_init_js(env: ntypes.napi_env, info: ntypes.napi_callback_info) ntypes.napi_value {
const args = common.parse_args(env, info, 1) catch {
Expand Down Expand Up @@ -51,6 +52,9 @@ const functions = [_]Function{ Function{
}, Function{
.name = "kivi_del",
.method = &del.kivi_del_js,
}, Function{
.name = "kivi_rm",
.method = &rm.kivi_rm_js,
}, Function{
.name = "kivi_deinit",
.method = &kivi_deinit_js,
Expand Down
6 changes: 1 addition & 5 deletions src/drivers/js/tests/kivi.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,7 @@ const run = (config) => {
Buffer.from("bar", "utf8")
);

assert(
"Value-when-delete",
k.del(Buffer.from("foo", "utf8")),
Buffer.from("bar", "utf8")
);
k.rm(Buffer.from("foo", "utf8"));

assert("Value-after-delete", k.get(Buffer.from("foo", "utf8")), null);

Expand Down

0 comments on commit 04b458b

Please sign in to comment.