#![cfg(feature = "secondary-indexes")]
use core::num::NonZeroU32;
use pipecircuit::storage::warp_table::{
Capacity, MutableSelectionForEachOutcome, WarpTable, WarpTableInsertWithIdOutcome, WarpTableRow,
};
#[global_allocator]
static ALLOCATOR: dhat::Alloc = dhat::Alloc;
#[derive(WarpTableRow)]
#[index(primary = u32)]
struct Unit {
#[index(secondary)]
team: u8,
#[index(range)]
health: u32,
}
#[test]
fn reserved_mutable_queries_reuse_snapshots_across_composition_refusal_and_drop()
-> Result<(), &'static str> {
let mut table =
WarpTable::<Unit>::try_new(Capacity::new(NonZeroU32::new(4097).ok_or("capacity")?))
.map_err(|_| "table")?;
for id in 0..4097 {
assert!(matches!(
table.insert_with_id(
id,
Unit {
team: 1,
health: id
}
),
WarpTableInsertWithIdOutcome::Inserted { .. }
));
}
table.reserve_queries(1).map_err(|_| "reserve")?;
let _profiler = dhat::Profiler::builder().testing().build();
for _ in 0..16 {
table.reserve_queries(1).map_err(|_| "repeat reservation")?;
assert_eq!(
table
.query_mut()
.find_team(1)
.and(|q| q.find_health_in(256..=4096))
.map_err(|_| "range")?
.for_each(|mut row| {
let _ = row.set_team(2);
}),
MutableSelectionForEachOutcome::Updated { rows: 3841 }
);
assert_eq!(
table
.query_mut()
.find_health_in(256..)
.map_err(|_| "range")?
.or(|q| q.find_team(99))
.and_not(|q| q.find_team(1))
.xor(|q| q.find_health_in(0..256))
.map_err(|_| "range")?
.len(),
4097
);
assert_eq!(
table.query_mut().find_team(2).for_each(|mut row| {
let _ = row.set_team(1);
}),
MutableSelectionForEachOutcome::Updated { rows: 3841 }
);
assert!(
table
.query_mut()
.find_health_in((core::ops::Bound::Included(9), core::ops::Bound::Included(1)))
.is_err()
);
assert!(
table
.query_mut()
.find_team(1)
.and(|q| q
.find_health_in((core::ops::Bound::Included(9), core::ops::Bound::Included(1))))
.is_err()
);
assert!(
table
.query_mut()
.find_team(1)
.for_each_in_dense_order(&mut [], |_| {})
.is_err()
);
assert!(table.query_mut().find_team(99).is_empty());
drop(table.query_mut().find_team(1));
}
let stats = dhat::HeapStats::get();
assert_eq!(stats.total_blocks, 0);
assert_eq!(stats.total_bytes, 0);
Ok(())
}