#[cfg(test)]
mod tests {
use crate::index::secondary::{JsonValue, SecondaryIndex};
use parking_lot::RwLock;
use std::collections::BTreeMap;
fn make_btree_index(entries: Vec<(JsonValue, Vec<u64>)>) -> SecondaryIndex {
let mut tree = BTreeMap::new();
for (key, ids) in entries {
tree.insert(key, ids);
}
SecondaryIndex::BTree(RwLock::new(tree))
}
#[test]
fn test_to_bitmap_returns_matching_ids() {
let key = JsonValue::String("tech".to_string());
let index = make_btree_index(vec![(key.clone(), vec![1, 5, 42])]);
let bm = index.to_bitmap(&key).expect("test: ids within u32 range");
assert_eq!(bm.len(), 3);
assert!(bm.contains(1));
assert!(bm.contains(5));
assert!(bm.contains(42));
}
#[test]
fn test_to_bitmap_returns_empty_for_missing_value() {
let key = JsonValue::String("tech".to_string());
let missing = JsonValue::String("science".to_string());
let index = make_btree_index(vec![(key, vec![1, 2, 3])]);
let bm = index
.to_bitmap(&missing)
.expect("test: ids within u32 range");
assert!(bm.is_empty());
}
#[test]
fn test_to_bitmap_returns_none_when_id_exceeds_u32_max() {
let key = JsonValue::String("mixed".to_string());
let large_id = u64::from(u32::MAX) + 1;
let index = make_btree_index(vec![(key.clone(), vec![10, large_id, 20])]);
assert!(
index.to_bitmap(&key).is_none(),
"bitmap must be None (incomplete) when an ID exceeds u32::MAX"
);
}
#[test]
fn test_range_bitmap_returns_none_when_id_exceeds_u32_max() {
use std::ops::Bound;
let key = JsonValue::Number(crate::index::secondary::F64Key::from(5.0));
let large_id = u64::from(u32::MAX) + 7;
let index = make_btree_index(vec![(key, vec![large_id])]);
assert!(
index
.range_bitmap(Bound::Unbounded, Bound::Unbounded)
.is_none(),
"range bitmap must be None when an in-range ID exceeds u32::MAX"
);
}
#[test]
fn test_to_bitmap_empty_id_list() {
let key = JsonValue::String("empty".to_string());
let index = make_btree_index(vec![(key.clone(), vec![])]);
let bm = index.to_bitmap(&key).expect("test: ids within u32 range");
assert!(bm.is_empty());
}
#[test]
fn test_to_bitmap_numeric_key() {
let key = JsonValue::Number(crate::index::secondary::F64Key::from(42.0));
let index = make_btree_index(vec![(key.clone(), vec![100, 200])]);
let bm = index.to_bitmap(&key).expect("test: ids within u32 range");
assert_eq!(bm.len(), 2);
assert!(bm.contains(100));
assert!(bm.contains(200));
}
#[test]
fn test_to_bitmap_bool_key() {
let key = JsonValue::Bool(true);
let index = make_btree_index(vec![(key.clone(), vec![7, 13])]);
let bm = index.to_bitmap(&key).expect("test: ids within u32 range");
assert_eq!(bm.len(), 2);
assert!(bm.contains(7));
assert!(bm.contains(13));
}
fn make_price_index() -> SecondaryIndex {
use crate::index::secondary::F64Key;
make_btree_index(vec![
(JsonValue::Number(F64Key::from(10.0)), vec![1]),
(JsonValue::Number(F64Key::from(20.0)), vec![2]),
(JsonValue::Number(F64Key::from(30.0)), vec![3]),
(JsonValue::Number(F64Key::from(40.0)), vec![4]),
(JsonValue::Number(F64Key::from(50.0)), vec![5]),
])
}
#[test]
fn test_range_bitmap_exclusive_lower() {
use std::ops::Bound;
let index = make_price_index();
let key30 = JsonValue::Number(crate::index::secondary::F64Key::from(30.0));
let bm = index
.range_bitmap(Bound::Excluded(&key30), Bound::Unbounded)
.expect("test: ids within u32 range");
assert_eq!(bm.len(), 2);
assert!(bm.contains(4));
assert!(bm.contains(5));
}
#[test]
fn test_range_bitmap_inclusive_lower() {
use std::ops::Bound;
let index = make_price_index();
let key30 = JsonValue::Number(crate::index::secondary::F64Key::from(30.0));
let bm = index
.range_bitmap(Bound::Included(&key30), Bound::Unbounded)
.expect("test: ids within u32 range");
assert_eq!(bm.len(), 3);
assert!(bm.contains(3));
assert!(bm.contains(4));
assert!(bm.contains(5));
}
#[test]
fn test_range_bitmap_exclusive_upper() {
use std::ops::Bound;
let index = make_price_index();
let key30 = JsonValue::Number(crate::index::secondary::F64Key::from(30.0));
let bm = index
.range_bitmap(Bound::Unbounded, Bound::Excluded(&key30))
.expect("test: ids within u32 range");
assert_eq!(bm.len(), 2);
assert!(bm.contains(1));
assert!(bm.contains(2));
}
#[test]
fn test_range_bitmap_inclusive_upper() {
use std::ops::Bound;
let index = make_price_index();
let key30 = JsonValue::Number(crate::index::secondary::F64Key::from(30.0));
let bm = index
.range_bitmap(Bound::Unbounded, Bound::Included(&key30))
.expect("test: ids within u32 range");
assert_eq!(bm.len(), 3);
assert!(bm.contains(1));
assert!(bm.contains(2));
assert!(bm.contains(3));
}
#[test]
fn test_range_bitmap_closed_interval() {
use std::ops::Bound;
let index = make_price_index();
let key20 = JsonValue::Number(crate::index::secondary::F64Key::from(20.0));
let key40 = JsonValue::Number(crate::index::secondary::F64Key::from(40.0));
let bm = index
.range_bitmap(Bound::Included(&key20), Bound::Included(&key40))
.expect("test: ids within u32 range");
assert_eq!(bm.len(), 3);
assert!(bm.contains(2));
assert!(bm.contains(3));
assert!(bm.contains(4));
}
#[test]
fn test_range_bitmap_empty_result() {
use std::ops::Bound;
let index = make_price_index();
let key999 = JsonValue::Number(crate::index::secondary::F64Key::from(999.0));
let bm = index
.range_bitmap(Bound::Excluded(&key999), Bound::Unbounded)
.expect("test: ids within u32 range");
assert!(bm.is_empty());
}
#[test]
fn test_range_bitmap_all_values() {
use std::ops::Bound;
let index = make_price_index();
let bm = index
.range_bitmap(Bound::Unbounded, Bound::Unbounded)
.expect("test: ids within u32 range");
assert_eq!(bm.len(), 5);
}
#[test]
fn test_range_bitmap_none_when_in_range_id_overflows_u32() {
use std::ops::Bound;
let large_id = u64::from(u32::MAX) + 1;
let index = make_btree_index(vec![
(
JsonValue::Number(crate::index::secondary::F64Key::from(10.0)),
vec![1, large_id],
),
(
JsonValue::Number(crate::index::secondary::F64Key::from(20.0)),
vec![2],
),
]);
let low_bound = JsonValue::Number(crate::index::secondary::F64Key::from(5.0));
assert!(
index
.range_bitmap(Bound::Excluded(&low_bound), Bound::Unbounded)
.is_none(),
"range bitmap must be None when any in-range id overflows u32"
);
let above_overflow_bound = JsonValue::Number(crate::index::secondary::F64Key::from(15.0));
let bm = index
.range_bitmap(Bound::Excluded(&above_overflow_bound), Bound::Unbounded)
.expect("test: ids within u32 range");
assert_eq!(bm.len(), 1);
assert!(bm.contains(2));
}
}