Show folder names immediately and refresh stale index sizes without walking the whole drive.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-26 11:21:20 +02:00
parent 6fc7506eb7
commit e2916aef9c
88 changed files with 5373 additions and 544 deletions

View File

@@ -839,7 +839,7 @@ Bitte diese Punkte klären. Empfohlene Defaults in Klammern:
## Hintergrundprozess: Explorer.Host.exe
Indexing, USN/watchers, transfer queue, hash worker, and history rollup run in **`Explorer.Host.exe`**, not in the WPF window.
Indexing, USN/watchers, transfer queue, hash worker, and history rollup run in **`Explorer.Host.exe`**, not in the WPF window. Idle-aware background maintenance is coordinated there as well (`GetLastInputInfo` / power status — no WPF dependency).
| | Explorer.Host.exe (current) | Windows Service |
|---|---|---|
@@ -893,7 +893,7 @@ Deviations from the design above, with reasons:
3. **WPF-UI (lepoco)** — not used. Light/Dark Fluent-style brushes live in `Themes/Dark.xaml` and `Themes/Light.xaml` so the UI toolkit stays replaceable.
4. **`PRAGMA mmap_size` / large `cache_size`** — not applied at runtime. They made SQLite native startup unreliable under concurrent test hosts; WAL + `synchronous=NORMAL` remain.
5. **App data folder**`%LocalAppData%\ExplorerWorkbench` (not `Explorer`) so the working name does not collide with Windows Explorer.
6. **Background work** — indexer, transfer queue, hash worker, history rollup, and watchers run as `IHostedService` instances inside **`Explorer.Host.exe`**. The WPF window is a named-pipe client (`Explorer.Hosting.Client`) with a read-only SQLite store. No Windows Service; optional current-user sign-in (`HKCU\Software\Microsoft\Windows\CurrentVersion\Run`).
6. **Background work** — indexer, transfer queue, hash worker, and watchers run as `IHostedService` instances inside **`Explorer.Host.exe`**. `BackgroundMaintenanceCoordinator` is the one extra 1s timer: it uses `IUserIdleMonitor` / `BackgroundWorkPolicy` to pause or resume duplicate hashing, enqueue at most one idle local full scan (`IndexWorkOrigin.Idle`, distinct from user/watcher/USN work), and call `HistoryRollupService` (no longer its own hosted loop). Copy/move/delete and explicit scans are never idle work. The WPF window is a named-pipe client (`Explorer.Hosting.Client`) with a read-only SQLite store. No Windows Service; optional current-user sign-in (`HKCU\Software\Microsoft\Windows\CurrentVersion\Run`).
7. **Search syntax** — structured `SearchQuery` exists; Everything-like lexer is not shipped (Phase 7).
8. **UNIQUE identity**`UNIQUE (source_id, ifnull(parent_id,-1), name_norm)` because SQLite UNIQUE treats NULLs as distinct.
9. **INSERT ids**`Microsoft.Data.Sqlite` + Dapper `ExecuteScalarAsync` on `INSERT … RETURNING` leaves the write connection busy and hangs the next command. Writer-connection SQL uses `SqliteCommand` (`SqliteExec`) and `last_insert_rowid()`.
@@ -901,4 +901,6 @@ Deviations from the design above, with reasons:
11. **Schema apply** — Microsoft.Data.Sqlite/`Execute` splitting on `;` broke `CREATE TRIGGER` bodies. Schema is applied as an explicit statement array (`SchemaScript.Statements`).
12. **Search CurrentFolder**`SearchRequest.DirectChildrenOnly` restricts to the folders children in SQL (not a client-side filter after paging).
13. **Duplicate hashing** — full-file hashes run only when another same-size file already shares the partial hash. Unique partial hashes skip the full read.
14. **Index freshness** — folder sizes in the listing come from `aggregate_size`. Watcher reconcile stays one directory deep. Opening a folder enqueues a 1-level reconcile of that path, then `FolderDisplayRefresh` probes up to 8 largest/visible child dirs (child count). Mismatches get `EnqueueVerify` for that child only and are cancelled when the browse generation changes. Idle maintenance still verifies each local indexed source (deep walk, cap 48). USN directory deletes also tombstone the path prefix.
15. **Browse names first** — live folder listing starts without waiting for source lookup, archive index, `MarkReachable`, or child-index overlay. The first name is published immediately (`BrowseHydration.FirstPublish`); folder sizes, cloud state, and Git badges arrive as later `BrowseDelta` updates. Archive paths still resolve through the index before live enumeration.