Skip to content

fix(windows): avoid orphaning mapped index generations on NTFS - #156

Merged
Shengyu Fu (shengyfu) merged 1 commit into
mainfrom
shengyfu-windows-index-cleanup
Sep 11, 2026
Merged

Shengyu Fu (shengyfu) merged 1 commit into
mainfrom
shengyfu-windows-index-cleanup

Conversation

@shengyfu

Copy link
Copy Markdown
Member

Summary

Prevent index publication from force-unlinking memory-mapped index generations into NTFS's $Deleted namespace.

  • Keep replaced files in uniquely named .retired generations, separate from reusable staging directories.
  • Use non-POSIX Windows deletion that refuses mapped files; apply the same protection to staging cleanup and rollback.
  • Release merge-reader snapshots before publication cleanup. Retry committed generations after publication, every minute while idle, and on startup.
  • Preserve uncommitted backups for recovery and report cleanup failures rather than silently discarding them.

Root cause

Both incremental merge and checkpoint paths retained the old reader through publication, while publication recursively deleted its backup files. Rust's Windows filesystem operations can fall back to POSIX deletion/replacement when mapped files reject ordinary deletion.

A regression on Windows reproduced the old index.bin handle changing to C:\$Extend\$Deleted\.... The updated path retains the generation under its original volume until Windows accepts non-POSIX deletion, including when an independent reader still maps it.

Platform behavior

The reported persistent NTFS $Deleted accumulation is Windows-specific. Linux and macOS can temporarily retain storage for an unlinked file while a handle or memory mapping remains alive; they normally reclaim it after the last reference closes. Their standard filesystem deletion behavior is unchanged.

This prevents new orphaned generations; it does not reclaim storage already stranded by an older build.

Validation

On Windows: 22 focused cleanup/publication/rollback regressions pass, 254 active CLI unit tests pass (one existing ignored), and 10 indexed-file/watcher integration tests pass. Targeted Clippy and rustfmt pass. Coverage includes multiple retained generations, independent readers, reloads, rejected publication, cleanup retry, and rollback without replacing a mapped file. Linux/macOS execution remains covered by the existing CI matrix.

Retain replaced index files in uniquely named generations and use non-POSIX deletion on Windows. Release merge readers before cleanup, retry retired generations on startup and idle ticks, and preserve uncommitted backups for recovery.

Co-authored-by: Copilot App <[email protected]>
Copilot AI balanced review requested due to automatic review settings September 11, 2026 16:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Windows-specific unsafe filesystem operations and crash-recovery semantics warrant final human validation.

Review tier: Balanced
Findings: None

What changed in this PR

Prevents Windows index publications from orphaning mapped generations in NTFS’s $Deleted namespace.

Changes:

  • Adds retryable retired-generation cleanup using non-POSIX Windows deletion.
  • Releases mapped readers before publication and preserves failed rollback backups.
  • Documents behavior and adds focused cleanup/publication regression tests.
File Description
tgrep-core/​src/​hybrid.rs Clarifies mapped-generation lifecycle requirements.
tgrep-cli/​src/​serve/​index_cleanup.rs Implements safe cleanup and retry logic.
tgrep-cli/​src/​serve.rs Integrates retirement, cleanup, rollback, and tests.
README.md Documents Windows cleanup behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@shengyfu
Shengyu Fu (shengyfu) merged commit 21ed84c into main Sep 11, 2026
10 checks passed
@shengyfu
Shengyu Fu (shengyfu) deleted the shengyfu-windows-index-cleanup branch September 11, 2026 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants