Skip to main content

exoware_server/
engine.rs

1//! Storage callbacks for the store services.
2//!
3//! Implement this trait for your backend. Errors are surfaced to clients as internal RPC failures
4//! (string message only; keep messages safe to expose if you rely on that).
5
6use bytes::Bytes;
7
8/// Implement these operations for your store. All methods must be thread-safe.
9pub trait StoreEngine: Send + Sync + 'static {
10    /// Persist key-value pairs atomically and return the new global sequence number for this write.
11    fn put_batch(&self, kvs: &[(Bytes, Bytes)]) -> Result<u64, String>;
12
13    /// Fetch the value for a single key. Returns `None` when the key does not exist.
14    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, String>;
15
16    /// Keys in `[start, end]` (inclusive) when `end` is non-empty; empty `end` means unbounded
17    /// above. Matches `store.query.v1.RangeRequest` / `ReduceRequest` on the wire. `limit` caps
18    /// rows returned.
19    fn range_scan(
20        &self,
21        start: &[u8],
22        end: &[u8],
23        limit: usize,
24        forward: bool,
25    ) -> Result<Vec<(Bytes, Bytes)>, String>;
26
27    /// Batch-get: returns `(key, Option<value>)` for each input key, preserving order.
28    fn get_many(&self, keys: &[&[u8]]) -> Result<Vec<(Vec<u8>, Option<Vec<u8>>)>, String> {
29        keys.iter()
30            .map(|k| Ok((k.to_vec(), self.get(k)?)))
31            .collect()
32    }
33
34    /// Delete a batch of keys atomically. Returns the new global sequence number.
35    fn delete_batch(&self, keys: &[&[u8]]) -> Result<u64, String>;
36
37    /// Current sequence number visible to readers (used for `min_sequence_number` checks).
38    fn current_sequence(&self) -> u64;
39}