Skip to main content

DbPool

Enum DbPool 

Source
pub enum DbPool {
    PerThread {
        path: PathBuf,
        poll: Box<ReentrantMutex<Db<ReadOnly>>>,
        conns: DashMap<ThreadId, Arc<ReentrantMutex<Db<ReadOnly>>>>,
    },
    Shared(Arc<ReentrantMutex<Db<ReadOnly>>>),
}
Expand description

with and with_poll may nest freely, on any variant: PerThread reads hand out cloned Arcs from the pool-owned map, and the connection locks are reentrant.

The poll/conns asymmetry is deliberate. poll is uniquely owned (the Box only keeps the variant small) because with_poll locks it in place and takes no other lock. conns is a DashMap, so with never serializes concurrent reads on a single map lock — a steady-state hit takes only a shard read lock. Values are Arc-wrapped so with can clone a handle and release the shard guard before running the caller’s closure — holding a (non-reentrant) shard guard across it would deadlock a nested with whose thread hashes to the same shard. The inner ReentrantMutex is never contended (only its owning thread locks it) but is load-bearing for the type system: Db is Send + !Sync, so the mutex wrapper is what keeps the map values, and therefore DbPool, Send + Sync.

Variants§

Implementations§

Source§

impl DbPool

Source

pub fn new(db: Db) -> Result<DbPool>

Build a pool from the DB used to construct the mount. File-backed DBs become per-thread pools (the passed connection becomes the poll connection — workers open their own); in-memory DBs are wrapped in a shared mutex.

Source

pub fn with_poll<R>( &self, f: impl FnOnce(&Db<ReadOnly>) -> Result<R>, ) -> Result<R>

Run f with the persistent poll connection.

For PerThread pools, PRAGMA data_version is connection-relative: a fresh thread-local connection starts at 0, so it can’t detect changes that happened before it opened. The poll connection is the original writer Db, kept alive precisely so it can observe incremental changes from other connections. For Shared pools (in-memory), the single shared connection serves both roles.

Source

pub fn with<R>(&self, f: impl FnOnce(&Db<ReadOnly>) -> Result<R>) -> Result<R>

Run f with a read connection.

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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.