pub struct FBPool<T, B: BackingStoreT> { /* private fields */ }Expand description
Manages a pool of Fb instances, backed by an in-memory cache
and a BackingStore for disk persistence.
§Caching Strategy (Segmented LRU Variant)
The pool utilizes a variation of an LRU (Least Recently Used) cache designed
to reduce overhead for frequently accessed items. The cache is conceptually
divided into two segments (e.g., a “front half” and a “back half”, typically
split evenly based on the total mem_size).
- Promotion: Items loaded from the backing store (
Strategy::load) or accessed while residing in the “back half” of the cache are promoted to the most recently used position (the front of the “front half”). - No Movement: Items accessed while already in the “front half” do not change position. This avoids the overhead of cache entry shuffling for frequently hit “hot” items that are already near the front.
- Insertion: New items inserted via
FBPool::insertalso enter the front of the “front half”. - Eviction: Items are eventually evicted from the least recently used end of the “back half” when the cache is full.
This approach aims to provide LRU-like behavior while optimizing for workloads where a subset of items is accessed very frequently.
Internally, we store each item in an Option<T>. When an item is evicted from cache,
we will replace Some(val) with None. Note that the size of None::<T>`` on the stack is the exact same as that of Some(val). What this means is that if T's resources are primarily represented by its space on the stack (e.g. when Tis[f32; 4096]), there will be zero savings when it's removed from cache. In these cases, you should use Box
Implementations§
Source§impl<T, B: BackingStoreT> FBPool<T, B>
impl<T, B: BackingStoreT> FBPool<T, B>
Sourcepub fn new(store: Arc<BackingStore<B>>, mem_size: usize) -> Self
pub fn new(store: Arc<BackingStore<B>>, mem_size: usize) -> Self
Creates a new pool managing items of type T.
§Arguments
store- The configuredBackingStoremanager.mem_size- The maximum number of items to keep loaded in the in-memory cache. This size is divided internally (50/50) to implement the two-segment caching strategy (see mainFBPooldocumentation for details).
Sourcepub fn store(&self) -> &Arc<BackingStore<B>>
pub fn store(&self) -> &Arc<BackingStore<B>>
Returns a reference to the underlying BackingStore.
Sourcepub fn insert(self: &Arc<Self>, data: T) -> Fb<T, B>
pub fn insert(self: &Arc<Self>, data: T) -> Fb<T, B>
Inserts new data into the pool, returning an Fb handle.
The data is initially placed only in the in-memory LRU cache. It will only be
written to the backing store’s temporary location if it’s evicted from the cache
or explicitly written viapersist/blocking_persist/spawn_write_now/blocking_write_now.
Whenever the data is evicted from memory, after being written to the backing store
with B::store, the data will be dropped normally, which means if there’s a custom Drop
implementation, it will be called. Each time the data is loaded back into memory, this
could happen again if the data is evicted again.
Sourcepub async fn register(
self: &Arc<Self>,
path: &Arc<TrackedPath<B::PersistPath>>,
key: Uuid,
) -> Option<Fb<T, B>>
pub async fn register( self: &Arc<Self>, path: &Arc<TrackedPath<B::PersistPath>>, key: Uuid, ) -> Option<Fb<T, B>>
Asynchronously registers an existing item from a persistent path into the pool.
Creates an Fb handle for an item identified by key located at the
tracked persistent path. This typically involves calling BackingStoreT::register
(e.g., hard-linking the file into the managed temporary area).
The item data is not loaded into memory by this call.
Returns None if the registration fails (e.g., the underlying store fails to find the key).
Sourcepub fn blocking_register(
self: &Arc<Self>,
path: &TrackedPath<B::PersistPath>,
key: Uuid,
) -> Option<Fb<T, B>>
pub fn blocking_register( self: &Arc<Self>, path: &TrackedPath<B::PersistPath>, key: Uuid, ) -> Option<Fb<T, B>>
Blocking version of register. Waits for the registration to complete.
Must not be called from an async context that isn’t allowed to block.