1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// SPDX-License-Identifier: MIT OR Apache-2.0
//! `cas-kit` — a content-addressed storage (CAS) primitive.
//!
//! Blobs are stored on the local filesystem and identified by their
//! BLAKE3 hash (32 bytes / 256 bits). Identical blobs are deduplicated
//! automatically; integrity can be verified on every read.
//!
//! # On-Disk Layout
//!
//! ```text
//! <root>/
//! objects/
//! ab/ # First 2 hex chars of the hash (256 buckets)
//! cdef... # Remaining 62 hex chars = blob filename
//! pack/
//! pack-<hex>.pack # Bundled blobs (always Zstd-compressed)
//! pack-<hex>.idx # Sorted hash -> offset index
//! ```
//!
//! The 2-hex-prefix bucketing avoids any single directory holding too
//! many entries. Pack files bundle many small blobs into one file to
//! reduce filesystem overhead; see [`PackFile`].
//!
//! # Correctness Properties
//!
//! - **Integrity**: `get(H(data)) == data` (BLAKE3 collision resistance),
//! enforced by optional-but-default verify-on-read.
//! - **Deduplication**: storing the same blob twice writes one copy.
//! - **Lossless**: Zstd compression/decompression is lossless.
//!
//! # Thread Safety
//!
//! [`BlobStore`] is `Send + Sync` and can be shared across threads via
//! `Arc`. Interior mutability (the blob cache, pack-index cache and
//! bucket-directory cache) uses `std::sync::Mutex`; lock poisoning is
//! reported as [`CasError::LockPoisoned`] rather than unwrapped.
//!
//! # Features
//!
//! - `zstd` (default): enables Zstd compression of loose blobs and pack
//! contents. Builds without this feature store everything raw and
//! cannot read stores written by zstd-enabled builds (reads of
//! compressed frames fail hash verification rather than silently
//! returning wrong bytes).
//! - `tokio` (optional): async wrappers `gc::mark_async` /
//! `gc::sweep_async` over the blocking thread pool.
//!
//! # Garbage collection
//!
//! Objects are opaque blobs, so reachability is a host-level concept;
//! [`gc`] implements mark–sweep over a host-supplied live set, with
//! dry-run / trash / delete modes and pack-rewrite support. The
//! `cas-gc` binary (same crate) drives it from the command line.
//!
//! # Example
//!
//! ```no_run
//! use cas_kit::BlobStore;
//!
//! # fn main() -> Result<(), cas_kit::CasError> {
//! let store = BlobStore::new("/tmp/my-store")?;
//! let hash = store.put_blob(b"hello, world")?;
//! assert_eq!(store.get_blob(&hash)?, b"hello, world".to_vec());
//! # Ok(())
//! # }
//! ```
pub use CasError;
pub use ;
pub use Hash;
pub use ;
pub use ;
pub use BlobStore;