authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-11 23:21:26 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-11 23:21:26 -07:00
logbd5f11314b2bb5cb61779e164f1525b5fc8107d9
tree726c4a3cbcf0e7b63e86bf9b68732f99b17c064b
parente0a0f997c9e236ecba67b9ff1e2d498d83f6b39d
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

include reftype in object content cache


1 files changed, 22 insertions(+), 20 deletions(-)

git.zig+22-20
......@@ -975,13 +975,15 @@ pub const BlameIterator = struct {
975975pub const Repository = struct {
976976 gitdir: nfs.Dir,
977977 gpa: std.mem.Allocator,
978 raw_object_contents: std.StringArrayHashMapUnmanaged([]const u8),
978 raw_object_contents: std.StringArrayHashMapUnmanaged(RawObject),
979979 idx_content: std.StringArrayHashMapUnmanaged([]const u8),
980980 pack_content: std.StringArrayHashMapUnmanaged([]const u8),
981981 commits: std.StringArrayHashMapUnmanaged(Commit),
982982 trees: std.StringArrayHashMapUnmanaged(Tree),
983983 tags: std.StringArrayHashMapUnmanaged(Tag),
984984
985 const RawObject = struct { RefType, []const u8 };
986
985987 pub fn init(gitdir: nfs.Dir, gpa: std.mem.Allocator) Repository {
986988 return .{
987989 .gitdir = gitdir,
......@@ -996,7 +998,7 @@ pub const Repository = struct {
996998 }
997999
9981000 pub fn deinit(r: *Repository) void {
999 for (r.raw_object_contents.values()) |v| r.gpa.free(v);
1001 for (r.raw_object_contents.values()) |v| r.gpa.free(v[1]);
10001002 r.raw_object_contents.deinit(r.gpa);
10011003 for (r.idx_content.values()) |v| nfs.munmap(v);
10021004 r.idx_content.deinit(r.gpa);
......@@ -1008,9 +1010,9 @@ pub const Repository = struct {
10081010 r.tags.deinit(r.gpa);
10091011 }
10101012
1011 fn getObject(r: *Repository, obj: Id, arena: std.mem.Allocator) !?[]const u8 {
1012 if (r.raw_object_contents.get(obj)) |content| {
1013 return content;
1013 fn getObject(r: *Repository, obj: Id, arena: std.mem.Allocator) !?RawObject {
1014 if (r.raw_object_contents.get(obj)) |data| {
1015 return data;
10141016 }
10151017 if (obj.len == 40) blk: { //sha1 object
10161018 var sub_path: [49:0]u8 = "objects/00/00000000000000000000000000000000000000".*;
......@@ -1026,9 +1028,16 @@ pub const Repository = struct {
10261028 errdefer list.deinit();
10271029 try list.ensureUnusedCapacity(512);
10281030 try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer());
1031 const data = list.items;
1032 const header = data[0..std.mem.indexOfScalar(u8, data, 0).?];
1033 const _type_s = header[0..std.mem.indexOfScalar(u8, header, ' ').?];
1034 const _type = std.meta.stringToEnum(RefType, _type_s).?;
1035 const content_len = try extras.parseDigits(u64, header[_type_s.len + 1 ..], 10);
1036 list.replaceRangeAssumeCapacity(0, header.len + 1, "");
10291037 const content = try list.toOwnedSlice();
1030 try r.raw_object_contents.put(r.gpa, obj, content);
1031 return content;
1038 std.debug.assert(content.len == content_len);
1039 try r.raw_object_contents.put(r.gpa, obj, .{ _type, content });
1040 return .{ _type, content };
10321041 }
10331042
10341043 // read .idx
......@@ -1092,7 +1101,7 @@ pub const Repository = struct {
10921101 return try r.getPackedObject(obj, pack_index, pack_offset);
10931102 }
10941103
1095 fn getPackedObject(r: *Repository, maybe_obj: ?Id, pack_index: usize, pack_offset: usize) ![]const u8 {
1104 fn getPackedObject(r: *Repository, maybe_obj: ?Id, pack_index: usize, pack_offset: usize) !RawObject {
10961105 const pack_content = r.pack_content.values()[pack_index];
10971106 if (!std.mem.eql(u8, pack_content[0..4], "PACK")) return error.InvalidGitPack;
10981107 const pack_version = std.mem.readInt(u32, pack_content[4..][0..4], .big);
......@@ -1128,12 +1137,11 @@ pub const Repository = struct {
11281137 var list: std.ArrayList(u8) = .init(r.gpa);
11291138 errdefer list.deinit();
11301139 try list.ensureUnusedCapacity(512);
1131 try list.appendSlice(@tagName(ty));
1132 try list.writer().print(" {d}\x00", .{size});
11331140 try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer());
1141 const _type = std.meta.stringToEnum(RefType, @tagName(ty)).?;
11341142 const content = try list.toOwnedSlice();
1135 if (maybe_obj) |obj| try r.raw_object_contents.put(r.gpa, obj, content);
1136 return content;
1143 if (maybe_obj) |obj| try r.raw_object_contents.put(r.gpa, obj, .{ _type, content });
1144 return .{ _type, content };
11371145 },
11381146 .ofs_delta => {
11391147 std.log.debug("type={s} size={d}", .{ @tagName(ty), size });
......@@ -1155,14 +1163,8 @@ pub const Repository = struct {
11551163
11561164 pub fn getGitObject(r: *Repository, arena: std.mem.Allocator, obj: Id) !?GitObject {
11571165 if (try r.getObject(obj, arena)) |data| {
1158 const header = data[0..std.mem.indexOfScalar(u8, data, 0).?];
1159 const _type = header[0..std.mem.indexOfScalar(u8, header, ' ').?];
1160 const content_len = try extras.parseDigits(u64, header[_type.len + 1 ..], 10);
1161 std.debug.assert(data[header.len + 1 ..].len == content_len);
1162 return .{
1163 .type = std.meta.stringToEnum(RefType, _type).?,
1164 .content = try arena.dupe(u8, data[header.len + 1 ..]),
1165 };
1166 const _type, const content = data;
1167 return .{ .type = _type, .content = content };
11661168 }
11671169 return null;
11681170 }