| ... | @@ -966,18 +966,20 @@ pub const Repository = struct { | ... | @@ -966,18 +966,20 @@ pub const Repository = struct { |
| 966 | else => |e| return e, | 966 | else => |e| return e, |
| 967 | }; | 967 | }; |
| 968 | defer objfile.close(); | 968 | defer objfile.close(); |
| 969 | var bufr = nio.BufferedReader(4096, nfs.File).init(objfile); | 969 | const compressed_content = try objfile.mmap(); |
| 970 | var list: std.ArrayList(u8) = .init(r.gpa); | 970 | defer nfs.munmap(compressed_content); |
| 971 | errdefer list.deinit(); | 971 | var list: std.ArrayListUnmanaged(u8) = .empty; |
| 972 | try list.ensureUnusedCapacity(512); | 972 | errdefer list.deinit(r.gpa); |
| 973 | try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer()); | 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); |
| 974 | const data = list.items; | 976 | const data = list.items; |
| 975 | const header = data[0..std.mem.indexOfScalar(u8, data, 0).?]; | 977 | const header = data[0..std.mem.indexOfScalar(u8, data, 0).?]; |
| 976 | const _type_s = header[0..std.mem.indexOfScalar(u8, header, ' ').?]; | 978 | const _type_s = header[0..std.mem.indexOfScalar(u8, header, ' ').?]; |
| 977 | const _type = std.meta.stringToEnum(RefType, _type_s).?; | 979 | const _type = std.meta.stringToEnum(RefType, _type_s).?; |
| 978 | const content_len = try extras.parseDigits(u64, header[_type_s.len + 1 ..], 10); | 980 | const content_len = try extras.parseDigits(u64, header[_type_s.len + 1 ..], 10); |
| 979 | list.replaceRangeAssumeCapacity(0, header.len + 1, ""); | 981 | list.replaceRangeAssumeCapacity(0, header.len + 1, ""); |
| 980 | const content = try list.toOwnedSlice(); | 982 | const content = try list.toOwnedSlice(r.gpa); |
| 981 | std.debug.assert(content.len == content_len); | 983 | std.debug.assert(content.len == content_len); |
| 982 | const obj: GitObject = .{ .type = _type, .content = content }; | 984 | const obj: GitObject = .{ .type = _type, .content = content }; |
| 983 | try r.unpacked_objects.put(r.gpa, oid, obj); | 985 | try r.unpacked_objects.put(r.gpa, oid, obj); |
| ... | @@ -1096,13 +1098,13 @@ pub const Repository = struct { | ... | @@ -1096,13 +1098,13 @@ pub const Repository = struct { |
| 1096 | }, | 1098 | }, |
| 1097 | .commit, .tree, .blob, .tag => { | 1099 | .commit, .tree, .blob, .tag => { |
| 1098 | const compressed_content = packedobj_fbs.rest()[0..size]; | 1100 | const compressed_content = packedobj_fbs.rest()[0..size]; |
| 1099 | var bufr = nio.FixedBufferStream([]const u8).init(compressed_content); | 1101 | var list: std.ArrayListUnmanaged(u8) = .empty; |
| 1100 | var list: std.ArrayList(u8) = .init(r.gpa); | 1102 | errdefer list.deinit(r.gpa); |
| 1101 | errdefer list.deinit(); | 1103 | try list.ensureUnusedCapacity(r.gpa, 512); |
| 1102 | try list.ensureUnusedCapacity(512); | 1104 | // try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer()); |
| 1103 | try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer()); | 1105 | try inflate_decompress(compressed_content, &list, r.gpa); |
| 1104 | const _type = std.meta.stringToEnum(RefType, @tagName(ty)).?; | 1106 | const _type = std.meta.stringToEnum(RefType, @tagName(ty)).?; |
| 1105 | const content = try list.toOwnedSlice(); | 1107 | const content = try list.toOwnedSlice(r.gpa); |
| 1106 | const obj: GitObject = .{ .type = _type, .content = content }; | 1108 | const obj: GitObject = .{ .type = _type, .content = content }; |
| 1107 | if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj); | 1109 | if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj); |
| 1108 | return obj; | 1110 | return obj; |
| ... | @@ -1140,12 +1142,11 @@ pub const Repository = struct { | ... | @@ -1140,12 +1142,11 @@ pub const Repository = struct { |
| 1140 | | 1142 | |
| 1141 | fn getDeltadObject(r: *Repository, maybe_oid: ?Id, packedobj_fbs: *nio.FixedBufferStream([]const u8), size: usize, base_obj: GitObject) !GitObject { | 1143 | fn getDeltadObject(r: *Repository, maybe_oid: ?Id, packedobj_fbs: *nio.FixedBufferStream([]const u8), size: usize, base_obj: GitObject) !GitObject { |
| 1142 | const compressed_content = packedobj_fbs.rest()[0..size]; | 1144 | const compressed_content = packedobj_fbs.rest()[0..size]; |
| 1143 | var bufr = nio.FixedBufferStream([]const u8).init(compressed_content); | | |
| 1144 | | | |
| 1145 | var list: std.ArrayListUnmanaged(u8) = .empty; | 1145 | var list: std.ArrayListUnmanaged(u8) = .empty; |
| 1146 | defer list.deinit(r.gpa); | 1146 | defer list.deinit(r.gpa); |
| 1147 | try list.ensureUnusedCapacity(r.gpa, size); | 1147 | 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); |
| 1149 | // std.log.debug("transformation data={d}", .{list.items}); | 1150 | // std.log.debug("transformation data={d}", .{list.items}); |
| 1150 | | 1151 | |
| 1151 | var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items); | 1152 | var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items); |
| ... | @@ -1362,3 +1363,58 @@ pub const Repository = struct { | ... | @@ -1362,3 +1363,58 @@ pub const Repository = struct { |
| 1362 | } | 1363 | } |
| 1363 | } | 1364 | } |
| 1364 | }; | 1365 | }; |
| | 1366 | |
| | 1367 | const z = @cImport({ |
| | 1368 | @cInclude("zlib.h"); |
| | 1369 | }); |
| | 1370 | |
| | 1371 | fn 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 | |
| | 1410 | const 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 | }; |