git_vdb/lib.rs
1#![deny(missing_docs)]
2#![deny(rustdoc::broken_intra_doc_links)]
3
4//! A deterministic, Git-native embedded vector database.
5//!
6//! `git-vdb` stores vectors, payloads, metadata, and search indexes as immutable
7//! Git objects. A canonical Git tree identifies the complete database state;
8//! commits and refs are an optional naming and history layer above that state.
9//! Equivalent configuration and points therefore produce the same root tree,
10//! independent of insertion order, repository path, history, or timestamps.
11//!
12//! Two APIs expose the same storage engine:
13//!
14//! - [`SnapshotEngine`] works directly with immutable root IDs and never creates
15//! commits or updates refs.
16//! - [`Database`] and [`Collection`] manage named collections under
17//! `refs/git-vdb/collections/*`, including history and compare-and-swap writes.
18//!
19//! # Immutable snapshot example
20//!
21//! ```
22//! use git_vdb::{CollectionConfig, Point, Query, SnapshotEngine};
23//!
24//! # fn main() -> git_vdb::Result<()> {
25//! let engine = SnapshotEngine::ephemeral()?;
26//! let snapshot = engine.build(
27//! CollectionConfig::new(2),
28//! vec![
29//! Point::new("east", [1.0, 0.0]),
30//! Point::new("north", [0.0, 1.0]),
31//! ],
32//! )?;
33//!
34//! let result = snapshot.query(Query::exact([0.9, 0.1], 1))?;
35//! assert_eq!(result.points[0].id.to_string(), "east");
36//! assert_eq!(result.root, snapshot.root());
37//! # Ok(())
38//! # }
39//! ```
40//!
41//! # Semantics and compatibility
42//!
43//! Exact cosine search scores every eligible point. Approximate search uses a
44//! deterministic LSH index and may underfill or omit globally better points when
45//! probe or candidate limits are exhausted; [`QueryResult::stats`] reports the
46//! work performed. Reads and validation never advance refs. Named writes create
47//! immutable objects first and then atomically compare-and-swap the collection
48//! ref, so [`Error::StaleRoot`] cannot silently overwrite a concurrent writer.
49//!
50//! The crate's semantic version and its persisted [`mod@format`] version are
51//! separate compatibility boundaries. Existing format-version-1 roots remain
52//! canonical regardless of physical Git packing.
53
54pub mod adapter;
55mod codec;
56mod filter;
57pub mod model;
58mod root;
59pub mod snapshot;
60
61/// The normative persisted format-version-1 specification.
62#[doc = include_str!("../docs/format.md")]
63pub mod format {}
64
65/// Design notes for immutable root snapshots and named collection history.
66#[doc = include_str!("../docs/snapshots.md")]
67pub mod snapshots {}
68
69pub use adapter::{Collection, Database};
70pub use model::{
71 CollectionConfig, CollectionInfo, Condition, CountResult, DeleteSelector, DiffResult, Distance,
72 Filter, GetRequest, GetResult, HistoryEntry, IndexConfig, JsonObject, MatchValue, ObjectId,
73 ObjectStats, Point, PointId, Query, QueryMode, QueryParams, QueryResult, QueryStats, Range,
74 Record, ScoredPoint, SnapshotInfo, SnapshotMutation, ValidationReport, WriteResult,
75};
76pub use snapshot::{Snapshot, SnapshotEngine};
77
78use thiserror::Error;
79
80#[derive(Debug, Error)]
81#[non_exhaustive]
82/// An error returned by a `git-vdb` operation.
83pub enum Error {
84 /// The underlying Git object database returned an error.
85 #[error("Git error: {0}")]
86 Git(#[from] git2::Error),
87 /// JSON serialization or deserialization failed.
88 #[error("JSON error: {0}")]
89 Json(#[from] serde_json::Error),
90 /// A filesystem operation failed.
91 #[error("I/O error: {0}")]
92 Io(#[from] std::io::Error),
93 /// The request or persisted value violated a declared invariant.
94 #[error("invalid request: {0}")]
95 Invalid(String),
96 /// A requested named collection does not exist.
97 #[error("collection not found: {0}")]
98 CollectionNotFound(String),
99 /// A collection could not be created because its name already exists.
100 #[error("collection already exists: {0}")]
101 CollectionExists(String),
102 /// A named write expected a different current collection root.
103 #[error("stale collection root: expected {expected}, actual {actual}")]
104 StaleRoot {
105 /// Root supplied by the writer as its compare-and-swap precondition.
106 expected: ObjectId,
107 /// Root resolved from the collection ref when the write was attempted.
108 actual: ObjectId,
109 },
110 /// A write was attempted through an immutable historical collection view.
111 #[error("read-only historical collection")]
112 ReadOnly,
113 /// Stored Git objects do not form a valid canonical collection root.
114 #[error("corrupt collection: {0}")]
115 Corrupt(String),
116}
117
118/// The result type returned by `git-vdb` operations.
119pub type Result<T> = std::result::Result<T, Error>;