pub struct Journal<E: Storage + Metrics, V: Codec>(/* private fields */);Expand description
A segmented journal with variable-size entries.
Each section is stored in a separate blob. Items are length-prefixed with a varint.
§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 (not init) because any blob could have trailing bytes. A nonempty section opened during initialization must be replayed from offset zero before it accepts new appends. Sections created during the current execution can be appended immediately.
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, V: CodecShared> Journal<E, V>
impl<E: Storage + Metrics, V: CodecShared> Journal<E, V>
Sourcepub async fn init(context: E, cfg: Config<V::Cfg>) -> Result<Self, Error>
pub async fn init(context: E, cfg: Config<V::Cfg>) -> Result<Self, Error>
Initialize a new Journal instance.
All backing blobs are opened but not read during
initialization. The replay method can be used
to iterate over all items in the Journal.
Sourcepub async fn replay(
self,
start_section: u64,
start_offset: u64,
buffer: NonZeroUsize,
read_options: ReadOptions,
) -> Result<Replay<E, V>, Error>
pub async fn replay( self, start_section: u64, start_offset: u64, buffer: NonZeroUsize, read_options: ReadOptions, ) -> Result<Replay<E, V>, Error>
Consumes the journal and returns an owned Replay reader over all items starting
with the item at the given start_section and start_offset into that section.
Setup flushes buffered pages so the reader observes every accepted write. It
validates the requested start bound 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 append(
self,
section: u64,
item: &V,
) -> Result<(Self, u64, u32), Error>
pub async fn append( self, section: u64, item: &V, ) -> Result<(Self, u64, u32), Error>
Appends an item to Journal in a given section, returning the offset
where the item was written and the size of the item (which may differ
from the raw encoded size if compression is enabled).
§Panics
Panics when section contained data at initialization and has not completed a replay
from offset zero.
Sourcepub async fn get(&self, section: u64, offset: u64) -> Result<V, Error>
pub async fn get(&self, section: u64, offset: u64) -> Result<V, Error>
Retrieves an item from Journal at a given section and offset.
§Errors
- Error::AlreadyPrunedToSection if the requested
sectionhas been pruned during the current execution. - Error::SectionOutOfRange if the requested
sectionis empty (i.e. has never had any data appended to it, or has been pruned in a previous execution). - An invalid
offsetfor a given section (that is, an offset that doesn’t correspond to a previously appended item) will result in an error, with the specific type being undefined.
Sourcepub async fn get_many(
&self,
section: u64,
offsets: &[u64],
) -> Result<Vec<V>, Error>
pub async fn get_many( &self, section: u64, offsets: &[u64], ) -> Result<Vec<V>, Error>
Read multiple items from the same section.
Offsets should be sorted in ascending order.
Sourcepub fn try_get_sync(&self, section: u64, offset: u64) -> Option<V>
pub fn try_get_sync(&self, section: u64, offset: u64) -> Option<V>
Get an item if it can be done synchronously (e.g. without I/O), returning None otherwise.
Sourcepub fn size(&self, section: u64) -> Result<u64, Error>
pub fn size(&self, section: u64) -> Result<u64, Error>
Gets the size of the journal for a specific section.
Returns 0 if the section does not exist.
Sourcepub async fn rewind(self, section: u64, size: u64) -> Result<Self, Error>
pub async fn rewind(self, section: u64, size: u64) -> Result<Self, Error>
Rewinds the journal to the given section and size.
This removes any data beyond the specified section and size.
§Warnings
- This operation is not guaranteed to survive restarts until sync is called.
- This operation is not atomic, but it will always leave the journal in a consistent state in the event of failure since blobs are always removed in reverse order of section.
Sourcepub async fn rewind_section(
self,
section: u64,
size: u64,
) -> Result<Self, Error>
pub async fn rewind_section( self, section: u64, size: u64, ) -> Result<Self, Error>
Rewinds the section to the given size.
Unlike Self::rewind, this method does not modify anything other than the given section.
§Warning
This operation is not guaranteed to survive restarts until sync is called.
Sourcepub async fn sync(self, sections: impl Sections) -> Result<Self, Error>
pub async fn sync(self, sections: impl Sections) -> Result<Self, Error>
Ensures the given sections are synced to the underlying store.
If a selected section does not exist (and has not been pruned), no error will be returned.
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>
Prunes all sections less than min. Returns true if any sections 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 number of the oldest section in the journal.
Sourcepub fn newest_section(&self) -> Option<u64>
pub fn newest_section(&self) -> Option<u64>
Returns the number of the newest section in the journal.
Sourcepub fn num_sections(&self) -> usize
pub fn num_sections(&self) -> usize
Returns the number of sections.
Trait Implementations§
Auto Trait Implementations§
impl<E, V> !RefUnwindSafe for Journal<E, V>
impl<E, V> !UnwindSafe for Journal<E, V>
impl<E, V> Freeze for Journal<E, V>
impl<E, V> Send for Journal<E, V>
impl<E, V> Sync for Journal<E, V>
impl<E, V> Unpin for Journal<E, V>
impl<E, V> UnsafeUnpin for Journal<E, V>where
Box<Inner<E, V>>: 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