diff --git a/Cargo.lock b/Cargo.lock index 555202c33d9a..736c8a0d6758 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4564,6 +4564,7 @@ dependencies = [ "re_types_core", "seq-macro", "similar-asserts", + "static_assertions", "web-time", ] diff --git a/crates/re_data_store/src/store.rs b/crates/re_data_store/src/store.rs index 4d26abd8c646..fbf0515b8fcc 100644 --- a/crates/re_data_store/src/store.rs +++ b/crates/re_data_store/src/store.rs @@ -554,6 +554,9 @@ pub struct StaticTable { /// place. pub cluster_key: ComponentName, + /// Keeps track of one and only one [`StaticCell`] per component. + /// + /// Last-write-wins semantics apply, where ordering is defined by `RowId`. pub cells: BTreeMap, } @@ -570,7 +573,9 @@ impl StaticTable { #[derive(Clone)] pub struct StaticCell { + /// None if [`DataStoreConfig::store_insert_ids`] is `false`. pub insert_id: Option, + pub row_id: RowId, pub num_instances: NumInstances, pub cell: DataCell, diff --git a/crates/re_data_store/src/store_format.rs b/crates/re_data_store/src/store_format.rs index 51b0e381cce6..657f60556f23 100644 --- a/crates/re_data_store/src/store_format.rs +++ b/crates/re_data_store/src/store_format.rs @@ -37,10 +37,9 @@ impl std::fmt::Display for DataStore { f.write_str(&indent::indent_all_by( 4, format!( - "{} static tables, for a total of {} across {} total cells\n", + "{} static tables, for a total of {}\n", static_tables.len(), format_bytes(self.static_size_bytes() as _), - format_uint(self.num_static_cells()) ), ))?; f.write_str(&indent::indent_all_by(4, "static_tables: [\n"))?; diff --git a/crates/re_data_store/src/store_read.rs b/crates/re_data_store/src/store_read.rs index 5a5dc8466768..e23387a2d8ff 100644 --- a/crates/re_data_store/src/store_read.rs +++ b/crates/re_data_store/src/store_read.rs @@ -96,6 +96,8 @@ impl DataStore { /// the specified [`Timeline`]. /// /// Static components are always included in the results. + /// + /// Returns `None` if the entity doesn't exist at all on this `timeline`. pub fn all_components( &self, timeline: &Timeline, diff --git a/crates/re_data_store/src/store_stats.rs b/crates/re_data_store/src/store_stats.rs index 084bbd7d4aec..64dde26eac72 100644 --- a/crates/re_data_store/src/store_stats.rs +++ b/crates/re_data_store/src/store_stats.rs @@ -118,7 +118,7 @@ impl DataStoreStats { let static_tables = { re_tracing::profile_scope!("static data"); DataStoreRowStats { - num_rows: store.num_static_cells(), + num_rows: store.num_static_rows(), num_bytes: store.static_size_bytes(), } }; @@ -190,14 +190,11 @@ impl SizeBytes for DataStore { } impl DataStore { - /// Returns the number of static cells stored across this entire store. + /// Returns the number of static rows stored across this entire store. #[inline] - pub fn num_static_cells(&self) -> u64 { - re_tracing::profile_function!(); - self.static_tables - .values() - .map(|static_table| static_table.cells.len() as u64) - .sum() + pub fn num_static_rows(&self) -> u64 { + // A static table only ever contains a single row. + self.static_tables.len() as _ } /// Returns the size of the static data stored across this entire store. diff --git a/crates/re_data_store/tests/data_store.rs b/crates/re_data_store/tests/data_store.rs index 541d6ff7e92a..2a67aeb307ed 100644 --- a/crates/re_data_store/tests/data_store.rs +++ b/crates/re_data_store/tests/data_store.rs @@ -839,7 +839,7 @@ fn protected_gc_clear_impl(store: &mut DataStore) { // The 3 static cells should still be around. let stats = DataStoreStats::from_store(store); - assert_eq!(stats.static_tables.num_rows, 2); + assert_eq!(stats.static_tables.num_rows, 1); // Now erase points and GC again let mut static_table = DataTable::from_rows(TableId::new(), [row4]); @@ -856,5 +856,5 @@ fn protected_gc_clear_impl(store: &mut DataStore) { }); let stats = DataStoreStats::from_store(store); - assert_eq!(stats.static_tables.num_rows, 2); + assert_eq!(stats.static_tables.num_rows, 1); } diff --git a/crates/re_entity_db/src/entity_db.rs b/crates/re_entity_db/src/entity_db.rs index 2c09fc106830..a0b6e818a3c9 100644 --- a/crates/re_entity_db/src/entity_db.rs +++ b/crates/re_entity_db/src/entity_db.rs @@ -238,8 +238,7 @@ impl EntityDb { } pub fn num_rows(&self) -> usize { - (self.data_store.num_static_cells() > 0) as usize - + self.data_store.num_temporal_rows() as usize + self.data_store.num_static_rows() as usize + self.data_store.num_temporal_rows() as usize } /// Return the current `StoreGeneration`. This can be used to determine whether the diff --git a/crates/re_log_types/src/time_point/time_int.rs b/crates/re_log_types/src/time_point/time_int.rs index 3ad4960710cc..605831c2ad3d 100644 --- a/crates/re_log_types/src/time_point/time_int.rs +++ b/crates/re_log_types/src/time_point/time_int.rs @@ -112,7 +112,7 @@ impl TimeInt { /// Returns `i64::MIN` for [`Self::STATIC`]. #[inline] - pub fn as_i64(&self) -> i64 { + pub const fn as_i64(&self) -> i64 { match self.0 { Some(t) => t.get(), None => i64::MIN, @@ -121,7 +121,7 @@ impl TimeInt { /// Returns `f64::MIN` for [`Self::STATIC`]. #[inline] - pub fn as_f64(&self) -> f64 { + pub const fn as_f64(&self) -> f64 { match self.0 { Some(t) => t.get() as _, None => f64::MIN, diff --git a/crates/re_query_cache/Cargo.toml b/crates/re_query_cache/Cargo.toml index 3f7f09561436..0c790914f3ac 100644 --- a/crates/re_query_cache/Cargo.toml +++ b/crates/re_query_cache/Cargo.toml @@ -36,6 +36,7 @@ itertools.workspace = true parking_lot.workspace = true paste.workspace = true seq-macro.workspace = true +static_assertions.workspace = true web-time.workspace = true diff --git a/crates/re_query_cache/src/cache.rs b/crates/re_query_cache/src/cache.rs index f75da6f6874c..16442e15dfe2 100644 --- a/crates/re_query_cache/src/cache.rs +++ b/crates/re_query_cache/src/cache.rs @@ -772,9 +772,8 @@ impl CacheBucket { /// multiple times. #[inline] pub fn static_range(&self) -> Range { - let start_index = self - .data_times - .partition_point(|(data_time, _)| data_time < &TimeInt::STATIC); + static_assertions::const_assert_eq!(TimeInt::STATIC.as_i64(), i64::MIN); + let start_index = 0; let end_index = self .data_times .partition_point(|(data_time, _)| data_time <= &TimeInt::STATIC); diff --git a/crates/re_space_view_text_log/src/space_view_class.rs b/crates/re_space_view_text_log/src/space_view_class.rs index 901576195041..d7b2ee356ecc 100644 --- a/crates/re_space_view_text_log/src/space_view_class.rs +++ b/crates/re_space_view_text_log/src/space_view_class.rs @@ -194,7 +194,7 @@ impl SpaceViewClass for TextSpaceView { let time_cursor_moved = state.latest_time != time; let scroll_to_row = time_cursor_moved.then(|| { re_tracing::profile_scope!("search scroll time"); - entries.partition_point(|te| te.time.unwrap_or(i64::MIN) < time) + entries.partition_point(|te| te.time.as_i64() < time) }); state.latest_time = time; diff --git a/crates/re_space_view_text_log/src/visualizer_system.rs b/crates/re_space_view_text_log/src/visualizer_system.rs index 543fc18b7ddb..76a46b084151 100644 --- a/crates/re_space_view_text_log/src/visualizer_system.rs +++ b/crates/re_space_view_text_log/src/visualizer_system.rs @@ -1,6 +1,6 @@ use re_data_store::TimeRange; use re_entity_db::EntityPath; -use re_log_types::RowId; +use re_log_types::{RowId, TimeInt}; use re_types::{ archetypes::TextLog, components::{Color, Text, TextLogLevel}, @@ -17,8 +17,7 @@ pub struct Entry { pub entity_path: EntityPath, - /// `None` for timeless data. - pub time: Option, + pub time: TimeInt, pub color: Option, @@ -74,7 +73,7 @@ impl VisualizerSystem for TextLogSystem { self.entries.push(Entry { row_id, entity_path: data_result.entity_path.clone(), - time: (time.is_static()).then(|| time.as_i64()), + time, color: *color, body: body.clone(), level: level.clone(),