use itertools::Itertools as _;
use re_data_store::{DataStore, LatestAtQuery, StoreSubscriber};
use re_log_types::{
build_frame_nr,
example_components::{MyColor, MyPoint, MyPoints},
DataRow, EntityPath, RowId, TimePoint,
};
use re_query_cache::Caches;
use re_types_core::{components::InstanceKey, Loggable as _};
#[test]
fn simple_query() {
let mut store = DataStore::new(
re_log_types::StoreId::random(re_log_types::StoreKind::Recording),
InstanceKey::name(),
Default::default(),
);
let mut caches = Caches::new(&store);
let ent_path = "point";
let timepoint = [build_frame_nr(123.into())];
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let row = DataRow::from_cells1_sized(RowId::new(), ent_path, timepoint, 2, positions).unwrap();
insert_and_react(&mut store, &mut caches, &row);
let color_instances = vec![InstanceKey(1)];
let colors = vec![MyColor::from_rgb(255, 0, 0)];
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path,
timepoint,
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
}
#[test]
fn timeless_query() {
let mut store = DataStore::new(
re_log_types::StoreId::random(re_log_types::StoreKind::Recording),
InstanceKey::name(),
Default::default(),
);
let mut caches = Caches::new(&store);
let ent_path = "point";
let timepoint = [build_frame_nr(123.into())];
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let row = DataRow::from_cells1_sized(RowId::new(), ent_path, timepoint, 2, positions).unwrap();
insert_and_react(&mut store, &mut caches, &row);
let color_instances = vec![InstanceKey(1)];
let colors = vec![MyColor::from_rgb(255, 0, 0)];
let row = DataRow::from_cells2_sized(RowId::new(), ent_path, [], 1, (color_instances, colors))
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
}
#[test]
fn no_instance_join_query() {
let mut store = DataStore::new(
re_log_types::StoreId::random(re_log_types::StoreKind::Recording),
InstanceKey::name(),
Default::default(),
);
let mut caches = Caches::new(&store);
let ent_path = "point";
let timepoint = [build_frame_nr(123.into())];
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let row = DataRow::from_cells1_sized(RowId::new(), ent_path, timepoint, 2, positions).unwrap();
insert_and_react(&mut store, &mut caches, &row);
let colors = vec![MyColor::from_rgb(255, 0, 0), MyColor::from_rgb(0, 255, 0)];
let row = DataRow::from_cells1_sized(RowId::new(), ent_path, timepoint, 2, colors).unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
}
#[test]
fn missing_column_join_query() {
let mut store = DataStore::new(
re_log_types::StoreId::random(re_log_types::StoreKind::Recording),
InstanceKey::name(),
Default::default(),
);
let mut caches = Caches::new(&store);
let ent_path = "point";
let timepoint = [build_frame_nr(123.into())];
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let row = DataRow::from_cells1_sized(RowId::new(), ent_path, timepoint, 2, positions).unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
}
#[test]
fn splatted_query() {
let mut store = DataStore::new(
re_log_types::StoreId::random(re_log_types::StoreKind::Recording),
InstanceKey::name(),
Default::default(),
);
let mut caches = Caches::new(&store);
let ent_path = "point";
let timepoint = [build_frame_nr(123.into())];
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let row = DataRow::from_cells1_sized(RowId::new(), ent_path, timepoint, 2, positions).unwrap();
insert_and_react(&mut store, &mut caches, &row);
let color_instances = vec![InstanceKey::SPLAT];
let colors = vec![MyColor::from_rgb(255, 0, 0)];
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path,
timepoint,
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
}
#[test]
fn invalidation() {
let ent_path = "point";
let test_invalidation = |query: LatestAtQuery,
present_data_timepoint: TimePoint,
past_data_timepoint: TimePoint,
future_data_timepoint: TimePoint| {
let mut store = DataStore::new(
re_log_types::StoreId::random(re_log_types::StoreKind::Recording),
InstanceKey::name(),
Default::default(),
);
let mut caches = Caches::new(&store);
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let row = DataRow::from_cells1_sized(
RowId::new(),
ent_path,
present_data_timepoint.clone(),
2,
positions,
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let color_instances = vec![InstanceKey(1)];
let colors = vec![MyColor::from_rgb(1, 2, 3)];
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path,
present_data_timepoint.clone(),
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
query_and_compare(&caches, &store, &query, &ent_path.into());
let positions = vec![MyPoint::new(10.0, 20.0), MyPoint::new(30.0, 40.0)];
let row = DataRow::from_cells1_sized(
RowId::new(),
ent_path,
present_data_timepoint.clone(),
2,
positions,
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
query_and_compare(&caches, &store, &query, &ent_path.into());
let colors = vec![MyColor::from_rgb(4, 5, 6), MyColor::from_rgb(7, 8, 9)];
let row =
DataRow::from_cells1_sized(RowId::new(), ent_path, present_data_timepoint, 2, colors)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
query_and_compare(&caches, &store, &query, &ent_path.into());
let positions = vec![MyPoint::new(100.0, 200.0), MyPoint::new(300.0, 400.0)];
let row = DataRow::from_cells1_sized(
RowId::new(),
ent_path,
past_data_timepoint.clone(),
2,
positions,
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
query_and_compare(&caches, &store, &query, &ent_path.into());
let colors = vec![MyColor::from_rgb(10, 11, 12), MyColor::from_rgb(13, 14, 15)];
let row =
DataRow::from_cells1_sized(RowId::new(), ent_path, past_data_timepoint, 2, colors)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
query_and_compare(&caches, &store, &query, &ent_path.into());
let positions = vec![MyPoint::new(1000.0, 2000.0), MyPoint::new(3000.0, 4000.0)];
let row = DataRow::from_cells1_sized(
RowId::new(),
ent_path,
future_data_timepoint.clone(),
2,
positions,
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
query_and_compare(&caches, &store, &query, &ent_path.into());
let colors = vec![MyColor::from_rgb(16, 17, 18)];
let row =
DataRow::from_cells1_sized(RowId::new(), ent_path, future_data_timepoint, 1, colors)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
query_and_compare(&caches, &store, &query, &ent_path.into());
};
let timeless = TimePoint::timeless();
let frame_122 = build_frame_nr(122.into());
let frame_123 = build_frame_nr(123.into());
let frame_124 = build_frame_nr(124.into());
test_invalidation(
LatestAtQuery {
timeline: frame_123.0,
at: frame_123.1,
},
[frame_123].into(),
[frame_122].into(),
[frame_124].into(),
);
test_invalidation(
LatestAtQuery {
timeline: frame_123.0,
at: frame_123.1,
},
[frame_123].into(),
timeless,
[frame_124].into(),
);
}
#[test]
fn invalidation_of_future_optionals() {
let mut store = DataStore::new(
re_log_types::StoreId::random(re_log_types::StoreKind::Recording),
InstanceKey::name(),
Default::default(),
);
let mut caches = Caches::new(&store);
let ent_path = "points";
let timeless = TimePoint::timeless();
let frame2 = [build_frame_nr(2.into())];
let frame3 = [build_frame_nr(3.into())];
let query_time = [build_frame_nr(9999.into())];
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let row = DataRow::from_cells1_sized(RowId::new(), ent_path, timeless, 2, positions).unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(query_time[0].0, query_time[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
let color_instances = vec![InstanceKey::SPLAT];
let colors = vec![MyColor::from_rgb(255, 0, 0)];
let row =
DataRow::from_cells2_sized(RowId::new(), ent_path, frame2, 1, (color_instances, colors))
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(query_time[0].0, query_time[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
let color_instances = vec![InstanceKey::SPLAT];
let colors = vec![MyColor::from_rgb(0, 0, 255)];
let row =
DataRow::from_cells2_sized(RowId::new(), ent_path, frame3, 1, (color_instances, colors))
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(query_time[0].0, query_time[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
let color_instances = vec![InstanceKey::SPLAT];
let colors = vec![MyColor::from_rgb(0, 255, 0)];
let row =
DataRow::from_cells2_sized(RowId::new(), ent_path, frame3, 1, (color_instances, colors))
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(query_time[0].0, query_time[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
}
#[test]
fn invalidation_timeless() {
let mut store = DataStore::new(
re_log_types::StoreId::random(re_log_types::StoreKind::Recording),
InstanceKey::name(),
Default::default(),
);
let mut caches = Caches::new(&store);
let ent_path = "points";
let timeless = TimePoint::timeless();
let query_time = [build_frame_nr(9999.into())];
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let row =
DataRow::from_cells1_sized(RowId::new(), ent_path, timeless.clone(), 2, positions).unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(query_time[0].0, query_time[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
let color_instances = vec![InstanceKey::SPLAT];
let colors = vec![MyColor::from_rgb(255, 0, 0)];
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path,
timeless.clone(),
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(query_time[0].0, query_time[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
let color_instances = vec![InstanceKey::SPLAT];
let colors = vec![MyColor::from_rgb(0, 0, 255)];
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path,
timeless,
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let query = re_data_store::LatestAtQuery::new(query_time[0].0, query_time[0].1);
query_and_compare(&caches, &store, &query, &ent_path.into());
}
fn insert_and_react(store: &mut DataStore, caches: &mut Caches, row: &DataRow) {
caches.on_events(&[store.insert_row(row).unwrap()]);
}
fn query_and_compare(
caches: &Caches,
store: &DataStore,
query: &LatestAtQuery,
ent_path: &EntityPath,
) {
re_log::setup_logging();
for _ in 0..3 {
let mut cached_data_time = None;
let mut cached_instance_keys = Vec::new();
let mut cached_positions = Vec::new();
let mut cached_colors = Vec::new();
caches
.query_archetype_pov1_comp1::<MyPoints, MyPoint, MyColor, _>(
store,
&query.clone().into(),
ent_path,
|((data_time, _), instance_keys, positions, colors)| {
cached_data_time = data_time;
cached_instance_keys.extend(instance_keys.iter().copied());
cached_positions.extend(positions.iter().copied());
cached_colors
.extend(re_query_cache::iter_or_repeat_opt(colors, positions.len()));
},
)
.unwrap();
let expected = re_query::query_archetype::<MyPoints>(store, query, ent_path).unwrap();
let expected_data_time = expected.data_time();
let expected_instance_keys = expected.iter_instance_keys().collect_vec();
let expected_positions = expected
.iter_required_component::<MyPoint>()
.unwrap()
.collect_vec();
let expected_colors = expected
.iter_optional_component::<MyColor>()
.unwrap()
.collect_vec();
similar_asserts::assert_eq!(expected_data_time, cached_data_time);
similar_asserts::assert_eq!(expected_instance_keys, cached_instance_keys);
similar_asserts::assert_eq!(expected_positions, cached_positions);
similar_asserts::assert_eq!(expected_colors, cached_colors);
}
}