╭ changed ────────────╮ │src/search_commit.zig│ ╰─────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 60 │ │ 61 fn docKeyLen(comptime hash_kind: hash.HashKind) usize { │ │ 62 return @sizeOf(u64) + hash.byteLen(hash_kind); │ │ 63 -} │ │ 64 - │ │ 65 -// the action a commit index refresh records when it runs on its own │ │ 66 -pub const undo_action = "haxy/commit-index"; │ │ 67 - │ │ 68 -// reconcile the index versions with the repo's ref tips, in a transaction of │ │ 69 -// its own │ │ 70 -pub fn refresh( │ │ 71 - comptime repo_opts: rp.RepoOpts(.xit), │ │ 72 - io: std.Io, │ │ 73 - allocator: std.mem.Allocator, │ │ 74 - repo: *rp.Repo(.xit, repo_opts), │ │ 75 -) !void { │ │ 76 - const Repo = rp.Repo(.xit, repo_opts); │ │ 77 - const DB = Repo.DB; │ │ 78 - const Save = struct { │ │ 79 - core: *Repo.Core, │ │ 80 - io: std.Io, │ │ 81 - allocator: std.mem.Allocator, │ │ 82 - │ │ 83 - pub fn run(ctx: @This(), cursor: *DB.Cursor(.read_write)) !void { │ │ 84 - var moment = try DB.HashMap(.read_write).init(cursor.*); │ │ 85 - const state = Repo.State(.read_write){ .core = ctx.core, .extra = .{ .moment = &moment } }; │ │ 86 - if (!try refreshInTransaction(repo_opts, state, &moment, ctx.io, ctx.allocator, &.{}, null)) return error.CancelTransaction; │ │ 87 - │ │ 88 - // record the user action for undo │ │ 89 - try xit.undo.write(repo_opts, state, std.Io.Timestamp.now(ctx.io, .real).toSeconds(), .{ .custom = .{ .action_kind = undo_action } }); │ │ 90 - } │ │ 91 - }; │ │ 92 - │ │ 93 - // held across the reads and the writes, so a concurrent refresh can't │ │ 94 - // change the entries these decisions were made from. │ │ 95 - try repo.core.db_file.lock(io, .exclusive); │ │ 96 - defer repo.core.db_file.unlock(io); │ │ 97 - │ │ 98 - const history = try DB.ArrayList(.read_write).init(repo.core.db.rootCursor()); │ │ 99 - history.appendContext(.{ .slot = try history.getSlot(-1) }, Save{ .core = &repo.core, .io = io, .allocator = allocator }) catch |err| switch (err) {│ │100 - error.CancelTransaction => {}, │ │101 - else => return err, │ │102 - }; │ │ 63 } │ │ 64 │ │ 65 // reconcile them inside the caller's transaction, so the index lands with the │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │323 var object = try obj.Object(.xit, repo_opts).init(state, io, allocator, entry.key_ptr); │ │324 defer object.deinit(); │ │325 const key = try readPosting(repo_opts, allocator, &message, &object); │ │366 - if (flags == Ancestry.one) { │ │367 - try srch.remove(DB, version, allocator, &key, message.items); │ │368 - } else { │ │369 - try srch.add(DB, version, allocator, &key, message.items); │ │370 - } │ │326 + const removed = flags == Ancestry.one; │ │327 + try srch.replace(DB, version, allocator, &key, if (removed) message.items else "", if (removed) "" else message.items);│ │328 } │ │329 progress.report(repo_opts, io, progress_ctx_maybe, .{ .end = .writing_patch }); │ │330 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │331 │ │332 // index every commit `tip` reaches into an empty `version`, as the walk │ │376 -// reaches it │ │333 +// reaches it. │ │334 +// TODO: the walk holds every visited oid in memory. if that proves too costly│ │335 +// for large repositories, consider indexing first-parent history only, which │ │336 +// needs no visited set and matches the commits list. │ │337 fn indexHistory( │ │338 comptime repo_opts: rp.RepoOpts(.xit), │ │339 state: rp.Repo(.xit, repo_opts).State(.read_only), │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │359 defer object.deinit(); │ │360 if (progress.cancelled(repo_opts, progress_ctx_maybe)) return error.ClientGone; │ │361 const key = try readPosting(repo_opts, allocator, &message, object); │ │402 - try srch.add(DB, version, allocator, &key, message.items); │ │362 + try srch.replace(DB, version, allocator, &key, "", message.items); │ │363 progress.report(repo_opts, io, progress_ctx_maybe, .{ .complete_one = .writing_patch });│ │364 } │ │365 progress.report(repo_opts, io, progress_ctx_maybe, .{ .end = .writing_patch }); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯