Skip to main content

trine_kv/
types.rs

1use std::ops::Bound;
2
3/// Stable numeric cursor for a committed database state.
4///
5/// `ReadVersion` is the public identifier callers use when they want to open a
6/// [`Snapshot`](crate::Snapshot) at a specific historical state. Values are
7/// database-scoped: a read version is meaningful only for the database lineage
8/// that produced it, even if another database happens to contain the same
9/// numeric value.
10///
11/// Use [`Db::latest_read_version`](crate::Db::latest_read_version) to capture
12/// the newest visible state, and [`Db::snapshot_at`](crate::Db::snapshot_at) to
13/// validate and pin a version before reading. Versions older than
14/// [`Db::oldest_retained_read_version`](crate::Db::oldest_retained_read_version)
15/// are expired and must not be read by falling back to latest.
16///
17/// # Examples
18///
19/// ```rust
20/// use trine_kv::{Db, DbOptions, ReadVersion};
21///
22/// # fn main() -> trine_kv::Result<()> {
23/// let db = Db::open_sync(DbOptions::memory())?;
24/// assert_eq!(db.latest_read_version(), ReadVersion::ZERO);
25///
26/// db.put_sync(b"k", b"v1")?;
27/// let version = db.latest_read_version();
28/// let keep_version = db.snapshot_at(version)?;
29///
30/// db.put_sync(b"k", b"v2")?;
31/// let snapshot = db.snapshot_at(version)?;
32/// assert_eq!(db.get_at_sync(&snapshot, b"k")?, Some(b"v1".to_vec()));
33/// drop(keep_version);
34/// # Ok(())
35/// # }
36/// ```
37#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
38pub struct ReadVersion(u64);
39
40impl ReadVersion {
41    /// Read version for the empty database state before the first successful
42    /// state-changing write.
43    pub const ZERO: Self = Self(0);
44
45    /// Creates a read version from its stable numeric cursor value.
46    ///
47    /// The value is suitable for application-owned cursors that were
48    /// previously obtained from this same database lineage. Creating a
49    /// `ReadVersion` from a number does not prove the version is still
50    /// retained; call [`Db::snapshot_at`](crate::Db::snapshot_at) to validate
51    /// it before reading.
52    #[must_use]
53    pub const fn from_u64(value: u64) -> Self {
54        Self(value)
55    }
56
57    /// Returns the stable numeric cursor value.
58    ///
59    /// Applications may persist this value and later rebuild it with
60    /// [`ReadVersion::from_u64`]. The number is a public cursor, not a promise
61    /// about Trine's internal commit allocation machinery.
62    #[must_use]
63    pub const fn as_u64(self) -> u64 {
64        self.0
65    }
66
67    pub(crate) const fn from_sequence(sequence: Sequence) -> Self {
68        Self(sequence.get())
69    }
70
71    pub(crate) const fn to_sequence(self) -> Sequence {
72        Sequence::new(self.0)
73    }
74}
75
76#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
77pub(crate) struct Sequence(u64);
78
79impl Sequence {
80    pub(crate) const ZERO: Self = Self(0);
81
82    #[must_use]
83    pub(crate) const fn new(value: u64) -> Self {
84        Self(value)
85    }
86
87    #[must_use]
88    pub(crate) const fn get(self) -> u64 {
89        self.0
90    }
91
92    #[must_use]
93    #[cfg(test)]
94    pub(crate) const fn next(self) -> Option<Self> {
95        match self.0.checked_add(1) {
96            Some(value) => Some(Self(value)),
97            None => None,
98        }
99    }
100}
101
102/// Value bytes stored for a key.
103pub type Value = Vec<u8>;
104
105/// Owned key/value row returned by eager iterators.
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct KeyValue {
108    /// User key bytes.
109    pub key: Vec<u8>,
110    /// Value bytes visible for the key.
111    pub value: Value,
112}
113
114impl KeyValue {
115    /// Creates an owned key/value row.
116    #[must_use]
117    pub fn new(key: impl Into<Vec<u8>>, value: impl Into<Value>) -> Self {
118        Self {
119            key: key.into(),
120            value: value.into(),
121        }
122    }
123}
124
125/// User-key range used by range scans and range deletes.
126#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct KeyRange {
128    /// Inclusive, exclusive, or unbounded start key.
129    pub start: Bound<Vec<u8>>,
130    /// Inclusive, exclusive, or unbounded end key.
131    pub end: Bound<Vec<u8>>,
132}
133
134impl KeyRange {
135    /// Returns an unbounded range over all user keys.
136    #[must_use]
137    pub const fn all() -> Self {
138        Self {
139            start: Bound::Unbounded,
140            end: Bound::Unbounded,
141        }
142    }
143
144    /// Creates a half-open range `[start, end)`.
145    #[must_use]
146    pub fn half_open(start: impl Into<Vec<u8>>, end: impl Into<Vec<u8>>) -> Self {
147        Self {
148            start: Bound::Included(start.into()),
149            end: Bound::Excluded(end.into()),
150        }
151    }
152}
153
154impl Default for KeyRange {
155    fn default() -> Self {
156        Self::all()
157    }
158}
159
160/// Information returned after a write becomes committed.
161#[derive(Debug, Clone, Copy, PartialEq, Eq)]
162pub struct CommitInfo {
163    sequence: Sequence,
164}
165
166impl CommitInfo {
167    #[must_use]
168    pub(crate) const fn new(sequence: Sequence) -> Self {
169        Self { sequence }
170    }
171
172    #[must_use]
173    #[cfg(test)]
174    pub(crate) const fn sequence(self) -> Sequence {
175        self.sequence
176    }
177
178    /// Returns the read version made visible by this write.
179    ///
180    /// For a state-changing atomic write, every operation in the write becomes
181    /// visible at this read version. An accepted empty write batch does not
182    /// create a new database state and returns the latest read version that was
183    /// already visible.
184    #[must_use]
185    pub const fn read_version(self) -> ReadVersion {
186        ReadVersion::from_sequence(self.sequence)
187    }
188}