pub struct BlobHeap<'a> { /* private fields */ }Expand description
Append-only byte heap addressed by dense BlobIds.
use plugmem_arena::{BlobHeap, BlobHeapCfg};
let mut heap = BlobHeap::new(BlobHeapCfg::new());
let hello = heap.push(b"hello").unwrap();
let world = heap.push(b"world").unwrap();
assert_eq!(heap.get(hello), b"hello");
assert_eq!(heap.get(world), b"world");
assert_eq!(heap.len(), 2);Implementations§
Source§impl<'a> BlobHeap<'a>
impl<'a> BlobHeap<'a>
Sourcepub const fn new(cfg: BlobHeapCfg) -> Self
pub const fn new(cfg: BlobHeapCfg) -> Self
Creates an empty heap. Allocates nothing until the first push.
Sourcepub fn push(&mut self, bytes: &[u8]) -> Result<BlobId, Error>
pub fn push(&mut self, bytes: &[u8]) -> Result<BlobId, Error>
Appends a blob and returns its id. Zero-length blobs are valid.
The bytes always land in the owned tail; a heap opened over a
borrowed base (load_borrowed) is appended to without cloning that
base.
§Errors
Error::BlobTooLargeifbytesis longer thanBlobHeapCfg::max_blob;Error::CapacityExceededif the pool would grow pastBlobHeapCfg::max_bytesor theusizepool ceiling (4 GiB on a 32-bit target).
Sourcepub fn get(&self, id: BlobId) -> &[u8]
pub fn get(&self, id: BlobId) -> &[u8]
Returns the bytes of a blob.
§Panics
Panics if id was not returned by this heap’s BlobHeap::push —
a dangling id is a caller bug, not a runtime condition.
Sourcepub fn pool_bytes(&self) -> usize
pub fn pool_bytes(&self) -> usize
Total bytes of blob content (the logical pool size).
Sourcepub fn iter(&self) -> impl Iterator<Item = (BlobId, &[u8])>
pub fn iter(&self) -> impl Iterator<Item = (BlobId, &[u8])>
Iterates over all blobs in id order as (id, bytes) pairs.
This is the substrate for the owner-driven compaction pass: walk the blobs, copy the live ones into a fresh heap, record the id remapping.
Sourcepub fn dump_index(&self, out: &mut Vec<u8>)
pub fn dump_index(&self, out: &mut Vec<u8>)
Appends the heap’s index section to out.
Layout (little-endian): [blobs u32] then one len u32 per blob.
Offsets are not stored — blobs are contiguous in push order, so the
lengths alone reconstruct the index (one redundancy less to
validate). Together with BlobHeap::dump_pool this is the
complete state; dumps are canonical.
Sourcepub fn dump_pool(&self, out: &mut Vec<u8>)
pub fn dump_pool(&self, out: &mut Vec<u8>)
Appends the heap’s pool section to out — a straight
copy of the logical pool (base then tail): every pool byte is
initialized blob content, so an overlay heap dumps byte-identically
to the owned heap holding the same blobs.
Sourcepub fn load(cfg: BlobHeapCfg, index: &[u8], pool: &[u8]) -> Result<Self, Error>
pub fn load(cfg: BlobHeapCfg, index: &[u8], pool: &[u8]) -> Result<Self, Error>
Rebuilds a heap from its two dumped sections.
The input is untrusted — validation is O(blobs), never panics
on arbitrary bytes: exact index length, per-blob length within
cfg.max_blob, and the lengths summing exactly to the pool size
(which itself must fit cfg.max_bytes and the usize pool ceiling).
Blob content is the owner’s data and is not interpreted.
§Errors
Error::Corrupt for any inconsistency.
Sourcepub fn load_borrowed(
cfg: BlobHeapCfg,
index: &[u8],
pool: &'a [u8],
) -> Result<Self, Error>
pub fn load_borrowed( cfg: BlobHeapCfg, index: &[u8], pool: &'a [u8], ) -> Result<Self, Error>
Rebuilds a heap that borrows its base pool from a longer-lived
buffer (a memory-mapped snapshot) instead of copying it.
The index is validated and rebuilt exactly as in BlobHeap::load;
no base byte is copied, so opening an 8 GiB heap this way touches
only the pages the reader dereferences.
Unlike the old whole-pool copy-on-write, this heap stays borrowed
even under mutation: a later BlobHeap::push appends to an owned
tail, never cloning the base. A read-only caller simply never pushes.
See also BlobHeap::load_overlay.
§Errors
Error::Corrupt for any inconsistency (same gates as load).
Sourcepub fn load_overlay(
cfg: BlobHeapCfg,
index: &[u8],
pool: &'a [u8],
) -> Result<Self, Error>
pub fn load_overlay( cfg: BlobHeapCfg, index: &[u8], pool: &'a [u8], ) -> Result<Self, Error>
Opens a heap over a borrowed base for the overlay write path: the
base is mapped read-only and appends accumulate in an owned tail. For
an append-only heap this is exactly BlobHeap::load_borrowed — the
alias exists so overlay-mode callers read uniformly across the flat
structures (the in-place Arena and
ChunkPool take a distinct page-copy-on-write
load_overlay).
§Errors
Error::Corrupt for any inconsistency (same gates as load).