diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 511fcb4..5c0fdaf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,12 +18,12 @@ jobs: - name: Install Zig run: | - wget https://ziglang.org/builds/zig-linux-x86_64-0.14.0-dev.2643+fb43e91b2.tar.xz - tar -xf zig-linux-x86_64-0.14.0-dev.2643+fb43e91b2.tar.xz - sudo mv zig-linux-x86_64-0.14.0-dev.2643+fb43e91b2 $HOME/zig + wget https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz + tar -xf zig-x86_64-linux-0.15.2.tar.xz + sudo mv zig-x86_64-linux-0.15.2 $HOME/zig $HOME/zig/zig version - name: Build and test run: | mkdir dirty - $HOME/zig/zig test src/root.zig \ No newline at end of file + $HOME/zig/zig test src/root.zig diff --git a/src/db.zig b/src/db.zig index bdd33ca..d7b67b5 100644 --- a/src/db.zig +++ b/src/db.zig @@ -107,8 +107,8 @@ pub const DB = struct { // When true, Update() and Begin(true) return Error.DatabaseReadOnly. readOnly: bool = false, - meta0: *Meta, - meta1: *Meta, + meta0: *align(1) Meta, + meta1: *align(1) Meta, opts: ?*const fn (std.fs.File, []const u8, u64) Error!usize, allocator: std.mem.Allocator, @@ -246,7 +246,7 @@ pub const DB = struct { if (sz < Page.headerSize()) { return Error.Invalid; } - var m: *Meta = undefined; + var m: *align(1) Meta = undefined; if (sz < db.pageSize) { const _p = Page.init(buf[0..sz]); m = _p.meta(); @@ -460,7 +460,7 @@ pub const DB = struct { } /// meta retriews the current meta page reference. - pub fn getMeta(self: *const Self) *Meta { + pub fn getMeta(self: *const Self) *align(1) Meta { // We have to return the meta with the highest txid which does't fail // validation. Otherwise, we can cause errors when in fact the database is // in a consistent state. metaA is the one with thwe higher txid. @@ -924,7 +924,7 @@ pub const Meta = struct { pub const header_size = @sizeOf(Meta); /// Validates the meta object. - pub fn validate(self: *const Self) errors.Error!void { + pub fn validate(self: *align(1) const Self) errors.Error!void { if (self.magic != consts.Magic) { return errors.Error.Invalid; } else if (self.version != consts.Version) { @@ -936,7 +936,7 @@ pub const Meta = struct { } /// Calculates the checksum of the meta object - pub fn sum64(self: *const Self) u64 { + pub fn sum64(self: *align(1) const Self) u64 { const endPos = @offsetOf(Self, "check_sum"); const ptr = @intFromPtr(self); const buf: [*]u8 = @ptrFromInt(ptr); @@ -946,7 +946,7 @@ pub const Meta = struct { } /// Copies one meta object to another - pub fn copy(self: *Self, dest: *Self) void { + pub fn copy(self: *align(1) const Self, dest: *Self) void { dest.* = self.*; } @@ -970,7 +970,7 @@ pub const Meta = struct { } /// Print the meta information - pub fn print(self: *const Self, allocator: std.mem.Allocator) !void { + pub fn print(self: *align(1) const Self, allocator: std.mem.Allocator) !void { var table = Table.init(allocator, 20, .Blue, "Meta"); defer table.deinit(); try table.addHeader(.{ "Field", "Value" }); diff --git a/src/page.zig b/src/page.zig index 77d89da..73c4daf 100644 --- a/src/page.zig +++ b/src/page.zig @@ -58,23 +58,19 @@ pub const Page = struct { } /// Returns a pointer to the metadata section of the page. - pub fn meta(self: *Self) *db.Meta { + /// Uses align(1) to support potentially unaligned buffers (e.g. from mmap). + pub fn meta(self: *Self) *align(1) db.Meta { const ptr: usize = self.getDataPtrInt(); - const _meta: *db.Meta = @ptrFromInt(ptr); - return _meta; + return @ptrFromInt(ptr); } // Retrives the branch node by index. - pub fn branchPageElement(self: *Self, index: usize) ?*BranchPageElement { + pub fn branchPageElement(self: *Self, index: usize) ?*align(1) BranchPageElement { if (self.count <= index) { return null; } const basePtr = self.getDataPtrInt() + index * BranchPageElement.headerSize(); - // const aligned_ptr = std.mem.alignForward(usize, basePtr + index * BranchPageElement.headerSize(), @alignOf(BranchPageElement)); - const dPtr: *BranchPageElement = @ptrFromInt(basePtr); - - // const dPtr: *BranchPageElement = @ptrFromInt(ptr); - return dPtr; + return @ptrFromInt(basePtr); } /// Converts a pointer to a specific type. @@ -83,53 +79,48 @@ pub const Page = struct { } /// Returns branch element reference by index. - pub fn branchPageElementRef(self: *const Self, index: usize) ?*const BranchPageElement { + pub fn branchPageElementRef(self: *const Self, index: usize) ?*align(1) const BranchPageElement { if (self.count <= index) { return null; } const basePtr = self.getDataPtrInt() + index * BranchPageElement.headerSize(); - // const aligned_ptr = std.mem.alignForward(usize, basePtr + index * BranchPageElement.headerSize(), @alignOf(BranchPageElement)); - const dPtr: *BranchPageElement = @ptrFromInt(basePtr); - return dPtr; + return @ptrFromInt(basePtr); } /// Retrives the leaf node by index. - pub fn leafPageElement(self: *Self, index: usize) ?*LeafPageElement { + pub fn leafPageElement(self: *Self, index: usize) ?*align(1) LeafPageElement { if (self.count <= index) { return null; } const ptr = self.getDataPtrInt() + index * LeafPageElement.headerSize(); - const dPtr: *LeafPageElement = @ptrFromInt(ptr); - return dPtr; + return @ptrFromInt(ptr); } /// Retrives the leaf page reference element by index. - pub fn leafPageElementRef(self: *const Self, index: usize) ?*const LeafPageElement { + pub fn leafPageElementRef(self: *const Self, index: usize) ?*align(1) const LeafPageElement { if (self.count <= index) { return null; } const ptr = self.getDataPtrIntRef() + index * LeafPageElement.headerSize(); - const dPtr: *const LeafPageElement = @ptrFromInt(ptr); - return dPtr; + return @ptrFromInt(ptr); } /// Returns the pointer of index's leaf elements - pub fn leafPageElementPtr(self: *Self, index: usize) *LeafPageElement { + pub fn leafPageElementPtr(self: *Self, index: usize) *align(1) LeafPageElement { if (self.count <= index) { return undefined; } const ptr = self.getDataPtrInt() + index * LeafPageElement.headerSize(); - const dPtr: *LeafPageElement = @ptrFromInt(ptr); - return dPtr; + return @ptrFromInt(ptr); } /// Retrives a list of leaf nodes. - pub fn leafPageElements(self: *Self) ?[]LeafPageElement { + pub fn leafPageElements(self: *Self) ?[]align(1) LeafPageElement { if (self.count == 0) { return null; } const firstPtr = self.leafPageElementPtr(0); - var elements: [*]LeafPageElement = @ptrCast(firstPtr); + var elements: [*]align(1) LeafPageElement = @ptrCast(firstPtr); return elements[0..self.count]; } @@ -434,7 +425,7 @@ test "page struct" { } const leafElements = pageRef.leafPageElements(); for (leafElements.?) |leaf| { - std.debug.print("{?}\n", .{leaf}); + std.debug.print("{any}\n", .{leaf}); } } } diff --git a/src/pretty_table.zig b/src/pretty_table.zig index 5f75709..267abf3 100644 --- a/src/pretty_table.zig +++ b/src/pretty_table.zig @@ -87,7 +87,7 @@ pub const Table = struct { /// Print a table. pub fn print(self: @This()) !void { - const writer = std.io.getStdOut().writer(); + const writer = std.fs.File.stdout().deprecatedWriter(); // calculate the total width of the table const totalWidth = self.columnWidth * self.headers.items.len + self.headers.items.len + 1; diff --git a/src/tx.zig b/src/tx.zig index afda39e..2cfc783 100644 --- a/src/tx.zig +++ b/src/tx.zig @@ -830,15 +830,14 @@ pub fn writeToWriter(self: *TX, writer: anytype) Error!usize { n += hasWritten; // Move past the meta pages in the file. - const reader = file.reader(); - reader.skipBytes(_db.pageSize * 2, .{}) catch |err| { + file.seekTo(_db.pageSize * 2) catch |err| { ctxLog.err("skip bytes failed: {any}", .{err}); return Error.FileIOError; }; while (true) { @memset(buffer, 0); - const hasRead = reader.read(buffer[0..]) catch |err| { + const hasRead = file.read(buffer[0..]) catch |err| { ctxLog.err("read data page failed: {any}", .{err}); return Error.FileIOError; }; @@ -882,15 +881,14 @@ pub fn writeToWriterByStream(self: *TX, writer: anytype) Error!usize { n += hasWritten; // Move past the meta pages in the file. - const reader = file.reader(); - reader.skipBytes(_db.pageSize * 2, .{}) catch |err| { + file.seekTo(_db.pageSize * 2) catch |err| { std.log.err("skip bytes failed: {any}", .{err}); return Error.FileIOError; }; while (true) { @memset(buffer, 0); - const hasRead = reader.read(buffer[0..]) catch |err| { + const hasRead = file.read(buffer[0..]) catch |err| { std.log.err("read data page failed: {any}", .{err}); return Error.FileIOError; };