alloc-ified many functions.

Updated README
This commit is contained in:
Caleb J. Gardner
2026-02-28 22:33:57 -06:00
parent b0160e005b
commit 5f629df47c
8 changed files with 126 additions and 169 deletions
+24 -22
View File
@@ -121,7 +121,7 @@ pub fn dataReader(self: Inode, alloc: std.mem.Allocator, archive: *Archive) !Dat
fn readerFromData(alloc: std.mem.Allocator, archive: *Archive, data: anytype) !DataReader {
var out: DataReader = .init(alloc, archive.*, data.block_sizes, data.block_start, data.size);
if (data.frag_idx != 0xFFFFFFFF)
out.addFragment(try archive.frag(data.frag_idx), data.frag_block_offset);
out.addFragment(try archive.frag_table.get(data.frag_idx), data.frag_block_offset);
return out;
}
/// Get a threaded data reader for a file inode.
@@ -135,7 +135,7 @@ pub fn threadedDataReader(self: Inode, alloc: std.mem.Allocator, archive: *Archi
fn threadedReaderFromData(alloc: std.mem.Allocator, archive: *Archive, data: anytype) !ThreadedDataReader {
var out: ThreadedDataReader = .init(alloc, archive.*, data.block_sizes, data.block_start, data.size);
if (data.frag_idx != 0xFFFFFFFF)
out.addFragment(try archive.frag(data.frag_idx), data.frag_block_offset);
out.addFragment(try archive.frag_table.get(data.frag_idx), data.frag_block_offset);
return out;
}
@@ -155,15 +155,15 @@ fn entriesFromData(alloc: std.mem.Allocator, archive: Archive, data: anytype) ![
}
/// Extract the inode to the given path. Single threaded.
pub fn extractTo(self: Inode, archive: *Archive, path: []const u8, options: ExtractionOptions) !void {
pub fn extractTo(self: Inode, alloc: std.mem.Allocator, archive: *Archive, path: []const u8, options: ExtractionOptions) !void {
if (options.threads > 1) return self.extractToThreaded(alloc, archive, path, options);
switch (self.hdr.inode_type) {
.dir, .ext_dir => {
// Removing any trailing separators since that's the easiest path forward.
if (path[path.len - 1] == '/') return self.extractTo(archive, path[0 .. path.len - 1], options);
if (path[path.len - 1] == '/') return self.extractTo(alloc, archive, path[0 .. path.len - 1], options);
std.fs.cwd().makeDir(path) catch |err| {
if (err != std.fs.Dir.MakeError.PathAlreadyExists) return err;
};
var alloc = archive.allocator();
const entries = try self.dirEntries(alloc, archive.*);
defer {
for (entries) |entry| entry.deinit(alloc);
@@ -178,10 +178,10 @@ pub fn extractTo(self: Inode, archive: *Archive, path: []const u8, options: Extr
var inode: Inode = try readFromEntry(alloc, archive, entry);
defer inode.deinit(alloc);
try inode.extractTo(archive, new_path, options);
try inode.extractTo(alloc, archive, new_path, options);
}
},
.file, .ext_file => try self.extractRegFile(archive.allocator(), archive, path, options),
.file, .ext_file => try self.extractRegFile(alloc, archive, path, options),
.symlink, .ext_symlink => try self.extractSymlink(path),
else => try self.extractDevice(archive, path, options),
}
@@ -209,8 +209,8 @@ const Parent = struct {
.alloc = alloc,
.path = path,
.uid = try archive.id(hdr.uid_idx),
.gid = try archive.id(hdr.gid_idx),
.uid = try archive.id_table.get(hdr.uid_idx),
.gid = try archive.id_table.get(hdr.gid_idx),
.perm = hdr.permissions,
.mod_time = hdr.mod_time,
@@ -244,12 +244,11 @@ const Parent = struct {
/// Functions identically to extractTo on all but regular files and directories.
///
/// If threads <= 1, then this just calls extractTo.
pub fn extractToThreaded(self: Inode, archive: *Archive, path: []const u8, options: ExtractionOptions, threads: usize) !void {
if (threads <= 1) return self.extractTo(archive, path, options);
fn extractToThreaded(self: Inode, allocator: std.mem.Allocator, archive: *Archive, path: []const u8, options: ExtractionOptions) !void {
switch (self.hdr.inode_type) {
.dir, .ext_dir => {
// Removing any trailing separators since that's the easiest path forward.
if (path[path.len - 1] == '/') return self.extractToThreaded(archive, path[0 .. path.len - 1], options, threads);
if (path[path.len - 1] == '/') return self.extractToThreaded(allocator, archive, path[0 .. path.len - 1], options);
// Fixed Allocator
// const mem_buf = archive.allocator().alloc(u8, 2 * 1024 * 1024 * 1024);
@@ -258,7 +257,7 @@ pub fn extractToThreaded(self: Inode, archive: *Archive, path: []const u8, optio
// const alloc = fixed_alloc.threadSafeAllocator();
// Arena Allocator
var arena_alloc: std.heap.ArenaAllocator = .init(archive.allocator());
var arena_alloc: std.heap.ArenaAllocator = .init(allocator);
defer arena_alloc.deinit();
var thread_alloc: std.heap.ThreadSafeAllocator = .{ .child_allocator = arena_alloc.allocator() };
const alloc = thread_alloc.allocator();
@@ -266,7 +265,7 @@ pub fn extractToThreaded(self: Inode, archive: *Archive, path: []const u8, optio
var wg: WaitGroup = .{};
// defer if(!options.ignore_permissions) perms.?.deinit(alloc); We don't need to do this due to ArenaAllocator
var pool: Pool = undefined;
try pool.init(.{ .allocator = alloc, .n_jobs = threads - 1 });
try pool.init(.{ .allocator = allocator, .n_jobs = options.threads - 1 });
defer pool.deinit();
var out_err: ?anyerror = null;
@@ -281,16 +280,19 @@ pub fn extractToThreaded(self: Inode, archive: *Archive, path: []const u8, optio
try fil.updateTimes(time, time);
if (options.ignore_permissions) {
try fil.chmod(self.hdr.permissions);
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
try fil.chown(try archive.id_table.get(self.hdr.uid_idx), try archive.id_table.get(self.hdr.gid_idx));
}
},
.file, .ext_file => {
const alloc = archive.allocator();
var pool: Pool = undefined;
try pool.init(.{ .allocator = alloc, .n_jobs = threads });
try pool.init(.{ .allocator = allocator, .n_jobs = options.threads - 1 });
defer pool.deinit();
var arena_alloc: std.heap.ArenaAllocator = .init(allocator);
defer arena_alloc.deinit();
var thread_alloc: std.heap.ThreadSafeAllocator = .{ .child_allocator = arena_alloc.allocator() };
const alloc = thread_alloc.allocator();
try self.extractRegFileThreaded(alloc, archive, path, options, &pool);
var fil = try std.fs.cwd().openFile(path, .{});
@@ -299,7 +301,7 @@ pub fn extractToThreaded(self: Inode, archive: *Archive, path: []const u8, optio
try fil.updateTimes(time, time);
if (!options.ignore_permissions) {
try fil.chmod(self.hdr.permissions);
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
try fil.chown(try archive.id_table.get(self.hdr.uid_idx), try archive.id_table.get(self.hdr.gid_idx));
}
},
.symlink, .ext_symlink => try self.extractSymlink(path),
@@ -445,7 +447,7 @@ fn extractRegFile(self: Inode, alloc: std.mem.Allocator, archive: *Archive, path
try fil.updateTimes(time, time);
if (!options.ignore_permissions) {
try fil.chmod(self.hdr.permissions);
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
try fil.chown(try archive.id_table.get(self.hdr.uid_idx), try archive.id_table.get(self.hdr.gid_idx));
}
}
/// Extract the inode file contents to the given path threadedly.
@@ -462,7 +464,7 @@ fn extractRegFileThreaded(self: Inode, alloc: std.mem.Allocator, archive: *Archi
try fil.updateTimes(time, time);
if (!options.ignore_permissions) {
try fil.chmod(self.hdr.permissions);
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
try fil.chown(try archive.id_table.get(self.hdr.uid_idx), try archive.id_table.get(self.hdr.gid_idx));
}
}
/// Creates the symlink described by the inode.
@@ -529,7 +531,7 @@ fn extractDevice(self: Inode, archive: *Archive, path: []const u8, options: Extr
try fil.updateTimes(time, time);
if (!options.ignore_permissions) {
try fil.chmod(self.hdr.permissions);
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
try fil.chown(try archive.id_table.get(self.hdr.uid_idx), try archive.id_table.get(self.hdr.gid_idx));
}
if (!options.ignore_xattr) {
// TODO