Skip to content

Batch per-id DELETE in PurgeStaleFiles into chunked IN clauses #1826

Description

@Widthdom

Summary

PurgeStaleFiles, PurgeFilesOutsideRetainedSet, and the related cleanup routines in DbWriter.cs:588-595, 628-635, 685-693 iterate the stale-id list and execute one DELETE per id. On large purges (e.g. ripping out 5000 stale entries after a git checkout of an unrelated branch), this is 5000 separate round-trips, each acquiring and releasing the WAL write lock. Round-trip cost dominates; one DELETE FROM files WHERE id IN (...) in chunks of ~500 ids would collapse this to ~10 statements with one lock acquisition each.

Where

  • src/CodeIndex/Database/DbWriter.cs:588-595 (PurgeStaleFiles loop)
  • src/CodeIndex/Database/DbWriter.cs:628-635 (PurgeFilesOutsideRetainedSet)
  • src/CodeIndex/Database/DbWriter.cs:685-693 (additional purge site)

Suggested approach

(1) Introduce a DeleteFilesByIdBatched(IReadOnlyList<long> ids, int chunkSize = 500) helper that issues DELETE FROM files WHERE id IN (?, ?, ...) per chunk, reusing prepared statements where possible. (2) Apply the helper at all three call sites. (3) Wrap the batched deletes in a single transaction so cascading deletes (symbols, references, chunks) commit atomically with the parent. (4) Add a benchmark fixture with 5000 stale-id deletes; fail CI if total wall time regresses by 2x. (5) Cross-link with the just-filed #1804 (TransactionScope state machine) — the batched delete should ride the same transaction primitive. (6) Cross-link with #1565 (DbReader per-instance schema scan) — same family of round-trip waste.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions