| ... | @@ -828,7 +828,8 @@ pub const BlameIterator = struct { | ... | @@ -828,7 +828,8 @@ pub const BlameIterator = struct { |
| 828 | pub const Repository = struct { | 828 | pub const Repository = struct { |
| 829 | gitdir: nfs.Dir, | 829 | gitdir: nfs.Dir, |
| 830 | gpa: std.mem.Allocator, | 830 | gpa: std.mem.Allocator, |
| 831 | unpacked_objects: std.StringArrayHashMapUnmanaged(GitObject), | 831 | unpacked_loose_objects: std.StringArrayHashMapUnmanaged(GitObject), |
| | 832 | unpacked_objects: std.AutoArrayHashMapUnmanaged(u64, GitObject), |
| 832 | idx_content: std.StringArrayHashMapUnmanaged([]const u8), | 833 | idx_content: std.StringArrayHashMapUnmanaged([]const u8), |
| 833 | pack_content: std.StringArrayHashMapUnmanaged([]const u8), | 834 | pack_content: std.StringArrayHashMapUnmanaged([]const u8), |
| 834 | commits: std.StringArrayHashMapUnmanaged(Commit), | 835 | commits: std.StringArrayHashMapUnmanaged(Commit), |
| ... | @@ -839,6 +840,7 @@ pub const Repository = struct { | ... | @@ -839,6 +840,7 @@ pub const Repository = struct { |
| 839 | return .{ | 840 | return .{ |
| 840 | .gitdir = gitdir, | 841 | .gitdir = gitdir, |
| 841 | .gpa = gpa, | 842 | .gpa = gpa, |
| | 843 | .unpacked_loose_objects = .empty, |
| 842 | .unpacked_objects = .empty, | 844 | .unpacked_objects = .empty, |
| 843 | .idx_content = .empty, | 845 | .idx_content = .empty, |
| 844 | .pack_content = .empty, | 846 | .pack_content = .empty, |
| ... | @@ -849,6 +851,8 @@ pub const Repository = struct { | ... | @@ -849,6 +851,8 @@ pub const Repository = struct { |
| 849 | } | 851 | } |
| 850 | | 852 | |
| 851 | pub fn deinit(r: *Repository) void { | 853 | pub fn deinit(r: *Repository) void { |
| | 854 | for (r.unpacked_loose_objects.values()) |v| r.gpa.free(v.content); |
| | 855 | r.unpacked_loose_objects.deinit(r.gpa); |
| 852 | for (r.unpacked_objects.values()) |v| r.gpa.free(v.content); | 856 | for (r.unpacked_objects.values()) |v| r.gpa.free(v.content); |
| 853 | r.unpacked_objects.deinit(r.gpa); | 857 | r.unpacked_objects.deinit(r.gpa); |
| 854 | for (r.idx_content.values()) |v| nfs.munmap(v); | 858 | for (r.idx_content.values()) |v| nfs.munmap(v); |
| ... | @@ -865,7 +869,7 @@ pub const Repository = struct { | ... | @@ -865,7 +869,7 @@ pub const Repository = struct { |
| 865 | const t = tracer.trace(@src(), " {s}", .{oid}); | 869 | const t = tracer.trace(@src(), " {s}", .{oid}); |
| 866 | defer t.end(); | 870 | defer t.end(); |
| 867 | | 871 | |
| 868 | if (r.unpacked_objects.get(oid)) |obj| { | 872 | if (r.unpacked_loose_objects.get(oid)) |obj| { |
| 869 | return obj; | 873 | return obj; |
| 870 | } | 874 | } |
| 871 | if (oid.len == 40) blk: { //sha1 object | 875 | if (oid.len == 40) blk: { //sha1 object |
| ... | @@ -893,7 +897,7 @@ pub const Repository = struct { | ... | @@ -893,7 +897,7 @@ pub const Repository = struct { |
| 893 | const content = try list.toOwnedSlice(r.gpa); | 897 | const content = try list.toOwnedSlice(r.gpa); |
| 894 | std.debug.assert(content.len == content_len); | 898 | std.debug.assert(content.len == content_len); |
| 895 | const obj: GitObject = .{ .type = _type, .content = content }; | 899 | const obj: GitObject = .{ .type = _type, .content = content }; |
| 896 | try r.unpacked_objects.put(r.gpa, oid, obj); | 900 | try r.unpacked_loose_objects.put(r.gpa, oid, obj); |
| 897 | return obj; | 901 | return obj; |
| 898 | } | 902 | } |
| 899 | | 903 | |
| ... | @@ -987,6 +991,9 @@ pub const Repository = struct { | ... | @@ -987,6 +991,9 @@ pub const Repository = struct { |
| 987 | const t = tracer.trace(@src(), " {?s} {d} {d} {s}", .{ maybe_oid, pack_index, pack_offset, r.pack_content.keys()[pack_index] }); | 991 | const t = tracer.trace(@src(), " {?s} {d} {d} {s}", .{ maybe_oid, pack_index, pack_offset, r.pack_content.keys()[pack_index] }); |
| 988 | defer t.end(); | 992 | defer t.end(); |
| 989 | | 993 | |
| | 994 | const key = std.hash.Wyhash.hash(0, &(std.mem.toBytes(pack_index) ++ std.mem.toBytes(pack_offset))); |
| | 995 | if (r.unpacked_objects.get(key)) |o| return o; |
| | 996 | |
| 990 | const pack_content = r.pack_content.values()[pack_index]; | 997 | const pack_content = r.pack_content.values()[pack_index]; |
| 991 | if (!std.mem.eql(u8, pack_content[0..4], "PACK")) return error.InvalidGitPack; | 998 | if (!std.mem.eql(u8, pack_content[0..4], "PACK")) return error.InvalidGitPack; |
| 992 | const pack_version = std.mem.readInt(u32, pack_content[4..][0..4], .big); | 999 | const pack_version = std.mem.readInt(u32, pack_content[4..][0..4], .big); |
| ... | @@ -1024,7 +1031,7 @@ pub const Repository = struct { | ... | @@ -1024,7 +1031,7 @@ pub const Repository = struct { |
| 1024 | const _type = std.meta.stringToEnum(RefType, @tagName(ty)).?; | 1031 | const _type = std.meta.stringToEnum(RefType, @tagName(ty)).?; |
| 1025 | const content = try list.toOwnedSlice(r.gpa); | 1032 | const content = try list.toOwnedSlice(r.gpa); |
| 1026 | const obj: GitObject = .{ .type = _type, .content = content }; | 1033 | const obj: GitObject = .{ .type = _type, .content = content }; |
| 1027 | if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj); | 1034 | try r.unpacked_objects.put(r.gpa, key, obj); |
| 1028 | return obj; | 1035 | return obj; |
| 1029 | }, | 1036 | }, |
| 1030 | .ofs_delta => { | 1037 | .ofs_delta => { |
| ... | @@ -1037,13 +1044,12 @@ pub const Repository = struct { | ... | @@ -1037,13 +1044,12 @@ pub const Repository = struct { |
| 1037 | } | 1044 | } |
| 1038 | const base_pack_offset = pack_offset - offset; | 1045 | const base_pack_offset = pack_offset - offset; |
| 1039 | const base_obj = try r.getPackedObject(arena, null, pack_index, base_pack_offset); | 1046 | const base_obj = try r.getPackedObject(arena, null, pack_index, base_pack_offset); |
| 1040 | defer r.gpa.free(base_obj.content); | 1047 | return r.getDeltadObject(maybe_oid, key, &packedobj_fbs, size, base_obj); |
| 1041 | return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj); | | |
| 1042 | }, | 1048 | }, |
| 1043 | .ref_delta => { | 1049 | .ref_delta => { |
| 1044 | const base_oid = extras.to_hex(packedobj_fbs.takeSlice(20)[0..20].*); | 1050 | const base_oid = extras.to_hex(packedobj_fbs.takeSlice(20)[0..20].*); |
| 1045 | const base_obj = (try r.getObject(arena, &base_oid)).?; | 1051 | const base_obj = (try r.getObject(arena, &base_oid)).?; |
| 1046 | return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj); | 1052 | return r.getDeltadObject(maybe_oid, key, &packedobj_fbs, size, base_obj); |
| 1047 | }, | 1053 | }, |
| 1048 | } | 1054 | } |
| 1049 | comptime unreachable; | 1055 | comptime unreachable; |
| ... | @@ -1055,7 +1061,7 @@ pub const Repository = struct { | ... | @@ -1055,7 +1061,7 @@ pub const Repository = struct { |
| 1055 | } | 1061 | } |
| 1056 | } | 1062 | } |
| 1057 | | 1063 | |
| 1058 | fn getDeltadObject(r: *Repository, maybe_oid: ?Id, packedobj_fbs: *nio.FixedBufferStream([]const u8), size: usize, base_obj: GitObject) !GitObject { | 1064 | fn getDeltadObject(r: *Repository, maybe_oid: ?Id, key: u64, packedobj_fbs: *nio.FixedBufferStream([]const u8), size: usize, base_obj: GitObject) !GitObject { |
| 1059 | const compressed_content = packedobj_fbs.rest(); | 1065 | const compressed_content = packedobj_fbs.rest(); |
| 1060 | var list: std.ArrayListUnmanaged(u8) = .empty; | 1066 | var list: std.ArrayListUnmanaged(u8) = .empty; |
| 1061 | defer list.deinit(r.gpa); | 1067 | defer list.deinit(r.gpa); |
| ... | @@ -1122,7 +1128,10 @@ pub const Repository = struct { | ... | @@ -1122,7 +1128,10 @@ pub const Repository = struct { |
| 1122 | const _type = base_obj.type; | 1128 | const _type = base_obj.type; |
| 1123 | const content = try list2.toOwnedSlice(r.gpa); | 1129 | const content = try list2.toOwnedSlice(r.gpa); |
| 1124 | const obj: GitObject = .{ .type = _type, .content = content }; | 1130 | const obj: GitObject = .{ .type = _type, .content = content }; |
| 1125 | if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj); | 1131 | if (maybe_oid) |oid| |
| | 1132 | try r.unpacked_loose_objects.put(r.gpa, oid, obj) |
| | 1133 | else |
| | 1134 | try r.unpacked_objects.put(r.gpa, key, obj); |
| 1126 | return obj; | 1135 | return obj; |
| 1127 | } | 1136 | } |
| 1128 | | 1137 | |