Expand description
Checksummed persistent blocks built on top of bstack.
§Overview
bblock wraps any BStackAllocator and appends a 4-byte checksum to
every allocation. Two checksum strategies are available:
| Module | Checksum | Update strategy | Use when |
|---|---|---|---|
crc | CRC32 | Full-block recompute | Detection strength matters most |
xor | XOR | Incremental (changed bytes only) | Write throughput matters most |
Both modules expose the same API shape. CRC types (BBlockAllocator,
BBlock, BBlockView, BBlockReader, BBlockWriter) are
re-exported at the crate root for backward compatibility.
§Composability
Both allocator wrappers implement bstack::BStackAllocator themselves,
so they can be used in any generic context that accepts T: BStackAllocator.
This is what allows BBlock and BXorBlock to implement
bstack::BStackGuardedSlice without requiring the stricter
BStackSliceAllocator bound.
The wrappers can be composed freely:
use bstack::{BStack, LinearBStackAllocator};
use bblock::{BBlockAllocator, xor::BXorBlockAllocator};
let stack = BStack::open("data.bstk").unwrap();
// XOR checksum over CRC32-checksummed blocks
let alloc = BXorBlockAllocator::new(BBlockAllocator::new(LinearBStackAllocator::new(stack)));§bstack guarded feature
When bstack is built with the guarded feature (enabled by default in this
crate), all four concrete types implement bstack::BStackGuardedSlice:
BBlock, BBlockView, BXorBlock, and BXorBlockView. The view
types additionally implement bstack::BStackGuardedSliceSubview.
as_slice()returns the data region only (the checksum trailer is hidden; for views, only the view’s sub-range is exposed).write()andzero()automatically keep the checksum consistent.BBlock/BBlockViewrecompute the full CRC32;BXorBlock/BXorBlockViewupdate incrementally.len(),is_empty()(block types) andlen(),is_empty(),read(),write(),zero()(view types) are provided by the trait — callers mustuse bstack::BStackGuardedSlice.
§Detection, not recovery
bblock only detects corruption — it does not repair or revert. A
verify() returning false means the data must not be trusted, but the
crate provides no mechanism to restore a previous good value.
§Quick start
§CRC32 (default, stronger integrity)
use bstack::{BStack, BStackAllocator, BStackGuardedSlice, LinearBStackAllocator};
use bblock::BBlockAllocator;
let stack = BStack::open("data.bstk").unwrap();
let alloc = BBlockAllocator::new(LinearBStackAllocator::new(stack));
let block = alloc.alloc(16).unwrap();
block.view().write(b"hello, bblock!!!").unwrap();
assert!(block.verify().unwrap());§XOR (faster writes)
use bstack::{BStack, BStackAllocator, BStackGuardedSlice, LinearBStackAllocator};
use bblock::xor::BXorBlockAllocator;
let stack = BStack::open("data.bstk").unwrap();
let alloc = BXorBlockAllocator::new(LinearBStackAllocator::new(stack));
let block = alloc.alloc(16).unwrap();
block.view().write(b"hello, bblock!!!").unwrap();
assert!(block.verify().unwrap());Re-exports§
pub use crc::BBlock;pub use crc::BBlockAllocator;pub use crc::BBlockReader;pub use crc::BBlockView;pub use crc::BBlockWriter;pub use crc::CHECKSUM_LENGTH;pub use xor::BXorBlock;pub use xor::BXorBlockAllocator;pub use xor::BXorBlockReader;pub use xor::BXorBlockView;pub use xor::BXorBlockWriter;