authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-13 02:33:28 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-13 02:33:28 -07:00
log52075b3bd908a77c2cd2aebc5b480354643496f7
treea98d0dc94b1bb20d265aa379d092be53e973ba46
parent3c080a86f2a7cc235c0d64245399fcf306cde245
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

use zlib c library for decompression


2 files changed, 95 insertions(+), 15 deletions(-)

git.zig+71-15
......@@ -966,18 +966,20 @@ pub const Repository = struct {
966966 else => |e| return e,
967967 };
968968 defer objfile.close();
969 var bufr = nio.BufferedReader(4096, nfs.File).init(objfile);
970 var list: std.ArrayList(u8) = .init(r.gpa);
971 errdefer list.deinit();
972 try list.ensureUnusedCapacity(512);
973 try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer());
969 const compressed_content = try objfile.mmap();
970 defer nfs.munmap(compressed_content);
971 var list: std.ArrayListUnmanaged(u8) = .empty;
972 errdefer list.deinit(r.gpa);
973 try list.ensureUnusedCapacity(r.gpa, 512);
974 // try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer());
975 try inflate_decompress(compressed_content, &list, r.gpa);
974976 const data = list.items;
975977 const header = data[0..std.mem.indexOfScalar(u8, data, 0).?];
976978 const _type_s = header[0..std.mem.indexOfScalar(u8, header, ' ').?];
977979 const _type = std.meta.stringToEnum(RefType, _type_s).?;
978980 const content_len = try extras.parseDigits(u64, header[_type_s.len + 1 ..], 10);
979981 list.replaceRangeAssumeCapacity(0, header.len + 1, "");
980 const content = try list.toOwnedSlice();
982 const content = try list.toOwnedSlice(r.gpa);
981983 std.debug.assert(content.len == content_len);
982984 const obj: GitObject = .{ .type = _type, .content = content };
983985 try r.unpacked_objects.put(r.gpa, oid, obj);
......@@ -1096,13 +1098,13 @@ pub const Repository = struct {
10961098 },
10971099 .commit, .tree, .blob, .tag => {
10981100 const compressed_content = packedobj_fbs.rest()[0..size];
1099 var bufr = nio.FixedBufferStream([]const u8).init(compressed_content);
1100 var list: std.ArrayList(u8) = .init(r.gpa);
1101 errdefer list.deinit();
1102 try list.ensureUnusedCapacity(512);
1103 try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer());
1101 var list: std.ArrayListUnmanaged(u8) = .empty;
1102 errdefer list.deinit(r.gpa);
1103 try list.ensureUnusedCapacity(r.gpa, 512);
1104 // try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer());
1105 try inflate_decompress(compressed_content, &list, r.gpa);
11041106 const _type = std.meta.stringToEnum(RefType, @tagName(ty)).?;
1105 const content = try list.toOwnedSlice();
1107 const content = try list.toOwnedSlice(r.gpa);
11061108 const obj: GitObject = .{ .type = _type, .content = content };
11071109 if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj);
11081110 return obj;
......@@ -1140,12 +1142,11 @@ pub const Repository = struct {
11401142
11411143 fn getDeltadObject(r: *Repository, maybe_oid: ?Id, packedobj_fbs: *nio.FixedBufferStream([]const u8), size: usize, base_obj: GitObject) !GitObject {
11421144 const compressed_content = packedobj_fbs.rest()[0..size];
1143 var bufr = nio.FixedBufferStream([]const u8).init(compressed_content);
1144
11451145 var list: std.ArrayListUnmanaged(u8) = .empty;
11461146 defer list.deinit(r.gpa);
11471147 try list.ensureUnusedCapacity(r.gpa, size);
1148 try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer(r.gpa));
1148 // try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer(r.gpa));
1149 try inflate_decompress(compressed_content, &list, r.gpa);
11491150 // std.log.debug("transformation data={d}", .{list.items});
11501151
11511152 var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items);
......@@ -1362,3 +1363,58 @@ pub const Repository = struct {
13621363 }
13631364 }
13641365};
1366
1367const z = @cImport({
1368 @cInclude("zlib.h");
1369});
1370
1371fn inflate_decompress(in: []const u8, out: *std.ArrayListUnmanaged(u8), allocator: std.mem.Allocator) !void {
1372 // std.log.debug("{x}", .{in});
1373 var strm: z.z_stream = std.mem.zeroes(z.z_stream);
1374 {
1375 const ret: ZlibCode = @enumFromInt(z.inflateInit(&strm));
1376 if (ret == .Z_MEM_ERROR) return error.OutOfMemory;
1377 std.debug.assert(ret != .Z_VERSION_ERROR);
1378 std.debug.assert(ret != .Z_STREAM_ERROR);
1379 }
1380 defer {
1381 const ret: ZlibCode = @enumFromInt(z.inflateEnd(&strm));
1382 std.debug.assert(ret != .Z_STREAM_ERROR);
1383 std.debug.assert(ret == .Z_OK);
1384 }
1385 strm.next_in = @constCast(in.ptr);
1386 strm.avail_in = @intCast(in.len);
1387 // std.log.debug("inflate_decompress: -> {*} {d}", .{ strm.next_in, strm.avail_in });
1388
1389 while (true) {
1390 var buf: [16384]u8 = @splat(0);
1391 strm.next_out = &buf;
1392 strm.avail_out = buf.len;
1393 // std.log.debug("inflate_decompress: -> {*} {*} {d} {d}", .{ strm.next_in, strm.next_out, strm.avail_in, strm.avail_out });
1394 const ret: ZlibCode = @enumFromInt(z.inflate(&strm, z.Z_NO_FLUSH));
1395 // std.log.debug("inflate_decompress: <- {*} {*} {d} {d} {s}", .{ strm.next_in, strm.next_out, strm.avail_in, strm.avail_out, @tagName(ret) });
1396 std.debug.assert(ret != .Z_STREAM_ERROR);
1397 // if (ret == .Z_BUF_ERROR) std.log.err("{s}", .{strm.msg});
1398 std.debug.assert(ret != .Z_BUF_ERROR);
1399 if (ret == .Z_MEM_ERROR) return error.OutOfMemory;
1400 if (ret == .Z_DATA_ERROR) return error.Z_DATA_ERROR;
1401 if (ret == .Z_NEED_DICT) return error.Z_NEED_DICT;
1402 // Z_ERRNO
1403 // Z_VERSION_ERROR
1404 std.debug.assert(ret == .Z_OK or ret == .Z_STREAM_END);
1405 try out.appendSlice(allocator, buf[0 .. buf.len - strm.avail_out]);
1406 if (ret == .Z_STREAM_END) break;
1407 }
1408}
1409
1410const ZlibCode = enum(c_int) {
1411 Z_OK = 0,
1412 Z_STREAM_END = 1,
1413 Z_NEED_DICT = 2,
1414 Z_ERRNO = -1,
1415 Z_STREAM_ERROR = -2,
1416 Z_DATA_ERROR = -3,
1417 Z_MEM_ERROR = -4,
1418 Z_BUF_ERROR = -5,
1419 Z_VERSION_ERROR = -6,
1420};
zig.mod+24
......@@ -9,6 +9,30 @@ dependencies:
99 - src: git https://github.com/nektro/zig-tracer
1010 - src: git https://github.com/nektro/zig-nfs
1111 - src: git https://github.com/nektro/zig-nio
12
13 - src: git https://github.com/madler/zlib tag-v1.3.2
14 license: Zlib
15 c_include_dirs:
16 -
17 c_source_files:
18 - inftrees.c
19 - inflate.c
20 - adler32.c
21 - zutil.c
22 - trees.c
23 - gzclose.c
24 - gzwrite.c
25 - gzread.c
26 - deflate.c
27 - compress.c
28 - crc32.c
29 - infback.c
30 - gzlib.c
31 - uncompr.c
32 - inffast.c
33 c_source_flags:
34 - -DZ_HAVE_UNISTD_H=1
35
1236root_dependencies:
1337 - src: git https://github.com/nektro/zig-extras
1438 - src: git https://github.com/nektro/zig-expect