Crates.io | cassadilia |
lib.rs | cassadilia |
version | 0.2.1 |
created_at | 2025-06-23 11:40:06.653472+00 |
updated_at | 2025-08-13 11:18:37.150857+00 |
description | A content-addressable storage (CAS) system optimized for large blobs with read-mostly access patterns |
homepage | https://github.com/broxus/cassadilia |
repository | https://github.com/broxus/cassadilia |
max_upload_size | |
id | 1722830 |
size | 214,967 |
Firstly store data in cas, then index it. With this approach you don't need to handle consistency errors in the user code. You can get list of orphaned blobs on startup and do something with them. As user, you can do nothing if you have a record in the index for blob, but no actual blob in cas. Hi mr. rocksdb :)
Blobs are stored in a classic cas manner /h/a/s/h.
Hash is blake3
Index is stored in a single file. Which is periodically rewritten on wal roll-over.
Internally index is a BtreeMap.
Cassadilia uses a two-level locking strategy to ensure consistency:
FsLock
)A single shared mutex protects CAS fs operations:
The lock is held only during filesystem metadata operations, not during index updates or blob content writes.
To prevent race conditions between concurrent commits and deletions, Cassadilia uses an intent tracking system / 2-phase commit protocol:
Before committing a blob to CAS, a transaction registers its intent with the index:
When the blob is moved in CAS, the transaction:
During deletion, the system checks both:
This prevents the race where Thread A could delete a blob that Thread B is in the process of committing.