mirror of
https://github.com/safishamsi/graphify.git
synced 2026-07-20 22:31:48 +00:00
_score_nodes and _find_node scan every node per query (O(nodes x terms)), so query latency scales with total graph size regardless of where the answer lives. Add a lazily-built character-trigram index (cached on the graph object, auto-invalidated on hot-reload like _idf_cache) that narrows each query to a small candidate superset before the unchanged scoring loop. Results are byte-identical: the index is a pure candidate generator over the exact fields the scorer reads (norm_label, label_tokens, nid, source_file); a non-candidate node always scores 0, and IDF stays a whole-graph statistic. _find_node candidates are returned in graph iteration order so its exact/prefix/substring ordering, and matches[0], stay unchanged. A selectivity guard falls back to the full scan when a query term is too short to trigram or its rarest trigram is still common (broad terms like model/client), preserving a never-worse contract. The index builds eagerly at load and before a reloaded graph is swapped in, so neither the first query nor the first post-reload query pays the one-time build cost. Storage format is unchanged (in-memory index only). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>