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
impl BlobStore
Sourcepub fn new(root: impl Into<PathBuf>) -> Result<Self, CasError>
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.
Sourcepub fn open_in_memory() -> Result<(TempDir, Self), CasError>
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.
Sourcepub fn new_uncompressed(root: impl Into<PathBuf>) -> Result<Self, CasError>
pub fn new_uncompressed(root: impl Into<PathBuf>) -> Result<Self, CasError>
Create a BlobStore with compression disabled (for testing).
Sourcepub fn set_verify_on_read(&mut self, verify: bool)
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.
Sourcepub fn verify_on_read(&self) -> bool
pub fn verify_on_read(&self) -> bool
Check whether hash verification is enabled on read.
Sourcepub fn put_blob(&self, data: &[u8]) -> Result<Hash, CasError>
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.
Sourcepub fn put_blob_new(&self, data: &[u8]) -> Result<Hash, CasError>
pub fn put_blob_new(&self, data: &[u8]) -> Result<Hash, CasError>
Store a blob, returning an error if it already exists.
Sourcepub fn put_blob_with_hash(
&self,
data: &[u8],
expected_hash: &Hash,
) -> Result<(), CasError>
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.
Sourcepub fn get_blob(&self, hash: &Hash) -> Result<Vec<u8>, CasError>
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)).
Sourcepub fn has_blob(&self, hash: &Hash) -> bool
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.
Sourcepub fn delete_blob(&self, hash: &Hash) -> Result<(), CasError>
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.
Sourcepub fn blob_count(&self) -> Result<u64, CasError>
pub fn blob_count(&self) -> Result<u64, CasError>
Get the total number of loose blobs in the store.
Sourcepub fn total_size(&self) -> Result<u64, CasError>
pub fn total_size(&self) -> Result<u64, CasError>
Get the total size of all loose blobs in the store (on-disk size).
Sourcepub fn list_blobs(&self) -> Result<Vec<Hash>, CasError>
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).
Sourcepub fn objects_dir(&self) -> PathBuf
pub fn objects_dir(&self) -> PathBuf
Get the path to the objects directory.
Sourcepub fn root(&self) -> &Path
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).
Sourcepub fn invalidate_pack_cache(&self)
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.
Sourcepub fn get_blob_packed(&self, hash: &Hash) -> Result<Vec<u8>, CasError>
pub fn get_blob_packed(&self, hash: &Hash) -> Result<Vec<u8>, CasError>
Retrieve a blob from pack files only (not loose objects).
Sourcepub fn has_blob_packed(&self, hash: &Hash) -> bool
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.
Sourcepub fn list_blobs_packed(&self) -> Result<Vec<Hash>, CasError>
pub fn list_blobs_packed(&self) -> Result<Vec<Hash>, CasError>
List all blob hashes stored in pack files.
Sourcepub fn repack(&self, threshold: usize) -> Result<usize, CasError>
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.