Files
zzet--gortex/internal/graph/reader.go
Andrey Kumanyaev eec5b86243 chore(cleanup): scrub stale ladybug/Kuzu references from comments
The ladybug/Kuzu backend is gone, but doc-comments across the graph,
indexer, analysis, query, and MCP layers still described query plans in
terms of Cypher / liblbug / cgo round-trips and named store_ladybug as
the sole implementor of various Store capabilities. Generalize them to
backend-agnostic wording (SQLite is now the on-disk backend) and delete
the obsolete ladybug-internals trivia. The rationale (why a capability
exists, the row-count tradeoffs) is preserved; only the backend naming
changed.

Two small non-comment follow-ups ride along: normalizeBackendTag's dead
"ladybug" snapshot-tag case becomes "sqlite", and enrich_churn's help
text drops the LadyBug write-lock name (the route-through-the-daemon
rationale still holds for SQLite's single-writer lock). Touched files
were re-run through gofmt (the project's make fmt standard), which
realigned a few struct blocks. No behavior change.

Excludes resolver.go and indexer.go, which also carry unrelated WIP.
2026-06-01 10:24:16 +02:00

84 lines
3.6 KiB
Go

package graph
// Reader is the read-only contract every graph consumer (query
// engine, MCP tool handlers, analyzers, resolver introspection) depends
// on. *Graph satisfies it directly; OverlaidView (overlay.go) wraps a
// base Reader plus a per-session overlay layer to deliver a non-
// mutating shadow view for editor-buffer queries.
//
// Mutation methods (AddNode, AddEdge, EvictFile, ReindexEdge, …) live
// on *Graph and are NOT part of this interface. Only the indexer and
// the resolver mutate; everyone else reads, and reads must go through
// Reader so the same call site transparently switches between base
// and overlay views.
//
// New read methods on *Graph should be added here too — keeping the
// surfaces in sync is what guarantees that a tool migrated to read
// through the Reader will keep working for both base and overlay
// queries.
type Reader interface {
// Identity lookups.
GetNode(id string) *Node
GetNodeByQualName(qualName string) *Node
FindNodesByName(name string) []*Node
// FindNodesByNameContaining returns nodes whose Name (case-
// insensitive) contains substr. The filter is pushed into the
// backend so only matching rows cross the boundary on a disk backend;
// the search hot path's substring fallback uses this instead of
// the old AllNodes()-then-filter pattern (which materialised the
// whole node set per call and didn't scale). limit caps the
// result; 0 means "no limit".
FindNodesByNameContaining(substr string, limit int) []*Node
// GetNodesByIDs is the batched sibling of GetNode. The disk-backed
// store collapses N individual point lookups into a
// single bulk query — critical on the search hot path where one
// query materialises 60+ candidate IDs. The in-memory backend
// forwards to per-id GetNode, so the cost matches an inline loop
// there. Missing IDs are simply absent from the map (no nil
// values); duplicates dedupe naturally.
GetNodesByIDs(ids []string) map[string]*Node
// File / repo scopes.
GetFileNodes(filePath string) []*Node
GetRepoNodes(repoPrefix string) []*Node
// Edge walks.
GetOutEdges(nodeID string) []*Edge
GetInEdges(nodeID string) []*Edge
// GetInEdgesByNodeIDs / GetOutEdgesByNodeIDs are the batched
// siblings of GetInEdges / GetOutEdges. The disk-backed store collapses
// N per-id queries into one bulk query over an `id IN $ids`
// filter; the in-memory backend forwards to per-id walks (no
// concurrency win — same algorithmic cost as an inline loop). On
// the rerank hot path this drops ~150 round-trips per
// search_symbols call down to ~4 (prepare collects every
// candidate's ids and fans them out in one inbound + one outbound
// batch). Missing nodes get nil slices in the returned map so
// callers can `for _, e := range m[id]` without an ok-check.
GetInEdgesByNodeIDs(ids []string) map[string][]*Edge
GetOutEdgesByNodeIDs(ids []string) map[string][]*Edge
// Bulk reads — used by analyzers (hotspots, cycles, dead code,
// communities, …) and by the embedded query engine's whole-graph
// passes.
AllNodes() []*Node
AllEdges() []*Edge
// Counters & stats.
NodeCount() int
EdgeCount() int
// EdgeIdentityRevisions is the running count of provenance-bearing
// edge-identity changes — see Graph.EdgeIdentityRevisions.
EdgeIdentityRevisions() int
Stats() GraphStats
RepoStats() map[string]GraphStats
}
// Compile-time assertion that *Graph satisfies Reader. If a new
// Reader method is added without a corresponding *Graph method (or
// the *Graph signature drifts), the build breaks here rather than at
// a far-away callsite.
var _ Reader = (*Graph)(nil)