Skip to content

Commit

Permalink
Update to the latest Zig
Browse files Browse the repository at this point in the history
  • Loading branch information
devraymondsh committed May 31, 2024
1 parent 70ea929 commit d3edac5
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 295 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
**/zig-cache
**/.zig-cache
**/zig-out
**/node_modules
**/pnpm-lock.yaml
**/package-lock.json
bench/faker/data/*
!bench/faker/data/README.md
perf.data
perf.data.old
perf.data.old
35 changes: 13 additions & 22 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var target: std.Target = undefined;
var optimize: std.builtin.OptimizeMode = undefined;
var resolved_target: std.Build.ResolvedTarget = undefined;

var global_deps: [3]Dependency = undefined;
var global_deps: [2]Dependency = undefined;
const Dependency = struct {
name: []const u8,
module: *std.Build.Module,
Expand All @@ -29,15 +29,11 @@ const Dependency = struct {
comptime name: []const u8,
comptime source: []const u8,
comptime n: comptime_int,
comptime link_module_to: ?comptime_int,
) void {
global_deps[n] = .{
.name = name,
.module = b.createModule(.{ .root_source_file = .{ .path = source } }),
.module = b.createModule(.{ .root_source_file = .{ .src_path = .{ .sub_path = source, .owner = b } } }),
};
if (link_module_to) |link_module| {
global_deps[n].module.addImport(global_deps[link_module].name, global_deps[link_module].module);
}
}
};

Expand All @@ -51,7 +47,7 @@ const Libs = struct {
strip = true;
}

const shared = b.addSharedLibrary(.{ .name = name, .root_source_file = .{ .path = path }, .target = resolved_target, .optimize = optimize });
const shared = b.addSharedLibrary(.{ .name = name, .root_source_file = .{ .src_path = .{ .sub_path = path, .owner = b } }, .target = resolved_target, .optimize = optimize });
shared.root_module.pic = true;
shared.root_module.strip = strip;
shared.linker_allow_shlib_undefined = true;
Expand All @@ -61,7 +57,7 @@ const Libs = struct {

var static: ?*std.Build.Step.Compile = null;
if (with_static) {
static = b.addStaticLibrary(.{ .name = name, .root_source_file = .{ .path = path }, .target = resolved_target, .optimize = optimize });
static = b.addStaticLibrary(.{ .name = name, .root_source_file = .{ .src_path = .{ .sub_path = path, .owner = b } }, .target = resolved_target, .optimize = optimize });
shared.root_module.pic = true;
static.?.root_module.strip = strip;
static.?.linker_allow_shlib_undefined = true;
Expand All @@ -82,15 +78,15 @@ const Libs = struct {
};

fn install_pnpm() !void {
const command_res = try std.ChildProcess.run(.{ .allocator = std.heap.page_allocator, .argv = &[_][]const u8{ "npm", "install", "-g", "pnpm@latest" } });
const command_res = try std.process.Child.run(.{ .allocator = std.heap.page_allocator, .argv = &[_][]const u8{ "npm", "install", "-g", "pnpm@latest" } });
if (command_res.stderr.len > 0) {
std.debug.print("{s}\n", .{command_res.stderr});
return error.PnpmNotFoundAndFailedToInstall;
}
}
// Checks if pnpm is installed on the machine and insatlls it if possible
fn pnpm_check(allocator: std.mem.Allocator) !void {
const npm_version_command = std.ChildProcess.run(.{ .allocator = allocator, .argv = &[2][]const u8{ "pnpm", "--version" } });
const npm_version_command = std.process.Child.run(.{ .allocator = allocator, .argv = &[2][]const u8{ "pnpm", "--version" } });
if (npm_version_command) |command_res| {
if (command_res.stderr.len > 0) {
return install_pnpm();
Expand All @@ -100,10 +96,6 @@ fn pnpm_check(allocator: std.mem.Allocator) !void {
}
}

fn get_lazypath(path: []const u8) std.Build.LazyPath {
return std.Build.LazyPath.relative(path);
}

inline fn run_npm_command(
b: *std.Build,
comptime dir: []const u8,
Expand All @@ -115,7 +107,7 @@ inline fn run_npm_command(
) void {
inline for (commands, 0..) |command, idx| {
const syscommand = b.addSystemCommand(&[3][]const u8{ "pnpm", "run", command });
syscommand.cwd = get_lazypath(dir);
syscommand.cwd = .{ .src_path = .{ .sub_path = dir, .owner = b } };

inline for (dependency_steps) |dependency_step| {
syscommand.step.dependOn(dependency_step);
Expand Down Expand Up @@ -146,21 +138,20 @@ pub fn build(b: *std.Build) !void {
const tag = @tagName(target.os.tag);

// Declares dependencies
Dependency.addExternal(b, "swiftzig", 0);
Dependency.addInternal(b, "Kivi", "src/core/Kivi.zig", 1, 0);
Dependency.addInternal(b, "core", "src/core/main.zig", 2, 0);
Dependency.addInternal(b, "Kivi", "src/core/Kivi.zig", 0);
Dependency.addInternal(b, "core", "src/core/main.zig", 1);

// Executes codegens
const codegen_step = b.step("codegen", "Generates bindings");
const core_codegen = b.addExecutable(.{
.name = "codegen_generate",
.root_source_file = .{ .path = "src/codegen/core.zig" },
.root_source_file = .{ .src_path = .{ .sub_path = "src/codegen/core.zig", .owner = b } },
.optimize = optimize,
.target = resolved_target,
});
const js_driver_codegen = b.addExecutable(.{
.name = "codegen_generate",
.root_source_file = .{ .path = "src/codegen/js_driver.zig" },
.root_source_file = .{ .src_path = .{ .sub_path = "src/codegen/core.zig", .owner = b } },
.optimize = optimize,
.target = resolved_target,
});
Expand Down Expand Up @@ -207,9 +198,9 @@ pub fn build(b: *std.Build) !void {
const ffi_tests = b.addExecutable(.{ .name = "ffi-tests", .target = resolved_target, .optimize = optimize });
ffi_tests.linkLibC();
ffi_tests.linkLibrary(core_targets.shared);
ffi_tests.addSystemIncludePath(.{ .path = "src/core/include" });
ffi_tests.addSystemIncludePath(.{ .src_path = .{ .sub_path = "src/core/include", .owner = b } });
ffi_tests.addCSourceFile(.{
.file = .{ .path = "src/core/tests/ffi.c" },
.file = .{ .src_path = .{ .sub_path = "src/core/tests/ffi.c", .owner = b } },
.flags = &.{"-std=c17"},
});
ffi_tests_step.dependOn(core_build_step);
Expand Down
9 changes: 2 additions & 7 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
.{
.name = "kivi",
.version = "0.0.0",
.minimum_zig_version = "0.11.0",
.dependencies = .{},
.minimum_zig_version = "0.12.0",
.paths = .{ "src", "build.zig", "build.zig.zon" },
.dependencies = .{
.swiftzig = .{
.url = "https://github.com/devraymondsh/swiftzig/archive/refs/tags/v0.4.0.tar.gz",
.hash = "12208f395f60bbb782d91309c7b6d5d0da64a41db784e227f28dfd22ae996c05abaa",
},
},
}
2 changes: 1 addition & 1 deletion src/codegen/core.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const std = @import("std");
const core_mod = @import("core");

const TypeMap = std.ComptimeStringMap([]const u8, .{
const TypeMap = std.static_string_map.StaticStringMap([]const u8).initComptime(.{
.{ "void", "void" },
.{ "usize", "const size_t" },
.{ "*Kivi", "struct Kivi *const" },
Expand Down
16 changes: 8 additions & 8 deletions src/core/ByteMap.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/// This is Byte(u8) hashmap implementation that relies on the caller to handle allocations and lifetimes.
const std = @import("std");
const builtin = @import("builtin");
const Wyhash = @import("./Wyhash.zig");
const swiftzig = @import("swiftzig");
const FreeListAlloc = @import("FreeListAlloc.zig");

const Entry = struct {
key: []u8,
Expand Down Expand Up @@ -68,10 +67,10 @@ table: []Group,
table_metadata: []GroupMetadata,
table_size: usize,

var hasher = Wyhash.init(0);
// var hasher = std.hash.Wyhash.init(0);

pub fn init(self: *ByteMap, allocator: swiftzig.mem.Allocator, size: usize) !void {
self.table_size = swiftzig.math.ceilPowerOfTwo(size);
pub fn init(self: *ByteMap, allocator: *FreeListAlloc, size: usize) !void {
self.table_size = try std.math.ceilPowerOfTwo(usize, size);
self.table_metadata = try allocator.alloc(GroupMetadata, self.table_size);
self.table = try allocator.alloc(Group, self.table_size);

Expand All @@ -83,7 +82,8 @@ pub fn init(self: *ByteMap, allocator: swiftzig.mem.Allocator, size: usize) !voi
}

fn hash(key: []const u8) usize {
return hasher.reset_hash(@intCast(key.len), key);
// return hasher.reset_hash(@intCast(key.len), key);
return std.hash.Wyhash.hash(@intCast(key.len), key);
}
fn hash_to_groupidx(self: *ByteMap, hashed: usize) usize {
return (hashed >> 7) % self.table_size;
Expand Down Expand Up @@ -183,7 +183,7 @@ pub fn get(self: *ByteMap, key: []const u8) ?[]u8 {
}
return null;
}
pub fn del(self: *ByteMap, allocator: swiftzig.mem.Allocator, key: []const u8) ?[]u8 {
pub fn del(self: *ByteMap, allocator: *FreeListAlloc, key: []const u8) ?[]u8 {
const found_entity = self.find_index(key, true);
if (found_entity) |entity| {
const entry = &self.table[entity.group_idx].elements[entity.elem_idx];
Expand Down
107 changes: 107 additions & 0 deletions src/core/FreeListAlloc.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
const std = @import("std");
const builtin = @import("builtin");

const is_windows: bool = builtin.os.tag == .windows;

const FreelistNode = packed struct {
len: usize,
next: ?*FreelistNode,
};
var empty_freelist = FreelistNode{ .len = 0, .next = null };

cursor: usize,
freelist: *FreelistNode,
mem: []align(std.mem.page_size) u8,

const FreeListAlloc = @This();

pub fn init(total_size: usize) !FreeListAlloc {
var mem: []align(std.mem.page_size) u8 = undefined;
const size = std.mem.alignForward(usize, total_size, std.mem.page_size);
if (!is_windows) {
mem = try std.posix.mmap(
null,
size,
std.posix.PROT.READ | std.posix.PROT.WRITE,
std.posix.MAP{ .ANONYMOUS = true, .TYPE = .PRIVATE },
-1,
0,
);
} else {
const lpvoid = try std.os.windows.VirtualAlloc(null, size, std.os.windows.MEM_RESERVE, std.os.windows.PAGE_NOACCESS);

mem.len = size;
mem.ptr = @alignCast(@ptrCast(lpvoid));
}

return FreeListAlloc{ .mem = mem, .cursor = 0, .freelist = &empty_freelist };
}

pub fn alloc_byte(self: *FreeListAlloc, size: usize) ![]u8 {
if (self.freelist.len != 0) {
if (self.freelist.len >= size) {
var freelist_slice: []u8 = undefined;
freelist_slice.len = self.freelist.len;
freelist_slice.ptr = @alignCast(@ptrCast(self.freelist));

if (self.freelist.len - size != 0) {
@memset(freelist_slice[size..self.freelist.len], 0);
}

if (self.freelist.next) |_| {
self.freelist = self.freelist.next.?;
} else {
self.freelist = &empty_freelist;
}

return freelist_slice[0..size];
}
}

const starting_pos = self.cursor;
var ending_pos: usize = starting_pos + 16;
if (size > 16) {
ending_pos += std.mem.alignForward(usize, size - 16, 8);
}

if (ending_pos >= self.mem.len) {
return error.OutOfMemory;
}

self.cursor = ending_pos;

return self.mem[starting_pos .. starting_pos + size];
}

pub fn alloc(self: *FreeListAlloc, comptime T: type, n: usize) ![]T {
var allocated: []T = undefined;
allocated.ptr = @alignCast(@ptrCast(try self.alloc_byte(n * @sizeOf(T))));
allocated.len = n;
return allocated;
}

pub fn free(self: *FreeListAlloc, data: []u8) void {
const freelist = @as(*FreelistNode, @alignCast(@ptrCast(data.ptr)));

if (data.len > 16) {
freelist.len = @intCast(std.mem.alignForward(usize, data.len, 8));
} else {
freelist.len = 16;
}

if (self.freelist.len != 0) {
freelist.next = self.freelist;
} else {
freelist.next = null;
}

self.freelist = freelist;
}

pub fn deinit(self: *FreeListAlloc) void {
if (!is_windows) {
std.posix.munmap(self.mem);
} else {
std.os.windows.VirtualFree(@alignCast(@ptrCast(self.mem.ptr)), 0, std.os.windows.MEM_RELEASE);
}
}
28 changes: 11 additions & 17 deletions src/core/Kivi.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const ByteMap = @import("ByteMap.zig");
const swiftzig = @import("swiftzig");
const FreeListAlloc = @import("FreeListAlloc.zig");

pub const Config = extern struct {
// (2 ** 18) * 16 = 4194304
Expand All @@ -8,8 +9,7 @@ pub const Config = extern struct {
};

map: ByteMap,
allocator: swiftzig.mem.Allocator,
freelist: swiftzig.mem.FreelistAllocator,
mem: FreeListAlloc,

const Kivi = @This();

Expand All @@ -21,21 +21,17 @@ fn stringcpy(dest: []u8, src: []const u8) !void {
}

pub fn init(self: *Kivi, config: *const Config) !usize {
const pages = try swiftzig.mem.PageAllocator.init(config.mem_size / swiftzig.os.page_size);

self.freelist = swiftzig.mem.FreelistAllocator.init(pages.mem);
self.allocator = self.freelist.allocator();

try self.map.init(self.allocator, config.group_size);
self.mem = try FreeListAlloc.init(config.mem_size);
try self.map.init(&self.mem, config.group_size);

return @sizeOf(Kivi);
}

pub fn reserve_key(self: *Kivi, size: usize) ![]u8 {
return self.allocator.alloc(u8, size);
return self.mem.alloc(u8, size);
}
pub fn reserve_value(self: *Kivi, size: usize) ![]u8 {
return try self.allocator.alloc(u8, size);
return self.mem.alloc(u8, size);
}
pub fn put_entry(self: *Kivi, key: []u8, value: []u8) !void {
return self.map.put(key, value);
Expand Down Expand Up @@ -69,7 +65,7 @@ pub fn get_copy(self: *Kivi, key: []const u8, value: ?[]u8) !usize {
}

pub fn del(self: *Kivi, key: []const u8) ![]u8 {
if (self.map.del(self.allocator, key)) |value| {
if (self.map.del(&self.mem, key)) |value| {
return value;
} else {
return error.NotFound;
Expand All @@ -83,19 +79,17 @@ pub fn del_copy(self: *Kivi, key: []const u8, value: ?[]u8) !usize {
try stringcpy(value.?, value_slice);
}

self.allocator.free(value_slice);
self.mem.free(value_slice);

return value_slice_len;
}

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

pub fn deinit(self: *Kivi) void {
var pages: swiftzig.mem.PageAllocator = .{ .mem = @alignCast(self.freelist.mem) };

self.map.deinit();
pages.deinit();
self.mem.deinit();
}
Loading

0 comments on commit d3edac5

Please sign in to comment.