2022-04-20 07:19:34 +03:00
|
|
|
const std = @import("std");
|
|
|
|
const os = std.os;
|
2022-04-21 09:30:39 +03:00
|
|
|
const fs = std.fs;
|
|
|
|
const Allocator = std.mem.Allocator;
|
2022-04-20 07:19:34 +03:00
|
|
|
|
2022-04-21 09:30:39 +03:00
|
|
|
const Corpus = @import("Corpus.zig");
|
2022-04-20 07:19:34 +03:00
|
|
|
const DB = @import("DB.zig");
|
|
|
|
const InvalidHeader = @import("header.zig").Invalid;
|
|
|
|
|
|
|
|
const File = @This();
|
|
|
|
|
|
|
|
db: DB,
|
|
|
|
ptr: []align(4096) const u8,
|
|
|
|
|
|
|
|
pub const Error = os.OpenError || os.FStatError || os.MMapError || InvalidHeader;
|
|
|
|
pub fn open(fname: []const u8) Error!File {
|
|
|
|
const fd = try os.open(fname, os.O.RDONLY, 0);
|
|
|
|
var fd_open = true;
|
2022-04-21 09:30:39 +03:00
|
|
|
errdefer if (fd_open) os.close(fd);
|
2022-04-20 07:19:34 +03:00
|
|
|
|
|
|
|
const st = try os.fstat(fd);
|
2022-04-21 09:30:39 +03:00
|
|
|
const size = @intCast(usize, st.size);
|
2022-04-20 07:19:34 +03:00
|
|
|
const ptr = try os.mmap(null, size, os.PROT.READ, os.MAP.SHARED, fd, 0);
|
|
|
|
errdefer os.munmap(ptr);
|
|
|
|
|
|
|
|
os.close(fd);
|
|
|
|
fd_open = false;
|
|
|
|
|
|
|
|
const db = try DB.fromBytes(ptr);
|
|
|
|
return File{ .db = db, .ptr = ptr };
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn close(self: *File) void {
|
|
|
|
os.munmap(self.ptr);
|
|
|
|
self.* = undefined;
|
|
|
|
}
|
2022-04-21 09:30:39 +03:00
|
|
|
|
|
|
|
const testing = std.testing;
|
|
|
|
|
|
|
|
pub const TestFile = struct {
|
|
|
|
dir: testing.TmpDir,
|
|
|
|
path: [:0]const u8,
|
|
|
|
|
|
|
|
pub fn init(allocator: Allocator) !TestFile {
|
|
|
|
var corpus = try Corpus.testCorpus(allocator);
|
|
|
|
defer corpus.deinit();
|
|
|
|
|
|
|
|
var db = try DB.fromCorpus(allocator, &corpus);
|
|
|
|
defer db.deinit(allocator);
|
|
|
|
|
|
|
|
var tmp = testing.tmpDir(.{});
|
|
|
|
errdefer tmp.cleanup();
|
|
|
|
|
|
|
|
const mode = os.O.RDWR | os.O.CREAT | os.O.EXCL;
|
|
|
|
const fd = try os.openat(tmp.dir.fd, "db.turbo", mode, 0o666);
|
|
|
|
defer os.close(fd);
|
|
|
|
|
|
|
|
_ = try os.writev(fd, db.iov().constSlice());
|
|
|
|
const dir_path = try tmp.getFullPath(allocator);
|
|
|
|
defer allocator.free(dir_path);
|
|
|
|
|
|
|
|
const full = &[_][]const u8{ dir_path, "db.turbo\x00" };
|
|
|
|
var result = try fs.path.join(allocator, full);
|
|
|
|
return TestFile{ .dir = tmp, .path = result[0 .. result.len - 1 :0] };
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn deinit(self: *TestFile, allocator: Allocator) void {
|
|
|
|
self.dir.cleanup();
|
|
|
|
allocator.free(self.path);
|
|
|
|
}
|
|
|
|
};
|