From 49640b2d676411f9df3ae1eedd1c448768a17d2b Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Wed, 12 Apr 2023 17:28:41 +0200 Subject: [PATCH] Datastore revamp 4: sunset `MsgId` --- crates/re_arrow_store/benches/data_store.rs | 12 +-- crates/re_arrow_store/src/polars_util.rs | 6 +- crates/re_arrow_store/src/store_read.rs | 43 ++++----- crates/re_arrow_store/src/test_util.rs | 4 +- crates/re_arrow_store/tests/correctness.rs | 26 ++--- crates/re_arrow_store/tests/data_store.rs | 70 +++++++------- crates/re_data_store/examples/memory_usage.rs | 6 +- crates/re_data_store/src/entity_properties.rs | 2 +- crates/re_data_store/src/entity_tree.rs | 26 ++--- crates/re_data_store/src/log_db.rs | 57 ++++++----- .../benches/msg_encode_benchmark.rs | 14 +-- crates/re_log_encoding/src/decoder.rs | 6 +- crates/re_log_types/src/arrow_msg.rs | 10 +- .../re_log_types/src/component_types/mod.rs | 5 +- .../src/component_types/msg_id.rs | 95 ------------------- crates/re_log_types/src/data_row.rs | 82 ++++++++++++---- crates/re_log_types/src/data_table.rs | 63 +++++++++++- crates/re_log_types/src/lib.rs | 27 +++--- crates/re_query/benches/query_benchmark.rs | 6 +- crates/re_query/examples/range.rs | 14 +-- crates/re_query/src/entity_view.rs | 10 +- crates/re_query/src/query.rs | 45 +++++---- crates/re_query/src/range.rs | 24 +++-- crates/re_query/tests/query_tests.rs | 20 ++-- crates/re_query/tests/range_tests.rs | 36 +++---- crates/re_sdk/src/lib.rs | 2 +- crates/re_sdk/src/msg_sender.rs | 12 +-- crates/re_sdk/src/session.rs | 4 +- crates/re_sdk_comms/src/buffered_client.rs | 4 +- crates/re_tuid/src/lib.rs | 12 +++ .../src/misc/caches/tensor_image_cache.rs | 8 +- crates/re_viewer/src/misc/item.rs | 10 +- crates/re_viewer/src/misc/selection_state.rs | 6 +- crates/re_viewer/src/misc/viewer_context.rs | 14 +-- crates/re_viewer/src/ui/annotations.rs | 24 +++-- .../src/ui/data_ui/component_path.rs | 2 +- .../src/ui/data_ui/component_ui_registry.rs | 1 - .../re_viewer/src/ui/data_ui/instance_path.rs | 4 +- crates/re_viewer/src/ui/data_ui/log_msg.rs | 4 +- crates/re_viewer/src/ui/data_ui/mod.rs | 2 +- .../src/ui/data_ui/{msg_id.rs => row_id.rs} | 8 +- crates/re_viewer/src/ui/event_log_view.rs | 16 ++-- .../re_viewer/src/ui/selection_history_ui.rs | 2 +- crates/re_viewer/src/ui/selection_panel.rs | 14 +-- .../re_viewer/src/ui/space_view_heuristics.rs | 1 - .../src/ui/time_panel/data_density_graph.rs | 4 +- crates/re_viewer/src/ui/view_text/scene.rs | 12 +-- crates/re_viewer/src/ui/view_text/ui.rs | 2 +- rerun_py/src/arrow.rs | 4 +- rerun_py/src/python_bridge.rs | 14 +-- rerun_py/src/python_session.rs | 8 +- 51 files changed, 460 insertions(+), 443 deletions(-) delete mode 100644 crates/re_log_types/src/component_types/msg_id.rs rename crates/re_viewer/src/ui/data_ui/{msg_id.rs => row_id.rs} (80%) diff --git a/crates/re_arrow_store/benches/data_store.rs b/crates/re_arrow_store/benches/data_store.rs index 10ba0f1bb629..385b4f83f904 100644 --- a/crates/re_arrow_store/benches/data_store.rs +++ b/crates/re_arrow_store/benches/data_store.rs @@ -8,8 +8,8 @@ use re_arrow_store::{DataStore, DataStoreConfig, LatestAtQuery, RangeQuery, Time use re_log_types::{ component_types::{InstanceKey, Rect2D}, datagen::{build_frame_nr, build_some_instances, build_some_rects}, - Component as _, ComponentName, DataCell, DataRow, DataTable, EntityPath, MsgId, TimeType, - Timeline, + Component as _, ComponentName, DataCell, DataRow, DataTable, EntityPath, RowId, TableId, + TimeType, Timeline, }; criterion_group!(benches, insert, latest_at, latest_at_missing, range); @@ -262,10 +262,10 @@ fn range(c: &mut Criterion) { fn build_table(n: usize, packed: bool) -> DataTable { let mut table = DataTable::from_rows( - MsgId::ZERO, + TableId::ZERO, (0..NUM_ROWS).map(move |frame_idx| { DataRow::from_cells2( - MsgId::random(), + RowId::random(), "rects", [build_frame_nr(frame_idx.into())], n as _, @@ -277,7 +277,7 @@ fn build_table(n: usize, packed: bool) -> DataTable { // Do a serialization roundtrip to pack everything in contiguous memory. if packed { let (schema, columns) = table.serialize().unwrap(); - table = DataTable::deserialize(MsgId::ZERO, &schema, &columns).unwrap(); + table = DataTable::deserialize(TableId::ZERO, &schema, &columns).unwrap(); } table @@ -304,7 +304,7 @@ fn latest_data_at( store .latest_at(&timeline_query, &ent_path, primary, secondaries) - .unwrap_or_else(|| [(); N].map(|_| None)) + .map_or_else(|| [(); N].map(|_| None), |(_, cells)| cells) } fn range_data( diff --git a/crates/re_arrow_store/src/polars_util.rs b/crates/re_arrow_store/src/polars_util.rs index 397cc3f83965..4e4beabbb69c 100644 --- a/crates/re_arrow_store/src/polars_util.rs +++ b/crates/re_arrow_store/src/polars_util.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use polars_core::{prelude::*, series::Series}; use polars_ops::prelude::*; -use re_log_types::{ComponentName, DataCell, EntityPath, TimeInt}; +use re_log_types::{ComponentName, DataCell, EntityPath, RowId, TimeInt}; use crate::{ArrayExt, DataStore, LatestAtQuery, RangeQuery}; @@ -37,9 +37,9 @@ pub fn latest_component( let cluster_key = store.cluster_key(); let components = &[cluster_key, primary]; - let cells = store + let (_, cells) = store .latest_at(query, ent_path, primary, components) - .unwrap_or([(); 2].map(|_| None)); + .unwrap_or((RowId::ZERO, [(); 2].map(|_| None))); dataframe_from_cells(&cells) } diff --git a/crates/re_arrow_store/src/store_read.rs b/crates/re_arrow_store/src/store_read.rs index 4eea9ed463e7..74f75c586363 100644 --- a/crates/re_arrow_store/src/store_read.rs +++ b/crates/re_arrow_store/src/store_read.rs @@ -4,7 +4,7 @@ use itertools::Itertools; use nohash_hasher::IntSet; use re_log::trace; use re_log_types::{ - ComponentName, DataCell, EntityPath, MsgId, RowId, TimeInt, TimePoint, TimeRange, Timeline, + ComponentName, DataCell, EntityPath, RowId, TimeInt, TimePoint, TimeRange, Timeline, }; use smallvec::SmallVec; @@ -151,7 +151,7 @@ impl DataStore { /// /// ```rust /// # use polars_core::{prelude::*, series::Series}; - /// # use re_log_types::{ComponentName, EntityPath, TimeInt}; + /// # use re_log_types::{ComponentName, EntityPath, RowId, TimeInt}; /// # use re_arrow_store::{DataStore, LatestAtQuery, RangeQuery}; /// # /// pub fn latest_component( @@ -163,9 +163,9 @@ impl DataStore { /// let cluster_key = store.cluster_key(); /// /// let components = &[cluster_key, primary]; - /// let cells = store - /// .latest_at(query, ent_path, primary, components) - /// .unwrap_or([(); 2].map(|_| None)); + /// let (_, cells) = store + /// .latest_at(&query, ent_path, primary, components) + /// .unwrap_or((RowId::ZERO, [(); 2].map(|_| None))); /// /// let series: Result, _> = cells /// .iter() @@ -193,7 +193,7 @@ impl DataStore { ent_path: &EntityPath, primary: ComponentName, components: &[ComponentName; N], - ) -> Option<[Option; N]> { + ) -> Option<(RowId, [Option; N])> { crate::profile_function!(); // TODO(cmc): kind & query_id need to somehow propagate through the span system. @@ -232,7 +232,7 @@ impl DataStore { // return the results immediately. if cells .as_ref() - .map_or(false, |cells| cells.iter().all(Option::is_some)) + .map_or(false, |(_, cells)| cells.iter().all(Option::is_some)) { return cells; } @@ -260,13 +260,13 @@ impl DataStore { (None, Some(cells_timeless)) => return Some(cells_timeless), // we have both temporal & timeless cells: let's merge the two when it makes sense // and return the end result. - (Some(mut cells), Some(cells_timeless)) => { + (Some((row_id, mut cells)), Some((_, cells_timeless))) => { for (i, row_idx) in cells_timeless.into_iter().enumerate() { if cells[i].is_none() { cells[i] = row_idx; } } - return Some(cells); + return Some((row_id, cells)); } // no cells at all. (None, None) => {} @@ -320,7 +320,7 @@ impl DataStore { /// ```rust /// # use arrow2::array::Array; /// # use polars_core::{prelude::*, series::Series}; - /// # use re_log_types::{ComponentName, DataCell, EntityPath, TimeInt}; + /// # use re_log_types::{ComponentName, DataCell, EntityPath, RowId, TimeInt}; /// # use re_arrow_store::{DataStore, LatestAtQuery, RangeQuery}; /// # /// # pub fn dataframe_from_cells( @@ -354,9 +354,9 @@ impl DataStore { /// let latest_time = query.range.min.as_i64().saturating_sub(1).into(); /// let df_latest = { /// let query = LatestAtQuery::new(query.timeline, latest_time); - /// let cells = store + /// let (_, cells) = store /// .latest_at(&query, ent_path, primary, &components) - /// .unwrap_or([(); 2].map(|_| None)); + /// .unwrap_or((RowId::ZERO, [(); 2].map(|_| None))); /// dataframe_from_cells(cells) /// }; /// @@ -425,10 +425,10 @@ impl DataStore { } } - pub fn get_msg_metadata(&self, msg_id: &MsgId) -> Option<&TimePoint> { + pub fn get_msg_metadata(&self, row_id: &RowId) -> Option<&TimePoint> { crate::profile_function!(); - self.metadata_registry.get(msg_id) + self.metadata_registry.get(row_id) } /// Sort all unsorted indices in the store. @@ -452,7 +452,7 @@ impl IndexedTable { time: TimeInt, primary: ComponentName, components: &[ComponentName; N], - ) -> Option<[Option; N]> { + ) -> Option<(RowId, [Option; N])> { crate::profile_function!(); // Early-exit if this entire table is unaware of this component. @@ -660,8 +660,9 @@ impl IndexedBucket { time: TimeInt, primary: ComponentName, components: &[ComponentName; N], - ) -> Option<[Option; N]> { + ) -> Option<(RowId, [Option; N])> { crate::profile_function!(); + self.sort_indices_if_needed(); let IndexedBucketInner { @@ -669,7 +670,7 @@ impl IndexedBucket { time_range: _, col_time, col_insert_id: _, - col_row_id: _, + col_row_id, col_num_instances: _, columns, size_bytes: _, @@ -679,8 +680,6 @@ impl IndexedBucket { // Early-exit if this bucket is unaware of this component. let column = columns.get(&primary)?; - crate::profile_function!(); - trace!( kind = "latest_at", %primary, @@ -759,7 +758,7 @@ impl IndexedBucket { } } - Some(cells) + Some((col_row_id[secondary_row_nr as usize], cells)) } /// Iterates the bucket in order to return the cells of the the specified `components`, @@ -983,7 +982,7 @@ impl PersistentIndexedTable { &self, primary: ComponentName, components: &[ComponentName; N], - ) -> Option<[Option; N]> { + ) -> Option<(RowId, [Option; N])> { if self.is_empty() { return None; } @@ -1057,7 +1056,7 @@ impl PersistentIndexedTable { } } - Some(cells) + Some((self.col_row_id[secondary_row_nr as usize], cells)) } /// Iterates the table in order to return the cells of the the specified `components`, diff --git a/crates/re_arrow_store/src/test_util.rs b/crates/re_arrow_store/src/test_util.rs index 00da9be207f9..0fe1b28bf8c2 100644 --- a/crates/re_arrow_store/src/test_util.rs +++ b/crates/re_arrow_store/src/test_util.rs @@ -7,7 +7,7 @@ use crate::DataStoreConfig; macro_rules! test_row { ($entity:ident @ $frames:tt => $n:expr; [$c0:expr $(,)*]) => { ::re_log_types::DataRow::from_cells1( - ::re_log_types::MsgId::random(), + ::re_log_types::RowId::random(), $entity.clone(), $frames, $n, @@ -16,7 +16,7 @@ macro_rules! test_row { }; ($entity:ident @ $frames:tt => $n:expr; [$c0:expr, $c1:expr $(,)*]) => { ::re_log_types::DataRow::from_cells2( - ::re_log_types::MsgId::random(), + ::re_log_types::RowId::random(), $entity.clone(), $frames, $n, diff --git a/crates/re_arrow_store/tests/correctness.rs b/crates/re_arrow_store/tests/correctness.rs index 708da1de917a..d6d68fcfe683 100644 --- a/crates/re_arrow_store/tests/correctness.rs +++ b/crates/re_arrow_store/tests/correctness.rs @@ -146,7 +146,7 @@ fn latest_at_emptiness_edge_cases_impl(store: &mut DataStore) { // bunch of non-existing components { let components = &["they".into(), "dont".into(), "exist".into()]; - let cells = store + let (_, cells) = store .latest_at( &LatestAtQuery::new(timeline_frame_nr, frame40), &ent_path, @@ -159,7 +159,7 @@ fn latest_at_emptiness_edge_cases_impl(store: &mut DataStore) { // empty component list { - let cells = store + let (_, cells) = store .latest_at( &LatestAtQuery::new(timeline_frame_nr, frame40), &ent_path, @@ -309,18 +309,18 @@ fn gc_correct() { // TODO(#1619): bring back garbage collection - // let msg_id_chunks = store.gc( + // let row_id_chunks = store.gc( // GarbageCollectionTarget::DropAtLeastPercentage(1.0), // Timeline::new("frame_nr", TimeType::Sequence), // MsgId::name(), // ); - // let msg_ids = msg_id_chunks + // let row_ids = row_id_chunks // .iter() // .flat_map(|chunk| arrow_array_deserialize_iterator::>(&**chunk).unwrap()) // .map(Option::unwrap) // MsgId is always present // .collect::>(); - // assert!(!msg_ids.is_empty()); + // assert!(!row_ids.is_empty()); // if let err @ Err(_) = store.sanity_check() { // store.sort_indices_if_needed(); @@ -328,11 +328,11 @@ fn gc_correct() { // err.unwrap(); // } // check_still_readable(&store); - // for msg_id in &msg_ids { - // assert!(store.get_msg_metadata(msg_id).is_some()); + // for row_id in &row_ids { + // assert!(store.get_msg_metadata(row_id).is_some()); // } - // store.clear_msg_metadata(&msg_ids); + // store.clear_msg_metadata(&row_ids); // if let err @ Err(_) = store.sanity_check() { // store.sort_indices_if_needed(); @@ -340,22 +340,22 @@ fn gc_correct() { // err.unwrap(); // } // check_still_readable(&store); - // for msg_id in &msg_ids { - // assert!(store.get_msg_metadata(msg_id).is_none()); + // for row_id in &row_ids { + // assert!(store.get_msg_metadata(row_id).is_none()); // } - // let msg_id_chunks = store.gc( + // let row_id_chunks = store.gc( // GarbageCollectionTarget::DropAtLeastPercentage(1.0), // Timeline::new("frame_nr", TimeType::Sequence), // MsgId::name(), // ); - // let msg_ids = msg_id_chunks + // let row_ids = row_id_chunks // .iter() // .flat_map(|chunk| arrow_array_deserialize_iterator::>(&**chunk).unwrap()) // .map(Option::unwrap) // MsgId is always present // .collect::>(); - // assert!(msg_ids.is_empty()); + // assert!(row_ids.is_empty()); // if let err @ Err(_) = store.sanity_check() { // store.sort_indices_if_needed(); diff --git a/crates/re_arrow_store/tests/data_store.rs b/crates/re_arrow_store/tests/data_store.rs index edc1f61f9e52..391f4624df12 100644 --- a/crates/re_arrow_store/tests/data_store.rs +++ b/crates/re_arrow_store/tests/data_store.rs @@ -75,18 +75,16 @@ fn all_components() { let cluster_key = store.cluster_key(); let components_a = &[ - ColorRGBA::name(), // added by us, timeless - Rect2D::name(), // added by us - cluster_key, // always here - re_log_types::MsgId::name(), // injected automatically (..for now) + ColorRGBA::name(), // added by test, timeless + Rect2D::name(), // added by test + cluster_key, // always here ]; let components_b = &[ - ColorRGBA::name(), // added by us, timeless - Point2D::name(), // added by us - Rect2D::name(), // added by us - cluster_key, // always here - re_log_types::MsgId::name(), // injected automatically (..for now) + ColorRGBA::name(), // added by test, timeless + Point2D::name(), // added by test + Rect2D::name(), // added by test + cluster_key, // always here ]; let row = test_row!(ent_path @ [] => 2; [build_some_colors(2)]); @@ -123,12 +121,12 @@ fn all_components() { let cluster_key = store.cluster_key(); // ┌──────────┬────────┬────────┬───────────┬──────────┐ - // │ frame_nr ┆ rect2d ┆ msg_id ┆ insert_id ┆ instance │ + // │ frame_nr ┆ rect2d ┆ row_id ┆ insert_id ┆ instance │ // ╞══════════╪════════╪════════╪═══════════╪══════════╡ // │ 1 ┆ 1 ┆ 1 ┆ 1 ┆ 1 │ // └──────────┴────────┴────────┴───────────┴──────────┘ // ┌──────────┬────────┬─────────┬────────┬───────────┬──────────┐ - // │ frame_nr ┆ rect2d ┆ point2d ┆ msg_id ┆ insert_id ┆ instance │ + // │ frame_nr ┆ rect2d ┆ point2d ┆ row_id ┆ insert_id ┆ instance │ // ╞══════════╪════════╪═════════╪════════╪═══════════╪══════════╡ // │ 2 ┆ - ┆ - ┆ 2 ┆ 2 ┆ 2 │ // ├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤ @@ -136,18 +134,16 @@ fn all_components() { // └──────────┴────────┴─────────┴────────┴───────────┴──────────┘ let components_a = &[ - ColorRGBA::name(), // added by us, timeless - Rect2D::name(), // added by us - cluster_key, // always here - re_log_types::MsgId::name(), // injected automatically (..for now) + ColorRGBA::name(), // added by test, timeless + Rect2D::name(), // added by test + cluster_key, // always here ]; let components_b = &[ - ColorRGBA::name(), // added by us, timeless - Rect2D::name(), // ⚠ inherited before the buckets got split apart! - Point2D::name(), // added by us - cluster_key, // always here - re_log_types::MsgId::name(), // injected automatically (..for now) + ColorRGBA::name(), // added by test, timeless + Rect2D::name(), // ⚠ inherited before the buckets got split apart! + Point2D::name(), // added by test + cluster_key, // always here ]; let row = test_row!(ent_path @ [] => 2; [build_some_colors(2)]); @@ -188,14 +184,14 @@ fn all_components() { let cluster_key = store.cluster_key(); // ┌──────────┬────────┬─────────┬────────┬───────────┬──────────┐ - // │ frame_nr ┆ rect2d ┆ point2d ┆ msg_id ┆ insert_id ┆ instance │ + // │ frame_nr ┆ rect2d ┆ point2d ┆ row_id ┆ insert_id ┆ instance │ // ╞══════════╪════════╪═════════╪════════╪═══════════╪══════════╡ // │ 1 ┆ - ┆ 1 ┆ 4 ┆ 4 ┆ 1 │ // ├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤ // │ 2 ┆ 1 ┆ - ┆ 1 ┆ 1 ┆ 1 │ // └──────────┴────────┴─────────┴────────┴───────────┴──────────┘ // ┌──────────┬────────┬────────┬───────────┬──────────┐ - // │ frame_nr ┆ rect2d ┆ msg_id ┆ insert_id ┆ instance │ + // │ frame_nr ┆ rect2d ┆ row_id ┆ insert_id ┆ instance │ // ╞══════════╪════════╪════════╪═══════════╪══════════╡ // │ 3 ┆ 2 ┆ 2 ┆ 2 ┆ 1 │ // ├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤ @@ -203,18 +199,16 @@ fn all_components() { // └──────────┴────────┴────────┴───────────┴──────────┘ let components_a = &[ - ColorRGBA::name(), // added by us, timeless - Rect2D::name(), // added by us - cluster_key, // always here - re_log_types::MsgId::name(), // injected automatically (..for now) + ColorRGBA::name(), // added by test, timeless + Rect2D::name(), // added by test + cluster_key, // always here ]; let components_b = &[ - ColorRGBA::name(), // added by us, timeless - Point2D::name(), // added by us but not contained in the second bucket - Rect2D::name(), // added by use - cluster_key, // always here - re_log_types::MsgId::name(), // injected automatically (..for now) + ColorRGBA::name(), // added by test, timeless + Point2D::name(), // added by test but not contained in the second bucket + Rect2D::name(), // added by test + cluster_key, // always here ]; let row = test_row!(ent_path @ [] => 2; [build_some_colors(2)]); @@ -870,26 +864,26 @@ fn gc_impl(store: &mut DataStore) { // TODO(#1619): bring back garbage collection - // let msg_id_chunks = store.gc( + // let row_id_chunks = store.gc( // GarbageCollectionTarget::DropAtLeastPercentage(1.0 / 3.0), // Timeline::new("frame_nr", TimeType::Sequence), // MsgId::name(), // ); - // let msg_ids = msg_id_chunks + // let row_ids = row_id_chunks // .iter() // .flat_map(|chunk| arrow_array_deserialize_iterator::>(&**chunk).unwrap()) // .map(Option::unwrap) // MsgId is always present // .collect::>(); - // for msg_id in &msg_ids { - // assert!(store.get_msg_metadata(msg_id).is_some()); + // for row_id in &row_ids { + // assert!(store.get_msg_metadata(row_id).is_some()); // } - // store.clear_msg_metadata(&msg_ids); + // store.clear_msg_metadata(&row_ids); - // for msg_id in &msg_ids { - // assert!(store.get_msg_metadata(msg_id).is_none()); + // for row_id in &row_ids { + // assert!(store.get_msg_metadata(row_id).is_none()); // } } } diff --git a/crates/re_data_store/examples/memory_usage.rs b/crates/re_data_store/examples/memory_usage.rs index 6e8518eae542..3e62a48367bb 100644 --- a/crates/re_data_store/examples/memory_usage.rs +++ b/crates/re_data_store/examples/memory_usage.rs @@ -48,7 +48,7 @@ fn live_bytes() -> usize { // ---------------------------------------------------------------------------- -use re_log_types::{entity_path, DataRow, MsgId, RecordingId}; +use re_log_types::{entity_path, DataRow, RecordingId, RowId}; fn main() { log_messages(); @@ -108,7 +108,7 @@ fn log_messages() { let used_bytes_start = live_bytes(); let table = Box::new( DataRow::from_cells1( - MsgId::random(), + RowId::random(), entity_path!("points"), [build_frame_nr(0.into())], 1, @@ -134,7 +134,7 @@ fn log_messages() { let used_bytes_start = live_bytes(); let table = Box::new( DataRow::from_cells1( - MsgId::random(), + RowId::random(), entity_path!("points"), [build_frame_nr(0.into())], NUM_POINTS as _, diff --git a/crates/re_data_store/src/entity_properties.rs b/crates/re_data_store/src/entity_properties.rs index 4c8ba0f4d6a6..6b2b746b58fc 100644 --- a/crates/re_data_store/src/entity_properties.rs +++ b/crates/re_data_store/src/entity_properties.rs @@ -208,7 +208,7 @@ where // single components this is easy enough. let data_store = &entity_db.data_store; - let cells = data_store.latest_at(query, entity_path, C::name(), &[C::name()])?; + let (_, cells) = data_store.latest_at(query, entity_path, C::name(), &[C::name()])?; let cell = cells.get(0)?.as_ref()?; let mut iter = cell.try_to_native::().ok()?; diff --git a/crates/re_data_store/src/entity_tree.rs b/crates/re_data_store/src/entity_tree.rs index 451bd8f5325f..d3a702ee9653 100644 --- a/crates/re_data_store/src/entity_tree.rs +++ b/crates/re_data_store/src/entity_tree.rs @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet}; use itertools::Itertools; use re_log_types::{ - ComponentName, ComponentPath, EntityPath, EntityPathPart, MsgId, PathOp, TimeInt, TimePoint, + ComponentName, ComponentPath, EntityPath, EntityPathPart, PathOp, RowId, TimeInt, TimePoint, Timeline, }; @@ -103,10 +103,10 @@ pub struct EntityTree { num_timeless_messages: usize, /// Book-keeping around whether we should clear fields when data is added - pub nonrecursive_clears: BTreeMap, + pub nonrecursive_clears: BTreeMap, /// Book-keeping around whether we should clear recursively when data is added - pub recursive_clears: BTreeMap, + pub recursive_clears: BTreeMap, /// Data logged at this entity path. pub components: BTreeMap, @@ -117,7 +117,7 @@ impl EntityTree { Self::new(EntityPath::root(), Default::default()) } - pub fn new(path: EntityPath, recursive_clears: BTreeMap) -> Self { + pub fn new(path: EntityPath, recursive_clears: BTreeMap) -> Self { Self { path, children: Default::default(), @@ -147,7 +147,7 @@ impl EntityTree { &mut self, time_point: &TimePoint, component_path: &ComponentPath, - ) -> Vec<(MsgId, TimePoint)> { + ) -> Vec<(RowId, TimePoint)> { crate::profile_function!(); let leaf = @@ -178,7 +178,7 @@ impl EntityTree { /// insertion. pub fn add_path_op( &mut self, - msg_id: MsgId, + row_id: RowId, time_point: &TimePoint, path_op: &PathOp, ) -> Vec { @@ -195,7 +195,7 @@ impl EntityTree { // Track that any future fields need a Null at the right // time-point when added. leaf.nonrecursive_clears - .entry(msg_id) + .entry(row_id) .or_insert_with(|| time_point.clone()); // For every existing field return a clear event @@ -215,13 +215,13 @@ impl EntityTree { // Track that any future children need a Null at the right // time-point when added. next.recursive_clears - .entry(msg_id) + .entry(row_id) .or_insert_with(|| time_point.clone()); // Track that any future fields need a Null at the right // time-point when added. next.nonrecursive_clears - .entry(msg_id) + .entry(row_id) .or_insert_with(|| time_point.clone()); // For every existing field append a clear event into the @@ -286,7 +286,7 @@ impl EntityTree { pub fn purge( &mut self, cutoff_times: &BTreeMap, - drop_msg_ids: &ahash::HashSet, + drop_row_ids: &ahash::HashSet, ) { let Self { path: _, @@ -306,11 +306,11 @@ impl EntityTree { } { crate::profile_scope!("nonrecursive_clears"); - nonrecursive_clears.retain(|msg_id, _| !drop_msg_ids.contains(msg_id)); + nonrecursive_clears.retain(|row_id, _| !drop_row_ids.contains(row_id)); } { crate::profile_scope!("recursive_clears"); - recursive_clears.retain(|msg_id, _| !drop_msg_ids.contains(msg_id)); + recursive_clears.retain(|row_id, _| !drop_row_ids.contains(row_id)); } { @@ -321,7 +321,7 @@ impl EntityTree { } for child in children.values_mut() { - child.purge(cutoff_times, drop_msg_ids); + child.purge(cutoff_times, drop_row_ids); } } diff --git a/crates/re_data_store/src/log_db.rs b/crates/re_data_store/src/log_db.rs index 8bafa9dbb29c..7795c5d2214a 100644 --- a/crates/re_data_store/src/log_db.rs +++ b/crates/re_data_store/src/log_db.rs @@ -3,8 +3,8 @@ use nohash_hasher::IntMap; use re_arrow_store::{DataStoreConfig, TimeInt}; use re_log_types::{ component_types::InstanceKey, ArrowMsg, BeginRecordingMsg, Component as _, ComponentPath, - DataCell, DataRow, DataTable, EntityPath, EntityPathHash, EntityPathOpMsg, LogMsg, MsgId, - PathOp, RecordingId, RecordingInfo, TimePoint, Timeline, + DataCell, DataRow, DataTable, EntityPath, EntityPathHash, EntityPathOpMsg, LogMsg, PathOp, + RecordingId, RecordingInfo, RowId, TimePoint, Timeline, }; use crate::{Error, TimesPerTimeline}; @@ -77,19 +77,16 @@ impl EntityDb { for cell in row.cells().iter() { let component_path = ComponentPath::new(row.entity_path().clone(), cell.component_name()); - if cell.component_name() == MsgId::name() { - continue; - } let pending_clears = self.tree.add_data_msg(row.timepoint(), &component_path); - for (msg_id, time_point) in pending_clears { + for (row_id, time_point) in pending_clears { // Create and insert an empty component into the arrow store // TODO(jleibs): Faster empty-array creation let cell = DataCell::from_arrow_empty(cell.component_name(), cell.datatype().clone()); let row = DataRow::from_cells1( - msg_id, + row_id, row.entity_path.clone(), time_point.clone(), cell.num_instances(), @@ -105,8 +102,8 @@ impl EntityDb { self.data_store.insert_row(row).map_err(Into::into) } - fn add_path_op(&mut self, msg_id: MsgId, time_point: &TimePoint, path_op: &PathOp) { - let cleared_paths = self.tree.add_path_op(msg_id, time_point, path_op); + fn add_path_op(&mut self, row_id: RowId, time_point: &TimePoint, path_op: &PathOp) { + let cleared_paths = self.tree.add_path_op(row_id, time_point, path_op); for component_path in cleared_paths { if let Some(data_type) = self @@ -118,7 +115,7 @@ impl EntityDb { let cell = DataCell::from_arrow_empty(component_path.component_name, data_type.clone()); let row = DataRow::from_cells1( - msg_id, + row_id, component_path.entity_path.clone(), time_point.clone(), cell.num_instances(), @@ -134,7 +131,7 @@ impl EntityDb { pub fn purge( &mut self, cutoff_times: &std::collections::BTreeMap, - drop_msg_ids: &ahash::HashSet, + drop_row_ids: &ahash::HashSet, ) { crate::profile_function!(); @@ -152,7 +149,7 @@ impl EntityDb { { crate::profile_scope!("tree"); - tree.purge(cutoff_times, drop_msg_ids); + tree.purge(cutoff_times, drop_row_ids); } } } @@ -163,13 +160,13 @@ impl EntityDb { #[derive(Default)] pub struct LogDb { /// Messages in the order they arrived - chronological_message_ids: Vec, - log_messages: ahash::HashMap, + chronological_row_ids: Vec, + log_messages: ahash::HashMap, /// Data that was logged with [`TimePoint::timeless`]. /// We need to re-insert those in any new timelines /// that are created after they were logged. - timeless_message_ids: Vec, + timeless_row_ids: Vec, /// Set by whomever created this [`LogDb`]. pub data_source: Option, @@ -217,11 +214,11 @@ impl LogDb { LogMsg::BeginRecordingMsg(msg) => self.add_begin_recording_msg(msg), LogMsg::EntityPathOpMsg(_, msg) => { let EntityPathOpMsg { - msg_id, + row_id, time_point, path_op, } = msg; - self.entity_db.add_path_op(*msg_id, time_point, path_op); + self.entity_db.add_path_op(*row_id, time_point, path_op); } LogMsg::ArrowMsg(_, inner) => self.entity_db.try_add_arrow_msg(inner)?, LogMsg::Goodbye(_) => {} @@ -230,7 +227,7 @@ impl LogDb { // TODO(#1619): the following only makes sense because, while we support sending and // receiving batches, we don't actually do so yet. // We need to stop storing raw `LogMsg`s before we can benefit from our batching. - self.chronological_message_ids.push(msg.id()); + self.chronological_row_ids.push(msg.id()); self.log_messages.insert(msg.id(), msg); Ok(()) @@ -246,13 +243,13 @@ impl LogDb { /// In the order they arrived pub fn chronological_log_messages(&self) -> impl Iterator { - self.chronological_message_ids + self.chronological_row_ids .iter() .filter_map(|id| self.get_log_msg(id)) } - pub fn get_log_msg(&self, msg_id: &MsgId) -> Option<&LogMsg> { - self.log_messages.get(msg_id) + pub fn get_log_msg(&self, row_id: &RowId) -> Option<&LogMsg> { + self.log_messages.get(row_id) } /// Free up some RAM by forgetting the older parts of all timelines. @@ -261,33 +258,33 @@ impl LogDb { assert!((0.0..=1.0).contains(&fraction_to_purge)); // TODO(#1619): bring back garbage collection - let drop_msg_ids: ahash::HashSet<_> = Default::default(); + let drop_row_ids: ahash::HashSet<_> = Default::default(); let cutoff_times = self.entity_db.data_store.oldest_time_per_timeline(); let Self { - chronological_message_ids, + chronological_row_ids, log_messages, - timeless_message_ids, + timeless_row_ids, data_source: _, recording_info: _, entity_db, } = self; { - crate::profile_scope!("chronological_message_ids"); - chronological_message_ids.retain(|msg_id| !drop_msg_ids.contains(msg_id)); + crate::profile_scope!("chronological_row_ids"); + chronological_row_ids.retain(|row_id| !drop_row_ids.contains(row_id)); } { crate::profile_scope!("log_messages"); - log_messages.retain(|msg_id, _| !drop_msg_ids.contains(msg_id)); + log_messages.retain(|row_id, _| !drop_row_ids.contains(row_id)); } { - crate::profile_scope!("timeless_message_ids"); - timeless_message_ids.retain(|msg_id| !drop_msg_ids.contains(msg_id)); + crate::profile_scope!("timeless_row_ids"); + timeless_row_ids.retain(|row_id| !drop_row_ids.contains(row_id)); } - entity_db.purge(&cutoff_times, &drop_msg_ids); + entity_db.purge(&cutoff_times, &drop_row_ids); } } diff --git a/crates/re_log_encoding/benches/msg_encode_benchmark.rs b/crates/re_log_encoding/benches/msg_encode_benchmark.rs index 373add32096e..ddc7fc9740d9 100644 --- a/crates/re_log_encoding/benches/msg_encode_benchmark.rs +++ b/crates/re_log_encoding/benches/msg_encode_benchmark.rs @@ -6,7 +6,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; use re_log_types::{ datagen::{build_frame_nr, build_some_colors, build_some_point2d}, - entity_path, DataRow, DataTable, Index, LogMsg, MsgId, RecordingId, + entity_path, DataRow, DataTable, Index, LogMsg, RecordingId, RowId, TableId, }; use criterion::{criterion_group, criterion_main, Criterion}; @@ -67,9 +67,9 @@ fn mono_points_arrow(c: &mut Criterion) { (0..NUM_POINTS) .map(|i| { DataTable::from_rows( - MsgId::ZERO, + TableId::ZERO, [DataRow::from_cells2( - MsgId::ZERO, + RowId::ZERO, entity_path!("points", Index::Sequence(i as _)), [build_frame_nr(0.into())], 1, @@ -123,10 +123,10 @@ fn mono_points_arrow(c: &mut Criterion) { fn mono_points_arrow_batched(c: &mut Criterion) { fn generate_table() -> DataTable { DataTable::from_rows( - MsgId::ZERO, + TableId::ZERO, (0..NUM_POINTS).map(|i| { DataRow::from_cells2( - MsgId::ZERO, + RowId::ZERO, entity_path!("points", Index::Sequence(i as _)), [build_frame_nr(0.into())], 1, @@ -179,9 +179,9 @@ fn mono_points_arrow_batched(c: &mut Criterion) { fn batch_points_arrow(c: &mut Criterion) { fn generate_tables() -> Vec { vec![DataTable::from_rows( - MsgId::ZERO, + TableId::ZERO, [DataRow::from_cells2( - MsgId::ZERO, + RowId::ZERO, entity_path!("points"), [build_frame_nr(0.into())], NUM_POINTS as _, diff --git a/crates/re_log_encoding/src/decoder.rs b/crates/re_log_encoding/src/decoder.rs index 411c580d4439..a4ba2592b757 100644 --- a/crates/re_log_encoding/src/decoder.rs +++ b/crates/re_log_encoding/src/decoder.rs @@ -172,12 +172,12 @@ impl Iterator for Decoder { #[test] fn test_encode_decode() { use re_log_types::{ - ApplicationId, BeginRecordingMsg, LogMsg, MsgId, RecordingId, RecordingInfo, - RecordingSource, Time, + ApplicationId, BeginRecordingMsg, LogMsg, RecordingId, RecordingInfo, RecordingSource, + RowId, Time, }; let messages = vec![LogMsg::BeginRecordingMsg(BeginRecordingMsg { - msg_id: MsgId::random(), + row_id: RowId::random(), info: RecordingInfo { application_id: ApplicationId("test".to_owned()), recording_id: RecordingId::random(), diff --git a/crates/re_log_types/src/arrow_msg.rs b/crates/re_log_types/src/arrow_msg.rs index bda5c66f8434..54e5c01b68e5 100644 --- a/crates/re_log_types/src/arrow_msg.rs +++ b/crates/re_log_types/src/arrow_msg.rs @@ -3,7 +3,7 @@ //! We have custom implementations of [`serde::Serialize`] and [`serde::Deserialize`] that wraps //! the inner Arrow serialization of [`Schema`] and [`Chunk`]. -use crate::{MsgId, TimePoint}; +use crate::{TableId, TimePoint}; use arrow2::{array::Array, chunk::Chunk, datatypes::Schema}; /// Message containing an Arrow payload @@ -14,7 +14,7 @@ pub struct ArrowMsg { /// /// NOTE(#1619): While we're in the process of transitioning towards end-to-end batching, the /// `table_id` is always the same as the `row_id` as the first and only row. - pub table_id: MsgId, + pub table_id: TableId, /// The maximum values for all timelines across the entire batch of data. /// @@ -79,7 +79,7 @@ impl<'de> serde::Deserialize<'de> for ArrowMsg { where A: serde::de::SeqAccess<'de>, { - let table_id: Option = seq.next_element()?; + let table_id: Option = seq.next_element()?; let timepoint_min: Option = seq.next_element()?; let buf: Option = seq.next_element()?; @@ -133,13 +133,13 @@ mod tests { use crate::{ datagen::{build_frame_nr, build_some_point2d, build_some_rects}, - DataRow, DataTable, MsgId, + DataRow, DataTable, RowId, }; #[test] fn arrow_msg_roundtrip() { let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), "world/rects", [build_frame_nr(0.into())], 1, diff --git a/crates/re_log_types/src/component_types/mod.rs b/crates/re_log_types/src/component_types/mod.rs index 9778c7d3b931..1ea83dd557ab 100644 --- a/crates/re_log_types/src/component_types/mod.rs +++ b/crates/re_log_types/src/component_types/mod.rs @@ -29,7 +29,6 @@ mod label; mod linestrip; mod mat; mod mesh3d; -mod msg_id; mod point; mod quaternion; mod radius; @@ -53,7 +52,6 @@ pub use label::Label; pub use linestrip::{LineStrip2D, LineStrip3D}; pub use mat::Mat3x3; pub use mesh3d::{EncodedMesh3D, Mesh3D, MeshFormat, MeshId, RawMesh3D}; -pub use msg_id::{MsgId, RowId, TableId}; pub use point::{Point2D, Point3D}; pub use quaternion::Quaternion; pub use radius::Radius; @@ -71,7 +69,7 @@ pub use vec::{Vec2D, Vec3D, Vec4D}; lazy_static! { //TODO(john): use a run-time type registry - static ref FIELDS: [Field; 26] = [ + static ref FIELDS: [Field; 25] = [ ::field(), ::field(), ::field(), @@ -83,7 +81,6 @@ lazy_static! { ::field(), ::field(), ::field(), - ::field(), ::field(), ::field(), ::field(), diff --git a/crates/re_log_types/src/component_types/msg_id.rs b/crates/re_log_types/src/component_types/msg_id.rs deleted file mode 100644 index baf066103e5f..000000000000 --- a/crates/re_log_types/src/component_types/msg_id.rs +++ /dev/null @@ -1,95 +0,0 @@ -use arrow2_convert::{ArrowDeserialize, ArrowField, ArrowSerialize}; - -use crate::{Component, ComponentName}; - -/// A unique id per [`crate::LogMsg`]. -/// -/// ## Examples -/// -/// ``` -/// # use re_log_types::component_types::MsgId; -/// # use arrow2_convert::field::ArrowField; -/// # use arrow2::datatypes::{DataType, Field}; -/// assert_eq!( -/// MsgId::data_type(), -/// DataType::Extension("rerun.tuid".into(), Box::new(DataType::Struct(vec![ -/// Field::new("time_ns", DataType::UInt64, false), -/// Field::new("inc", DataType::UInt64, false), -/// ])), None), -/// ); -/// ``` -#[derive( - Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, ArrowField, ArrowSerialize, ArrowDeserialize, -)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -#[arrow_field(transparent)] -pub struct MsgId(re_tuid::Tuid); - -// TODO(#1758): Turn these two into actual independent types. -pub type TableId = MsgId; - -pub type RowId = MsgId; - -impl std::fmt::Debug for MsgId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:032X}", self.0.as_u128()) - } -} - -impl std::fmt::Display for MsgId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:032X}", self.0.as_u128()) - } -} - -impl MsgId { - /// All zeroes. - pub const ZERO: Self = Self(re_tuid::Tuid::ZERO); - - /// All ones. - pub const MAX: Self = Self(re_tuid::Tuid::MAX); - - #[inline] - #[cfg(not(target_arch = "wasm32"))] - pub fn random() -> Self { - Self(re_tuid::Tuid::random()) - } - - #[inline] - pub fn as_u128(&self) -> u128 { - self.0.as_u128() - } - - #[inline] - pub fn nanoseconds_since_epoch(&self) -> u64 { - self.0.nanoseconds_since_epoch() - } - - /// A shortened string representation of the message id. - #[inline] - pub fn short_string(&self) -> String { - // We still want this to look like a part of the full message id (i.e. what is printed on std::fmt::Display). - // Per Thread randomness plus increment is in the last part, so show only that. - // (the first half is time in nanoseconds which for the _most part_ doesn't change that often) - let str = self.to_string(); - str[(str.len() - 8)..].to_string() - } -} - -impl Component for MsgId { - #[inline] - fn name() -> ComponentName { - "rerun.msg_id".into() - } -} - -#[test] -fn test_msgid_roundtrip() { - use arrow2::array::Array; - use arrow2_convert::{deserialize::TryIntoCollection, serialize::TryIntoArrow}; - - let msg_ids_in = vec![MsgId::random(), MsgId::random()]; - let array: Box = msg_ids_in.try_into_arrow().unwrap(); - let msg_ids_out: Vec = TryIntoCollection::try_into_collection(array).unwrap(); - assert_eq!(msg_ids_in, msg_ids_out); -} diff --git a/crates/re_log_types/src/data_row.rs b/crates/re_log_types/src/data_row.rs index a96e1c80bc48..62dac0388ec2 100644 --- a/crates/re_log_types/src/data_row.rs +++ b/crates/re_log_types/src/data_row.rs @@ -2,7 +2,7 @@ use ahash::HashSetExt; use nohash_hasher::IntSet; use smallvec::SmallVec; -use crate::{ComponentName, DataCell, DataCellError, DataTable, EntityPath, RowId, TimePoint}; +use crate::{ComponentName, DataCell, DataCellError, DataTable, EntityPath, TableId, TimePoint}; // --- @@ -87,6 +87,62 @@ impl std::ops::IndexMut for DataCellRow { // --- +/// A unique ID for a [`DataRow`]. +#[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + arrow2_convert::ArrowField, + arrow2_convert::ArrowSerialize, + arrow2_convert::ArrowDeserialize, +)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[arrow_field(transparent)] +pub struct RowId(pub(crate) re_tuid::Tuid); + +impl std::fmt::Display for RowId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl RowId { + pub const ZERO: Self = Self(re_tuid::Tuid::ZERO); + + #[inline] + #[cfg(not(target_arch = "wasm32"))] + pub fn random() -> Self { + Self(re_tuid::Tuid::random()) + } + + /// Temporary utility while we transition to batching. See #1619. + #[doc(hidden)] + pub fn into_table_id(self) -> TableId { + TableId(self.0) + } +} + +impl std::ops::Deref for RowId { + type Target = re_tuid::Tuid; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for RowId { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + /// A row's worth of data, i.e. an event: a list of [`DataCell`]s associated with an auto-generated /// `RowId`, a user-specified [`TimePoint`] and [`EntityPath`], and an expected number of /// instances. @@ -134,8 +190,8 @@ impl std::ops::IndexMut for DataCellRow { /// /// ```rust /// # use re_log_types::{ -/// # component_types::{ColorRGBA, Label, RowId, Point2D}, -/// # DataRow, Timeline, +/// # component_types::{ColorRGBA, Label, Point2D}, +/// # DataRow, RowId, Timeline, /// # }; /// # /// # let row_id = RowId::ZERO; @@ -162,7 +218,6 @@ impl std::ops::IndexMut for DataCellRow { pub struct DataRow { /// Auto-generated `TUID`, uniquely identifying this event and keeping track of the client's /// wall-clock. - // TODO(#1619): introduce RowId & TableId pub row_id: RowId, /// User-specified [`TimePoint`] for this event. @@ -226,26 +281,13 @@ impl DataRow { } } - let mut this = Self { + Ok(Self { row_id, entity_path, timepoint, num_instances, cells, - }; - - // TODO(cmc): Since we don't yet support mixing splatted data within instanced rows, - // we need to craft an array of `MsgId`s that matches the length of the other components. - // TODO(#1619): This goes away once the store supports the new control columns - use crate::Component as _; - if !components.contains(&RowId::name()) { - let num_instances = this.num_instances(); - this.cells.0.push(DataCell::from_native( - vec![row_id; num_instances as _].iter(), - )); - } - - Ok(this) + }) } /// Builds a new `DataRow` from an iterable of [`DataCell`]s. @@ -271,7 +313,7 @@ impl DataRow { #[doc(hidden)] #[inline] pub fn into_table(self) -> DataTable { - DataTable::from_rows(self.row_id, [self]) + DataTable::from_rows(self.row_id.into_table_id(), [self]) } } diff --git a/crates/re_log_types/src/data_table.rs b/crates/re_log_types/src/data_table.rs index a15e340e31e8..22267de70c3d 100644 --- a/crates/re_log_types/src/data_table.rs +++ b/crates/re_log_types/src/data_table.rs @@ -7,7 +7,7 @@ use smallvec::SmallVec; use crate::{ ArrowMsg, ComponentName, DataCell, DataCellError, DataRow, DataRowError, EntityPath, RowId, - TableId, TimePoint, Timeline, + TimePoint, Timeline, }; // --- @@ -122,6 +122,62 @@ impl DataCellColumn { // --- +/// A unique ID for a [`DataTable`]. +#[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + arrow2_convert::ArrowField, + arrow2_convert::ArrowSerialize, + arrow2_convert::ArrowDeserialize, +)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[arrow_field(transparent)] +pub struct TableId(pub(crate) re_tuid::Tuid); + +impl std::fmt::Display for TableId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl TableId { + pub const ZERO: Self = Self(re_tuid::Tuid::ZERO); + + #[inline] + #[cfg(not(target_arch = "wasm32"))] + pub fn random() -> Self { + Self(re_tuid::Tuid::random()) + } + + /// Temporary utility while we transition to batching. See #1619. + #[doc(hidden)] + pub fn into_row_id(self) -> RowId { + RowId(self.0) + } +} + +impl std::ops::Deref for TableId { + type Target = re_tuid::Tuid; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for TableId { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + /// A sparse table's worth of data, i.e. a batch of events: a collection of [`DataRow`]s. /// This is the top-level layer in our data model. /// @@ -196,8 +252,8 @@ impl DataCellColumn { /// /// ```rust /// # use re_log_types::{ -/// # component_types::{ColorRGBA, Label, Point2D, RowId, TableId}, -/// # DataRow, DataTable, Timeline, TimePoint, +/// # component_types::{ColorRGBA, Label, Point2D}, +/// # DataRow, DataTable, RowId, TableId, Timeline, TimePoint, /// # }; /// # /// # let table_id = TableId::random(); @@ -257,7 +313,6 @@ impl DataCellColumn { /// # /// # assert_eq!(table_in, table_out); /// ``` -// TODO(#1619): introduce RowId & TableId #[derive(Debug, Clone, PartialEq)] pub struct DataTable { /// Auto-generated `TUID`, uniquely identifying this batch of data and keeping track of the diff --git a/crates/re_log_types/src/lib.rs b/crates/re_log_types/src/lib.rs index 38f6de4dc615..0a20ae6ef4da 100644 --- a/crates/re_log_types/src/lib.rs +++ b/crates/re_log_types/src/lib.rs @@ -25,6 +25,7 @@ mod time_real; pub mod external { pub use arrow2; pub use arrow2_convert; + pub use re_tuid; #[cfg(feature = "glam")] pub use glam; @@ -41,15 +42,14 @@ pub use self::component_types::AnnotationContext; pub use self::component_types::Arrow3D; pub use self::component_types::ViewCoordinates; pub use self::component_types::{EncodedMesh3D, Mesh3D, MeshFormat, MeshId, RawMesh3D}; -pub use self::component_types::{MsgId, RowId, TableId}; pub use self::data::*; pub use self::data_cell::{DataCell, DataCellError, DataCellInner, DataCellResult}; -pub use self::data_row::{DataRow, DataRowError, DataRowResult}; +pub use self::data_row::{DataRow, DataRowError, DataRowResult, RowId}; pub use self::data_table::{ DataCellColumn, DataCellOptVec, DataTable, DataTableError, DataTableResult, EntityPathVec, - ErasedTimeVec, NumInstancesVec, RowIdVec, TimePointVec, COLUMN_ENTITY_PATH, COLUMN_INSERT_ID, - COLUMN_NUM_INSTANCES, COLUMN_ROW_ID, COLUMN_TIMEPOINT, METADATA_KIND, METADATA_KIND_CONTROL, - METADATA_KIND_DATA, + ErasedTimeVec, NumInstancesVec, RowIdVec, TableId, TimePointVec, COLUMN_ENTITY_PATH, + COLUMN_INSERT_ID, COLUMN_NUM_INSTANCES, COLUMN_ROW_ID, COLUMN_TIMEPOINT, METADATA_KIND, + METADATA_KIND_CONTROL, METADATA_KIND_DATA, }; pub use self::index::*; pub use self::path::*; @@ -180,19 +180,19 @@ pub enum LogMsg { ArrowMsg(RecordingId, ArrowMsg), /// Sent when the client shuts down the connection. - Goodbye(MsgId), + Goodbye(RowId), } impl LogMsg { - pub fn id(&self) -> MsgId { + pub fn id(&self) -> RowId { match self { - Self::BeginRecordingMsg(msg) => msg.msg_id, - Self::EntityPathOpMsg(_, msg) => msg.msg_id, - Self::Goodbye(msg_id) => *msg_id, + Self::BeginRecordingMsg(msg) => msg.row_id, + Self::EntityPathOpMsg(_, msg) => msg.row_id, + Self::Goodbye(row_id) => *row_id, // TODO(#1619): the following only makes sense because, while we support sending and // receiving batches, we don't actually do so yet. // We need to stop storing raw `LogMsg`s before we can benefit from our batching. - Self::ArrowMsg(_, msg) => msg.table_id, + Self::ArrowMsg(_, msg) => msg.table_id.into_row_id(), } } @@ -215,8 +215,7 @@ impl_into_enum!(BeginRecordingMsg, LogMsg, BeginRecordingMsg); #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct BeginRecordingMsg { - pub msg_id: MsgId, - + pub row_id: RowId, pub info: RecordingInfo, } @@ -308,7 +307,7 @@ impl std::fmt::Display for RecordingSource { #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct EntityPathOpMsg { /// A unique id per [`EntityPathOpMsg`]. - pub msg_id: MsgId, + pub row_id: RowId, /// Time information (when it was logged, when it was received, …). /// diff --git a/crates/re_query/benches/query_benchmark.rs b/crates/re_query/benches/query_benchmark.rs index d65c2947cbeb..a79c416e44c9 100644 --- a/crates/re_query/benches/query_benchmark.rs +++ b/crates/re_query/benches/query_benchmark.rs @@ -8,7 +8,7 @@ use re_arrow_store::{DataStore, LatestAtQuery}; use re_log_types::{ component_types::{ColorRGBA, InstanceKey, Point2D, Vec3D}, datagen::{build_frame_nr, build_some_colors, build_some_point2d, build_some_vec3d}, - entity_path, Component, DataRow, EntityPath, Index, MsgId, TimeType, Timeline, + entity_path, Component, DataRow, EntityPath, Index, RowId, TimeType, Timeline, }; use re_query::query_entity_with_primary; @@ -124,7 +124,7 @@ fn build_points_rows(paths: &[EntityPath], pts: usize) -> Vec { .flat_map(move |frame_idx| { paths.iter().map(move |path| { DataRow::from_cells2( - MsgId::ZERO, + RowId::ZERO, path.clone(), [build_frame_nr((frame_idx as i64).into())], pts as _, @@ -140,7 +140,7 @@ fn build_vecs_rows(paths: &[EntityPath], pts: usize) -> Vec { .flat_map(move |frame_idx| { paths.iter().map(move |path| { DataRow::from_cells1( - MsgId::ZERO, + RowId::ZERO, path.clone(), [build_frame_nr((frame_idx as i64).into())], pts as _, diff --git a/crates/re_query/examples/range.rs b/crates/re_query/examples/range.rs index 47251d85c75c..10328e328b04 100644 --- a/crates/re_query/examples/range.rs +++ b/crates/re_query/examples/range.rs @@ -8,7 +8,7 @@ use re_arrow_store::{DataStore, RangeQuery, TimeRange}; use re_log_types::{ component_types::{InstanceKey, Point2D, Rect2D}, datagen::{build_frame_nr, build_some_point2d, build_some_rects}, - Component as _, DataRow, EntityPath, MsgId, TimeType, + Component as _, DataRow, EntityPath, RowId, TimeType, }; use re_query::range_entity_with_primary; @@ -23,27 +23,27 @@ fn main() { let frame4 = [build_frame_nr(4.into())]; let rects = build_some_rects(2); - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), frame1, 2, &rects); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), frame1, 2, &rects); store.insert_row(&row).unwrap(); let points = build_some_point2d(2); - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), frame2, 2, &points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), frame2, 2, &points); store.insert_row(&row).unwrap(); let points = build_some_point2d(4); - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), frame3, 4, &points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), frame3, 4, &points); store.insert_row(&row).unwrap(); let rects = build_some_rects(3); - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), frame4, 3, &rects); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), frame4, 3, &rects); store.insert_row(&row).unwrap(); let points = build_some_point2d(3); - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), frame4, 3, &points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), frame4, 3, &points); store.insert_row(&row).unwrap(); let rects = build_some_rects(3); - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), frame4, 3, &rects); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), frame4, 3, &rects); store.insert_row(&row).unwrap(); let query = RangeQuery::new(frame2[0].0, TimeRange::new(frame2[0].1, frame4[0].1)); diff --git a/crates/re_query/src/entity_view.rs b/crates/re_query/src/entity_view.rs index e0054b917d30..ea3a8c18a1fb 100644 --- a/crates/re_query/src/entity_view.rs +++ b/crates/re_query/src/entity_view.rs @@ -7,7 +7,7 @@ use re_log_types::{ external::arrow2_convert::{ deserialize::arrow_array_deserialize_iterator, field::ArrowField, serialize::ArrowSerialize, }, - Component, ComponentName, DeserializableComponent, SerializableComponent, + Component, ComponentName, DeserializableComponent, RowId, SerializableComponent, }; use crate::QueryError; @@ -254,6 +254,7 @@ where /// the primary component using instance keys. #[derive(Clone, Debug)] pub struct EntityView { + pub(crate) row_id: RowId, pub(crate) primary: ComponentWithInstances, pub(crate) components: BTreeMap, pub(crate) phantom: PhantomData, @@ -281,6 +282,11 @@ where pub fn num_instances(&self) -> usize { self.primary.len() } + + #[inline] + pub fn row_id(&self) -> RowId { + self.row_id + } } impl EntityView @@ -353,6 +359,7 @@ where let primary = ComponentWithInstances::from_native(c0.0, c0.1)?; Ok(Self { + row_id: RowId::ZERO, primary, components: Default::default(), phantom: PhantomData, @@ -374,6 +381,7 @@ where let components = [(component_c1.name, component_c1)].into(); Ok(Self { + row_id: RowId::ZERO, primary, components, phantom: PhantomData, diff --git a/crates/re_query/src/query.rs b/crates/re_query/src/query.rs index adb29f55aa9e..5c4bd34194b0 100644 --- a/crates/re_query/src/query.rs +++ b/crates/re_query/src/query.rs @@ -1,7 +1,9 @@ use std::collections::BTreeMap; use re_arrow_store::{DataStore, LatestAtQuery}; -use re_log_types::{component_types::InstanceKey, Component, ComponentName, DataRow, EntityPath}; +use re_log_types::{ + component_types::InstanceKey, Component, ComponentName, DataRow, EntityPath, RowId, +}; use crate::{ComponentWithInstances, EntityView, QueryError}; @@ -14,7 +16,7 @@ use crate::{ComponentWithInstances, EntityView, QueryError}; /// let ent_path = "point"; /// let query = LatestAtQuery::new(Timeline::new_sequence("frame_nr"), 123.into()); /// -/// let component = re_query::get_component_with_instances( +/// let (_, component) = re_query::get_component_with_instances( /// &store, /// &query, /// &ent_path.into(), @@ -46,21 +48,24 @@ pub fn get_component_with_instances( query: &LatestAtQuery, ent_path: &EntityPath, component: ComponentName, -) -> crate::Result { +) -> crate::Result<(RowId, ComponentWithInstances)> { let components = [InstanceKey::name(), component]; - let mut cells = store + let (row_id, mut cells) = store .latest_at(query, ent_path, component, &components) .ok_or(QueryError::PrimaryNotFound)?; - Ok(ComponentWithInstances { - name: component, - instance_keys: cells[0].take().map(|cell| cell.to_arrow()), - values: cells[1] - .take() - .map(|cell| cell.to_arrow()) - .ok_or(QueryError::PrimaryNotFound)?, - }) + Ok(( + row_id, + ComponentWithInstances { + name: component, + instance_keys: cells[0].take().map(|cell| cell.to_arrow()), + values: cells[1] + .take() + .map(|cell| cell.to_arrow()) + .ok_or(QueryError::PrimaryNotFound)?, + }, + )) } /// Retrieve an `EntityView` from the `DataStore` @@ -116,7 +121,7 @@ pub fn query_entity_with_primary( ) -> crate::Result> { crate::profile_function!(); - let primary = get_component_with_instances(store, query, ent_path, Primary::name())?; + let (row_id, primary) = get_component_with_instances(store, query, ent_path, Primary::name())?; // TODO(jleibs): lots of room for optimization here. Once "instance" is // guaranteed to be sorted we should be able to leverage this during the @@ -125,11 +130,13 @@ pub fn query_entity_with_primary( let components: crate::Result> = components .iter() - // Filter out `Primary` and `InstanceKey` from the component list since are + // Filter out `Primary` and `InstanceKey` from the component list since they are // always queried above when creating the primary. .filter(|component| *component != &Primary::name() && *component != &InstanceKey::name()) .filter_map(|component| { - match get_component_with_instances(store, query, ent_path, *component) { + match get_component_with_instances(store, query, ent_path, *component) + .map(|(_, cwi)| cwi) + { Ok(component_result) => Some(Ok((*component, component_result))), Err(QueryError::PrimaryNotFound) => None, Err(err) => Some(Err(err)), @@ -138,6 +145,7 @@ pub fn query_entity_with_primary( .collect(); Ok(EntityView { + row_id, primary, components: components?, phantom: std::marker::PhantomData, @@ -149,7 +157,6 @@ pub fn __populate_example_store() -> DataStore { use re_log_types::{ component_types::{ColorRGBA, Point2D}, datagen::build_frame_nr, - MsgId, }; let mut store = DataStore::new(InstanceKey::name(), Default::default()); @@ -161,7 +168,7 @@ pub fn __populate_example_store() -> DataStore { let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; let row = DataRow::from_cells2( - MsgId::ZERO, + RowId::ZERO, ent_path, timepoint, instances.len() as _, @@ -173,7 +180,7 @@ pub fn __populate_example_store() -> DataStore { let colors = vec![ColorRGBA(0xff000000)]; let row = DataRow::from_cells2( - MsgId::ZERO, + RowId::ZERO, ent_path, timepoint, instances.len() as _, @@ -195,7 +202,7 @@ fn simple_get_component() { let ent_path = "point"; let query = LatestAtQuery::new(Timeline::new_sequence("frame_nr"), 123.into()); - let component = + let (_, component) = get_component_with_instances(&store, &query, &ent_path.into(), Point2D::name()).unwrap(); #[cfg(feature = "polars")] diff --git a/crates/re_query/src/range.rs b/crates/re_query/src/range.rs index 4b3bdae4ca06..0fbd7925030c 100644 --- a/crates/re_query/src/range.rs +++ b/crates/re_query/src/range.rs @@ -93,17 +93,22 @@ pub fn range_entity_with_primary<'a, Primary: Component + 'a, const N: usize>( .chain( store .range(query, ent_path, components) - .map(move |(time, _, mut cells)| { + .map(move |(time, row_id, mut cells)| { let instance_keys = cells[cluster_col].take().map(|cell| cell.to_arrow()); let is_primary = cells[primary_col].is_some(); let cwis = cells .into_iter() .enumerate() .map(|(i, cell)| { - cell.map(|cell| ComponentWithInstances { - name: components[i], - instance_keys: instance_keys.clone(), /* shallow */ - values: cell.to_arrow(), + cell.map(|cell| { + ( + row_id, + ComponentWithInstances { + name: components[i], + instance_keys: instance_keys.clone(), /* shallow */ + values: cell.to_arrow(), + }, + ) }) }) .collect::>(); @@ -121,13 +126,16 @@ pub fn range_entity_with_primary<'a, Primary: Component + 'a, const N: usize>( // We only yield if the primary component has been updated! is_primary.then(|| { + // NOTE: safe to unwrap, set just above + let (row_id, cwi) = state[primary_col].clone().unwrap(); // shallow + let ent_view = EntityView { - // safe to unwrap, set just above - primary: state[primary_col].clone().unwrap(), // shallow + row_id, + primary: cwi, components: components .iter() .zip(state.iter().cloned() /* shallow */) - .filter_map(|(component, cwi)| cwi.map(|cwi| (*component, cwi))) + .filter_map(|(component, cwi)| cwi.map(|(_, cwi)| (*component, cwi))) .collect(), phantom: std::marker::PhantomData, }; diff --git a/crates/re_query/tests/query_tests.rs b/crates/re_query/tests/query_tests.rs index a1f28a5724eb..becd59681d7f 100644 --- a/crates/re_query/tests/query_tests.rs +++ b/crates/re_query/tests/query_tests.rs @@ -5,7 +5,7 @@ use re_log_types::{ component_types::InstanceKey, component_types::{ColorRGBA, Point2D}, datagen::build_frame_nr, - Component, DataRow, MsgId, + Component, DataRow, RowId, }; use re_query::query_entity_with_primary; @@ -18,14 +18,14 @@ fn simple_query() { // Create some points with implicit instances let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path, timepoint, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path, timepoint, 2, points); store.insert_row(&row).unwrap(); // Assign one of them a color with an explicit instance let color_instances = vec![InstanceKey(1)]; let colors = vec![ColorRGBA(0xff000000)]; let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path, timepoint, 1, @@ -89,13 +89,13 @@ fn timeless_query() { // Create some points with implicit instances let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path, timepoint, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path, timepoint, 2, points); 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![ColorRGBA(0xff000000)]; - let row = DataRow::from_cells2(MsgId::random(), ent_path, [], 1, (color_instances, colors)); + let row = DataRow::from_cells2(RowId::random(), ent_path, [], 1, (color_instances, colors)); store.insert_row(&row).unwrap(); // Retrieve the view @@ -154,12 +154,12 @@ fn no_instance_join_query() { // Create some points with an implicit instance let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path, timepoint, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path, timepoint, 2, points); store.insert_row(&row).unwrap(); // Assign them colors with explicit instances let colors = vec![ColorRGBA(0xff000000), ColorRGBA(0x00ff0000)]; - let row = DataRow::from_cells1(MsgId::random(), ent_path, timepoint, 2, colors); + let row = DataRow::from_cells1(RowId::random(), ent_path, timepoint, 2, colors); store.insert_row(&row).unwrap(); // Retrieve the view @@ -218,7 +218,7 @@ fn missing_column_join_query() { // Create some points with an implicit instance let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path, timepoint, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path, timepoint, 2, points); store.insert_row(&row).unwrap(); // Retrieve the view @@ -276,14 +276,14 @@ fn splatted_query() { // Create some points with implicit instances let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path, timepoint, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path, timepoint, 2, points); store.insert_row(&row).unwrap(); // Assign all of them a color via splat let color_instances = vec![InstanceKey::SPLAT]; let colors = vec![ColorRGBA(0xff000000)]; let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path, timepoint, 1, diff --git a/crates/re_query/tests/range_tests.rs b/crates/re_query/tests/range_tests.rs index 26367a11787a..7b5aea29749b 100644 --- a/crates/re_query/tests/range_tests.rs +++ b/crates/re_query/tests/range_tests.rs @@ -5,7 +5,7 @@ use re_log_types::{ component_types::InstanceKey, component_types::{ColorRGBA, Point2D}, datagen::build_frame_nr, - Component, DataRow, EntityPath, MsgId, + Component, DataRow, EntityPath, RowId, }; use re_query::range_entity_with_primary; @@ -19,14 +19,14 @@ fn simple_range() { { // Create some points with implicit instances let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), timepoint1, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), timepoint1, 2, points); store.insert_row(&row).unwrap(); // Assign one of them a color with an explicit instance let color_instances = vec![InstanceKey(1)]; let colors = vec![ColorRGBA(0xff000000)]; let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path.clone(), timepoint1, 1, @@ -41,7 +41,7 @@ fn simple_range() { let color_instances = vec![InstanceKey(0)]; let colors = vec![ColorRGBA(0xff000000)]; let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path.clone(), timepoint2, 1, @@ -54,7 +54,7 @@ fn simple_range() { { // Create some points with implicit instances let points = vec![Point2D { x: 10.0, y: 20.0 }, Point2D { x: 30.0, y: 40.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), timepoint3, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), timepoint3, 2, points); store.insert_row(&row).unwrap(); } @@ -237,18 +237,18 @@ fn timeless_range() { { // Create some points with implicit instances let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), timepoint1, 2, &points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), timepoint1, 2, &points); store.insert_row(&row).unwrap(); // Insert timelessly too! - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), [], 2, &points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), [], 2, &points); store.insert_row(&row).unwrap(); // Assign one of them a color with an explicit instance let color_instances = vec![InstanceKey(1)]; let colors = vec![ColorRGBA(0xff000000)]; let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path.clone(), timepoint1, 1, @@ -258,7 +258,7 @@ fn timeless_range() { // Insert timelessly too! let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path.clone(), [], 1, @@ -273,7 +273,7 @@ fn timeless_range() { let color_instances = vec![InstanceKey(0)]; let colors = vec![ColorRGBA(0xff000000)]; let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path.clone(), timepoint2, 1, @@ -283,7 +283,7 @@ fn timeless_range() { // Insert timelessly too! let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path.clone(), timepoint2, 1, @@ -296,16 +296,16 @@ fn timeless_range() { { // Create some points with implicit instances let points = vec![Point2D { x: 10.0, y: 20.0 }, Point2D { x: 30.0, y: 40.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), timepoint3, 2, &points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), timepoint3, 2, &points); store.insert_row(&row).unwrap(); // Insert timelessly too! - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), [], 2, &points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), [], 2, &points); store.insert_row(&row).unwrap(); } // ┌───────────┬──────────┬────────┬─────────────────┬────────────────────┬──────────────────────┬────────────────────────────┐ - // │ insert_id ┆ frame_nr ┆ entity ┆ rerun.colorrgba ┆ rerun.instance_key ┆ rerun.msg_id ┆ rerun.point2d │ + // │ insert_id ┆ frame_nr ┆ entity ┆ rerun.colorrgba ┆ rerun.instance_key ┆ rerun.row_id ┆ rerun.point2d │ // ╞═══════════╪══════════╪════════╪═════════════════╪════════════════════╪══════════════════════╪════════════════════════════╡ // │ 2 ┆ null ┆ point ┆ null ┆ [0, 1] ┆ [{167328063302243... ┆ [{1.0,2.0}, {3.0,4.0}] │ // ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ @@ -670,14 +670,14 @@ fn simple_splatted_range() { { // Create some points with implicit instances let points = vec![Point2D { x: 1.0, y: 2.0 }, Point2D { x: 3.0, y: 4.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), timepoint1, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), timepoint1, 2, points); store.insert_row(&row).unwrap(); // Assign one of them a color with an explicit instance let color_instances = vec![InstanceKey(1)]; let colors = vec![ColorRGBA(0xff000000)]; let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path.clone(), timepoint1, 1, @@ -692,7 +692,7 @@ fn simple_splatted_range() { let color_instances = vec![InstanceKey::SPLAT]; let colors = vec![ColorRGBA(0x00ff0000)]; let row = DataRow::from_cells2( - MsgId::random(), + RowId::random(), ent_path.clone(), timepoint2, 1, @@ -705,7 +705,7 @@ fn simple_splatted_range() { { // Create some points with implicit instances let points = vec![Point2D { x: 10.0, y: 20.0 }, Point2D { x: 30.0, y: 40.0 }]; - let row = DataRow::from_cells1(MsgId::random(), ent_path.clone(), timepoint3, 2, points); + let row = DataRow::from_cells1(RowId::random(), ent_path.clone(), timepoint3, 2, points); store.insert_row(&row).unwrap(); } diff --git a/crates/re_sdk/src/lib.rs b/crates/re_sdk/src/lib.rs index eca93ef69f16..ce3f2baf5009 100644 --- a/crates/re_sdk/src/lib.rs +++ b/crates/re_sdk/src/lib.rs @@ -57,7 +57,7 @@ pub mod sink { /// Things directly related to logging. pub mod log { - pub use re_log_types::{DataCell, DataRow, DataTable, LogMsg, MsgId, PathOp}; + pub use re_log_types::{DataCell, DataRow, DataTable, LogMsg, PathOp, RowId, TableId}; } /// Time-related types. diff --git a/crates/re_sdk/src/msg_sender.rs b/crates/re_sdk/src/msg_sender.rs index 2bc377010444..0bd6832a3f2f 100644 --- a/crates/re_sdk/src/msg_sender.rs +++ b/crates/re_sdk/src/msg_sender.rs @@ -1,10 +1,10 @@ use std::borrow::Borrow; -use re_log_types::{component_types::InstanceKey, DataRow, DataTableError, RecordingId}; +use re_log_types::{component_types::InstanceKey, DataRow, DataTableError, RecordingId, RowId}; use crate::{ components::Transform, - log::{DataCell, LogMsg, MsgId}, + log::{DataCell, LogMsg}, sink::LogSink, time::{Time, TimeInt, TimePoint, Timeline}, Component, EntityPath, SerializableComponent, Session, @@ -320,7 +320,7 @@ impl MsgSender { // Standard rows[0] = (!standard_cells.is_empty()).then(|| { DataRow::from_cells( - MsgId::random(), + RowId::random(), timepoint.clone(), entity_path.clone(), num_instances.unwrap_or(0), @@ -331,7 +331,7 @@ impl MsgSender { // Transforms rows[1] = (!transform_cells.is_empty()).then(|| { DataRow::from_cells( - MsgId::random(), + RowId::random(), timepoint.clone(), entity_path.clone(), num_transform_instances, @@ -340,10 +340,10 @@ impl MsgSender { }); // Splats - // TODO(cmc): unsplit splats once new data cells are in + // TODO(#1629): unsplit splats once new data cells are in rows[2] = (!splatted.is_empty()).then(|| { splatted.push(DataCell::from_native(&[InstanceKey::SPLAT])); - DataRow::from_cells(MsgId::random(), timepoint, entity_path, 1, splatted) + DataRow::from_cells(RowId::random(), timepoint, entity_path, 1, splatted) }); rows diff --git a/crates/re_sdk/src/session.rs b/crates/re_sdk/src/session.rs index 94d336b30fcc..b9fbc1d419d3 100644 --- a/crates/re_sdk/src/session.rs +++ b/crates/re_sdk/src/session.rs @@ -222,7 +222,7 @@ impl Session { sink.send( re_log_types::BeginRecordingMsg { - msg_id: re_log_types::MsgId::random(), + row_id: re_log_types::RowId::random(), info: recording_info.clone(), } .into(), @@ -289,7 +289,7 @@ impl Session { self.send(LogMsg::EntityPathOpMsg( self.recording_id(), re_log_types::EntityPathOpMsg { - msg_id: re_log_types::MsgId::random(), + row_id: re_log_types::RowId::random(), time_point: time_point.clone(), path_op, }, diff --git a/crates/re_sdk_comms/src/buffered_client.rs b/crates/re_sdk_comms/src/buffered_client.rs index a50f951e3663..2828d7585e8b 100644 --- a/crates/re_sdk_comms/src/buffered_client.rs +++ b/crates/re_sdk_comms/src/buffered_client.rs @@ -2,7 +2,7 @@ use std::{net::SocketAddr, thread::JoinHandle}; use crossbeam::channel::{select, Receiver, Sender}; -use re_log_types::{LogMsg, MsgId}; +use re_log_types::{LogMsg, RowId}; #[derive(Debug, PartialEq, Eq)] struct FlushedMsg; @@ -146,7 +146,7 @@ impl Drop for Client { /// Wait until everything has been sent. fn drop(&mut self) { re_log::debug!("Shutting down the client connection…"); - self.send(LogMsg::Goodbye(MsgId::random())); + self.send(LogMsg::Goodbye(RowId::random())); self.flush(); self.encode_quit_tx.send(QuitMsg).ok(); self.send_quit_tx.send(InterruptMsg::Quit).ok(); diff --git a/crates/re_tuid/src/lib.rs b/crates/re_tuid/src/lib.rs index b9c52ace609c..a23a971fbc32 100644 --- a/crates/re_tuid/src/lib.rs +++ b/crates/re_tuid/src/lib.rs @@ -101,6 +101,18 @@ impl Tuid { pub fn nanoseconds_since_epoch(&self) -> u64 { self.time_ns } + + /// A shortened string representation of the `Tuid`. + #[inline] + pub fn short_string(&self) -> String { + // We still want this to look like a part of the full TUID (i.e. what is printed on + // `std::fmt::Display`). + // Per Thread randomness plus increment is in the last part, so show only that. + // (the first half is time in nanoseconds which for the _most part_ doesn't change that + // often) + let str = self.to_string(); + str[(str.len() - 8)..].to_string() + } } /// Returns a high-precision, monotonically increasing count that approximates nanoseconds since unix epoch. diff --git a/crates/re_viewer/src/misc/caches/tensor_image_cache.rs b/crates/re_viewer/src/misc/caches/tensor_image_cache.rs index 30fce52003e1..b96ba4ecd149 100644 --- a/crates/re_viewer/src/misc/caches/tensor_image_cache.rs +++ b/crates/re_viewer/src/misc/caches/tensor_image_cache.rs @@ -5,7 +5,7 @@ use egui_extras::RetainedImage; use image::DynamicImage; use re_log_types::{ component_types::{self, ClassId, Tensor, TensorData, TensorDataMeaning}, - MsgId, + RowId, }; use re_renderer::{ resource_managers::{GpuTexture2DHandle, Texture2DCreationDesc}, @@ -90,13 +90,13 @@ impl<'store, 'cache> ColoredTensorView<'store, 'cache> { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] struct ImageCacheKey { tensor_id: component_types::TensorId, - annotation_msg_id: MsgId, + annotation_row_id: RowId, } impl ImageCacheKey { fn hash64(&self) -> u64 { let msg_hash = self.tensor_id.0.as_u128() as u64; - let annotation_hash = (self.annotation_msg_id.as_u128() >> 1) as u64; + let annotation_hash = (self.annotation_row_id.as_u128() >> 1) as u64; msg_hash ^ annotation_hash } } @@ -127,7 +127,7 @@ impl ImageCache { ) -> ColoredTensorView<'store, 'cache> { let key = ImageCacheKey { tensor_id: tensor.id(), - annotation_msg_id: annotations.msg_id, + annotation_row_id: annotations.row_id, }; let ci = self.images.entry(key).or_insert_with(|| { let debug_name = format!("tensor {:?}", tensor.shape()); diff --git a/crates/re_viewer/src/misc/item.rs b/crates/re_viewer/src/misc/item.rs index 358e293a4d09..096dc815599c 100644 --- a/crates/re_viewer/src/misc/item.rs +++ b/crates/re_viewer/src/misc/item.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use re_data_store::{InstancePath, LogDb}; -use re_log_types::{ComponentPath, MsgId}; +use re_log_types::{ComponentPath, RowId}; use crate::ui::SpaceViewId; @@ -11,7 +11,7 @@ use crate::ui::SpaceViewId; /// A set of these is a an [`ItemCollection`]. #[derive(Clone, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)] pub enum Item { - MsgId(MsgId), + RowId(RowId), ComponentPath(ComponentPath), SpaceView(SpaceViewId), InstancePath(Option, InstancePath), @@ -21,7 +21,7 @@ pub enum Item { impl std::fmt::Debug for Item { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Item::MsgId(s) => s.fmt(f), + Item::RowId(s) => s.fmt(f), Item::ComponentPath(s) => s.fmt(f), Item::SpaceView(s) => write!(f, "{s:?}"), Item::InstancePath(sid, path) => write!(f, "({sid:?}, {path})"), @@ -38,7 +38,7 @@ impl Item { Item::InstancePath(space_view_id, _) => space_view_id .map(|space_view_id| blueprint.viewport.space_view(&space_view_id).is_some()) .unwrap_or(true), - Item::MsgId(msg_id) => log_db.get_log_msg(msg_id).is_some(), + Item::RowId(row_id) => log_db.get_log_msg(row_id).is_some(), Item::SpaceView(space_view_id) => { blueprint.viewport.space_view(space_view_id).is_some() } @@ -57,7 +57,7 @@ impl Item { pub fn kind(self: &Item) -> &'static str { match self { - Item::MsgId(_) => "Message", + Item::RowId(_) => "Message", Item::InstancePath(space_view_id, instance_path) => { match ( instance_path.instance_key.is_specific(), diff --git a/crates/re_viewer/src/misc/selection_state.rs b/crates/re_viewer/src/misc/selection_state.rs index c651f93af36a..2da6eed17d74 100644 --- a/crates/re_viewer/src/misc/selection_state.rs +++ b/crates/re_viewer/src/misc/selection_state.rs @@ -298,7 +298,7 @@ impl SelectionState { .hovered_previous_frame .iter() .any(|current| match current { - Item::MsgId(_) + Item::RowId(_) | Item::ComponentPath(_) | Item::SpaceView(_) | Item::DataBlueprintGroup(_, _) => current == test, @@ -356,7 +356,7 @@ impl SelectionState { for current_selection in self.selection.iter() { match current_selection { - Item::MsgId(_) | Item::ComponentPath(_) | Item::SpaceView(_) => {} + Item::RowId(_) | Item::ComponentPath(_) | Item::SpaceView(_) => {} Item::DataBlueprintGroup(group_space_view_id, group_handle) => { if *group_space_view_id == space_view_id { @@ -432,7 +432,7 @@ impl SelectionState { for current_hover in self.hovered_previous_frame.iter() { match current_hover { - Item::MsgId(_) | Item::ComponentPath(_) | Item::SpaceView(_) => {} + Item::RowId(_) | Item::ComponentPath(_) | Item::SpaceView(_) => {} Item::DataBlueprintGroup(group_space_view_id, group_handle) => { // Unlike for selected objects/data we are more picky for data blueprints with our hover highlights diff --git a/crates/re_viewer/src/misc/viewer_context.rs b/crates/re_viewer/src/misc/viewer_context.rs index 631f17231112..0068e8b038e6 100644 --- a/crates/re_viewer/src/misc/viewer_context.rs +++ b/crates/re_viewer/src/misc/viewer_context.rs @@ -1,5 +1,5 @@ use re_data_store::{log_db::LogDb, InstancePath}; -use re_log_types::{ComponentPath, EntityPath, MsgId, TimeInt, Timeline}; +use re_log_types::{ComponentPath, EntityPath, RowId, TimeInt, Timeline}; use crate::ui::{ data_ui::{ComponentUiRegistry, DataUi}, @@ -35,15 +35,15 @@ pub struct ViewerContext<'a> { } impl<'a> ViewerContext<'a> { - /// Show an [`MsgId`] and make it selectable - pub fn msg_id_button(&mut self, ui: &mut egui::Ui, msg_id: MsgId) -> egui::Response { - let item = Item::MsgId(msg_id); + /// Show a [`RowId`] and make it selectable. + pub fn row_id_button(&mut self, ui: &mut egui::Ui, row_id: RowId) -> egui::Response { + let item = Item::RowId(row_id); let response = ui - .selectable_label(self.selection().contains(&item), msg_id.short_string()) + .selectable_label(self.selection().contains(&item), row_id.short_string()) .on_hover_ui(|ui| { - ui.label(format!("Message ID: {msg_id}")); + ui.label(format!("Row ID: {row_id}")); ui.separator(); - msg_id.data_ui(self, ui, UiVerbosity::Small, &self.current_query()); + row_id.data_ui(self, ui, UiVerbosity::Small, &self.current_query()); }); self.cursor_interact_with_selectable(response, item) } diff --git a/crates/re_viewer/src/ui/annotations.rs b/crates/re_viewer/src/ui/annotations.rs index 3a25bc132fd1..69e97cb25149 100644 --- a/crates/re_viewer/src/ui/annotations.rs +++ b/crates/re_viewer/src/ui/annotations.rs @@ -8,7 +8,7 @@ use re_data_store::EntityPath; use re_log_types::{ component_types::{ClassId, KeypointId}, context::{AnnotationInfo, ClassDescription}, - AnnotationContext, Component, MsgId, + AnnotationContext, RowId, }; use re_query::query_entity_with_primary; @@ -16,7 +16,7 @@ use crate::{misc::ViewerContext, ui::scene::SceneQuery}; #[derive(Clone, Debug)] pub struct Annotations { - pub msg_id: MsgId, + pub row_id: RowId, pub context: AnnotationContext, } @@ -162,18 +162,16 @@ impl AnnotationMap { data_store, &latest_at_query, &parent, - &[MsgId::name()], + &[], ) .ok() .and_then(|entity| { - if let (Some(context), Some(msg_id)) = ( - entity.iter_primary().ok()?.next()?, - entity.iter_component::().ok()?.next()?, - ) { - Some(entry.insert(Arc::new(Annotations { msg_id, context }))) - } else { - None - } + entity.iter_primary().ok()?.next()?.map(|context| { + entry.insert(Arc::new(Annotations { + row_id: entity.row_id(), + context, + })) + }) }) .is_some() { @@ -207,12 +205,12 @@ impl AnnotationMap { // --- -const MISSING_MSG_ID: MsgId = MsgId::ZERO; +const MISSING_ROW_ID: RowId = RowId::ZERO; lazy_static! { pub static ref MISSING_ANNOTATIONS: Arc = { Arc::new(Annotations { - msg_id: MISSING_MSG_ID, + row_id: MISSING_ROW_ID, context: Default::default(), }) }; diff --git a/crates/re_viewer/src/ui/data_ui/component_path.rs b/crates/re_viewer/src/ui/data_ui/component_path.rs index 504844738adc..f834f6cc5fb9 100644 --- a/crates/re_viewer/src/ui/data_ui/component_path.rs +++ b/crates/re_viewer/src/ui/data_ui/component_path.rs @@ -25,7 +25,7 @@ impl DataUi for ComponentPath { // Any other failure to get a component is unexpected ui.label(ctx.re_ui.error_text(format!("Error: {err}"))); } - Ok(component_data) => { + Ok((_, component_data)) => { super::component::EntityComponentWithInstances { entity_path: self.entity_path.clone(), component_data, diff --git a/crates/re_viewer/src/ui/data_ui/component_ui_registry.rs b/crates/re_viewer/src/ui/data_ui/component_ui_registry.rs index dc5e885c6739..daf46b4f8a52 100644 --- a/crates/re_viewer/src/ui/data_ui/component_ui_registry.rs +++ b/crates/re_viewer/src/ui/data_ui/component_ui_registry.rs @@ -47,7 +47,6 @@ impl Default for ComponentUiRegistry { registry.add::(); registry.add::(); registry.add::(); - registry.add::(); // registry.add::(); // registry.add::(); // registry.add::(); diff --git a/crates/re_viewer/src/ui/data_ui/instance_path.rs b/crates/re_viewer/src/ui/data_ui/instance_path.rs index 6bd727eb4092..d6154d980044 100644 --- a/crates/re_viewer/src/ui/data_ui/instance_path.rs +++ b/crates/re_viewer/src/ui/data_ui/instance_path.rs @@ -7,7 +7,7 @@ use crate::{misc::ViewerContext, ui::UiVerbosity}; use super::DataUi; const HIDDEN_COMPONENTS_FOR_ALL_VERBOSITY: &[&str] = &["rerun.instance_key"]; -const HIDDEN_COMPONENTS_FOR_LOW_VERBOSITY: &[&str] = &["rerun.msg_id"]; +const HIDDEN_COMPONENTS_FOR_LOW_VERBOSITY: &[&str] = &[]; impl DataUi for InstancePath { fn data_ui( @@ -65,7 +65,7 @@ impl DataUi for InstancePath { Err(err) => { ui.label(ctx.re_ui.error_text(format!("Error: {err}"))); } - Ok(component_data) => { + Ok((_, component_data)) => { if self.instance_key.is_splat() { super::component::EntityComponentWithInstances { entity_path: self.entity_path.clone(), diff --git a/crates/re_viewer/src/ui/data_ui/log_msg.rs b/crates/re_viewer/src/ui/data_ui/log_msg.rs index 260e132feb31..c4c982c2d066 100644 --- a/crates/re_viewer/src/ui/data_ui/log_msg.rs +++ b/crates/re_viewer/src/ui/data_ui/log_msg.rs @@ -34,7 +34,7 @@ impl DataUi for BeginRecordingMsg { _query: &re_arrow_store::LatestAtQuery, ) { ui.code("BeginRecordingMsg"); - let BeginRecordingMsg { msg_id: _, info } = self; + let BeginRecordingMsg { row_id: _, info } = self; let RecordingInfo { application_id, recording_id, @@ -76,7 +76,7 @@ impl DataUi for EntityPathOpMsg { query: &re_arrow_store::LatestAtQuery, ) { let EntityPathOpMsg { - msg_id: _, + row_id: _, time_point, path_op, } = self; diff --git a/crates/re_viewer/src/ui/data_ui/mod.rs b/crates/re_viewer/src/ui/data_ui/mod.rs index cb94694d0a40..09580773c449 100644 --- a/crates/re_viewer/src/ui/data_ui/mod.rs +++ b/crates/re_viewer/src/ui/data_ui/mod.rs @@ -14,7 +14,7 @@ mod entity_path; pub(crate) mod image; mod instance_path; mod log_msg; -mod msg_id; +mod row_id; pub(crate) use component_ui_registry::ComponentUiRegistry; diff --git a/crates/re_viewer/src/ui/data_ui/msg_id.rs b/crates/re_viewer/src/ui/data_ui/row_id.rs similarity index 80% rename from crates/re_viewer/src/ui/data_ui/msg_id.rs rename to crates/re_viewer/src/ui/data_ui/row_id.rs index b954bdfcb198..603bd924a0d4 100644 --- a/crates/re_viewer/src/ui/data_ui/msg_id.rs +++ b/crates/re_viewer/src/ui/data_ui/row_id.rs @@ -1,10 +1,10 @@ -use re_log_types::MsgId; +use re_log_types::RowId; use crate::misc::ViewerContext; use super::{DataUi, UiVerbosity}; -impl DataUi for MsgId { +impl DataUi for RowId { fn data_ui( &self, ctx: &mut ViewerContext<'_>, @@ -14,13 +14,13 @@ impl DataUi for MsgId { ) { match verbosity { UiVerbosity::Small | UiVerbosity::MaxHeight(_) => { - ctx.msg_id_button(ui, *self); + ctx.row_id_button(ui, *self); } UiVerbosity::All | UiVerbosity::Reduced => { if let Some(msg) = ctx.log_db.get_log_msg(self) { msg.data_ui(ctx, ui, verbosity, query); } else { - ctx.msg_id_button(ui, *self); + ctx.row_id_button(ui, *self); } } } diff --git a/crates/re_viewer/src/ui/event_log_view.rs b/crates/re_viewer/src/ui/event_log_view.rs index 3820710be32e..306e02192dc5 100644 --- a/crates/re_viewer/src/ui/event_log_view.rs +++ b/crates/re_viewer/src/ui/event_log_view.rs @@ -49,7 +49,7 @@ pub(crate) fn message_table(ctx: &mut ViewerContext<'_>, ui: &mut egui::Ui, mess .max_scroll_height(f32::INFINITY) // Fill up whole height .cell_layout(egui::Layout::left_to_right(egui::Align::Center)) .resizable(true) - .column(Column::initial(100.0).at_least(50.0).clip(true)) // msg_id + .column(Column::initial(100.0).at_least(50.0).clip(true)) // row_id .column(Column::initial(130.0).at_least(50.0).clip(true)) // message type .columns( // timeline(s): @@ -112,7 +112,7 @@ fn table_row( ) { match msg { LogMsg::BeginRecordingMsg(msg) => { - let BeginRecordingMsg { msg_id, info } = msg; + let BeginRecordingMsg { row_id, info } = msg; let RecordingInfo { application_id, recording_id, @@ -122,7 +122,7 @@ fn table_row( } = info; row.col(|ui| { - ctx.msg_id_button(ui, *msg_id); + ctx.row_id_button(ui, *row_id); }); row.col(|ui| { ui.monospace("BeginRecordingMsg"); @@ -143,13 +143,13 @@ fn table_row( } LogMsg::EntityPathOpMsg(_, msg) => { let EntityPathOpMsg { - msg_id, + row_id, time_point, path_op, } = msg; row.col(|ui| { - ctx.msg_id_button(ui, *msg_id); + ctx.row_id_button(ui, *row_id); }); row.col(|ui| { ui.monospace("EntityPathOpMsg"); @@ -180,7 +180,7 @@ fn table_row( Ok(table) => { for datarow in table.to_rows() { row.col(|ui| { - ctx.msg_id_button(ui, datarow.row_id()); + ctx.row_id_button(ui, datarow.row_id()); }); row.col(|ui| { ui.monospace("ArrowMsg"); @@ -222,9 +222,9 @@ fn table_row( }); } }, - LogMsg::Goodbye(msg_id) => { + LogMsg::Goodbye(row_id) => { row.col(|ui| { - ctx.msg_id_button(ui, *msg_id); + ctx.row_id_button(ui, *row_id); }); row.col(|ui| { ui.monospace("Goodbye"); diff --git a/crates/re_viewer/src/ui/selection_history_ui.rs b/crates/re_viewer/src/ui/selection_history_ui.rs index 1aa6b542dfd1..5ff3563482e0 100644 --- a/crates/re_viewer/src/ui/selection_history_ui.rs +++ b/crates/re_viewer/src/ui/selection_history_ui.rs @@ -201,7 +201,7 @@ fn item_to_string(blueprint: &Blueprint, item: &Item) -> String { "".to_owned() } } - Item::MsgId(msg_id) => msg_id.short_string(), + Item::RowId(row_id) => row_id.short_string(), Item::ComponentPath(path) => { format!("{} {}", path.entity_path, path.component_name.short_name(),) } diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index c33278af29eb..307bd3f32020 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -119,7 +119,7 @@ impl SelectionPanel { fn has_data_section(item: &Item) -> bool { match item { - Item::MsgId(_) | Item::ComponentPath(_) | Item::InstancePath(_, _) => true, + Item::RowId(_) | Item::ComponentPath(_) | Item::InstancePath(_, _) => true, // Skip data ui since we don't know yet what to show for these. Item::SpaceView(_) | Item::DataBlueprintGroup(_, _) => false, } @@ -133,10 +133,10 @@ pub fn what_is_selected_ui( item: &Item, ) { match item { - Item::MsgId(msg_id) => { + Item::RowId(row_id) => { ui.horizontal(|ui| { - ui.label("Message ID:"); - ctx.msg_id_button(ui, *msg_id); + ui.label("Row ID:"); + ctx.row_id_button(ui, *row_id); }); } Item::ComponentPath(re_log_types::ComponentPath { @@ -230,8 +230,8 @@ impl DataUi for Item { // If you add something in here make sure to adjust SelectionPanel::contents accordingly. debug_assert!(!has_data_section(self)); } - Item::MsgId(msg_id) => { - msg_id.data_ui(ctx, ui, verbosity, query); + Item::RowId(row_id) => { + row_id.data_ui(ctx, ui, verbosity, query); } Item::ComponentPath(component_path) => { component_path.data_ui(ctx, ui, verbosity, query); @@ -251,7 +251,7 @@ fn blueprint_ui( item: &Item, ) { match item { - Item::MsgId(_) => { + Item::RowId(_) => { // TODO(andreas): Show space views that contains entities that's part of this message. ui.weak("(nothing)"); } diff --git a/crates/re_viewer/src/ui/space_view_heuristics.rs b/crates/re_viewer/src/ui/space_view_heuristics.rs index 80e66e303723..df1da9956907 100644 --- a/crates/re_viewer/src/ui/space_view_heuristics.rs +++ b/crates/re_viewer/src/ui/space_view_heuristics.rs @@ -253,7 +253,6 @@ fn is_default_added_to_space_view( let ignored_components = [ re_log_types::Transform::name(), re_log_types::ViewCoordinates::name(), - re_log_types::MsgId::name(), re_log_types::component_types::InstanceKey::name(), re_log_types::component_types::KeypointId::name(), DataStore::insert_id_key(), diff --git a/crates/re_viewer/src/ui/time_panel/data_density_graph.rs b/crates/re_viewer/src/ui/time_panel/data_density_graph.rs index b5a7dfae9c84..bdf311b4ccf2 100644 --- a/crates/re_viewer/src/ui/time_panel/data_density_graph.rs +++ b/crates/re_viewer/src/ui/time_panel/data_density_graph.rs @@ -488,7 +488,7 @@ pub fn data_density_graph_ui( ctx.rec_cfg.time_ctrl.set_time(hovered_time_range.min); ctx.rec_cfg.time_ctrl.pause(); } else if !ui.ctx().memory(|mem| mem.is_anything_being_dragged()) { - show_msg_ids_tooltip( + show_row_ids_tooltip( ctx, blueprint, ui.ctx(), @@ -518,7 +518,7 @@ fn make_brighter(color: Color32) -> Color32 { ) } -fn show_msg_ids_tooltip( +fn show_row_ids_tooltip( ctx: &mut ViewerContext<'_>, blueprint: &mut Blueprint, egui_ctx: &egui::Context, diff --git a/crates/re_viewer/src/ui/view_text/scene.rs b/crates/re_viewer/src/ui/view_text/scene.rs index f83162bd0319..7016961dabb8 100644 --- a/crates/re_viewer/src/ui/view_text/scene.rs +++ b/crates/re_viewer/src/ui/view_text/scene.rs @@ -2,7 +2,7 @@ use re_arrow_store::TimeRange; use re_data_store::EntityPath; use re_log_types::{ component_types::{self, InstanceKey}, - Component, MsgId, + Component, RowId, }; use re_query::{range_entity_with_primary, QueryError}; @@ -15,7 +15,7 @@ use super::ui::ViewTextFilters; #[derive(Debug, Clone)] pub struct TextEntry { // props - pub msg_id: Option, + pub row_id: RowId, pub entity_path: EntityPath, @@ -63,19 +63,17 @@ impl SceneText { let components = [ InstanceKey::name(), - MsgId::name(), component_types::TextEntry::name(), component_types::ColorRGBA::name(), ]; - let ent_views = range_entity_with_primary::( + let ent_views = range_entity_with_primary::( store, &query, ent_path, components, ); for (time, ent_view) in ent_views { - match ent_view.visit3( + match ent_view.visit2( |_instance, text_entry: component_types::TextEntry, - msg_id: Option, color: Option| { let component_types::TextEntry { body, level } = text_entry; @@ -86,7 +84,7 @@ impl SceneText { if is_visible { self.text_entries.push(TextEntry { - msg_id, + row_id: ent_view.row_id(), entity_path: entity_path.clone(), time: time.map(|time| time.as_i64()), color: color.map(|c| c.to_array()), diff --git a/crates/re_viewer/src/ui/view_text/ui.rs b/crates/re_viewer/src/ui/view_text/ui.rs index f0ff28dc1cba..3186edbf35a2 100644 --- a/crates/re_viewer/src/ui/view_text/ui.rs +++ b/crates/re_viewer/src/ui/view_text/ui.rs @@ -188,7 +188,7 @@ fn get_time_point(ctx: &ViewerContext<'_>, entry: &TextEntry) -> Option