Skip to main content

BlobStore

Struct BlobStore 

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

The content-addressable-storage blob store.

Stores blobs indexed by BLAKE3 hash on the local filesystem. Provides deduplication, optional compression, and integrity verification.

§Thread Safety

BlobStore is Send + Sync and can be shared across threads via Arc. The pack index cache uses Mutex for interior mutability.

Implementations§

Source§

impl BlobStore

Source

pub fn new(root: impl Into<PathBuf>) -> Result<Self, CasError>

Create a new BlobStore rooted at the given directory.

Creates the objects/ subdirectory if it doesn’t exist.

Source

pub fn open_in_memory() -> Result<(TempDir, Self), CasError>

Create a BlobStore backed by a temporary directory.

Useful for testing and in-memory repository usage. The temporary directory is cleaned up when the returned TempDir is dropped.

Source

pub fn new_uncompressed(root: impl Into<PathBuf>) -> Result<Self, CasError>

Create a BlobStore with compression disabled (for testing).

Source

pub fn set_verify_on_read(&mut self, verify: bool)

Set whether to verify blob hashes on read.

When disabled, get_blob() skips the BLAKE3 hash verification step, saving O(n) computation per read. The content-addressed storage scheme already provides correctness by construction (the filename is the hash), so this is safe for performance-critical paths which may read many blobs in sequence.

Source

pub fn verify_on_read(&self) -> bool

Check whether hash verification is enabled on read.

Source

pub fn put_blob(&self, data: &[u8]) -> Result<Hash, CasError>

Store a blob, returning its BLAKE3 hash.

If a blob with the same hash already exists, this is a no-op (deduplication). Returns the hash either way.

Source

pub fn put_blob_new(&self, data: &[u8]) -> Result<Hash, CasError>

Store a blob, returning an error if it already exists.

Source

pub fn put_blob_with_hash( &self, data: &[u8], expected_hash: &Hash, ) -> Result<(), CasError>

Store a blob with an explicit hash (used when receiving blobs from a remote).

Verifies the data matches the expected hash before storing.

Source

pub fn get_blob(&self, hash: &Hash) -> Result<Vec<u8>, CasError>

Retrieve a blob by its BLAKE3 hash.

Tries the in-memory cache, then loose objects, then pack files. Decompresses if necessary and verifies the hash of the result (unless verification was disabled via set_verify_on_read(false)).

Source

pub fn has_blob(&self, hash: &Hash) -> bool

Check if a blob exists in the store.

Checks loose objects first, then pack files. This does NOT verify the blob’s integrity — it only checks for existence.

Source

pub fn delete_blob(&self, hash: &Hash) -> Result<(), CasError>

Delete a blob from the store.

The caller is responsible for ensuring no patches reference this blob.

Source

pub fn blob_count(&self) -> Result<u64, CasError>

Get the total number of loose blobs in the store.

Source

pub fn total_size(&self) -> Result<u64, CasError>

Get the total size of all loose blobs in the store (on-disk size).

Source

pub fn list_blobs(&self) -> Result<Vec<Hash>, CasError>

List all loose blob hashes in the store.

Entries whose names do not form valid 64-char hex are skipped (they are not valid content addresses).

Source

pub fn objects_dir(&self) -> PathBuf

Get the path to the objects directory.

Source

pub fn root(&self) -> &Path

Get the store root directory (the parent of objects/).

GC sweeps in trash mode place recoverable copies under <root>/trash/ (see crate::gc).

Source

pub fn pack_dir(&self) -> PathBuf

Get the path to the pack directory.

Source

pub fn invalidate_pack_cache(&self)

Invalidate the pack cache (call after repack or external pack changes).

Best-effort: if the lock is poisoned the cache is left as-is; the next successful lock still sees whatever entries exist, and pack lookups remain correct because pack content is immutable once written.

Source

pub fn get_blob_packed(&self, hash: &Hash) -> Result<Vec<u8>, CasError>

Retrieve a blob from pack files only (not loose objects).

Source

pub fn has_blob_packed(&self, hash: &Hash) -> bool

Check if a blob exists in any pack file.

Best-effort: a poisoned pack-cache lock reads as “not present” rather than panicking; callers doing integrity-critical work should use get_blob (which propagates lock poisoning) instead.

Source

pub fn list_blobs_packed(&self) -> Result<Vec<Hash>, CasError>

List all blob hashes stored in pack files.

Source

pub fn repack(&self, threshold: usize) -> Result<usize, CasError>

Repack loose blobs into a pack file if the count exceeds the threshold.

Returns the number of blobs that were packed. If the loose blob count is at or below the threshold, no packing occurs and 0 is returned. After successful packing, the loose blobs are removed.

Loose-blob deletion after the pack write is best-effort: if a delete fails, the blob simply remains loose (and takes read priority), so no data is lost and no error is raised.

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

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.