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