file_backed
Provides types for managing collections of large objects, using an in-memory LRU cache backed by persistent storage (typically the filesystem).
Overview
This crate provides FBPool
and FBArc
(File-Backed Arc) to manage data (T
) that might be too large or numerous to keep entirely in memory. It uses a strategy similar to a swap partition:
- In-Memory Cache: An LRU cache (
FBPool
) keeps frequently/recently used items readily available in memory. - Backing Store: When items are evicted from the cache, or when explicitly requested, they are serialized and written to a temporary location in a backing store (like disk).
- Lazy Loading: When an item not in the cache is accessed via its
FBArc
handle (.load()
,.load_async()
, etc.), it's automatically read back from the backing store. - Reference Counting:
FBArc
acts likestd::sync::Arc
, tracking references. - Automatic Cleanup: When the last
FBArc
for an item is dropped, its corresponding data in the temporary backing store is automatically deleted via a background task. - Persistence: Items can be explicitly "persisted" (e.g., hard-linked) to a separate, permanent location and later "registered" back into a pool, allowing data to survive application restarts.
Core Components
FBPool<T, B>
: Manages the collection, including the LRU cache and interaction with the backing store.FBArc<T, B>
: A smart pointer (likeArc
) to an item managed by the pool. Access requires calling a.load()
variant.BackingStoreT
Trait: Defines the low-level storage operations (delete, persist, register, etc.). You typically implement this or use a provided one (likeFBStore
). This handles where and how raw data blobs (identified byUuid
) are physically stored.Strategy<T>
Trait: ExtendsBackingStoreT
. Defines how your specific data typeT
is serialized (store
) and deserialized (load
).BackingStore<B>
Struct: A wrapper around aBackingStoreT
implementation that manages concurrency, background tasks (using Tokio), and tracking of persistent paths.FBPool
uses this internally.ReadGuard
/WriteGuard
: RAII guards returned byload
methods, providing access to the data and ensuring it stays loaded.WriteGuard
marks data as dirty for writing back to the store.
Features
bincoder
: Providesfbstore::BinCoder
, an implementation offbstore::Coder<T>
usingbincode
for serialization (requiresT: Serialize + DeserializeOwned
).prostcoder
: Providesfbstore::ProstCoder
, an implementation offbstore::Coder<T>
usingprost
for serialization (requiresT: prost::Message + Default
).dupe
: Implementsdupe::Dupe
forFBArc
.
Basic Usage
This example shows basic insertion, loading (which may come from cache or disk), and automatic cleanup.
// examples/simple_usage.rs
use Arc;
use tempdir;
use Handle;
use ;
use ;
async
Persistence
Items can be persisted to survive application restarts using persist
and brought back using register
. This typically uses hard links in file-based stores.
// examples/persistence.rs
use Arc;
use tempdir;
use Handle;
use ;
use ;
async
Provided Filesystem Backing (FBStore
)
FBStore
is a filesystem-based implementation of BackingStoreT
.
- It requires a
Coder<T>
(BinCoder
orProstCoder
via features, or your own implementation) to handle serialization. - It uses a
PreparedPath
, which manages a directory structure (subdirectories00
toff
) for sharding files based on theirUuid
. persist
andregister
are implemented usingstd::fs::hard_link
.
Concurrency
- The
BackingStore
uses a Tokio runtime (tokio::runtime::Handle
) provided during initialization to manage background tasks (like deletions, cache write-backs) and async operations. - Methods often come in pairs:
some_operation_async()
/spawn_some_operation()
: Return aFuture
orJoinHandle
, suitable for async contexts.blocking_some_operation()
: Perform the operation blockingly. Must not be called from an async context unless usingspawn_blocking
orblock_in_place
.
FBArc::load()
: Special case. If data isn't in memory, it usestokio::task::block_in_place
to call the blocking load logic. Warning: This will panic if called within atokio::runtime::Runtime
created usingRuntime::new_current_thread
. Useload_async
in async code.- The library aims to be thread-safe and select/cancel-safe; concurrent access via different
FBArc
handles (even for the same data) or pool operations from multiple threads should be handled correctly via internal synchronization.
Running Examples
cargo run --example simple_usage --features=bincoder
cargo run --example persistence --features=bincoder