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 {
12701270 defer commit_id_prev = commit_id;
12711271 commit = commit_idx.reify(r);
12721272 const new_tree_id = try traverseTo(r, arena, commit.tree, dir_path) orelse {
1273 for (result.keys(), 0..) |k, i| {
1274 if (set.isSet(i)) continue;
1273 var i: usize = 0;
1274 while (findFirstUnset(set, i)) |j| : (i += 1) {
1275 i = j;
1276 const k = result.keys()[i];
12751277 found += 1;
12761278 result.putAssumeCapacity(k, commit_id_prev);
12771279 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 });
12791281 continue;
12801282 }
12811283 break;
......@@ -1283,21 +1285,23 @@ pub const Repository = struct {
12831285 if (new_tree_id.eql(tree_id)) continue;
12841286 tree_id = new_tree_id;
12851287 const tree = try r.getTreeA(arena, tree_id.id);
1286 for (result.keys(), 0..) |k, i| {
1287 if (set.isSet(i)) continue;
1288 var i: usize = 0;
1289 while (findFirstUnset(set, i)) |j| : (i += 1) {
1290 i = j;
1291 const k = result.keys()[i];
12881292 const new = tree.get(k, base_tree.children[i].mode.type);
12891293 if (new == null) {
12901294 found += 1;
12911295 result.putAssumeCapacity(k, commit_id_prev);
12921296 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 });
12941298 continue;
12951299 }
12961300 if (!std.mem.eql(u8, new.?.id.erase(), base_tree.children[i].id.erase())) {
12971301 found += 1;
12981302 result.putAssumeCapacity(k, commit_id_prev);
12991303 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 });
13011305 continue;
13021306 }
13031307 }
......@@ -1646,3 +1650,19 @@ pub const Ref = struct {
16461650 oid: Id,
16471651 label: string,
16481652};
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}