authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-06-27 19:31:01 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-06-27 19:31:01 -07:00
logba166a3a7d614ee1bfd2475460410146666aebb9
treef6d5c5a5d81af0031a16939065ac8c6ae351dfec
parentfc9a0e648f726225767dbf69ed931b3b321a8dcc
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

make Tree own its memory


1 files changed, 25 insertions(+), 15 deletions(-)

git.zig+25-15
...@@ -724,7 +724,7 @@ pub const Repository = struct {...@@ -724,7 +724,7 @@ pub const Repository = struct {
724 idx_content: std.StringArrayHashMapUnmanaged([]const u8),724 idx_content: std.StringArrayHashMapUnmanaged([]const u8),
725 pack_content: std.StringArrayHashMapUnmanaged([]const u8),725 pack_content: std.StringArrayHashMapUnmanaged([]const u8),
726 commits: std.StringArrayHashMapUnmanaged(Commit),726 commits: std.StringArrayHashMapUnmanaged(Commit),
727 trees: std.StringArrayHashMapUnmanaged(Tree),727 trees: std.StringArrayHashMapUnmanaged(*Tree),
728 tags: std.StringArrayHashMapUnmanaged(*Tag),728 tags: std.StringArrayHashMapUnmanaged(*Tag),
729 mailmap: std.hash_map.StringHashMapUnmanaged([]const u8),729 mailmap: std.hash_map.StringHashMapUnmanaged([]const u8),
730 mailmap_names: std.hash_map.StringHashMapUnmanaged([]const u8),730 mailmap_names: std.hash_map.StringHashMapUnmanaged([]const u8),
...@@ -759,7 +759,7 @@ pub const Repository = struct {...@@ -759,7 +759,7 @@ pub const Repository = struct {
759 r.pack_content.deinit(r.gpa);759 r.pack_content.deinit(r.gpa);
760 for (r.commits.values()) |v| r.gpa.free(v.parents);760 for (r.commits.values()) |v| r.gpa.free(v.parents);
761 r.commits.deinit(r.gpa);761 r.commits.deinit(r.gpa);
762 for (r.trees.values()) |*v| r.gpa.free(v.children);762 for (r.trees.values()) |v| v.destroy(r);
763 r.trees.deinit(r.gpa);763 r.trees.deinit(r.gpa);
764 for (r.tags.values()) |v| v.destroy(r);764 for (r.tags.values()) |v| v.destroy(r);
765 r.tags.deinit(r.gpa);765 r.tags.deinit(r.gpa);
...@@ -1125,16 +1125,18 @@ pub const Repository = struct {...@@ -1125,16 +1125,18 @@ pub const Repository = struct {
1125 return (try r.getCommit(.{ .id = id }, cache_behavior)).?.@"1";1125 return (try r.getCommit(.{ .id = id }, cache_behavior)).?.@"1";
1126 }1126 }
11271127
1128 pub fn getTree(r: *Repository, id: TreeId, cache_behavior: CacheBehavior) !?struct { TreeId, Tree } {1128 pub fn getTree(r: *Repository, id: TreeId, cache_behavior: CacheBehavior) !?struct { TreeId, *Tree } {
1129 const t = tracer.trace(@src(), " {s}", .{id.id});1129 const t = tracer.trace(@src(), " {s}", .{id.id});
1130 defer t.end();1130 defer t.end();
11311131
1132 if (cache_behavior == .cache) if (r.trees.getPtr(id.id)) |val| {1132 if (cache_behavior == .cache) if (r.trees.get(id.id)) |val| {
1133 return .{ id, val.* };1133 return .{ id, val };
1134 };1134 };
1135 if (try r.getObject(id.id, cache_behavior)) |obj| {1135 if (try r.getObject(id.id, cache_behavior)) |obj| {
1136 if (obj.type == .tree) {1136 if (obj.type == .tree) {
1137 errdefer if (cache_behavior == .no_cache) r.gpa.free(obj.content);1137 errdefer if (cache_behavior == .no_cache) r.gpa.free(obj.content);
1138 const raw = try r.gpa.dupe(u8, obj.content);
1139 errdefer r.gpa.free(raw);
1138 var children: std.ArrayList(Tree.Object) = .empty;1140 var children: std.ArrayList(Tree.Object) = .empty;
1139 errdefer children.deinit(r.gpa);1141 errdefer children.deinit(r.gpa);
1140 try children.ensureUnusedCapacity(r.gpa, 33);1142 try children.ensureUnusedCapacity(r.gpa, 33);
...@@ -1173,7 +1175,9 @@ pub const Repository = struct {...@@ -1173,7 +1175,9 @@ pub const Repository = struct {
1173 .symlink => .{ .blob = .{ .id = &item.id_bytes } },1175 .symlink => .{ .blob = .{ .id = &item.id_bytes } },
1174 .none => unreachable,1176 .none => unreachable,
1175 };1177 };
1176 const tree: Tree = .{ .raw = obj.content, .children = children_slice };1178 const tree = try r.gpa.create(Tree);
1179 errdefer r.gpa.destroy(tree);
1180 tree.* = .{ .raw = obj.content, .children = children_slice };
1177 if (cache_behavior == .cache) try r.trees.put(r.gpa, id.id, tree);1181 if (cache_behavior == .cache) try r.trees.put(r.gpa, id.id, tree);
1178 return .{ id, tree };1182 return .{ id, tree };
1179 }1183 }
...@@ -1182,7 +1186,7 @@ pub const Repository = struct {...@@ -1182,7 +1186,7 @@ pub const Repository = struct {
1182 return null;1186 return null;
1183 }1187 }
11841188
1185 pub fn getTreeA(r: *Repository, id: Id, cache_behavior: CacheBehavior) !Tree {1189 pub fn getTreeA(r: *Repository, id: Id, cache_behavior: CacheBehavior) !*Tree {
1186 return (try r.getTree(.{ .id = id }, cache_behavior)).?.@"1";1190 return (try r.getTree(.{ .id = id }, cache_behavior)).?.@"1";
1187 }1191 }
11881192
...@@ -1190,8 +1194,8 @@ pub const Repository = struct {...@@ -1190,8 +1194,8 @@ pub const Repository = struct {
1190 const t = tracer.trace(@src(), " {s}", .{id.id});1194 const t = tracer.trace(@src(), " {s}", .{id.id});
1191 defer t.end();1195 defer t.end();
11921196
1193 if (cache_behavior == .cache) if (r.tags.getPtr(id.id)) |val| {1197 if (cache_behavior == .cache) if (r.tags.get(id.id)) |val| {
1194 return .{ id, val.* };1198 return .{ id, val };
1195 };1199 };
1196 if (try r.getObject(id.id, cache_behavior)) |obj| {1200 if (try r.getObject(id.id, cache_behavior)) |obj| {
1197 if (obj.type == .tag) {1201 if (obj.type == .tag) {
...@@ -1719,7 +1723,13 @@ pub const Tree = struct {...@@ -1719,7 +1723,13 @@ pub const Tree = struct {
1719 raw: []const u8,1723 raw: []const u8,
1720 children: []const Object,1724 children: []const Object,
17211725
1722 pub fn get(self: Tree, name: string) ?Object {1726 pub fn destroy(t: *Tree, r: *Repository) void {
1727 r.gpa.free(t.children);
1728 r.gpa.free(t.raw);
1729 r.gpa.destroy(t);
1730 }
1731
1732 pub fn get(self: *Tree, name: string) ?Object {
1723 // modified std.sort.binarySearch1733 // modified std.sort.binarySearch
1724 const i = blk: {1734 const i = blk: {
1725 var low: usize = 0;1735 var low: usize = 0;
...@@ -1749,13 +1759,13 @@ pub const Tree = struct {...@@ -1749,13 +1759,13 @@ pub const Tree = struct {
1749 return self.children[i];1759 return self.children[i];
1750 }1760 }
17511761
1752 pub fn getBlob(self: Tree, name: string, hint: Object.Type) ?Object {1762 pub fn getBlob(self: *Tree, name: string, hint: Object.Type) ?Object {
1753 const o = self.get(name, hint) orelse return null;1763 const o = self.get(name, hint) orelse return null;
1754 if (o.id != .blob) return null;1764 if (o.id != .blob) return null;
1755 return o;1765 return o;
1756 }1766 }
17571767
1758 pub fn find(self: Tree, name: string) ?Object {1768 pub fn find(self: *Tree, name: string) ?Object {
1759 for (self.children, 0..) |item, i| {1769 for (self.children, 0..) |item, i| {
1760 if (std.ascii.eqlIgnoreCase(item.name, name)) {1770 if (std.ascii.eqlIgnoreCase(item.name, name)) {
1761 return self.children[i];1771 return self.children[i];
...@@ -1764,7 +1774,7 @@ pub const Tree = struct {...@@ -1764,7 +1774,7 @@ pub const Tree = struct {
1764 return null;1774 return null;
1765 }1775 }
17661776
1767 pub fn findBlob(self: Tree, name: string) ?Object {1777 pub fn findBlob(self: *Tree, name: string) ?Object {
1768 const o = self.find(name) orelse return null;1778 const o = self.find(name) orelse return null;
1769 if (o.id != .blob) return null;1779 if (o.id != .blob) return null;
1770 return o;1780 return o;
...@@ -1929,7 +1939,7 @@ pub const Tree = struct {...@@ -1929,7 +1939,7 @@ pub const Tree = struct {
1929 };1939 };
1930 };1940 };
19311941
1932 pub fn walk(self: Tree, r: *Repository) !Walker {1942 pub fn walk(self: *Tree, r: *Repository) !Walker {
1933 var stack: std.ArrayListUnmanaged(Walker.StackItem) = .empty;1943 var stack: std.ArrayListUnmanaged(Walker.StackItem) = .empty;
19341944
1935 try stack.append(r.gpa, .{1945 try stack.append(r.gpa, .{
...@@ -1955,7 +1965,7 @@ pub const Tree = struct {...@@ -1955,7 +1965,7 @@ pub const Tree = struct {
1955 };1965 };
19561966
1957 const StackItem = struct {1967 const StackItem = struct {
1958 tree: Tree,1968 tree: *Tree,
1959 idx: usize,1969 idx: usize,
1960 dirname_len: usize,1970 dirname_len: usize,
1961 };1971 };