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 snapshot;
21mod verify;
22
23pub use backend::{Admission, JournalBackend, StoredState};
24pub use entry::JournalEntry;
25pub use head::JournalHead;
26pub use host::HostDirJournalBackend;
27pub use lease::Lease;
28pub use memory::MemoryBackend;
29pub use native_codec::{
30 BackendCapabilities, EntryLocation, EntryNamespace, Failpoint, NativeFormatId,
31 NativeStateEnvelope, VerifiedNativePrefixRef,
32};
33pub use object::JournalObject;
34pub use persistent::{
35 PersistentObjectStore, PersistentSemanticObjects, StoreError, StoredDatumRef,
36};
37pub use projection::{DirProjection, ProjectionRow, TableProjection};
38pub use replay::{Replay, replay};
39pub use snapshot::VerifiedSnapshot;
40pub use verify::{JournalError, Verification};
41
42use sim_kernel::{ContentId, Symbol};
43
44pub struct Journal<B> {
46 backend: B,
47}
48
49impl<B: JournalBackend> Journal<B> {
50 pub fn new(backend: B) -> Self {
52 Self { backend }
53 }
54
55 pub fn acquire_lease(&self) -> Result<Lease, JournalError> {
57 self.backend.acquire_lease()
58 }
59
60 pub fn head(&self) -> Result<Option<JournalHead>, JournalError> {
62 let state = self.backend.read_state()?;
63 verify::verify_state(&state).map(|v| v.head)
64 }
65
66 pub fn publish(
71 &self,
72 lease: &Lease,
73 expected: Option<&JournalHead>,
74 objects: Vec<JournalObject>,
75 entries: Vec<JournalEntry>,
76 ) -> Result<JournalHead, JournalError> {
77 if entries.is_empty() {
78 return Err(JournalError::EmptyBatch);
79 }
80 let before = self.backend.read_state()?;
81 verify::verify_state(&before)?;
82 verify::verify_batch(&before, expected, &objects, &entries)?;
83 let head = self.backend.admit(Admission {
84 fence: lease.fence,
85 expected: expected.cloned(),
86 objects,
87 entries: entries.clone(),
88 })?;
89 Ok(head)
90 }
91
92 pub fn verify(&self) -> Result<Verification, JournalError> {
94 verify::verify_state(&self.backend.read_state()?)
95 }
96
97 pub fn replay(&self) -> Result<Replay, JournalError> {
99 replay(self.backend.read_state()?)
100 }
101
102 pub fn verified_snapshot(&self) -> Result<VerifiedSnapshot, JournalError> {
108 VerifiedSnapshot::from_state(self.backend.read_state()?)
109 }
110
111 pub fn table_projection(&self) -> Result<TableProjection, JournalError> {
113 Ok(TableProjection::from_verification(self.verify()?))
114 }
115
116 pub fn dir_projection(&self) -> Result<DirProjection, JournalError> {
118 Ok(DirProjection::from_verification(self.verify()?))
119 }
120
121 pub fn entry(
123 sequence: u64,
124 previous: Option<ContentId>,
125 kind: Symbol,
126 payloads: Vec<ContentId>,
127 ) -> JournalEntry {
128 JournalEntry::new(sequence, previous, kind, payloads)
129 }
130}
131
132#[cfg(test)]
133mod tests;