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 the
44//! root's deterministic IVF-flat index and may 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. New roots use format version 2; existing
52//! format-version-1 roots remain readable and canonical regardless of physical
53//! Git packing.
54
55pub mod adapter;
56mod codec;
57mod filter;
58pub mod model;
59mod root;
60mod root_v2;
61pub mod snapshot;
62
63/// The normative persisted format-version-2 specification.
64#[doc = include_str!("../docs/format-v2.md")]
65pub mod format {}
66
67/// The legacy persisted format-version-1 specification.
68#[doc = include_str!("../docs/format.md")]
69pub mod format_v1 {}
70
71/// Design notes for immutable root snapshots and named collection history.
72#[doc = include_str!("../docs/snapshots.md")]
73pub mod snapshots {}
74
75pub use adapter::{Collection, Database};
76pub use model::{
77 CollectionConfig, CollectionInfo, Condition, CountResult, DeleteSelector, DiffResult, Distance,
78 Filter, GetRequest, GetResult, HistoryEntry, IndexConfig, JsonObject, MatchValue, ObjectId,
79 ObjectStats, Point, PointId, Query, QueryMode, QueryParams, QueryResult, QueryStats, Range,
80 Record, ScoredPoint, SnapshotInfo, SnapshotMutation, ValidationReport, WriteResult,
81};
82pub use snapshot::{Snapshot, SnapshotEngine};
83
84use thiserror::Error;
85
86#[derive(Debug, Error)]
87#[non_exhaustive]
88/// An error returned by a `git-vdb` operation.
89pub enum Error {
90 /// The underlying Git object database returned an error.
91 #[error("Git error: {0}")]
92 Git(#[from] git2::Error),
93 /// JSON serialization or deserialization failed.
94 #[error("JSON error: {0}")]
95 Json(#[from] serde_json::Error),
96 /// A filesystem operation failed.
97 #[error("I/O error: {0}")]
98 Io(#[from] std::io::Error),
99 /// The request or persisted value violated a declared invariant.
100 #[error("invalid request: {0}")]
101 Invalid(String),
102 /// A requested named collection does not exist.
103 #[error("collection not found: {0}")]
104 CollectionNotFound(String),
105 /// A collection could not be created because its name already exists.
106 #[error("collection already exists: {0}")]
107 CollectionExists(String),
108 /// A named write expected a different current collection root.
109 #[error("stale collection root: expected {expected}, actual {actual}")]
110 StaleRoot {
111 /// Root supplied by the writer as its compare-and-swap precondition.
112 expected: ObjectId,
113 /// Root resolved from the collection ref when the write was attempted.
114 actual: ObjectId,
115 },
116 /// A write was attempted through an immutable historical collection view.
117 #[error("read-only historical collection")]
118 ReadOnly,
119 /// Stored Git objects do not form a valid canonical collection root.
120 #[error("corrupt collection: {0}")]
121 Corrupt(String),
122}
123
124/// The result type returned by `git-vdb` operations.
125pub type Result<T> = std::result::Result<T, Error>;