use itertools::Itertools as _;
use re_data_store::{DataStore, RangeQuery, StoreSubscriber};
use re_log_types::{
build_frame_nr,
example_components::{MyColor, MyLabel, MyPoint, MyPoints},
DataRow, EntityPath, RowId, TimeInt, TimePoint, TimeRange,
};
use re_query_cache::Caches;
use re_types::components::InstanceKey;
use re_types_core::Loggable as _;
#[test]
fn simple_range() {
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: EntityPath = "point".into();
let timepoint1 = [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.clone(), timepoint1, 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.clone(),
timepoint1,
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let timepoint2 = [build_frame_nr(223.into())];
{
let color_instances = vec![InstanceKey(0)];
let colors = vec![MyColor::from_rgb(255, 0, 0)];
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path.clone(),
timepoint2,
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let timepoint3 = [build_frame_nr(323.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.clone(), timepoint3, 2, positions)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let query = re_data_store::RangeQuery::new(
timepoint1[0].0,
TimeRange::new((timepoint1[0].1.as_i64() + 1).into(), timepoint3[0].1),
);
query_and_compare(&caches, &store, &query, &ent_path);
let query = re_data_store::RangeQuery::new(
timepoint1[0].0,
TimeRange::new(timepoint1[0].1, timepoint3[0].1),
);
query_and_compare(&caches, &store, &query, &ent_path);
}
#[test]
fn timeless_range() {
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: EntityPath = "point".into();
let timepoint1 = [build_frame_nr(123.into())];
{
let positions = vec![MyPoint::new(1.0, 2.0), MyPoint::new(3.0, 4.0)];
let mut row =
DataRow::from_cells1(RowId::new(), ent_path.clone(), timepoint1, 2, &positions)
.unwrap();
row.compute_all_size_bytes();
insert_and_react(&mut store, &mut caches, &row);
let row =
DataRow::from_cells1_sized(RowId::new(), ent_path.clone(), [], 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.clone(),
timepoint1,
1,
(color_instances.clone(), colors.clone()),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path.clone(),
[],
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let timepoint2 = [build_frame_nr(223.into())];
{
let color_instances = vec![InstanceKey(0)];
let colors = vec![MyColor::from_rgb(255, 0, 0)];
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path.clone(),
timepoint2,
1,
(color_instances.clone(), colors.clone()),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let row = DataRow::from_cells2_sized(
RowId::new(),
ent_path.clone(),
timepoint2,
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let timepoint3 = [build_frame_nr(323.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.clone(), timepoint3, 2, &positions)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
let row =
DataRow::from_cells1_sized(RowId::new(), ent_path.clone(), [], 2, &positions).unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let query = re_data_store::RangeQuery::new(
timepoint1[0].0,
TimeRange::new((timepoint1[0].1.as_i64() + 1).into(), timepoint3[0].1),
);
query_and_compare(&caches, &store, &query, &ent_path);
let query = re_data_store::RangeQuery::new(
timepoint1[0].0,
TimeRange::new(timepoint1[0].1, timepoint3[0].1),
);
query_and_compare(&caches, &store, &query, &ent_path);
let query =
re_data_store::RangeQuery::new(timepoint1[0].0, TimeRange::new(TimeInt::MIN, TimeInt::MAX));
query_and_compare(&caches, &store, &query, &ent_path);
}
#[test]
fn simple_splatted_range() {
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: EntityPath = "point".into();
let timepoint1 = [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.clone(), timepoint1, 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.clone(),
timepoint1,
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let timepoint2 = [build_frame_nr(223.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.clone(),
timepoint2,
1,
(color_instances, colors),
)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let timepoint3 = [build_frame_nr(323.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.clone(), timepoint3, 2, positions)
.unwrap();
insert_and_react(&mut store, &mut caches, &row);
}
let query = re_data_store::RangeQuery::new(
timepoint1[0].0,
TimeRange::new((timepoint1[0].1.as_i64() + 1).into(), timepoint3[0].1),
);
query_and_compare(&caches, &store, &query, &ent_path);
let query = re_data_store::RangeQuery::new(
timepoint1[0].0,
TimeRange::new(timepoint1[0].1, timepoint3[0].1),
);
query_and_compare(&caches, &store, &query, &ent_path);
}
#[test]
fn invalidation() {
let ent_path = "point";
let test_invalidation = |query: RangeQuery,
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.clone(),
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(
RangeQuery::new(frame_123.0, TimeRange::EVERYTHING),
[frame_123].into(),
[frame_122].into(),
[frame_124].into(),
);
test_invalidation(
RangeQuery::new(frame_123.0, TimeRange::EVERYTHING),
[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 = re_data_store::RangeQuery::new(frame2[0].0, TimeRange::EVERYTHING);
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);
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);
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);
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);
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 frame0 = [build_frame_nr(0.into())];
let query = re_data_store::RangeQuery::new(frame0[0].0, TimeRange::EVERYTHING);
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);
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);
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);
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: &RangeQuery,
ent_path: &EntityPath,
) {
for _ in 0..3 {
let mut cached_data_times = Vec::new();
let mut cached_instance_keys = Vec::new();
let mut cached_positions = Vec::new();
let mut cached_colors = Vec::new();
caches
.query_archetype_pov1_comp2::<MyPoints, MyPoint, MyColor, MyLabel, _>(
store,
&query.clone().into(),
ent_path,
|((data_time, _), instance_keys, positions, colors, _)| {
cached_data_times.push(data_time);
cached_instance_keys.push(instance_keys.to_vec());
cached_positions.push(positions.to_vec());
cached_colors.push(
re_query_cache::iter_or_repeat_opt(colors, positions.len())
.copied()
.collect_vec(),
);
},
)
.unwrap();
let mut expected_data_times = Vec::new();
let mut expected_instance_keys = Vec::new();
let mut expected_positions = Vec::new();
let mut expected_colors = Vec::new();
let expected = re_query::range_archetype::<MyPoints, { MyPoints::NUM_COMPONENTS }>(
store, query, ent_path,
);
for arch_view in expected {
expected_data_times.push(arch_view.data_time());
expected_instance_keys.push(arch_view.iter_instance_keys().collect_vec());
expected_positions.push(
arch_view
.iter_required_component::<MyPoint>()
.unwrap()
.collect_vec(),
);
expected_colors.push(
arch_view
.iter_optional_component::<MyColor>()
.unwrap()
.collect_vec(),
);
}
similar_asserts::assert_eq!(expected_data_times, cached_data_times);
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);
}
}