ENH: per-directory files for the directory index-location map - #772
Conversation
Replace the single shared JSON index-location map with one small JSON file per data directory under a cache directory. This is the simplified successor to the SQLite approach in #764. Different directories use different files, so concurrent writers to distinct directories cannot lose each other's entries, and a corrupt entry only affects its own directory and self-heals on the next write (see #508) -- with no locks, corruption-recovery protocol, or at-fork hooks. Writes swap a sibling temp file into place, so readers never see a half-written entry. The read-only-directory fallback derives a deterministic index name and needs no map entry at all; only a user-specified custom index path is recorded. Config option `directory_index_map_path` becomes `directory_index_map_dir` (a directory). The map is a disposable cache; any old shared `cache_paths.json` is ignored and left in place.
…ling - _get_mapped_index_path no longer unlinks corrupt entries on read (that could delete a concurrent writer's repair); a miss self-heals on the next atomic write instead. - Treat non-UTF-8 / malformed JSON and non-string/empty index_path payloads as misses (catch ValueError; validate shape). - Use the full sha256 via os.fsencode in _path_digest: avoids a read-only index-file-name collision and handles non-UTF-8 path bytes.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughChangesThe index-location map now uses per-directory JSON entries under Index map refactor
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #772 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 164 164
Lines 17357 17356 -1
=========================================
- Hits 17357 17356 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| file) and non-UTF-8 filename bytes digest without error. | ||
| """ | ||
| Return a fresh dict of index locations read from disk. | ||
| return hashlib.sha256(os.fsencode(path)).hexdigest() |
There was a problem hiding this comment.
We may also need to support URLs in the future. Please just use fsencode if possible, fallback to string only hash if not.
There was a problem hiding this comment.
Done in 34c4bb1: _path_digest now tries os.fsencode first (exact local-path bytes) and falls back to a plain string encoding for inputs it rejects — e.g. a remote URL/UPath directory whose __fspath__ isn't available — instead of raising. Added a regression covering the fallback branch.
…nput Prefer os.fsencode for exact local-path digests, but fall back to a plain string encoding for inputs it rejects (e.g. remote URL/UPath directories we may support later) instead of raising.
Description
Simplified successor to #764: it replaces the shared JSON directory index-location map with one small JSON file per data directory, instead of the SQLite database (with corruption-recovery locks and
os.register_at_forkhooks) that #764 proposed.The index-location map records where a directory's index lives when the data directory itself is read-only, or when a user supplies a custom index path. Its goals are (a) concurrent writers to distinct data directories must not lose each other's entries, and (b) a corrupt entry (see #508) must not break indexing.
What changed
<sha256(dir)>.json) under a cache directory, replacing the single sharedcache_paths.json. Different directories use different files, so concurrent writers to distinct directories cannot clobber one another.directory_index_map_pathbecomesdirectory_index_map_dir(now a directory). The map is a disposable cache; any old sharedcache_paths.jsonis ignored and left in place.Why not the SQLite approach from #764
For a disposable convenience cache whose only production reads/writes are single-key, per-entry files give the same lost-update and corruption guarantees by construction, with ~10% of the code and none of the process-wide side effects (the
os.register_at_forkhooks in #764 serialize every fork in the host process through a library lock). It is also friendlier to NFS home directories, where SQLite locking is unreliable.Supersedes #764. Part of the free-threading work extracted from #763.
Validation
tests/test_io/test_indexer.py,tests/test_io/test_index/,tests/test_utils/test_config.py: pass.tests/test_io/: 2053 passed, 63 skipped, 1 xfailed.prek/pre-commit hooks pass on changed files.Changelog
directory_index_map_dirinstead of a sharedcache_paths.json, so a corrupt entry only affects its own directory. Any oldcache_paths.jsonis ignored and left in place.Checklist
I have (if applicable):
Summary by CodeRabbit
New Features
API Changes
directory_index_map_pathsetting withdirectory_index_map_dir.Bug Fixes