From 2d39d881a3156a1bfa394496e7b541d64e077bf8 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Thu, 11 Jan 2024 17:29:27 +0100 Subject: [PATCH] port re_query's range test suite 1:1 --- crates/re_query_cache/tests/latest_at.rs | 84 +++-- crates/re_query_cache/tests/range.rs | 386 +++++++++++++++++++++++ 2 files changed, 424 insertions(+), 46 deletions(-) create mode 100644 crates/re_query_cache/tests/range.rs diff --git a/crates/re_query_cache/tests/latest_at.rs b/crates/re_query_cache/tests/latest_at.rs index d33e4a0a6de1b..4574e3e2fe8b8 100644 --- a/crates/re_query_cache/tests/latest_at.rs +++ b/crates/re_query_cache/tests/latest_at.rs @@ -5,13 +5,13 @@ use itertools::Itertools as _; use re_data_store::{DataStore, LatestAtQuery}; -use re_log_types::{build_frame_nr, DataRow, EntityPath, RowId, TimePoint}; -use re_query_cache::query_archetype_pov1_comp1; -use re_types::{ - archetypes::Points2D, - components::{Color, InstanceKey, Position2D}, +use re_log_types::{ + build_frame_nr, + example_components::{MyColor, MyPoint, MyPoints}, + DataRow, EntityPath, RowId, TimePoint, }; -use re_types_core::Loggable as _; +use re_query_cache::query_archetype_pov1_comp1; +use re_types_core::{components::InstanceKey, Loggable as _}; // --- @@ -27,13 +27,13 @@ fn simple_query() { let timepoint = [build_frame_nr(123.into())]; // Create some positions with implicit instances - let positions = vec![Position2D::new(1.0, 2.0), Position2D::new(3.0, 4.0)]; + 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(); store.insert_row(&row).unwrap(); // Assign one of them a color with an explicit instance let color_instances = vec![InstanceKey(1)]; - let colors = vec![Color::from_rgb(255, 0, 0)]; + let colors = vec![MyColor::from_rgb(255, 0, 0)]; let row = DataRow::from_cells2_sized( RowId::new(), ent_path, @@ -44,7 +44,6 @@ fn simple_query() { .unwrap(); store.insert_row(&row).unwrap(); - // Retrieve the view let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1); query_and_compare(&store, &query, &ent_path.into()); } @@ -61,18 +60,17 @@ fn timeless_query() { let timepoint = [build_frame_nr(123.into())]; // Create some positions with implicit instances - let positions = vec![Position2D::new(1.0, 2.0), Position2D::new(3.0, 4.0)]; + 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(); store.insert_row(&row).unwrap(); // Assign one of them a color with an explicit instance.. timelessly! let color_instances = vec![InstanceKey(1)]; - let colors = vec![Color::from_rgb(255, 0, 0)]; + let colors = vec![MyColor::from_rgb(255, 0, 0)]; let row = DataRow::from_cells2_sized(RowId::new(), ent_path, [], 1, (color_instances, colors)) .unwrap(); store.insert_row(&row).unwrap(); - // Retrieve the view let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1); query_and_compare(&store, &query, &ent_path.into()); } @@ -89,16 +87,15 @@ fn no_instance_join_query() { let timepoint = [build_frame_nr(123.into())]; // Create some positions with an implicit instance - let positions = vec![Position2D::new(1.0, 2.0), Position2D::new(3.0, 4.0)]; + 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(); store.insert_row(&row).unwrap(); // Assign them colors with explicit instances - let colors = vec![Color::from_rgb(255, 0, 0), Color::from_rgb(0, 255, 0)]; + 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(); store.insert_row(&row).unwrap(); - // Retrieve the view let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1); query_and_compare(&store, &query, &ent_path.into()); } @@ -115,11 +112,10 @@ fn missing_column_join_query() { let timepoint = [build_frame_nr(123.into())]; // Create some positions with an implicit instance - let positions = vec![Position2D::new(1.0, 2.0), Position2D::new(3.0, 4.0)]; + 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(); store.insert_row(&row).unwrap(); - // Retrieve the view let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1); query_and_compare(&store, &query, &ent_path.into()); } @@ -136,13 +132,13 @@ fn splatted_query() { let timepoint = [build_frame_nr(123.into())]; // Create some positions with implicit instances - let positions = vec![Position2D::new(1.0, 2.0), Position2D::new(3.0, 4.0)]; + 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(); store.insert_row(&row).unwrap(); // Assign all of them a color via splat let color_instances = vec![InstanceKey::SPLAT]; - let colors = vec![Color::from_rgb(255, 0, 0)]; + let colors = vec![MyColor::from_rgb(255, 0, 0)]; let row = DataRow::from_cells2_sized( RowId::new(), ent_path, @@ -153,7 +149,6 @@ fn splatted_query() { .unwrap(); store.insert_row(&row).unwrap(); - // Retrieve the view let query = re_data_store::LatestAtQuery::new(timepoint[0].0, timepoint[0].1); query_and_compare(&store, &query, &ent_path.into()); } @@ -173,7 +168,7 @@ fn invalidation() { ); // Create some positions with implicit instances - let positions = vec![Position2D::new(1.0, 2.0), Position2D::new(3.0, 4.0)]; + 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, @@ -186,7 +181,7 @@ fn invalidation() { // Assign one of them a color with an explicit instance let color_instances = vec![InstanceKey(1)]; - let colors = vec![Color::from_rgb(1, 2, 3)]; + let colors = vec![MyColor::from_rgb(1, 2, 3)]; let row = DataRow::from_cells2_sized( RowId::new(), ent_path, @@ -202,7 +197,7 @@ fn invalidation() { // --- Modify present --- // Modify the PoV component - let positions = vec![Position2D::new(10.0, 20.0), Position2D::new(30.0, 40.0)]; + 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, @@ -216,7 +211,7 @@ fn invalidation() { query_and_compare(&store, &query, &ent_path.into()); // Modify the optional component - let colors = vec![Color::from_rgb(4, 5, 6), Color::from_rgb(7, 8, 9)]; + 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(); @@ -227,7 +222,7 @@ fn invalidation() { // --- Modify past --- // Modify the PoV component - let positions = vec![Position2D::new(100.0, 200.0), Position2D::new(300.0, 400.0)]; + 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, @@ -241,7 +236,7 @@ fn invalidation() { query_and_compare(&store, &query, &ent_path.into()); // Modify the optional component - let colors = vec![Color::from_rgb(10, 11, 12), Color::from_rgb(13, 14, 15)]; + 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(); @@ -252,10 +247,7 @@ fn invalidation() { // --- Modify future --- // Modify the PoV component - let positions = vec![ - Position2D::new(1000.0, 2000.0), - Position2D::new(3000.0, 4000.0), - ]; + 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, @@ -269,7 +261,7 @@ fn invalidation() { query_and_compare(&store, &query, &ent_path.into()); // Modify the optional component - let colors = vec![Color::from_rgb(16, 17, 18)]; + 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(); @@ -312,19 +304,19 @@ fn invalidation() { // # Expected: points=[[1,2,3]] colors=[] // // rr.set_time(2) -// rr.log_components("points", rr.components.Color(0xFF0000)) +// rr.log_components("points", rr.components.MyColor(0xFF0000)) // // # Do second query here: LatestAt(+inf) // # Expected: points=[[1,2,3]] colors=[0xFF0000] // // rr.set_time(3) -// rr.log_components("points", rr.components.Color(0x0000FF)) +// rr.log_components("points", rr.components.MyColor(0x0000FF)) // // # Do third query here: LatestAt(+inf) // # Expected: points=[[1,2,3]] colors=[0x0000FF] // // rr.set_time(3) -// rr.log_components("points", rr.components.Color(0x00FF00)) +// rr.log_components("points", rr.components.MyColor(0x00FF00)) // // # Do fourth query here: LatestAt(+inf) // # Expected: points=[[1,2,3]] colors=[0x00FF00] @@ -345,7 +337,7 @@ fn invalidation_of_future_optionals() { let query_time = [build_frame_nr(9999.into())]; - let positions = vec![Position2D::new(1.0, 2.0), Position2D::new(3.0, 4.0)]; + 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(); store.insert_row(&row).unwrap(); @@ -353,7 +345,7 @@ fn invalidation_of_future_optionals() { query_and_compare(&store, &query, &ent_path.into()); let color_instances = vec![InstanceKey::SPLAT]; - let colors = vec![Color::from_rgb(255, 0, 0)]; + 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(); @@ -363,7 +355,7 @@ fn invalidation_of_future_optionals() { query_and_compare(&store, &query, &ent_path.into()); let color_instances = vec![InstanceKey::SPLAT]; - let colors = vec![Color::from_rgb(0, 0, 255)]; + 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(); @@ -373,7 +365,7 @@ fn invalidation_of_future_optionals() { query_and_compare(&store, &query, &ent_path.into()); let color_instances = vec![InstanceKey::SPLAT]; - let colors = vec![Color::from_rgb(0, 255, 0)]; + 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(); @@ -397,7 +389,7 @@ fn invalidation_timeless() { let query_time = [build_frame_nr(9999.into())]; - let positions = vec![Position2D::new(1.0, 2.0), Position2D::new(3.0, 4.0)]; + 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(); store.insert_row(&row).unwrap(); @@ -406,7 +398,7 @@ fn invalidation_timeless() { query_and_compare(&store, &query, &ent_path.into()); let color_instances = vec![InstanceKey::SPLAT]; - let colors = vec![Color::from_rgb(255, 0, 0)]; + let colors = vec![MyColor::from_rgb(255, 0, 0)]; let row = DataRow::from_cells2_sized( RowId::new(), ent_path, @@ -421,7 +413,7 @@ fn invalidation_timeless() { query_and_compare(&store, &query, &ent_path.into()); let color_instances = vec![InstanceKey::SPLAT]; - let colors = vec![Color::from_rgb(0, 0, 255)]; + let colors = vec![MyColor::from_rgb(0, 0, 255)]; let row = DataRow::from_cells2_sized( RowId::new(), ent_path, @@ -444,7 +436,7 @@ fn query_and_compare(store: &DataStore, query: &LatestAtQuery, ent_path: &Entity let mut uncached_instance_keys = Vec::new(); let mut uncached_positions = Vec::new(); let mut uncached_colors = Vec::new(); - query_archetype_pov1_comp1::( + query_archetype_pov1_comp1::( false, // cached? store, &query.clone().into(), @@ -462,7 +454,7 @@ fn query_and_compare(store: &DataStore, query: &LatestAtQuery, ent_path: &Entity let mut cached_instance_keys = Vec::new(); let mut cached_positions = Vec::new(); let mut cached_colors = Vec::new(); - query_archetype_pov1_comp1::( + query_archetype_pov1_comp1::( true, // cached? store, &query.clone().into(), @@ -477,14 +469,14 @@ fn query_and_compare(store: &DataStore, query: &LatestAtQuery, ent_path: &Entity .unwrap(); let (expected_data_time, expected) = - re_query::query_archetype::(store, query, ent_path).unwrap(); + re_query::query_archetype::(store, query, ent_path).unwrap(); let expected_instance_keys = expected.iter_instance_keys().collect_vec(); let expected_positions = expected - .iter_required_component::() + .iter_required_component::() .unwrap() .collect_vec(); let expected_colors = expected - .iter_optional_component::() + .iter_optional_component::() .unwrap() .collect_vec(); diff --git a/crates/re_query_cache/tests/range.rs b/crates/re_query_cache/tests/range.rs new file mode 100644 index 0000000000000..0d6b8438de955 --- /dev/null +++ b/crates/re_query_cache/tests/range.rs @@ -0,0 +1,386 @@ +//! Contains: +//! - A 1:1 port of the tests in `crates/re_query/tests/archetype_range_tests.rs`, with caching enabled. +//! - Invalidation tests. + +use itertools::Itertools as _; + +use re_data_store::{DataStore, RangeQuery}; +use re_log_types::{ + build_frame_nr, + example_components::{MyColor, MyLabel, MyPoint, MyPoints}, + DataRow, EntityPath, RowId, TimeInt, TimeRange, +}; +use re_query_cache::query_archetype_pov1_comp2; +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 ent_path: EntityPath = "point".into(); + + let timepoint1 = [build_frame_nr(123.into())]; + { + // Create some Positions with implicit instances + 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(); + store.insert_row(&row).unwrap(); + + // Assign one of them a color with an explicit instance + 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(); + store.insert_row(&row).unwrap(); + } + + let timepoint2 = [build_frame_nr(223.into())]; + { + // Assign one of them a color with an explicit instance + 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(); + store.insert_row(&row).unwrap(); + } + + let timepoint3 = [build_frame_nr(323.into())]; + { + // Create some Positions with implicit instances + 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(); + store.insert_row(&row).unwrap(); + } + + // --- First test: `(timepoint1, timepoint3]` --- + + // The exclusion of `timepoint1` means latest-at semantics will kick in! + + 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(&store, &query, &ent_path); + + // --- Second test: `[timepoint1, timepoint3]` --- + + // The inclusion of `timepoint1` means latest-at semantics will _not_ kick in! + + let query = re_data_store::RangeQuery::new( + timepoint1[0].0, + TimeRange::new(timepoint1[0].1, timepoint3[0].1), + ); + + query_and_compare(&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 ent_path: EntityPath = "point".into(); + + let timepoint1 = [build_frame_nr(123.into())]; + { + // Create some Positions with implicit instances + 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(); + store.insert_row(&row).unwrap(); + + // Insert timelessly too! + let row = + DataRow::from_cells1_sized(RowId::new(), ent_path.clone(), [], 2, &positions).unwrap(); + store.insert_row(&row).unwrap(); + + // Assign one of them a color with an explicit instance + 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(); + store.insert_row(&row).unwrap(); + + // Insert timelessly too! + let row = DataRow::from_cells2_sized( + RowId::new(), + ent_path.clone(), + [], + 1, + (color_instances, colors), + ) + .unwrap(); + store.insert_row(&row).unwrap(); + } + + let timepoint2 = [build_frame_nr(223.into())]; + { + // Assign one of them a color with an explicit instance + 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(); + store.insert_row(&row).unwrap(); + + // Insert timelessly too! + let row = DataRow::from_cells2_sized( + RowId::new(), + ent_path.clone(), + timepoint2, + 1, + (color_instances, colors), + ) + .unwrap(); + store.insert_row(&row).unwrap(); + } + + let timepoint3 = [build_frame_nr(323.into())]; + { + // Create some Positions with implicit instances + 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(); + store.insert_row(&row).unwrap(); + + // Insert timelessly too! + let row = + DataRow::from_cells1_sized(RowId::new(), ent_path.clone(), [], 2, &positions).unwrap(); + store.insert_row(&row).unwrap(); + } + + // --- First test: `(timepoint1, timepoint3]` --- + + // The exclusion of `timepoint1` means latest-at semantics will kick in! + + 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(&store, &query, &ent_path); + + // --- Second test: `[timepoint1, timepoint3]` --- + + // The inclusion of `timepoint1` means latest-at semantics will fall back to timeless data! + + let query = re_data_store::RangeQuery::new( + timepoint1[0].0, + TimeRange::new(timepoint1[0].1, timepoint3[0].1), + ); + + query_and_compare(&store, &query, &ent_path); + + // --- Third test: `[-inf, +inf]` --- + + let query = + re_data_store::RangeQuery::new(timepoint1[0].0, TimeRange::new(TimeInt::MIN, TimeInt::MAX)); + + query_and_compare(&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 ent_path: EntityPath = "point".into(); + + let timepoint1 = [build_frame_nr(123.into())]; + { + // Create some Positions with implicit instances + 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(); + store.insert_row(&row).unwrap(); + + // Assign one of them a color with an explicit instance + 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(); + store.insert_row(&row).unwrap(); + } + + let timepoint2 = [build_frame_nr(223.into())]; + { + // Assign one of them a color with a splatted instance + 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(); + store.insert_row(&row).unwrap(); + } + + let timepoint3 = [build_frame_nr(323.into())]; + { + // Create some Positions with implicit instances + 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(); + store.insert_row(&row).unwrap(); + } + + // --- First test: `(timepoint1, timepoint3]` --- + + // The exclusion of `timepoint1` means latest-at semantics will kick in! + + 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(&store, &query, &ent_path); + + // --- Second test: `[timepoint1, timepoint3]` --- + + // The inclusion of `timepoint1` means latest-at semantics will _not_ kick in! + + let query = re_data_store::RangeQuery::new( + timepoint1[0].0, + TimeRange::new(timepoint1[0].1, timepoint3[0].1), + ); + + query_and_compare(&store, &query, &ent_path); +} + +// --- + +fn query_and_compare(store: &DataStore, query: &RangeQuery, ent_path: &EntityPath) { + for _ in 0..3 { + let mut uncached_data_times = Vec::new(); + let mut uncached_instance_keys = Vec::new(); + let mut uncached_positions = Vec::new(); + let mut uncached_colors = Vec::new(); + query_archetype_pov1_comp2::( + false, // cached? + store, + &query.clone().into(), + ent_path, + |((data_time, _), instance_keys, positions, colors, _)| { + uncached_data_times.push(data_time); + uncached_instance_keys.push(instance_keys.to_vec()); + uncached_positions.push(positions.to_vec()); + uncached_colors.push(colors.to_vec()); + }, + ) + .unwrap(); + + // 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(); + // query_archetype_pov1_comp2::( + // true, // cached? + // 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(colors.iter().copied()); + // }, + // ) + // .unwrap(); + + let expected = re_query::range_archetype::( + store, query, ent_path, + ); + + 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(); + + for (data_time, arch_view) in expected { + expected_data_times.push(data_time); + expected_instance_keys.push(arch_view.iter_instance_keys().collect_vec()); + expected_positions.push( + arch_view + .iter_required_component::() + .unwrap() + .collect_vec(), + ); + expected_colors.push( + arch_view + .iter_optional_component::() + .unwrap() + .collect_vec(), + ); + } + + // Keep this around for the next unlucky chap. + // eprintln!("(expected={expected_data_times:?}, uncached={uncached_data_times:?}, cached={cached_data_times:?})"); + + // TODO + similar_asserts::assert_eq!(expected_data_times, uncached_data_times); + similar_asserts::assert_eq!(expected_instance_keys, uncached_instance_keys); + similar_asserts::assert_eq!(expected_positions, uncached_positions); + similar_asserts::assert_eq!(expected_colors, uncached_colors); + + // TODO + // 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); + } +}