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 {...@@ -917,15 +917,19 @@ pub const Repository = struct {
917 const t4 = tracer.trace(@src(), " find pack_index/pack_offset", .{});917 const t4 = tracer.trace(@src(), " find pack_index/pack_offset", .{});
918 errdefer t4.end();918 errdefer t4.end();
919 const pack_index, const pack_offset = blk: for (r.idx_content.keys(), r.idx_content.values()) |idx_path, idx_content| {919 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();
922 if (std.mem.startsWith(u8, idx_content, "\xfftOc")) {920 if (std.mem.startsWith(u8, idx_content, "\xfftOc")) {
923 std.debug.assert(std.mem.readInt(u32, idx_content[4..][0..4], .big) == 2);921 var idx_fbs: nio.FixedBufferStream([]const u8) = .init(idx_content);
924 const flfo_table_bytes = idx_content[8..][0 .. 256 * 4];922 _ = idx_fbs.takeSlice(4);
925 const object_count = std.mem.readInt(u32, flfo_table_bytes[255 * 4 ..][0..4], .big);923 std.debug.assert(idx_fbs.takeInt(u32, .big) == 2);
926 const name_bytes = idx_content[8..][1024..][0 .. object_count * 20];924 const fanout_be_bytes = idx_fbs.takeSlice(255 * 4);
927 const crc32_bytes = idx_content[8..][1024..][name_bytes.len..][0 .. object_count * 4];925 _ = fanout_be_bytes;
928 const offset_bytes = idx_content[8..][1024..][name_bytes.len..][crc32_bytes.len..][0 .. object_count * 4];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
929 // std.sort.binarySearch;933 // std.sort.binarySearch;
930 const i = bll: {934 const i = bll: {
931 var low: usize = 0;935 var low: usize = 0;
...@@ -941,8 +945,11 @@ pub const Repository = struct {...@@ -941,8 +945,11 @@ pub const Repository = struct {
941 }945 }
942 continue;946 continue;
943 };947 };
944 const pack_offset = std.mem.readInt(u32, offset_bytes[i * 4 ..][0..4], .big);948
945 // std.log.debug("found {s} in {s} at offset {d}", .{ oid, idx_path, pack_offset });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
946 const pack_index = r.pack_content.getIndex(idx_path) orelse clk: {953 const pack_index = r.pack_content.getIndex(idx_path) orelse clk: {
947 var pack_path: [128]u8 = @splat(0);954 var pack_path: [128]u8 = @splat(0);
948 @memcpy(pack_path[0..13], "objects/pack/");955 @memcpy(pack_path[0..13], "objects/pack/");
...@@ -980,12 +987,12 @@ pub const Repository = struct {...@@ -980,12 +987,12 @@ pub const Repository = struct {
980 const packedobj_content = pack_content[pack_offset..];987 const packedobj_content = pack_content[pack_offset..];
981 var packedobj_fbs = nio.FixedBufferStream([]const u8).init(packedobj_content);988 var packedobj_fbs = nio.FixedBufferStream([]const u8).init(packedobj_content);
982 const PackedObjType = enum(u3) { none, commit, tree, blob, tag, reserved, ofs_delta, ref_delta };989 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];
984 const ty: PackedObjType = @enumFromInt((c >> 4) & 7);991 const ty: PackedObjType = @enumFromInt((c >> 4) & 7);
985 var size: usize = c & 15;992 var size: usize = c & 15;
986 var shift: u6 = 4;993 var shift: u6 = 4;
987 while (c & 0x80 > 0) {994 while (c & 0x80 > 0) {
988 c = packedobj_fbs.takeByte();995 c = packedobj_fbs.takeArray(1)[0];
989 size += (c & 0x7f) << shift;996 size += (c & 0x7f) << shift;
990 shift += 7;997 shift += 7;
991 }998 }
...@@ -1015,7 +1022,7 @@ pub const Repository = struct {...@@ -1015,7 +1022,7 @@ pub const Repository = struct {
1015 .ofs_delta => {1022 .ofs_delta => {
1016 var offset: usize = 0;1023 var offset: usize = 0;
1017 while (true) {1024 while (true) {
1018 const c2: usize = packedobj_fbs.takeByte();1025 const c2: usize = packedobj_fbs.takeArray(1)[0];
1019 offset = (offset << 7) | (c2 & 0x7f);1026 offset = (offset << 7) | (c2 & 0x7f);
1020 if (c2 & 0x80 == 0) break;1027 if (c2 & 0x80 == 0) break;
1021 offset += 1;1028 offset += 1;
...@@ -1058,7 +1065,7 @@ pub const Repository = struct {...@@ -1058,7 +1065,7 @@ pub const Repository = struct {
10581065
1059 var base_size: usize = 0;1066 var base_size: usize = 0;
1060 while (true) {1067 while (true) {
1061 const c2: usize = unpackedobj_fbs.takeByte();1068 const c2: usize = unpackedobj_fbs.takeArray(1)[0];
1062 base_size = (base_size << 7) | (c2 & 0x7f);1069 base_size = (base_size << 7) | (c2 & 0x7f);
1063 if (c2 & 0x80 == 0) break;1070 if (c2 & 0x80 == 0) break;
1064 base_size += 1;1071 base_size += 1;
...@@ -1067,7 +1074,7 @@ pub const Repository = struct {...@@ -1067,7 +1074,7 @@ pub const Repository = struct {
10671074
1068 var obj_size: usize = 0;1075 var obj_size: usize = 0;
1069 while (true) {1076 while (true) {
1070 const c2: usize = unpackedobj_fbs.takeByte();1077 const c2: usize = unpackedobj_fbs.takeArray(1)[0];
1071 obj_size = (obj_size << 7) | (c2 & 0x7f);1078 obj_size = (obj_size << 7) | (c2 & 0x7f);
1072 if (c2 & 0x80 == 0) break;1079 if (c2 & 0x80 == 0) break;
1073 obj_size += 1;1080 obj_size += 1;
...@@ -1075,13 +1082,13 @@ pub const Repository = struct {...@@ -1075,13 +1082,13 @@ pub const Repository = struct {
1075 // std.log.debug("obj_size={d}", .{obj_size});1082 // std.log.debug("obj_size={d}", .{obj_size});
10761083
1077 while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) {1084 while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) {
1078 const c2 = unpackedobj_fbs.takeByte();1085 const c2 = unpackedobj_fbs.takeArray(1)[0];
1079 if (c2 & 0x80 > 0) {1086 if (c2 & 0x80 > 0) {
1080 // copy range from base1087 // copy range from base
1081 var b: extras.RingBuffer(u8, 7) = .{};1088 var b: extras.RingBuffer(u8, 7) = .{};
1082 for (0..7) |i| {1089 for (0..7) |i| {
1083 const mask = @as(u8, 1) << @intCast(i);1090 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);
1085 }1092 }
1086 const start: u32 = @bitCast(b.items[0..4].*);1093 const start: u32 = @bitCast(b.items[0..4].*);
1087 var nbytes: u24 = @bitCast(b.items[4..7].*);1094 var nbytes: u24 = @bitCast(b.items[4..7].*);