pipecircuit 0.0.25

Correct. Robust. Fast. Portable. Pick four.
Documentation
#![cfg(feature = "secondary-indexes")]

use core::num::NonZeroU32;
use pipecircuit::storage::warp_table::{
    Capacity, OrderedRowLimit, OrderedSelectionFirstCuttingTiesOutcome,
    OrderedSelectionFirstKeepingTiesOutcome, 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,
    #[index(range)]
    x: u32,
}

#[test]
fn fluent_queries_reuse_reserved_storage_from_the_first_operation() -> Result<(), &'static str> {
    let mut tables = Vec::new();
    for capacity in [65_u32, 4097, 65537, 100000] {
        let mut table =
            WarpTable::<Unit>::try_new(Capacity::new(NonZeroU32::new(capacity).ok_or("capacity")?))
                .map_err(|_| "table")?;
        for id in 0..capacity {
            assert!(matches!(
                table.insert_with_id(
                    id,
                    Unit {
                        team: (id % 3) as u8,
                        health: id % 17,
                        x: id
                    }
                ),
                WarpTableInsertWithIdOutcome::Inserted { .. }
            ));
        }
        table.reserve_queries(3).map_err(|_| "reserve")?;
        tables.push(table);
    }
    let ten = OrderedRowLimit::new(NonZeroU32::new(10).ok_or("limit")?);
    let one = OrderedRowLimit::new(NonZeroU32::MIN);
    let mut unused =
        WarpTable::<Unit>::try_new(Capacity::new(NonZeroU32::MIN)).map_err(|_| "unused table")?;
    let _profiler = dhat::Profiler::builder().testing().build();
    unused.reserve_queries(0).map_err(|_| "zero reservation")?;
    assert_eq!(unused.query().find_team(1).len(), 0);
    for table in &tables {
        for _ in 0..4 {
            let held = table.query().find_x_in(1..20).map_err(|_| "held")?;
            let result = table
                .query()
                .find_x_in(..)
                .map_err(|_| "range")?
                .and(|q| q.find_x_in(3..))
                .map_err(|_| "intersection")?
                .and_not(|q| q.find_team(2))
                .xor(|q| q.find_x_in(20..30))
                .map_err(|_| "xor")?
                .ordered_by(|q| q.health_largest_first().then(q.x_smallest_first()))
                .first_cutting_ties(ten)
                .map_err(|_| "rank")?;
            let rows = match result {
                OrderedSelectionFirstCuttingTiesOutcome::Exact { rows }
                | OrderedSelectionFirstCuttingTiesOutcome::TiesCut { rows, .. } => rows,
            };
            let kept = table
                .query()
                .ordered_by(|q| q.health_largest_first())
                .first_keeping_ties(one)
                .map_err(|_| "ties")?;
            match kept {
                OrderedSelectionFirstKeepingTiesOutcome::Exact { rows } => {
                    assert_eq!(rows.count(), 1)
                }
                OrderedSelectionFirstKeepingTiesOutcome::TiesKept { leaders, tied } => {
                    assert_eq!(leaders.count(), 0);
                    let replacement = table
                        .query()
                        .find_x_in(..3)
                        .map_err(|_| "small")?
                        .ordered_by(|q| q.x_largest_first())
                        .first_cutting_ties(one)
                        .map_err(|_| "small rank")?;
                    match replacement {
                        OrderedSelectionFirstCuttingTiesOutcome::Exact { rows }
                        | OrderedSelectionFirstCuttingTiesOutcome::TiesCut { rows, .. } => {
                            assert_eq!(rows.count(), 1)
                        }
                    }
                    assert!(tied.count() > 1);
                }
            }
            assert_eq!(rows.count(), 10);
            assert_eq!(
                held.rows().fold(0_u32, |count, _| count.saturating_add(1)),
                19
            );
            let compared = table
                .query()
                .find_team(1)
                .ordered_by(|q| q.health_largest_first())
                .then_compare_rows(|left, right| left.x.cmp(right.x))
                .first_keeping_ties(ten)
                .map_err(|_| "compared")?;
            match compared {
                OrderedSelectionFirstKeepingTiesOutcome::Exact { rows } => {
                    assert_eq!(rows.count(), 10)
                }
                OrderedSelectionFirstKeepingTiesOutcome::TiesKept { .. } => {
                    return Err("unexpected ties");
                }
            }
            assert!(
                table
                    .query()
                    .find_x_in(..)
                    .map_err(|_| "range")?
                    .and(|q| q
                        .find_x_in((core::ops::Bound::Included(2), core::ops::Bound::Included(1))))
                    .is_err()
            );
        }
    }
    let stats = dhat::HeapStats::get();
    assert_eq!(stats.total_blocks, 0);
    assert_eq!(stats.total_bytes, 0);
    let table = tables.first().ok_or("table missing")?;
    for repetition in 0..2 {
        let before = dhat::HeapStats::get();
        let held = [
            table.query().find_x_in(..).map_err(|_| "growth")?,
            table.query().find_x_in(..).map_err(|_| "growth")?,
            table.query().find_x_in(..).map_err(|_| "growth")?,
            table.query().find_x_in(..).map_err(|_| "growth")?,
        ];
        for selection in held {
            assert_eq!(selection.len(), 65);
        }
        let after = dhat::HeapStats::get();
        if repetition == 0 {
            assert!(after.total_blocks > before.total_blocks);
        } else {
            assert_eq!(after.total_blocks, before.total_blocks);
            assert_eq!(after.total_bytes, before.total_bytes);
        }
    }
    Ok(())
}