radixdb-storage 1.1.0

Storage contracts and physical persistence engine for RadixDB
Documentation
use std::cell::Cell;
use std::rc::Rc;

use super::*;

struct CountedBlock {
    kind: DataBlockKind,
    column: u32,
    visits: Rc<Cell<usize>>,
}

impl ColumnBlockDescriptor for CountedBlock {
    fn kind(&self) -> DataBlockKind {
        self.visits.set(self.visits.get() + 1);
        self.kind
    }

    fn column_ordinal(&self) -> u32 {
        self.visits.set(self.visits.get() + 1);
        self.column
    }
}

#[test]
fn column_block_map_visits_each_descriptor_at_most_twice() {
    let visits = Rc::new(Cell::new(0));
    let columns = 64_u32;
    let groups = 1024_u32;
    let mut blocks = Vec::new();
    for _group in 0..groups {
        blocks.push(CountedBlock {
            kind: DataBlockKind::RowIds,
            column: u32::MAX,
            visits: Rc::clone(&visits),
        });
        for column in 0..columns {
            blocks.push(CountedBlock {
                kind: DataBlockKind::Column,
                column,
                visits: Rc::clone(&visits),
            });
        }
    }

    let (first, counts) = collect_column_block_map(&blocks, columns as usize).unwrap();

    assert!(visits.get() <= blocks.len() * 2);
    for column in 0..columns as usize {
        assert_eq!(first[column], column as u32 + 1);
        assert_eq!(counts[column], groups);
    }
}

#[test]
fn column_block_map_rejects_an_out_of_range_ordinal() {
    let visits = Rc::new(Cell::new(0));
    let blocks = [CountedBlock {
        kind: DataBlockKind::Column,
        column: 2,
        visits,
    }];

    assert!(collect_column_block_map(&blocks, 2).is_err());
}