| ... | @@ -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 | |
| | 1654 | pub 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 | } |