use pipecircuit::storage::query_workspace::{
MembershipInsertOutcome, MembershipOperation, MembershipRemoveOutcome, QueryChunk,
QueryWorkspace,
};
#[global_allocator]
static ALLOCATOR: dhat::Alloc = dhat::Alloc;
#[test]
fn caller_storage_constructs_and_composes_without_allocating() -> Result<(), &'static str> {
let _profiler = dhat::Profiler::builder().testing().build();
let before_calibration = dhat::HeapStats::get();
let calibration = core::hint::black_box(vec![0_u8; 19]);
assert!(dhat::HeapStats::get().total_blocks > before_calibration.total_blocks);
drop(calibration);
let mut left_chunks = [const { QueryChunk::EMPTY }; 2];
let mut right_chunks = [const { QueryChunk::EMPTY }; 2];
let mut result_chunks = [const { QueryChunk::EMPTY }; 2];
let mut left_scratch = QueryChunk::EMPTY;
let mut right_scratch = QueryChunk::EMPTY;
let mut result_scratch = QueryChunk::EMPTY;
let before = dhat::HeapStats::get();
let mut left = QueryWorkspace::new(65537, &mut left_chunks[..], &mut left_scratch)
.map_err(|_| "left workspace")?;
let mut right = QueryWorkspace::new(65537, &mut right_chunks[..], &mut right_scratch)
.map_err(|_| "right workspace")?;
let mut result = QueryWorkspace::new(65537, &mut result_chunks[..], &mut result_scratch)
.map_err(|_| "result workspace")?;
{
let mut a = left.membership().map_err(|_| "left lease")?;
let mut b = right.membership().map_err(|_| "right lease")?;
let mut output = result.membership().map_err(|_| "output lease")?;
for slot in 0..4096 {
assert_eq!(
a.insert(slot).map_err(|_| "insert")?,
MembershipInsertOutcome::Inserted { slot }
);
}
for slot in 2048..6144 {
b.insert(slot).map_err(|_| "insert")?;
}
assert!(!a.is_subset(&b).map_err(|_| "sparse subset")?);
assert!(!a.is_disjoint(&b).map_err(|_| "sparse disjoint")?);
for (operation, cardinality) in [
(MembershipOperation::Union, 6144),
(MembershipOperation::Intersection, 2048),
(MembershipOperation::Difference, 2048),
(MembershipOperation::SymmetricDifference, 4096),
] {
for (left, right) in [(&a, &b), (&b, &a)] {
output
.assign(operation, left, right)
.map_err(|_| "sparse assign")?;
assert_eq!(output.len(), cardinality);
assert_eq!(output.slots().count() as u64, cardinality);
output
.assign(MembershipOperation::Union, left, left)
.map_err(|_| "seed in place")?;
output
.apply(operation, right)
.map_err(|_| "sparse in place")?;
assert_eq!(output.len(), cardinality);
assert_eq!(output.slots().count() as u64, cardinality);
}
}
for promote_right in [false, true] {
if promote_right {
b.insert(6144).map_err(|_| "promote right")?;
b.remove(6144).map_err(|_| "retain dense right")?;
}
for _ in 0..128 {
assert_eq!(
a.insert(4096).map_err(|_| "promote")?,
MembershipInsertOutcome::Inserted { slot: 4096 }
);
assert_eq!(
a.remove(4096).map_err(|_| "remove")?,
MembershipRemoveOutcome::Removed { slot: 4096 }
);
for (operation, cardinality) in [
(MembershipOperation::Union, 6144),
(MembershipOperation::Intersection, 2048),
(MembershipOperation::Difference, 2048),
(MembershipOperation::SymmetricDifference, 4096),
] {
for (left, right) in [(&a, &b), (&b, &a)] {
output
.assign(operation, left, right)
.map_err(|_| "assign")?;
assert_eq!(output.len(), cardinality);
assert_eq!(output.slots().count() as u64, cardinality);
}
}
}
}
a.apply(MembershipOperation::Union, &b)
.map_err(|_| "in place")?;
assert_eq!(a.len(), 6144);
}
left.clear();
right.clear();
result.clear();
let after = dhat::HeapStats::get();
assert_eq!(after.total_blocks, before.total_blocks);
assert_eq!(after.total_bytes, before.total_bytes);
Ok(())
}