1mod backend;
9mod datum_codec;
10mod entry;
11mod head;
12mod host;
13mod lease;
14mod memory;
15mod native_codec;
16mod object;
17mod persistent;
18mod projection;
19mod replay;
20mod verify;
21
22pub use backend::{Admission, JournalBackend, StoredState};
23pub use entry::JournalEntry;
24pub use head::JournalHead;
25pub use host::HostDirJournalBackend;
26pub use lease::Lease;
27pub use memory::MemoryBackend;
28pub use native_codec::{
29 BackendCapabilities, EntryLocation, EntryNamespace, Failpoint, NativeFormatId,
30 NativeStateEnvelope, VerifiedNativePrefixRef,
31};
32pub use object::JournalObject;
33pub use persistent::{
34 PersistentObjectStore, PersistentSemanticObjects, StoreError, StoredDatumRef,
35};
36pub use projection::{DirProjection, ProjectionRow, TableProjection};
37pub use replay::{Replay, replay};
38pub use verify::{JournalError, Verification};
39
40use sim_kernel::{ContentId, Symbol};
41
42pub struct Journal<B> {
44 backend: B,
45}
46
47impl<B: JournalBackend> Journal<B> {
48 pub fn new(backend: B) -> Self {
50 Self { backend }
51 }
52
53 pub fn acquire_lease(&self) -> Result<Lease, JournalError> {
55 self.backend.acquire_lease()
56 }
57
58 pub fn head(&self) -> Result<Option<JournalHead>, JournalError> {
60 let state = self.backend.read_state()?;
61 verify::verify_state(&state).map(|v| v.head)
62 }
63
64 pub fn publish(
69 &self,
70 lease: &Lease,
71 expected: Option<&JournalHead>,
72 objects: Vec<JournalObject>,
73 entries: Vec<JournalEntry>,
74 ) -> Result<JournalHead, JournalError> {
75 if entries.is_empty() {
76 return Err(JournalError::EmptyBatch);
77 }
78 let before = self.backend.read_state()?;
79 verify::verify_state(&before)?;
80 verify::verify_batch(&before, expected, &objects, &entries)?;
81 let head = self.backend.admit(Admission {
82 fence: lease.fence,
83 expected: expected.cloned(),
84 objects,
85 entries: entries.clone(),
86 })?;
87 Ok(head)
88 }
89
90 pub fn verify(&self) -> Result<Verification, JournalError> {
92 verify::verify_state(&self.backend.read_state()?)
93 }
94
95 pub fn replay(&self) -> Result<Replay, JournalError> {
97 replay(self.backend.read_state()?)
98 }
99
100 pub fn table_projection(&self) -> Result<TableProjection, JournalError> {
102 Ok(TableProjection::from_verification(self.verify()?))
103 }
104
105 pub fn dir_projection(&self) -> Result<DirProjection, JournalError> {
107 Ok(DirProjection::from_verification(self.verify()?))
108 }
109
110 pub fn entry(
112 sequence: u64,
113 previous: Option<ContentId>,
114 kind: Symbol,
115 payloads: Vec<ContentId>,
116 ) -> JournalEntry {
117 JournalEntry::new(sequence, previous, kind, payloads)
118 }
119}
120
121#[cfg(test)]
122mod tests;