Expand description
Persistent on-disk cache for Phase K.
The cache stores a serialized FileIndex per PHP file, keyed on
(uri, content). On a warm start scan_workspace reads the cached index
instead of parsing the file, shrinking cold-start I/O from O(parse) to
O(read + bincode-decode) — roughly 10–50× faster per file.
§Layout
~/.cache/php-lsp/<schema-version>/<workspace-hash>/<uri-hash>.bin<schema-version>—php-lspcrate version; bumping it rotates the entire cache so old entries are never decoded against a newer schema. The previous version’s directory is pruned by the nextWorkspaceCache::newcall rather than left to accumulate release over release.<workspace-hash>— blake3 of the canonicalized absolute path of the first workspace root, truncated to 16 hex chars. Two separate projects get isolated caches; two checkouts of the same project at the same absolute path share one. Holds aworkspace.jsonrecording the root path and last-used time, so the background pruner can drop caches for roots that no longer exist or haven’t been opened in [WORKSPACE_MAX_IDLE].<uri-hash>— blake3 of the URI, truncated to 32 hex chars. One file per URI, not per(uri, content)pair: a content hash is stored inside the entry and checked on read, so re-indexing an edited file overwrites its existing slot in place instead of leaving the previous revision’s entry to rot on disk.
<workspace-hash> also holds a session/ subdirectory: mir’s own
AnalysisCache, nested here (not under mir’s default .mir-cache/) so
both caches share schema/workspace rotation and cleanup. size_bytes
recurses into it for the size cap.
§Format
bincode v2 (binary, fast, schema-stable via serde derives on
FileIndex et al), prefixed with the entry’s content hash so a stale
revision reads back as a miss. Files are written atomically via a
temp-file rename to avoid half-written entries on an interrupted
shutdown.
§Invalidation
Rotating the schema version invalidates everything; rotating the content
invalidates just that entry’s slot (overwritten on next write). The size
cap in WorkspaceCache::new is a backstop for workspaces that outgrow
it, not the primary cleanup mechanism.
Structs§
- Cache
Key - Identifies a single cache entry. Opaque — callers produce it via
WorkspaceCache::key_forand pass it straight back to read/write. - Workspace
Cache - Handle to the cache directory for a single workspace. Construction is
cheap (creates directories on demand); the same handle can be shared
across threads via
Arc— it holds no mutable state.
Constants§
- CACHE_
SIZE_ CAP - Size cap (bytes) for a single workspace’s cache directory. At
startup, if the directory exceeds this, we reset it — simpler than
LRU eviction and the rebuild cost is bounded (it’s just the next
workspace scan running as if cold). 512 MiB fits a mega-workspace
(50 k files × ~10 KB average
FileIndex) with headroom and is small enough that no reasonable disk will choke on it. - TOTAL_
CACHE_ SIZE_ CAP - A workspace cache unused for this long is deleted on the next startup. Cap (bytes) on all workspace caches together. Past it, the least recently used workspace directories are deleted until the total fits again.