Persistent registry mapping file SHA-256 hashes to metadata dicts.
| 9 | |
| 10 | |
| 11 | class HashRegistry: |
| 12 | """Persistent registry mapping file SHA-256 hashes to metadata dicts.""" |
| 13 | |
| 14 | def __init__(self, path: Path) -> None: |
| 15 | self._path = path |
| 16 | if path.exists(): |
| 17 | with path.open("r", encoding="utf-8") as fh: |
| 18 | self._data: dict[str, dict] = json.load(fh) |
| 19 | else: |
| 20 | self._data = {} |
| 21 | |
| 22 | # ------------------------------------------------------------------ |
| 23 | # Query helpers |
| 24 | # ------------------------------------------------------------------ |
| 25 | |
| 26 | def is_known(self, file_hash: str) -> bool: |
| 27 | """Return True if file_hash is already registered.""" |
| 28 | return file_hash in self._data |
| 29 | |
| 30 | def get(self, file_hash: str) -> dict | None: |
| 31 | """Return metadata for file_hash, or None if not found.""" |
| 32 | return self._data.get(file_hash) |
| 33 | |
| 34 | def all_entries(self) -> dict[str, dict]: |
| 35 | """Return a shallow copy of all hash -> metadata entries.""" |
| 36 | return dict(self._data) |
| 37 | |
| 38 | def get_by_path(self, path: str) -> dict | None: |
| 39 | """Return metadata whose path/raw_path/source_path equals ``path``. |
| 40 | |
| 41 | ``path`` is a registry path string (posix, relative to the KB dir |
| 42 | when inside it) as produced by ``converter._registry_path``. Entries |
| 43 | written before the path index existed carry none of these fields and |
| 44 | never match. |
| 45 | """ |
| 46 | for metadata in self._data.values(): |
| 47 | if path in ( |
| 48 | metadata.get("path"), |
| 49 | metadata.get("raw_path"), |
| 50 | metadata.get("source_path"), |
| 51 | ): |
| 52 | return metadata |
| 53 | return None |
| 54 | |
| 55 | def find_legacy_by_stem(self, stem: str) -> tuple[str, dict] | None: |
| 56 | """Find a pre-path-index entry matching ``stem``. |
| 57 | |
| 58 | Returns ``(file_hash, metadata)`` for an entry that has no truthy |
| 59 | ``path`` (a missing or empty ``path`` is treated as unindexed) and |
| 60 | whose ``doc_name`` — or, for even older entries lacking |
| 61 | ``doc_name``, the stem of its ``name`` — equals ``stem``. When |
| 62 | several legacy entries match (pre-fix registries can hold |
| 63 | same-named entries), the first in insertion order is returned. |
| 64 | Callers use the hash to backfill ``path`` via :meth:`add`. Returns |
| 65 | None when every matching name is already path-indexed. The |
| 66 | comparison is NFKC-normalized on both sides, so macOS NFD |
| 67 | filenames match their NFC registry entries. |
| 68 | """ |
no outgoing calls