@@ -18,7 +18,7 @@ use re_types_core::{
1818 components:: InstanceKey , Archetype , ArchetypeName , Component , ComponentName , SizeBytes as _,
1919} ;
2020
21- use crate :: { ErasedFlatVecDeque , FlatVecDeque } ;
21+ use crate :: { ErasedFlatVecDeque , FlatVecDeque , LatestAtCache , RangeCache } ;
2222
2323// ---
2424
@@ -67,6 +67,17 @@ pub struct CachesPerArchetype {
6767 // than an `ArchetypeName`: the query system doesn't care about archetypes.
6868 pub ( crate ) latest_at_per_archetype : RwLock < HashMap < ArchetypeName , Arc < RwLock < LatestAtCache > > > > ,
6969
70+ /// Which [`Archetype`] are we querying for?
71+ ///
72+ /// This is very important because of our data model: we not only query for components, but we
73+ /// query for components from a specific point-of-view (the so-called primary component).
74+ /// Different archetypes have different point-of-views, and therefore can end up with different
75+ /// results, even from the same raw data.
76+ //
77+ // TODO(cmc): At some point we should probably just store the PoV and optional components rather
78+ // than an `ArchetypeName`: the query system doesn't care about archetypes.
79+ pub ( crate ) range_per_archetype : RwLock < HashMap < ArchetypeName , Arc < RwLock < RangeCache > > > > ,
80+
7081 /// Everything greater than or equal to this timestamp has been asynchronously invalidated.
7182 ///
7283 /// The next time this cache gets queried, it must remove any entry matching this criteria.
@@ -134,6 +145,42 @@ impl Caches {
134145 f ( & mut cache)
135146 }
136147
148+ /// Gives write access to the appropriate `RangeCache` according to the specified
149+ /// query parameters.
150+ #[ inline]
151+ pub fn with_range < A , F , R > (
152+ store_id : StoreId ,
153+ entity_path : EntityPath ,
154+ query : & RangeQuery ,
155+ mut f : F ,
156+ ) -> R
157+ where
158+ A : Archetype ,
159+ F : FnMut ( & mut RangeCache ) -> R ,
160+ {
161+ let key = CacheKey :: new ( store_id, entity_path, query. timeline ) ;
162+
163+ let cache =
164+ re_data_store:: DataStore :: with_subscriber_once ( * CACHES , move |caches : & Caches | {
165+ let mut caches = caches. 0 . write ( ) ;
166+
167+ let caches_per_archetype = caches. entry ( key. clone ( ) ) . or_default ( ) ;
168+ caches_per_archetype. handle_pending_invalidation ( & key) ;
169+
170+ let mut range_per_archetype = caches_per_archetype. range_per_archetype . write ( ) ;
171+ let range_cache = range_per_archetype. entry ( A :: name ( ) ) . or_default ( ) ;
172+
173+ Arc :: clone ( range_cache)
174+
175+ // Implicitly releasing all intermediary locks.
176+ } )
177+ // NOTE: downcasting cannot fail, this is our own private handle.
178+ . unwrap ( ) ;
179+
180+ let mut cache = cache. write ( ) ;
181+ f ( & mut cache)
182+ }
183+
137184 #[ inline]
138185 pub ( crate ) fn with < F : FnMut ( & Caches ) -> R , R > ( f : F ) -> R {
139186 // NOTE: downcasting cannot fail, this is our own private handle.
@@ -347,6 +394,9 @@ pub struct CacheBucket {
347394 ///
348395 /// This corresponds to the data time and `RowId` returned by `re_query::query_archetype`.
349396 ///
397+ /// This is guaranteed to always be sorted and dense (i.e. there cannot be a hole in the cached
398+ /// data, unless the raw data itself in the store has a hole at that particular point in time).
399+ ///
350400 /// Reminder: within a single timestamp, rows are sorted according to their [`RowId`]s.
351401 pub ( crate ) data_times : VecDeque < ( TimeInt , RowId ) > ,
352402
@@ -375,6 +425,18 @@ impl CacheBucket {
375425 self . data_times . iter ( )
376426 }
377427
428+ #[ inline]
429+ pub fn contains_data_time ( & self , data_time : TimeInt ) -> bool {
430+ let first_time = self . data_times . front ( ) . map_or ( & TimeInt :: MAX , |( t, _) | t) ;
431+ let last_time = self . data_times . back ( ) . map_or ( & TimeInt :: MIN , |( t, _) | t) ;
432+ * first_time <= data_time && data_time <= * last_time
433+ }
434+
435+ #[ inline]
436+ pub fn contains_data_row ( & self , data_time : TimeInt , row_id : RowId ) -> bool {
437+ self . data_times . binary_search ( & ( data_time, row_id) ) . is_ok ( )
438+ }
439+
378440 /// Iterate over the [`InstanceKey`] batches of the point-of-view components.
379441 #[ inline]
380442 pub fn iter_pov_instance_keys ( & self ) -> impl Iterator < Item = & [ InstanceKey ] > {
@@ -554,42 +616,3 @@ impl CacheBucket {
554616 Ok ( added_size_bytes)
555617 }
556618}
557-
558- // ---
559-
560- // NOTE: Because we're working with deserialized data, everything has to be done with metaprogramming,
561- // which is notoriously painful in Rust (i.e., macros).
562- // For this reason we move as much of the code as possible into the already existing macros in `query.rs`.
563-
564- /// Caches the results of `LatestAt` archetype queries (`ArchetypeView`).
565- ///
566- /// There is one `LatestAtCache` for each unique [`CacheKey`].
567- ///
568- /// All query steps are cached: index search, cluster key joins and deserialization.
569- #[ derive( Default ) ]
570- pub struct LatestAtCache {
571- /// Organized by _query_ time.
572- ///
573- /// If the data you're looking for isn't in here, try partially running the query (i.e. run the
574- /// index search in order to find a data time, but don't actually deserialize and join the data)
575- /// and check if there is any data available for the resulting _data_ time in [`Self::per_data_time`].
576- pub per_query_time : BTreeMap < TimeInt , Arc < RwLock < CacheBucket > > > ,
577-
578- /// Organized by _data_ time.
579- ///
580- /// Due to how our latest-at semantics work, any number of queries at time `T+n` where `n >= 0`
581- /// can result in a data time of `T`.
582- pub per_data_time : BTreeMap < TimeInt , Arc < RwLock < CacheBucket > > > ,
583-
584- /// Dedicated bucket for timeless data, if any.
585- ///
586- /// Query time and data time are one and the same in the timeless case, therefore we only need
587- /// this one bucket.
588- //
589- // NOTE: Lives separately so we don't pay the extra `Option` cost in the much more common
590- // timeful case.
591- pub timeless : Option < CacheBucket > ,
592-
593- /// Total size of the data stored in this cache in bytes.
594- pub total_size_bytes : u64 ,
595- }
0 commit comments