pub struct Journal<E: Storage + Metrics, A: CodecFixed>(/* private fields */);Expand description
A segmented journal with fixed-size entries.
Each section is stored in a separate blob. Within each blob, items are fixed-size.
§Repair
Like sqlite and rocksdb, the first invalid data read will be considered the new end of the journal (and the underlying Blob will be truncated to the last valid item). Repair occurs during replay so clean initialization reads only each blob’s terminal page. A nonempty section opened during initialization must be replayed from position zero before it accepts new appends.
Mutating functions consume the journal and return it only on success: an error (or a dropped future) destroys the handle. Journal::replay consumes the journal into an owned Replay reader, which returns it via Replay::finish once exhausted. Mutations on pruned sections fail with Error::AlreadyPrunedToSection without mutating. Check Journal::pruned first to keep the handle.
Implementations§
Source§impl<E: Storage + Metrics, A: CodecFixedShared> Journal<E, A>
impl<E: Storage + Metrics, A: CodecFixedShared> Journal<E, A>
Sourcepub const CHUNK_SIZE: usize = Inner<E, A>::CHUNK_SIZE
pub const CHUNK_SIZE: usize = Inner<E, A>::CHUNK_SIZE
Size of each entry.
Sourcepub async fn init(context: E, cfg: Config) -> Result<Self, Error>
pub async fn init(context: E, cfg: Config) -> Result<Self, Error>
Initialize a new Journal instance.
Backing blobs are opened without scanning their full page prefixes. Use replay to validate
and iterate over all items before appending to a retained section.
Sourcepub async fn append(self, section: u64, item: &A) -> Result<(Self, u64), Error>
pub async fn append(self, section: u64, item: &A) -> Result<(Self, u64), Error>
Append a new item to the journal in the given section.
Returns the position of the item within the section (0-indexed).
§Panics
Panics when section contained an unvalidated suffix at initialization and has not
completed a replay from position zero.
Sourcepub async fn get(&self, section: u64, position: u64) -> Result<A, Error>
pub async fn get(&self, section: u64, position: u64) -> Result<A, Error>
Read the item at the given section and position.
§Errors
- Error::AlreadyPrunedToSection if the section has been pruned.
- Error::SectionOutOfRange if the section doesn’t exist.
- Error::ItemOutOfRange if the position is beyond the blob size.
Sourcepub async fn get_many(
&self,
section: u64,
positions: &[u64],
buf: &mut [u8],
) -> Result<(Vec<A>, usize), Error>
pub async fn get_many( &self, section: u64, positions: &[u64], buf: &mut [u8], ) -> Result<(Vec<A>, usize), Error>
Read multiple items from the same section into a caller buffer.
buf must be at least positions.len() * CHUNK_SIZE bytes. All positions must be
strictly increasing and within the section’s bounds.
Returns the decoded items and the number served without a blob read (page cache or tip buffer hits).
Sourcepub fn try_get_sync(&self, section: u64, position: u64) -> Option<A>
pub fn try_get_sync(&self, section: u64, position: u64) -> Option<A>
Get an item if it can be done synchronously (e.g. without I/O), returning None otherwise.
Sourcepub async fn last(&self, section: u64) -> Result<Option<A>, Error>
pub async fn last(&self, section: u64) -> Result<Option<A>, Error>
Read the last item in a section, if any.
Returns Ok(None) if the section is empty.
§Errors
- Error::AlreadyPrunedToSection if the section has been pruned.
- Error::SectionOutOfRange if the section doesn’t exist.
Sourcepub async fn replay(
self,
start_section: u64,
start_position: u64,
buffer: NonZeroUsize,
read_options: ReadOptions,
) -> Result<Replay<E, A>, Error>
pub async fn replay( self, start_section: u64, start_position: u64, buffer: NonZeroUsize, read_options: ReadOptions, ) -> Result<Replay<E, A>, Error>
Consumes the journal and returns an owned Replay reader over all items starting
from start_position in start_section.
Setup flushes buffered pages so the reader observes every accepted write. It
validates replay setup but does not allocate buffer bytes per blob. Page buffers
are allocated lazily as the reader advances. Every backing blob read performed by
the returned replay uses read_options, including reads after advancing to
another section.
A nonzero start must be a boundary already validated by a prior replay or a durable marker: torn-page repair treats everything below it as proven.
Sourcepub async fn sync(self, sections: impl Sections) -> Result<Self, Error>
pub async fn sync(self, sections: impl Sections) -> Result<Self, Error>
Sync the given sections to storage.
Sourcepub async fn start_sync(
self,
sections: impl Sections,
) -> Result<(Self, Handle<()>), Error>
pub async fn start_sync( self, sections: impl Sections, ) -> Result<(Self, Handle<()>), Error>
Start syncing the given sections to storage.
An error reported by the returned Handle is fatal to the journal: the caller must stop using the returned journal.
Sourcepub async fn prune(self, min: u64) -> Result<(Self, bool), Error>
pub async fn prune(self, min: u64) -> Result<(Self, bool), Error>
Prune all sections less than min. Returns true if any were pruned.
Sourcepub fn pruned(&self, section: u64) -> bool
pub fn pruned(&self, section: u64) -> bool
Returns true when section is below the prune floor.
The floor only tracks prunes from the current execution and resets at init, so a section pruned in a previous execution reports false.
Sourcepub fn oldest_section(&self) -> Option<u64>
pub fn oldest_section(&self) -> Option<u64>
Returns the oldest section number, if any blobs exist.
Sourcepub fn newest_section(&self) -> Option<u64>
pub fn newest_section(&self) -> Option<u64>
Returns the newest section number, if any blobs exist.
Sourcepub fn sections(&self) -> impl Iterator<Item = u64> + '_
pub fn sections(&self) -> impl Iterator<Item = u64> + '_
Returns an iterator over all section numbers.
Sourcepub fn section_len(&self, section: u64) -> Result<u64, Error>
pub fn section_len(&self, section: u64) -> Result<u64, Error>
Returns the number of items in the given section.
Sourcepub fn size(&self, section: u64) -> Result<u64, Error>
pub fn size(&self, section: u64) -> Result<u64, Error>
Returns the byte size of the given section.
Sourcepub async fn rewind(self, section: u64, size: u64) -> Result<Self, Error>
pub async fn rewind(self, section: u64, size: u64) -> Result<Self, Error>
Rewind the journal to a specific section and byte size.
This truncates the section to the given size. All sections
after section are removed.
Trait Implementations§
Auto Trait Implementations§
impl<E, A> !RefUnwindSafe for Journal<E, A>
impl<E, A> !UnwindSafe for Journal<E, A>
impl<E, A> Freeze for Journal<E, A>
impl<E, A> Send for Journal<E, A>
impl<E, A> Sync for Journal<E, A>
impl<E, A> Unpin for Journal<E, A>
impl<E, A> UnsafeUnpin for Journal<E, A>where
Box<Inner<E, A>>: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more