use plugmem_arena::{Arena, ArenaCfg, ChunkPool, ChunkPoolCfg, ListHandle, ShardMode, Slot, key};
#[derive(Debug, PartialEq)]
struct Row {
id: u64,
value: u64,
}
impl Slot for Row {
const SIZE: usize = 16;
const KEY_LEN: usize = 8;
fn write(&self, out: &mut [u8]) {
key::write_u64(out, self.id);
key::write_u64(&mut out[8..], self.value);
}
fn read(bytes: &[u8]) -> Self {
Row {
id: key::read_u64(bytes),
value: key::read_u64(&bytes[8..]),
}
}
}
fn key8(id: u64) -> [u8; 8] {
let mut k = [0u8; 8];
key::write_u64(&mut k, id);
k
}
fn main() {
arena_overlay();
chunk_pool_overlay();
println!("\nboth overlays stayed byte-identical to owned — and never touched the base.");
}
fn arena_overlay() {
let mut source = Arena::<Row>::new(ArenaCfg::new(4, ShardMode::Ordered)).unwrap();
for id in 0..1000 {
source.insert(&Row { id, value: id * 10 }).unwrap();
}
let (mut meta, mut image) = (Vec::new(), Vec::new());
source.dump_meta(&mut meta);
source.dump_pool(&mut image);
let image_at_open = image.clone();
let mut overlay = Arena::<Row>::load_overlay(*source.cfg(), &meta, &image).unwrap();
assert_eq!(
overlay.get(&key8(500)),
Some(Row {
id: 500,
value: 5000
})
);
for id in 0..1000 {
overlay
.insert(&Row {
id: 1_000_000 + id,
value: id,
})
.unwrap();
}
if let Some(payload) = overlay.payload_mut(&key8(500)) {
payload.copy_from_slice(&42u64.to_be_bytes());
}
assert_eq!(overlay.len(), 2000);
assert_eq!(overlay.get(&key8(500)), Some(Row { id: 500, value: 42 }));
assert_eq!(
image, image_at_open,
"the borrowed image must not be mutated"
);
let mut owned = Arena::<Row>::load(*source.cfg(), &meta, &image).unwrap();
for id in 0..1000 {
owned
.insert(&Row {
id: 1_000_000 + id,
value: id,
})
.unwrap();
}
owned
.payload_mut(&key8(500))
.unwrap()
.copy_from_slice(&42u64.to_be_bytes());
let dump = |a: &Arena<'_, Row>| {
let (mut m, mut p) = (Vec::new(), Vec::new());
a.dump_meta(&mut m);
a.dump_pool(&mut p);
(m, p)
};
assert_eq!(dump(&overlay), dump(&owned));
println!("arena: 1000 borrowed rows + 1000 grown + an in-place edit — base intact.");
}
fn chunk_pool_overlay() {
let mut source = ChunkPool::new(ChunkPoolCfg::new());
let mut list = ListHandle::EMPTY;
for n in 0..100u32 {
source.push(&mut list, &n.to_be_bytes()).unwrap();
}
let (mut meta, mut image) = (Vec::new(), Vec::new());
source.dump_meta(&mut meta);
source.dump_pool(&mut image);
let image_at_open = image.clone();
let mut overlay = ChunkPool::load_overlay(ChunkPoolCfg::new(), &meta, &image).unwrap();
for n in 100..400u32 {
overlay.push(&mut list, &n.to_be_bytes()).unwrap();
}
let values: Vec<u32> = overlay
.iter(&list)
.flatten()
.copied()
.collect::<Vec<u8>>()
.chunks_exact(4)
.map(|b| u32::from_be_bytes(b.try_into().unwrap()))
.collect();
assert_eq!(values, (0..400).collect::<Vec<_>>());
assert_eq!(
image, image_at_open,
"the borrowed image must not be mutated"
);
println!("chunk pool: 100 borrowed values + 300 appended across chunks — base intact.");
}