authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-12 22:26:40 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-12 22:26:40 -07:00
logc75a9bfb2d1523607ab3f3d676ce747a2f897a59
tree5f936c5616f79fb23debc358b46e86470b23858c
parentb955d30521e39514d57dd08ad666ea24425dd7b6
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

dry up a bit with getDeltadObject


1 files changed, 71 insertions(+), 132 deletions(-)

git.zig+71-132
...@@ -1098,143 +1098,14 @@ pub const Repository = struct {...@@ -1098,143 +1098,14 @@ pub const Repository = struct {
1098 const base_pack_offset = pack_offset - offset;1098 const base_pack_offset = pack_offset - offset;
1099 const base_obj = try r.getPackedObject(arena, null, pack_index, base_pack_offset);1099 const base_obj = try r.getPackedObject(arena, null, pack_index, base_pack_offset);
1100 // std.log.debug("base: type={s} content=[{d}]", .{ @tagName(base_obj.type), base_obj.content.len });1100 // std.log.debug("base: type={s} content=[{d}]", .{ @tagName(base_obj.type), base_obj.content.len });
11011101 return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj);
1102 const compressed_content = packedobj_fbs.rest()[0..size];
1103 var bufr = nio.FixedBufferStream([]const u8).init(compressed_content);
1104
1105 var list: std.ArrayListUnmanaged(u8) = .empty;
1106 defer list.deinit(r.gpa);
1107 try list.ensureUnusedCapacity(r.gpa, size);
1108 try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer(r.gpa));
1109 // std.log.debug("transformation data={d}", .{list.items});
1110
1111 var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items);
1112
1113 var list2: std.ArrayListUnmanaged(u8) = .empty;
1114 errdefer list2.deinit(r.gpa);
1115
1116 var base_size: usize = 0;
1117 while (true) {
1118 const c2: usize = unpackedobj_fbs.takeByte();
1119 base_size = (base_size << 7) | (c2 & 0x7f);
1120 if (c2 & 0x80 == 0) break;
1121 base_size += 1;
1122 }
1123 // std.log.debug("base_size={d}", .{base_size});
1124
1125 var obj_size: usize = 0;
1126 while (true) {
1127 const c2: usize = unpackedobj_fbs.takeByte();
1128 obj_size = (obj_size << 7) | (c2 & 0x7f);
1129 if (c2 & 0x80 == 0) break;
1130 obj_size += 1;
1131 }
1132 // std.log.debug("obj_size={d}", .{obj_size});
1133
1134 while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) {
1135 const c2 = unpackedobj_fbs.takeByte();
1136 if (c2 & 0x80 > 0) {
1137 // copy range from base
1138 var b: extras.RingBuffer(u8, 7) = .{};
1139 for (0..7) |i| {
1140 const mask = @as(u8, 1) << @intCast(i);
1141 b.append(if (c2 & mask > 0) unpackedobj_fbs.takeByte() else 0);
1142 }
1143 const start: u32 = @bitCast(b.items[0..4].*);
1144 const nbytes: u24 = @bitCast(b.items[4..7].*);
1145 // std.log.debug("- copy from base: start={d} nbytes={d}", .{ start, nbytes });
1146 const bytes = base_obj.content[start..][0..nbytes];
1147 // std.log.debug("{s}\n", .{bytes});
1148 try list2.appendSlice(r.gpa, bytes);
1149 } else {
1150 // append new data
1151 const nbytes = c2 & 0x7f;
1152 // std.log.debug("- append new bytes={d}", .{nbytes});
1153 if (nbytes == 0) continue;
1154 const bytes = unpackedobj_fbs.takeSlice(nbytes);
1155 // std.log.debug("{s}\n", .{bytes});
1156 try list2.appendSlice(r.gpa, bytes);
1157 }
1158 }
1159
1160 // std.log.debug("- done", .{});
1161 // std.log.debug("{s}\n", .{list2.items});
1162 const _type = base_obj.type;
1163 const content = try list2.toOwnedSlice(r.gpa);
1164 const obj: GitObject = .{ .type = _type, .content = content };
1165 if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj);
1166 return obj;
1167 },1102 },
1168 .ref_delta => {1103 .ref_delta => {
1169 // std.log.debug("type={s} size={d}", .{ @tagName(ty), size });1104 // std.log.debug("type={s} size={d}", .{ @tagName(ty), size });
1170 const base_oid = extras.to_hex(packedobj_fbs.takeSlice(20)[0..20].*);1105 const base_oid = extras.to_hex(packedobj_fbs.takeSlice(20)[0..20].*);
1171 const base_obj = (try r.getObject(arena, &base_oid)).?;1106 const base_obj = (try r.getObject(arena, &base_oid)).?;
11721107 // std.log.debug("base: type={s} content=[{d}]", .{ @tagName(base_obj.type), base_obj.content.len });
1173 const compressed_content = packedobj_fbs.rest()[0..size];1108 return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj);
1174 var bufr = nio.FixedBufferStream([]const u8).init(compressed_content);
1175
1176 var list: std.ArrayListUnmanaged(u8) = .empty;
1177 defer list.deinit(r.gpa);
1178 try list.ensureUnusedCapacity(r.gpa, size);
1179 try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer(r.gpa));
1180 // std.log.debug("transformation data={d}", .{list.items});
1181
1182 var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items);
1183
1184 var list2: std.ArrayListUnmanaged(u8) = .empty;
1185 errdefer list2.deinit(r.gpa);
1186
1187 var base_size: usize = 0;
1188 while (true) {
1189 const c2: usize = unpackedobj_fbs.takeByte();
1190 base_size = (base_size << 7) | (c2 & 0x7f);
1191 if (c2 & 0x80 == 0) break;
1192 base_size += 1;
1193 }
1194 // std.log.debug("base_size={d}", .{base_size});
1195
1196 var obj_size: usize = 0;
1197 while (true) {
1198 const c2: usize = unpackedobj_fbs.takeByte();
1199 obj_size = (obj_size << 7) | (c2 & 0x7f);
1200 if (c2 & 0x80 == 0) break;
1201 obj_size += 1;
1202 }
1203 // std.log.debug("obj_size={d}", .{obj_size});
1204
1205 while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) {
1206 const c2 = unpackedobj_fbs.takeByte();
1207 if (c2 & 0x80 > 0) {
1208 // copy range from base
1209 var b: extras.RingBuffer(u8, 7) = .{};
1210 for (0..7) |i| {
1211 const mask = @as(u8, 1) << @intCast(i);
1212 b.append(if (c2 & mask > 0) unpackedobj_fbs.takeByte() else 0);
1213 }
1214 const start: u32 = @bitCast(b.items[0..4].*);
1215 const nbytes: u24 = @bitCast(b.items[4..7].*);
1216 // std.log.debug("- copy from base: start={d} nbytes={d}", .{ start, nbytes });
1217 const bytes = base_obj.content[start..][0..nbytes];
1218 // std.log.debug("{s}\n", .{bytes});
1219 try list2.appendSlice(r.gpa, bytes);
1220 } else {
1221 // append new data
1222 const nbytes = c2 & 0x7f;
1223 // std.log.debug("- append new bytes={d}", .{nbytes});
1224 if (nbytes == 0) continue;
1225 const bytes = unpackedobj_fbs.takeSlice(nbytes);
1226 // std.log.debug("{s}\n", .{bytes});
1227 try list2.appendSlice(r.gpa, bytes);
1228 }
1229 }
1230
1231 // std.log.debug("- done", .{});
1232 // std.log.debug("{s}\n", .{list2.items});
1233 const _type = base_obj.type;
1234 const content = try list2.toOwnedSlice(r.gpa);
1235 const obj: GitObject = .{ .type = _type, .content = content };
1236 if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj);
1237 return obj;
1238 },1109 },
1239 }1110 }
1240 comptime unreachable;1111 comptime unreachable;
...@@ -1246,6 +1117,74 @@ pub const Repository = struct {...@@ -1246,6 +1117,74 @@ pub const Repository = struct {
1246 }1117 }
1247 }1118 }
12481119
1120 fn getDeltadObject(r: *Repository, maybe_oid: ?Id, packedobj_fbs: *nio.FixedBufferStream([]const u8), size: usize, base_obj: GitObject) !GitObject {
1121 const compressed_content = packedobj_fbs.rest()[0..size];
1122 var bufr = nio.FixedBufferStream([]const u8).init(compressed_content);
1123
1124 var list: std.ArrayListUnmanaged(u8) = .empty;
1125 defer list.deinit(r.gpa);
1126 try list.ensureUnusedCapacity(r.gpa, size);
1127 try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer(r.gpa));
1128 // std.log.debug("transformation data={d}", .{list.items});
1129
1130 var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items);
1131
1132 var list2: std.ArrayListUnmanaged(u8) = .empty;
1133 errdefer list2.deinit(r.gpa);
1134
1135 var base_size: usize = 0;
1136 while (true) {
1137 const c2: usize = unpackedobj_fbs.takeByte();
1138 base_size = (base_size << 7) | (c2 & 0x7f);
1139 if (c2 & 0x80 == 0) break;
1140 base_size += 1;
1141 }
1142 // std.log.debug("base_size={d}", .{base_size});
1143
1144 var obj_size: usize = 0;
1145 while (true) {
1146 const c2: usize = unpackedobj_fbs.takeByte();
1147 obj_size = (obj_size << 7) | (c2 & 0x7f);
1148 if (c2 & 0x80 == 0) break;
1149 obj_size += 1;
1150 }
1151 // std.log.debug("obj_size={d}", .{obj_size});
1152
1153 while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) {
1154 const c2 = unpackedobj_fbs.takeByte();
1155 if (c2 & 0x80 > 0) {
1156 // copy range from base
1157 var b: extras.RingBuffer(u8, 7) = .{};
1158 for (0..7) |i| {
1159 const mask = @as(u8, 1) << @intCast(i);
1160 b.append(if (c2 & mask > 0) unpackedobj_fbs.takeByte() else 0);
1161 }
1162 const start: u32 = @bitCast(b.items[0..4].*);
1163 const nbytes: u24 = @bitCast(b.items[4..7].*);
1164 // std.log.debug("- copy from base: start={d} nbytes={d}", .{ start, nbytes });
1165 const bytes = base_obj.content[start..][0..nbytes];
1166 // std.log.debug("{s}\n", .{bytes});
1167 try list2.appendSlice(r.gpa, bytes);
1168 } else {
1169 // append new data
1170 const nbytes = c2 & 0x7f;
1171 // std.log.debug("- append new bytes={d}", .{nbytes});
1172 if (nbytes == 0) continue;
1173 const bytes = unpackedobj_fbs.takeSlice(nbytes);
1174 // std.log.debug("{s}\n", .{bytes});
1175 try list2.appendSlice(r.gpa, bytes);
1176 }
1177 }
1178
1179 // std.log.debug("- done", .{});
1180 // std.log.debug("{s}\n", .{list2.items});
1181 const _type = base_obj.type;
1182 const content = try list2.toOwnedSlice(r.gpa);
1183 const obj: GitObject = .{ .type = _type, .content = content };
1184 if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj);
1185 return obj;
1186 }
1187
1249 const GitObject = struct {1188 const GitObject = struct {
1250 type: RefType,1189 type: RefType,
1251 content: []const u8,1190 content: []const u8,