authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-06-14 18:49:15 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-06-14 18:49:15 -07:00
log562f0437847c3f643525d07f5a283cf17c415522
tree7e288c9dbd1e8088707e949e2fffc3a53c4c1cdf
parentf0621c440300a072e2da9b9925b4049228c20ad8
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

getTree: use findFirstUnset


1 files changed, 27 insertions(+), 7 deletions(-)

git.zig+27-7
...@@ -1270,12 +1270,14 @@ pub const Repository = struct {...@@ -1270,12 +1270,14 @@ pub const Repository = struct {
1270 defer commit_id_prev = commit_id;1270 defer commit_id_prev = commit_id;
1271 commit = commit_idx.reify(r);1271 commit = commit_idx.reify(r);
1272 const new_tree_id = try traverseTo(r, arena, commit.tree, dir_path) orelse {1272 const new_tree_id = try traverseTo(r, arena, commit.tree, dir_path) orelse {
1273 for (result.keys(), 0..) |k, i| {1273 var i: usize = 0;
1274 if (set.isSet(i)) continue;1274 while (findFirstUnset(set, i)) |j| : (i += 1) {
1275 i = j;
1276 const k = result.keys()[i];
1275 found += 1;1277 found += 1;
1276 result.putAssumeCapacity(k, commit_id_prev);1278 result.putAssumeCapacity(k, commit_id_prev);
1277 set.set(i);1279 set.set(i);
1278 // std.log.debug("found [{d}/{d}] objects after searching {d} commits", .{ found, total, searched });1280 // std.log.debug("found [{d}/{d}] objects after searching {d} commits, found {s}", .{ found, total, searched, k });
1279 continue;1281 continue;
1280 }1282 }
1281 break;1283 break;
...@@ -1283,21 +1285,23 @@ pub const Repository = struct {...@@ -1283,21 +1285,23 @@ pub const Repository = struct {
1283 if (new_tree_id.eql(tree_id)) continue;1285 if (new_tree_id.eql(tree_id)) continue;
1284 tree_id = new_tree_id;1286 tree_id = new_tree_id;
1285 const tree = try r.getTreeA(arena, tree_id.id);1287 const tree = try r.getTreeA(arena, tree_id.id);
1286 for (result.keys(), 0..) |k, i| {1288 var i: usize = 0;
1287 if (set.isSet(i)) continue;1289 while (findFirstUnset(set, i)) |j| : (i += 1) {
1290 i = j;
1291 const k = result.keys()[i];
1288 const new = tree.get(k, base_tree.children[i].mode.type);1292 const new = tree.get(k, base_tree.children[i].mode.type);
1289 if (new == null) {1293 if (new == null) {
1290 found += 1;1294 found += 1;
1291 result.putAssumeCapacity(k, commit_id_prev);1295 result.putAssumeCapacity(k, commit_id_prev);
1292 set.set(i);1296 set.set(i);
1293 // std.log.debug("found [{d}/{d}] objects after searching {d} commits", .{ found, total, searched });1297 // std.log.debug("found [{d}/{d}] objects after searching {d} commits, at {d} found {s}", .{ found, total, searched, i, k });
1294 continue;1298 continue;
1295 }1299 }
1296 if (!std.mem.eql(u8, new.?.id.erase(), base_tree.children[i].id.erase())) {1300 if (!std.mem.eql(u8, new.?.id.erase(), base_tree.children[i].id.erase())) {
1297 found += 1;1301 found += 1;
1298 result.putAssumeCapacity(k, commit_id_prev);1302 result.putAssumeCapacity(k, commit_id_prev);
1299 set.set(i);1303 set.set(i);
1300 // std.log.debug("found [{d}/{d}] objects after searching {d} commits", .{ found, total, searched });1304 // std.log.debug("found [{d}/{d}] objects after searching {d} commits, at {d} found {s}", .{ found, total, searched, i, k });
1301 continue;1305 continue;
1302 }1306 }
1303 }1307 }
...@@ -1646,3 +1650,19 @@ pub const Ref = struct {...@@ -1646,3 +1650,19 @@ pub const Ref = struct {
1646 oid: Id,1650 oid: Id,
1647 label: string,1651 label: string,
1648};1652};
1653
1654pub fn findFirstUnset(set: std.bit_set.DynamicBitSetUnmanaged, after: usize) ?usize {
1655 const MaskInt = std.bit_set.DynamicBitSetUnmanaged.MaskInt;
1656 if (after >= set.bit_length) return null;
1657 if (!set.isSet(after)) return after;
1658 var maski = after / @bitSizeOf(MaskInt);
1659 while (set.masks[maski] == std.math.maxInt(MaskInt)) maski += 1;
1660 var mask = set.masks[maski];
1661 mask |= (@as(usize, 1) << @intCast((after -| (maski * @bitSizeOf(MaskInt))) % @bitSizeOf(MaskInt))) - 1;
1662 if (mask == std.math.maxInt(MaskInt)) maski += 1;
1663 while (set.masks[maski] == std.math.maxInt(MaskInt)) maski += 1;
1664 if (mask == std.math.maxInt(MaskInt)) mask = set.masks[maski];
1665 const candidate = maski * @bitSizeOf(MaskInt) + @ctz(~mask);
1666 if (candidate >= set.bit_length) return null;
1667 return candidate;
1668}