use super::*;
use crate::relation::RelationKind;
use crate::test_support::{relation_fixture, RelationFixture, TID};
use gnitz_expr::SchemaFacts;
use gnitz_wire::TypeCode;
use gnitz_zset::repr::BatchBuilder;
use gnitz_zset::schema::{SchemaColumn, SchemaDescriptor};
const ROWS: u64 = 50;
fn fixture(indexed: bool) -> RelationFixture {
let schema = SchemaDescriptor::new(
&[
SchemaColumn::new(TypeCode::U64, false),
SchemaColumn::new(TypeCode::I64, true),
],
&[0],
);
let mut bb = BatchBuilder::new(&schema);
for id in 0..ROWS {
bb.begin_row(id as u128, 1);
match id % 7 {
0 => bb.put_null(),
_ => bb.put_int((-((id / 2) as i64)) as u128),
}
bb.end_row();
}
let indexed: &[u32] = if indexed { &[1] } else { &[] };
relation_fixture(RelationKind::BaseTable, schema, indexed, [bb.finish()])
}
fn drain(mut spans: KeySpans) -> (Vec<Vec<u8>>, Vec<usize>) {
let (mut keys, mut chunks) = (Vec::new(), Vec::new());
while !spans.chunk().is_empty() {
let chunk = spans.chunk();
keys.extend((0..chunk.len()).map(|i| chunk.get_pk_bytes(i).to_vec()));
chunks.push(chunk.len());
spans.advance();
}
spans.advance();
assert!(spans.chunk().is_empty(), "nothing follows the first empty chunk");
(keys, chunks)
}
#[test]
fn the_index_and_the_sort_yield_the_same_sorted_spans() {
let span_schema = crate::test_support::pk_only_schema(&[TypeCode::I64]);
let mut want: Vec<Vec<u8>> = (0..ROWS)
.filter(|id| id % 7 != 0)
.map(|id| {
let val = -((id / 2) as i64);
span_schema.opk_key_cols(&[val as u128]).pk_bytes().to_vec()
})
.collect();
want.sort();
for chunk_rows in [1, 4, 1024] {
for indexed in [true, false] {
let mut r = fixture(indexed);
r.config.scan_chunk_rows = chunk_rows;
r.config.key_spans_spill_bytes = 24;
assert_eq!(r.relation(TID).unwrap().index_on(&[1]).is_some(), indexed);
let (got, chunks) = drain(r.key_spans(TID, &[1]).unwrap());
assert_eq!(got, want, "indexed={indexed}, chunk_rows={chunk_rows}");
assert!(
chunks.iter().all(|&n| n <= chunk_rows),
"indexed={indexed}: {chunks:?} over {chunk_rows}"
);
assert_eq!(chunks.len(), want.len().div_ceil(chunk_rows), "indexed={indexed}");
}
}
}
#[test]
fn spans_of_a_column_the_relation_lacks_are_refused() {
let r = fixture(false);
assert!(r.key_spans(TID, &[9]).is_err());
assert!(r.key_spans(TID + 100, &[1]).is_err());
}