authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-16 19:15:05 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-16 19:15:05 -07:00
logfe1cf2146cda5dd185c2f7cb6347e4911d9c44b8
tree81433dd69f4b90f86dbcee409b4e371e59234e0e
parent1996137bb2545e171717a11f523ca0bde10b758c
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

handle large pack_offset


1 files changed, 24 insertions(+), 17 deletions(-)

git.zig+24-17
......@@ -917,15 +917,19 @@ pub const Repository = struct {
917917 const t4 = tracer.trace(@src(), " find pack_index/pack_offset", .{});
918918 errdefer t4.end();
919919 const pack_index, const pack_offset = blk: for (r.idx_content.keys(), r.idx_content.values()) |idx_path, idx_content| {
920 const t5 = tracer.trace(@src(), " {s}", .{idx_path});
921 defer t5.end();
922920 if (std.mem.startsWith(u8, idx_content, "\xfftOc")) {
923 std.debug.assert(std.mem.readInt(u32, idx_content[4..][0..4], .big) == 2);
924 const flfo_table_bytes = idx_content[8..][0 .. 256 * 4];
925 const object_count = std.mem.readInt(u32, flfo_table_bytes[255 * 4 ..][0..4], .big);
926 const name_bytes = idx_content[8..][1024..][0 .. object_count * 20];
927 const crc32_bytes = idx_content[8..][1024..][name_bytes.len..][0 .. object_count * 4];
928 const offset_bytes = idx_content[8..][1024..][name_bytes.len..][crc32_bytes.len..][0 .. object_count * 4];
921 var idx_fbs: nio.FixedBufferStream([]const u8) = .init(idx_content);
922 _ = idx_fbs.takeSlice(4);
923 std.debug.assert(idx_fbs.takeInt(u32, .big) == 2);
924 const fanout_be_bytes = idx_fbs.takeSlice(255 * 4);
925 _ = fanout_be_bytes;
926 const object_count = idx_fbs.takeInt(u32, .big);
927 const name_bytes = idx_fbs.takeSlice(object_count * 20);
928 const crc32_bytes = idx_fbs.takeSlice(object_count * 4);
929 _ = crc32_bytes;
930 const offsets_be = idx_fbs.takeIntSlice(u32, object_count);
931 const largeoffsets_be: []align(1) const u64 = @ptrCast(idx_fbs.rest());
932
929933 // std.sort.binarySearch;
930934 const i = bll: {
931935 var low: usize = 0;
......@@ -941,8 +945,11 @@ pub const Repository = struct {
941945 }
942946 continue;
943947 };
944 const pack_offset = std.mem.readInt(u32, offset_bytes[i * 4 ..][0..4], .big);
945 // std.log.debug("found {s} in {s} at offset {d}", .{ oid, idx_path, pack_offset });
948
949 const pack_offset_candidate = @byteSwap(offsets_be[i]);
950 const pack_offset = if (pack_offset_candidate & 0x80000000 == 0) pack_offset_candidate else @byteSwap(largeoffsets_be[pack_offset_candidate & 0x7fffffff]);
951 // std.log.debug("found {s} in {s} at offset {d} {d}", .{ oid, idx_path, pack_offset_candidate, pack_offset });
952
946953 const pack_index = r.pack_content.getIndex(idx_path) orelse clk: {
947954 var pack_path: [128]u8 = @splat(0);
948955 @memcpy(pack_path[0..13], "objects/pack/");
......@@ -980,12 +987,12 @@ pub const Repository = struct {
980987 const packedobj_content = pack_content[pack_offset..];
981988 var packedobj_fbs = nio.FixedBufferStream([]const u8).init(packedobj_content);
982989 const PackedObjType = enum(u3) { none, commit, tree, blob, tag, reserved, ofs_delta, ref_delta };
983 var c: usize = packedobj_fbs.takeByte();
990 var c: usize = packedobj_fbs.takeArray(1)[0];
984991 const ty: PackedObjType = @enumFromInt((c >> 4) & 7);
985992 var size: usize = c & 15;
986993 var shift: u6 = 4;
987994 while (c & 0x80 > 0) {
988 c = packedobj_fbs.takeByte();
995 c = packedobj_fbs.takeArray(1)[0];
989996 size += (c & 0x7f) << shift;
990997 shift += 7;
991998 }
......@@ -1015,7 +1022,7 @@ pub const Repository = struct {
10151022 .ofs_delta => {
10161023 var offset: usize = 0;
10171024 while (true) {
1018 const c2: usize = packedobj_fbs.takeByte();
1025 const c2: usize = packedobj_fbs.takeArray(1)[0];
10191026 offset = (offset << 7) | (c2 & 0x7f);
10201027 if (c2 & 0x80 == 0) break;
10211028 offset += 1;
......@@ -1058,7 +1065,7 @@ pub const Repository = struct {
10581065
10591066 var base_size: usize = 0;
10601067 while (true) {
1061 const c2: usize = unpackedobj_fbs.takeByte();
1068 const c2: usize = unpackedobj_fbs.takeArray(1)[0];
10621069 base_size = (base_size << 7) | (c2 & 0x7f);
10631070 if (c2 & 0x80 == 0) break;
10641071 base_size += 1;
......@@ -1067,7 +1074,7 @@ pub const Repository = struct {
10671074
10681075 var obj_size: usize = 0;
10691076 while (true) {
1070 const c2: usize = unpackedobj_fbs.takeByte();
1077 const c2: usize = unpackedobj_fbs.takeArray(1)[0];
10711078 obj_size = (obj_size << 7) | (c2 & 0x7f);
10721079 if (c2 & 0x80 == 0) break;
10731080 obj_size += 1;
......@@ -1075,13 +1082,13 @@ pub const Repository = struct {
10751082 // std.log.debug("obj_size={d}", .{obj_size});
10761083
10771084 while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) {
1078 const c2 = unpackedobj_fbs.takeByte();
1085 const c2 = unpackedobj_fbs.takeArray(1)[0];
10791086 if (c2 & 0x80 > 0) {
10801087 // copy range from base
10811088 var b: extras.RingBuffer(u8, 7) = .{};
10821089 for (0..7) |i| {
10831090 const mask = @as(u8, 1) << @intCast(i);
1084 b.append(if (c2 & mask > 0) unpackedobj_fbs.takeByte() else 0);
1091 b.append(if (c2 & mask > 0) unpackedobj_fbs.takeArray(1)[0] else 0);
10851092 }
10861093 const start: u32 = @bitCast(b.items[0..4].*);
10871094 var nbytes: u24 = @bitCast(b.items[4..7].*);