Commit Graph
1 Commits
Author SHA1 Message Date
rohit-jsfreaky 39f004ea32 perf(serve): build the MCP traversal view and shortest-path graphs once per graph
query_graph copied every edge of the loaded graph into an undirected
traversal view on every call, and shortest_path rebuilt a sorted
DiGraph (or Graph) of every edge on every call. The structures are the
same for a given graph object, so build each once and cache it on
G.graph, exactly like the trigram index: a hot reload swaps in a new G,
so a cached structure never outlives its graph.

Sharing is safe because nothing writes to them: _filter_graph_by_context
builds a new graph when a filter applies, the traversals and the
renderer only read the view, and only nx.shortest_path reads the path
graphs. The path graph is still built from sorted node and edge lists,
so #2074's deterministic route is unchanged. The traversal-view
docstring that chose a fresh copy per query is updated.

graphify's own graph (18,865 nodes / 38,458 edges), the same calls run
interleaved with the cache cleared vs kept, 240 outputs identical:
query_graph 524 -> 316 ms median (filtered "what calls X": 508 -> 360),
shortest_path 211 -> 0.8 ms directed, 109 -> 0.7 ms undirected.
Memory: +8 MB for the view, +24 MB for both path graphs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit fbb21791da)
2026-10-07 17:26:00 +01:00