sqlite_blob

package
v2.4.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package sqlite_blob implements the always-available zero-CGO VectorIndex adapter (ADR-05, REQ-VEC-001).

It wraps the SQLite BLOB vector store (internal/store/sqlite) behind the domain.VectorIndex port. This is the single highest-leverage change of the vector modernization: bundle.Stores.Vectors changes from the concrete *sqlite.VectorStore to domain.VectorIndex, unblocking every future adapter (qdrant, pgvector) without touching MCP/HTTP/CLI/TUI.

Search is the REQ-VEC-SCAN-001 two-pass coarse-to-fine scan:

  1. A Matryoshka prefix pass scores every candidate row over the leading 1-1/coarseDivisor of the stored dimensions and shortlists the strongest max(limit*shortlistFactor, minShortlist) rows.
  2. An int8 refinement pass rescores only that shortlist across the full stored prefix.
  3. Both passes shard disjoint row ranges across goroutines and the merge orders by (score desc, observation id asc), so concurrency never changes the returned sequence.

Metadata-filtered searches (REQ-VEC-FILTER-001) switch plans on a deterministic cardinality probe: a highly selective filter refines every matching row (exact plan, full top-k guaranteed), a broad filter keeps the two-pass scan (constrained plan), and zero matches short-circuits to an empty result before any corpus row is read. The unfiltered path never runs the probe, so its scan behavior is unchanged.

Storage uses the same scheme: Upsert writes a pre-normalized int8 payload holding the shortest leading prefix that retains energyRetain of the vector's L2 energy. Matryoshka embeddings concentrate that energy in the leading dimensions, which is where the storage reduction comes from; a fully unstructured vector degrades gracefully to the int8 floor instead of losing recall.

Build-tag semantics are PRESERVED EXACTLY:

  • Default build (cortex_vectors NOT set, zero-CGO): the underlying sqlite.VectorStore is the stub that returns ErrVectorSearchDisabled. The adapter reports degraded and passes the disabled error through without issuing any SQL. No external service, no CGO.
  • cortex_vectors build tag: the underlying sqlite.VectorStore is available and the adapter runs the two-pass scan above.

Dimension-mismatch corruption is FIXED (REQ-VEC-001 error scenario): the legacy cosine path logged a warning and scored mismatched vectors 0 (silent corruption). This adapter REJECTS any upsert whose vector dimension does not match the declared ModelInfo.Dimension with domain.ErrDimensionMismatch — the mismatched vector is never stored. At scan time a row whose stored dimension differs from the query still scores 0 with a warning, matching the legacy scan instead of silently comparing misaligned coordinates.

A non-finite vector (NaN/Inf) keeps the legacy float32 blob so its scan semantics are unchanged: it still scores NaN and is filtered out, rather than being corrupted into an int8 code.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Adapter

type Adapter struct {
	// contains filtered or unexported fields
}

Adapter wraps the existing concrete *sqlite.VectorStore as a domain.VectorIndex. It is the zero-CGO default and is always available for wiring (operations return ErrVectorSearchDisabled when the cortex_vectors tag is not set).

func New

func New(db *sql.DB) *Adapter

New creates a sqlite_blob adapter over the existing concrete VectorStore. The db may be nil for capability/health-only wiring (tests, capability negotiation before the database is open). A nil db produces a stub store that reports unavailable, matching the zero-CGO default.

func (*Adapter) Capabilities

func (a *Adapter) Capabilities(_ context.Context) (domain.Capabilities, error)

Capabilities declares the sqlite_blob adapter's supported features for capability-driven strategy selection (ADR-05). sqlite_blob is a coarse-to- fine cosine scan with post-filtering, strong consistency (same SQLite tx), and batch upsert support.

func (*Adapter) Close

func (a *Adapter) Close() error

Close releases resources. sqlite_blob holds no resources beyond the shared *sql.DB (owned by the caller), so Close is a no-op.

func (*Adapter) Delete

func (a *Adapter) Delete(ctx context.Context, ids []int64) error

Delete removes vectors by observation ID. The underlying store's DeleteEmbedding handles the not-found case; missing IDs in the batch are tolerated (idempotent delete).

func (*Adapter) Health

func (a *Adapter) Health(_ context.Context) domain.Health

Health reports the adapter's current health. When the underlying store is unavailable (zero-CGO stub), Health returns degraded with a diagnostic message. When the store is available (cortex_vectors enabled), Health returns healthy.

func (*Adapter) ID

func (a *Adapter) ID() string

ID returns the stable adapter identifier.

func (*Adapter) Search

Search runs the two-pass coarse-to-fine scan. Filters map "project"/"scope" onto the legacy Project/Scope fields, preserving the concrete store's local filter behavior; "type" and "source" join them in the pushed-down WHERE and cardinality probe.

func (*Adapter) Upsert

func (a *Adapter) Upsert(ctx context.Context, points []domain.VectorPoint) error

Upsert stores a batch of vectors. Each point's vector dimension MUST match its declared ModelInfo.Dimension; a mismatch is rejected with domain.ErrDimensionMismatch (REQ-VEC-001 dim-mismatch corruption pin). The mismatched point and every subsequent point in the batch are rejected — the caller treats the batch atomically.

Model-version namespace: ModelInfo.Name identifies the embedding model so vectors stay namespaced by model, preventing cross-model corruption.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL