Skip to main content

DurableRoot

Struct DurableRoot 

Source
pub struct DurableRoot { /* private fields */ }
Expand description

Descriptor-pinned root for durable state owned by a database.

Every relative operation rejects .., symlinks, reparse points, and non-regular final files. Unix operations stay descriptor-relative. Windows keeps the root and each traversed ancestor open without delete sharing.

§Deferred fsync (batch-create) mode

Self::open_deferred produces a root whose write/mkdir/rename operations skip their per-call fsyncs. The caller must invoke Self::finalize_deferred_sync once to fsync the whole tree and re-enable eager (per-call) fsync for subsequent operations. This is the primary mechanism for amortizing fsync cost out of batch-create paths such as crate::engine::Table::create, which would otherwise pay ~9 fsync round-trips for a fresh table. Security semantics (descriptor-pinning, path validation) are unaffected — only durability timing changes.

Implementations§

Source§

impl DurableRoot

Source

pub fn try_clone(&self) -> Result<Self>

Source

pub fn open(root: impl AsRef<Path>) -> Result<Self>

Source

pub fn canonical_path(&self) -> &Path

Source

pub fn file_identity(&self) -> Result<DurableFileIdentity>

Return the stable identity of the pinned directory handle.

Source

pub fn open_deferred(root: impl AsRef<Path>) -> Result<Self>

Open the root in deferred-fsync mode: subsequent write_new, write_atomic*, create_directory_*, replace*, and copy_new_from operations skip their per-call fsyncs. The caller must invoke Self::finalize_deferred_sync exactly once to make the deferred writes durable and re-enable eager fsync for future operations.

Intended for batch-create paths (e.g. crate::engine::Table::create) that issue many independent durable writes against a fresh tree. On a filesystem where each fsync costs ~1 ms, this collapses ~9 fsync round-trips per create into a single recursive pass. Security semantics (descriptor-pinning, path validation, symlink rejection) are identical to Self::open; only the timing of fsync changes. Calling this on a root that will receive ongoing individual durable writes without a matching finalize would silently lose durability — restrict it to batch paths that finalize on every exit path.

Source

pub fn finalize_deferred_sync(&self) -> Result<()>

Fsync every file and directory under this root, then re-enable eager (per-call) fsync for subsequent operations. Idempotent: a root already in eager mode returns immediately after syncing the tree once. Returns the first sync error encountered (the caller must treat the tree as untrusted if this errors).

Source

pub fn finalize_deferred_sync_shallow(&self) -> Result<()>

Shallow variant of Self::finalize_deferred_sync: fsync the data of every regular file directly under the root, then fsync the root directory and each immediate subdirectory for entry-name durability. Does NOT recurse into subdirectories or fsync files inside them.

This matches the pre-hardening durability contract: the manifest (and any other root-level file) is data-durable, and all entry names in the root and its immediate children are durable. Files inside _wal/, _runs/, etc. rely on the OS page cache and the first commit() or flush() to become data-durable — identical to the behavior before the descriptor-pinned hardening pass. Used by plaintext Table::create where the extra fsyncs of the recursive variant would dominate batch-create cost without changing the observable crash-recovery contract (a table is always reopened via its manifest, and the first commit makes everything else durable).

Source

pub fn io_path(&self) -> Result<PathBuf>

Stable operational path backed by the pinned directory descriptor. Use this for legacy path-based code while the DurableRoot stays alive.

Source

pub fn open_directory(&self, relative: impl AsRef<Path>) -> Result<DurableRoot>

Source

pub fn create_directory_all(&self, relative: impl AsRef<Path>) -> Result<()>

Source

pub fn create_directory_all_pinned( &self, relative: impl AsRef<Path>, ) -> Result<DurableRoot>

Source

pub fn create_directory_new(&self, relative: impl AsRef<Path>) -> Result<()>

Source

pub fn open_regular(&self, relative: impl AsRef<Path>) -> Result<File>

Source

pub fn entry_exists(&self, relative: impl AsRef<Path>) -> Result<bool>

Source

pub fn write_new(&self, relative: impl AsRef<Path>, bytes: &[u8]) -> Result<()>

Source

pub fn write_new_atomic( &self, relative: impl AsRef<Path>, bytes: &[u8], ) -> Result<()>

Write an immutable file and publish its name only after its contents are durable. Concurrent creators get AlreadyExists and can safely read the complete winner.

Source

pub fn copy_new_from( &self, relative: impl AsRef<Path>, source: &mut File, ) -> Result<u64>

Source

pub fn write_atomic( &self, relative: impl AsRef<Path>, bytes: &[u8], ) -> Result<()>

Source

pub fn open_lock_file(&self, relative: impl AsRef<Path>) -> Result<File>

Source

pub fn list_regular_files( &self, relative: impl AsRef<Path>, ) -> Result<Vec<OsString>>

Source

pub fn remove_file(&self, relative: impl AsRef<Path>) -> Result<()>

Source

pub fn rename_directory_new( &self, source: impl AsRef<Path>, destination_root: &DurableRoot, destination: impl AsRef<Path>, ) -> Result<()>

Source

pub fn rename_directory_new_with_after<F>( &self, source: impl AsRef<Path>, destination_root: &DurableRoot, destination: impl AsRef<Path>, after_publish: F, ) -> Result<()>
where F: FnOnce(),

Source

pub fn remove_directory_all(&self, relative: impl AsRef<Path>) -> Result<()>

Trait Implementations§

Source§

impl Debug for DurableRoot

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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.