authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-20 17:46:26 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-20 17:46:26 -07:00
log0099e96f6f35c65569d8370c617640503d48edbb
tree0c9c9fe157cd9dba332e299878cd6005045597f6
parent52d3c1ee59c734fa12302409e2b4531af05b8ae8
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

cache ofs_delta objects too


1 files changed, 18 insertions(+), 9 deletions(-)

git.zig+18-9
......@@ -828,7 +828,8 @@ pub const BlameIterator = struct {
828828pub const Repository = struct {
829829 gitdir: nfs.Dir,
830830 gpa: std.mem.Allocator,
831 unpacked_objects: std.StringArrayHashMapUnmanaged(GitObject),
831 unpacked_loose_objects: std.StringArrayHashMapUnmanaged(GitObject),
832 unpacked_objects: std.AutoArrayHashMapUnmanaged(u64, GitObject),
832833 idx_content: std.StringArrayHashMapUnmanaged([]const u8),
833834 pack_content: std.StringArrayHashMapUnmanaged([]const u8),
834835 commits: std.StringArrayHashMapUnmanaged(Commit),
......@@ -839,6 +840,7 @@ pub const Repository = struct {
839840 return .{
840841 .gitdir = gitdir,
841842 .gpa = gpa,
843 .unpacked_loose_objects = .empty,
842844 .unpacked_objects = .empty,
843845 .idx_content = .empty,
844846 .pack_content = .empty,
......@@ -849,6 +851,8 @@ pub const Repository = struct {
849851 }
850852
851853 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);
852856 for (r.unpacked_objects.values()) |v| r.gpa.free(v.content);
853857 r.unpacked_objects.deinit(r.gpa);
854858 for (r.idx_content.values()) |v| nfs.munmap(v);
......@@ -865,7 +869,7 @@ pub const Repository = struct {
865869 const t = tracer.trace(@src(), " {s}", .{oid});
866870 defer t.end();
867871
868 if (r.unpacked_objects.get(oid)) |obj| {
872 if (r.unpacked_loose_objects.get(oid)) |obj| {
869873 return obj;
870874 }
871875 if (oid.len == 40) blk: { //sha1 object
......@@ -893,7 +897,7 @@ pub const Repository = struct {
893897 const content = try list.toOwnedSlice(r.gpa);
894898 std.debug.assert(content.len == content_len);
895899 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);
897901 return obj;
898902 }
899903
......@@ -987,6 +991,9 @@ pub const Repository = struct {
987991 const t = tracer.trace(@src(), " {?s} {d} {d} {s}", .{ maybe_oid, pack_index, pack_offset, r.pack_content.keys()[pack_index] });
988992 defer t.end();
989993
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
990997 const pack_content = r.pack_content.values()[pack_index];
991998 if (!std.mem.eql(u8, pack_content[0..4], "PACK")) return error.InvalidGitPack;
992999 const pack_version = std.mem.readInt(u32, pack_content[4..][0..4], .big);
......@@ -1024,7 +1031,7 @@ pub const Repository = struct {
10241031 const _type = std.meta.stringToEnum(RefType, @tagName(ty)).?;
10251032 const content = try list.toOwnedSlice(r.gpa);
10261033 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);
10281035 return obj;
10291036 },
10301037 .ofs_delta => {
......@@ -1037,13 +1044,12 @@ pub const Repository = struct {
10371044 }
10381045 const base_pack_offset = pack_offset - offset;
10391046 const base_obj = try r.getPackedObject(arena, null, pack_index, base_pack_offset);
1040 defer r.gpa.free(base_obj.content);
1041 return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj);
1047 return r.getDeltadObject(maybe_oid, key, &packedobj_fbs, size, base_obj);
10421048 },
10431049 .ref_delta => {
10441050 const base_oid = extras.to_hex(packedobj_fbs.takeSlice(20)[0..20].*);
10451051 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);
10471053 },
10481054 }
10491055 comptime unreachable;
......@@ -1055,7 +1061,7 @@ pub const Repository = struct {
10551061 }
10561062 }
10571063
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 {
10591065 const compressed_content = packedobj_fbs.rest();
10601066 var list: std.ArrayListUnmanaged(u8) = .empty;
10611067 defer list.deinit(r.gpa);
......@@ -1122,7 +1128,10 @@ pub const Repository = struct {
11221128 const _type = base_obj.type;
11231129 const content = try list2.toOwnedSlice(r.gpa);
11241130 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);
11261135 return obj;
11271136 }
11281137