Skip to main content

Journal

Struct Journal 

Source
pub struct Journal<S: Store> {
    store: S,
    ledger: Ledger,
    offset: u64,
    checkpoint_seq: u64,
    head: Hash,
    pending_sentinel: Option<(TxnId, Vec<u8>)>,
}

Fields§

§store: S§ledger: Ledger§offset: u64

Byte offset of the next record in the log.

§checkpoint_seq: u64

The checkpoint seq this handle’s ledger incorporates.

§head: Hash

The hash chain’s head after the last record this handle has read (I18).

§pending_sentinel: Option<(TxnId, Vec<u8>)>

During a reload: the sentinel’s transaction and bytes, not yet applied (§12c). Its interlock is applied just before a Resolved that names it, or after the scan.

Implementations§

Source§

impl<S: Store> Journal<S>

Source

pub fn open(store: S) -> Result<Journal<S>, JournalError>

Load the checkpoint, replay the log, truncate a torn tail.

Source

fn load_checkpoint(&self) -> Result<Option<(u64, Ledger, Hash)>, JournalError>

Source

fn checkpoint_seq_on_disk(&self) -> Result<u64, JournalError>

Source

fn reload(&mut self) -> Result<(), JournalError>

Source

fn clear_resolved_sentinel(&mut self) -> Result<(), JournalError>

At compaction: the checkpoint now carries the resolution, so the sentinel of a resolved transaction is zeroed and a reload does not set the interlock again. (A crash before the zeroing leaves it set: the safe side; resolving again clears it.)

Source

fn scan(&mut self, reload: bool) -> Result<(), JournalError>

Read records from self.offset onward; the first frame that is not intact, or whose seq does not follow, ends the scan.

reload (scanning from offset 0 after loading the checkpoint) differs in two ways. A leading run of frames at or below the checkpoint’s seq is skipped, which happens only if a crash came between writing a checkpoint and resetting the log. And the frame that ends the scan has its header zeroed (torn-tail truncation). When catching up from a later offset, nothing is skipped: a frame there with an old seq is a leftover from before a compaction, and skipping it would move the write offset past it.

Source

fn stop_at_tail(&mut self, truncate: bool) -> Result<(), JournalError>

The scan stopped at self.offset. On reload that is the torn tail, truncated, unless an intact record with a later seq follows it: then a record before the tail was damaged or edited (I18), and nothing is truncated.

Source

fn later_record(&self) -> Result<Option<u64>, JournalError>

An intact frame after self.offset whose seq is past the ledger’s: the sign of a damaged record rather than a torn tail. Bytes left over from before a compaction all carry seqs at or below the checkpoint’s.

Source

pub fn verify_chain(&mut self) -> Result<(), JournalError>

Re-read the whole segment from the checkpoint and check that it still chains to the head this handle holds (I18): catches a retained record edited on disk after it was read. Read-only.

Source

pub fn head(&self) -> Hash

The chain head after the last record (carried by the next checkpoint).

Source

fn refresh(&mut self) -> Result<(), JournalError>

Catch up on records written by other handles since this one last looked.

Source

pub fn ledger(&self) -> &Ledger

Source

pub fn store(&self) -> &S

Source

pub fn sync_ledger(&mut self) -> Result<&Ledger, JournalError>

Re-read the shared journal and return the current ledger.

Source

pub fn append( &mut self, at: Timestamp, record: Record, ) -> Result<Entry, JournalError>

Validate, write, fsync, then apply (write-ahead). Returns the entry.

Source

pub fn locked<R>( &mut self, f: impl FnOnce(&mut Locked<'_, S>) -> R, ) -> Result<R, JournalError>

Run f with the store lock held, after catching up. Used for read-decide-append sequences that must not interleave with another handle (lease takeover).

Source

fn append_locked( &mut self, at: Timestamp, record: Record, ) -> Result<Entry, JournalError>

Source

pub fn segment(&mut self) -> Result<Vec<Entry>, JournalError>

The entries in the current log segment (everything since the last checkpoint), in order.

Source

pub fn offset(&self) -> u64

Byte offset where the next record will be written.

Source

pub fn usage_permille(&self) -> u64

Fraction of the preallocation in use, in per-mille.

Source

pub fn needs_compaction(&self) -> bool

Compaction triggers at 75% full (§12c).

Source

pub fn compact(&mut self) -> Result<(), JournalError>

Checkpoint-then-truncate. If the checkpoint write fails, nothing changes.

Source

pub fn write_sentinel( &mut self, txn: TxnId, note: &str, ) -> Result<(), JournalError>

The fixed-size fallback when a recovery-path record cannot be written (§12c): marks the transaction RecoveryFailed outside the journal and sets the interlock.

Source

fn apply_sentinel(&mut self, bytes: &[u8])

Auto Trait Implementations§

§

impl<S> Freeze for Journal<S>
where S: Freeze,

§

impl<S> RefUnwindSafe for Journal<S>
where S: RefUnwindSafe,

§

impl<S> Send for Journal<S>
where S: Send,

§

impl<S> Sync for Journal<S>
where S: Sync,

§

impl<S> Unpin for Journal<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for Journal<S>
where S: UnsafeUnpin,

§

impl<S> UnwindSafe for Journal<S>
where S: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.