| ... | ... | @@ -1098,143 +1098,14 @@ pub const Repository = struct { |
| 1098 | 1098 | const base_pack_offset = pack_offset - offset; |
| 1099 | 1099 | const base_obj = try r.getPackedObject(arena, null, pack_index, base_pack_offset); |
| 1100 | 1100 | // std.log.debug("base: type={s} content=[{d}]", .{ @tagName(base_obj.type), base_obj.content.len }); |
| 1101 | | |
| 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; |
| 1101 | return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj); |
| 1167 | 1102 | }, |
| 1168 | 1103 | .ref_delta => { |
| 1169 | 1104 | // std.log.debug("type={s} size={d}", .{ @tagName(ty), size }); |
| 1170 | 1105 | const base_oid = extras.to_hex(packedobj_fbs.takeSlice(20)[0..20].*); |
| 1171 | 1106 | const base_obj = (try r.getObject(arena, &base_oid)).?; |
| 1172 | | |
| 1173 | | const compressed_content = packedobj_fbs.rest()[0..size]; |
| 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; |
| 1107 | // std.log.debug("base: type={s} content=[{d}]", .{ @tagName(base_obj.type), base_obj.content.len }); |
| 1108 | return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj); |
| 1238 | 1109 | }, |
| 1239 | 1110 | } |
| 1240 | 1111 | comptime unreachable; |
| ... | ... | @@ -1246,6 +1117,74 @@ pub const Repository = struct { |
| 1246 | 1117 | } |
| 1247 | 1118 | } |
| 1248 | 1119 | |
| 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 | 1188 | const GitObject = struct { |
| 1250 | 1189 | type: RefType, |
| 1251 | 1190 | content: []const u8, |