Documentation
¶
Index ¶
- Variables
- type Hit
- type HitContribution
- type Query
- type QueryContext
- type QueryParameters
- type QueryResult
- type Recall
- func (r Recall[K, P]) GetGraphID() uint8
- func (r Recall[K, P]) Hash(h hash.Hasher[K, string]) K
- func (r Recall[K, P]) IsWrite() bool
- func (r *Recall[K, P]) Plan(config *config.ConfigSet) (*Stream[K, P], error)
- func (r *Recall[K, P]) SetGraphID(id uint8)
- func (r Recall[K, P]) Since(now time.Time) time.Time
- func (r Recall[K, P]) Until(now time.Time) time.Time
- type Remember
- type Stream
Constants ¶
This section is empty.
Variables ¶
var ( // ErrParsingFailed is returned when a raw query string cannot be parsed into // an executable query. It wraps the underlying *parser.Error (with its // position), so callers can errors.As it out at the boundary. ErrParsingFailed = errors.New("query: parsing error") // ErrMissingParameter is returned when a query references a placeholder // (e.g. vec:$v) that has no matching entry in the supplied parameters. ErrMissingParameter = errors.New("query: missing parameter") // ErrLimitExceeded is returned when a query asks for more than a configured // ceiling allows (top:, depth:, or the length of a bound vector). It is a // client error: the request is rejected rather than clamped, so the caller // learns their bound was too high. ErrLimitExceeded = errors.New("query: request limit exceeded") )
Functions ¶
This section is empty.
Types ¶
type Hit ¶
type Hit[K comparable, P float32 | float64] struct { Node *graph.Node[K] Score P // Contributions is the hit's per-source breakdown, populated only when // the stream ran in explain mode; nil otherwise. nil doubles as the // serialization switch — a recall hit always has at least one // contribution, so nil unambiguously means "not asked for", never // "asked for and empty". The entries are wire-shaped (anchor identities // already resolved to their values) because resolution needs the graph, // which only the commit site holds. Contributions []HitContribution[P] }
func (Hit[K, P]) MarshalJSON ¶
MarshalJSON flattens the node into the hit so the response carries only the value, timestamp and score, with no nested Node object. The contribution breakdown appears only when the hit carries one (explain mode), keeping the ordinary query response byte-compatible with what it was before explain existed.
type HitContribution ¶
type HitContribution[P float32 | float64] struct { Source string `json:"source"` Score P `json:"score"` Rank uint16 `json:"rank"` Via string `json:"via,omitempty"` Degree uint32 `json:"degree,omitempty"` Count uint16 `json:"count"` }
HitContribution is the wire form of one contribution: the source is serialized by name, not by its Go constant, because the payload documents ranking to clients that never see the enum. A text or vector entry carries its raw mass and list position; a graph entry — one per funding anchor — carries the anchor's full observed mass, the anchor's value under via, its degree, and how many seeds funded it. With the query-level background rate, these are exactly the inputs of the scoring fold, so a client can recompute the hit's score from its own payload.
type Query ¶
type Query[K comparable, P float32 | float64] interface { Plan(config *config.ConfigSet) (*Stream[K, P], error) GetGraphID() uint8 hash.Hashable[K, string] IsWrite() bool SetGraphID(id uint8) }
func Parse ¶
func Parse[K comparable, P float32 | float64](q string, params map[string][]P, c *config.ConfigSet) (Query[K, P], []parser.Warning, error)
Parse turns a raw query string into an executable Query. Vector arguments are passed out-of-band in params, keyed by the placeholder name used in the query (e.g. `vec:$v` binds to params["v"]). This keeps the parser lightweight: it only records the placeholder, and the real vector is injected here.
Warnings accompany a query that parsed and will run: they flag a reading the client may not have meant (see parser.Warning) and must travel to the client alongside the results, never attached to the query itself — the plan cache substitutes query objects on a hash hit, so state on the query would leak between requests.
type QueryContext ¶
type QueryContext struct {
GraphID uint8
}
type QueryParameters ¶
type QueryParameters[K comparable] struct { Top int Depth int Since containers.TimeValue[K] Until containers.TimeValue[K] }
type QueryResult ¶
type QueryResult[K comparable, P float32 | float64] struct { Count int `json:"count"` Hits []Hit[K, P] `json:"hits"` // Background is the query's background rate ρ₀ — the average seed mass // per unit of anchor degree the traversal observed — attached only in // explain mode. Together with each hit's contribution breakdown it lets a // client recompute every score: S = m + α²·Σ max(0, M_A − m − d_A·ρ₀). // omitempty doubles as the mode switch: a plain query never carries it. Background P `json:"background,omitempty"` }
type Recall ¶
type Recall[K comparable, P float32 | float64] struct { Keywords []string Vector containers.Vector[K, P] Entities []string Topics []string Parameters QueryParameters[K] // contains filtered or unexported fields }
func (Recall[K, P]) GetGraphID ¶
func (Recall[K, P]) Hash ¶
Hash keys the query for the plan cache. It must fold in everything that changes the result set: two recalls that differ only in graph, depth, top, time bounds or the bound vector must not collide, or the cache would hand back a stale plan. The lists are delimited so ["ab"] and ["a","b"] do not hash alike.
func (*Recall[K, P]) SetGraphID ¶
type Remember ¶
type Remember[K comparable, P float32 | float64] struct { Value string Entities []string Topics []string Vector containers.Vector[K, P] // contains filtered or unexported fields }
func (Remember[K, P]) GetGraphID ¶
func (Remember[K, P]) Hash ¶
Hash keys the query for the plan cache. Like Recall it must fold in the graph selector and every field that changes what gets written — including the bound vector: hashing only Value would make `remember@3 'x' topic:a` and `remember@5 'x' topic:b` collide, so the second would reuse the first's plan and write to the wrong graph.
func (*Remember[K, P]) SetGraphID ¶
type Stream ¶
type Stream[K comparable, P float32 | float64] struct { Query Query[K, P] Result *QueryResult[K, P] Err error // Explain asks the read path to attach each hit's contribution records to // the result. It lives on the stream, not the query, on purpose: the // engine caches query objects by hash and substitutes them on a hit, so a // flag on the query would either leak one request's explain choice into // another's or have to widen the cache key for a bit that never changes // the plan. The stream is built per request and never cached. Explain bool // contains filtered or unexported fields }
data structure representing a stream: language of the scheduler A stream is the language for the engine to the worker Streams can be read-only or read and write.
func NewStream ¶
func NewStream[K comparable, P float32 | float64](q Query[K, P]) *Stream[K, P]
NewStream returns a stream ready to be scheduled for q: Done() blocks until the scheduler commits or rolls the stream back.
func (*Stream[K, P]) Commit ¶
Commit executes the stream's query against g directly. The caller must hold the appropriate lock (the write lock for writes, a read lock for reads — see Acquire): the lock is already exclusive for writes, so mutating g in place exposes no intermediate state, and the write costs O(fact + incremental index updates) regardless of graph size. Copying the graph here (as staging once did) would make every single-fact write O(total graph) and lock readers out for the duration — that is the failure mode, not the safety mechanism.
Failure ordering: the vector insert runs before any graph mutation, so the one realistic commit failure (a vector-dimension mismatch) rejects the write with g untouched. Later index errors are pathological; they surface in the returned error with the write partially applied.