Skip to main content

weavatrix_memory/
store.rs

1mod file;
2pub(crate) mod frame;
3mod in_memory;
4mod subscription;
5
6pub use file::{Durability, FileEventStore, FileStoreOptions, RecoveryPolicy};
7pub use in_memory::InMemoryStore;
8pub use subscription::{CatchUpSubscription, SubscriptionCheckpoint};
9
10use crate::{NewEvent, Result, StoredEvent, StreamId};
11
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
13pub struct AppendReceipt {
14    pub event_count: usize,
15    pub first_stream_version: Option<u64>,
16    pub last_stream_version: Option<u64>,
17    pub first_global_position: Option<u64>,
18    pub last_global_position: Option<u64>,
19}
20
21impl AppendReceipt {
22    fn from_events<E>(events: &[StoredEvent<E>]) -> Self {
23        Self {
24            event_count: events.len(),
25            first_stream_version: events.first().map(|event| event.metadata.stream_version),
26            last_stream_version: events.last().map(|event| event.metadata.stream_version),
27            first_global_position: events.first().map(|event| event.metadata.global_position),
28            last_global_position: events.last().map(|event| event.metadata.global_position),
29        }
30    }
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum ExpectedVersion {
35    Any,
36    NoStream,
37    Exact(u64),
38}
39
40pub trait EventStore<E: Clone> {
41    /// Atomically appends a batch to one stream.
42    ///
43    /// # Errors
44    ///
45    /// Returns a version conflict, duplicate event, or capacity error without
46    /// committing a partial batch.
47    fn append(
48        &mut self,
49        stream: &StreamId,
50        expected: ExpectedVersion,
51        events: &[NewEvent<E>],
52    ) -> Result<Vec<StoredEvent<E>>>;
53
54    /// Appends an owned batch without requiring callers to retain the inputs.
55    ///
56    /// Stores may override this to move payloads into committed envelopes and
57    /// avoid the input clone required by [`Self::append`].
58    ///
59    /// # Errors
60    ///
61    /// Returns the same version, duplicate-event, capacity, or persistence
62    /// errors as [`Self::append`].
63    fn append_owned(
64        &mut self,
65        stream: &StreamId,
66        expected: ExpectedVersion,
67        events: Vec<NewEvent<E>>,
68    ) -> Result<Vec<StoredEvent<E>>> {
69        self.append(stream, expected, &events)
70    }
71
72    /// Appends an owned batch and returns positions without cloning committed
73    /// payloads back to the caller.
74    ///
75    /// Stores may override this high-throughput path to move the committed
76    /// envelopes directly into storage.
77    ///
78    /// # Errors
79    ///
80    /// Returns the same errors as [`Self::append_owned`].
81    fn append_owned_receipt(
82        &mut self,
83        stream: &StreamId,
84        expected: ExpectedVersion,
85        events: Vec<NewEvent<E>>,
86    ) -> Result<AppendReceipt> {
87        self.append_owned(stream, expected, events)
88            .map(|events| AppendReceipt::from_events(&events))
89    }
90
91    fn load_stream(&self, stream: &StreamId, after: Option<u64>) -> Vec<StoredEvent<E>>;
92
93    fn load_all(&self, after: Option<u64>, limit: usize) -> Vec<StoredEvent<E>>;
94
95    fn stream_version(&self, stream: &StreamId) -> Option<u64>;
96
97    fn len(&self) -> usize;
98
99    fn is_empty(&self) -> bool {
100        self.len() == 0
101    }
102}