#![cfg(feature = "storage")]
use core::mem::MaybeUninit;
use pipecircuit::storage::warp_table::{
CallerUniqueIndexStorage, ColumnLease, UniqueIndex, UniqueIndexInsertError,
UniqueIndexInsertOutcome, UniqueIndexLookupOutcome, UniqueIndexRemoveOutcome,
UniqueIndexReplaceOutcome,
};
#[global_allocator]
static ALLOCATOR: dhat::Alloc = dhat::Alloc;
#[test]
fn construction_full_refusal_and_churn_allocate_nothing() -> Result<(), &'static str> {
let mut keys = [MaybeUninit::<u64>::uninit(); 17];
let mut buckets = [0; 34];
let _profiler = dhat::Profiler::builder().testing().build();
let mut index = UniqueIndex::try_from_storage(
17,
CallerUniqueIndexStorage {
keys: ColumnLease::new(&mut keys),
buckets: &mut buckets,
},
)
.map_err(|_| "construction")?;
for key in 0..17 {
let UniqueIndexInsertOutcome::Inserted { key: inserted, .. } = index
.try_prepare_insert(key)
.map_err(|_| "insert")?
.commit();
assert_eq!(inserted, key);
}
assert_eq!(
index.try_prepare_insert(17).err(),
Some(UniqueIndexInsertError::Full {
key: 17,
maximum_keys: 17
})
);
for source in 0..256 {
let row = match index.find(source).map_err(|_| "lookup")? {
UniqueIndexLookupOutcome::Present { row, .. } => row,
UniqueIndexLookupOutcome::Absent { .. } => return Err("missing key"),
};
let target = source.checked_add(17).ok_or("target")?;
assert_eq!(
index
.try_prepare_replace(source, target, row)
.map_err(|_| "replace")?
.commit(),
UniqueIndexReplaceOutcome::Replaced {
source,
target,
row
}
);
assert_eq!(
index
.try_prepare_remove(target)
.map_err(|_| "remove")?
.commit(),
UniqueIndexRemoveOutcome::Removed { key: target, row }
);
assert_eq!(
index
.try_prepare_insert(target)
.map_err(|_| "reinsert")?
.commit(),
UniqueIndexInsertOutcome::Inserted {
key: target,
row: 16
}
);
}
drop(index);
let stats = dhat::HeapStats::get();
assert_eq!(stats.total_blocks, 0);
assert_eq!(stats.total_bytes, 0);
Ok(())
}