use re_chunk::EntityPath;
#[expect(unused_imports)]
use re_chunk_store::ComponentColumnDescriptor;
use re_chunk_store::{ChunkStoreHandle, QueryExpression};
use re_log_types::EntityPathFilter;
use re_query::{QueryCache, QueryCacheHandle, StorageEngine, StorageEngineLike};
use re_sorbet::ChunkColumnDescriptors;
use crate::QueryHandle;
#[derive(Clone)]
pub struct QueryEngine<E: StorageEngineLike> {
pub engine: E,
}
impl QueryEngine<StorageEngine> {
#[inline]
pub fn new(store: ChunkStoreHandle, cache: QueryCacheHandle) -> Self {
#[expect(unsafe_code)]
let engine = unsafe { StorageEngine::new(store, cache) };
Self { engine }
}
#[inline]
pub fn from_store(store: ChunkStoreHandle) -> Self {
Self::new(store.clone(), QueryCache::new_handle(store))
}
#[cfg(not(target_arch = "wasm32"))]
#[inline]
pub fn from_rrd_filepath(
store_config: &re_chunk_store::ChunkStoreConfig,
path_to_rrd: impl AsRef<std::path::Path>,
) -> anyhow::Result<std::collections::BTreeMap<re_log_types::StoreId, Self>> {
Ok(
re_chunk_store::ChunkStore::handle_from_rrd_filepath(store_config, path_to_rrd)?
.into_iter()
.map(|(store_id, store)| (store_id, Self::from_store(store)))
.collect(),
)
}
}
impl<E: StorageEngineLike + Clone> QueryEngine<E> {
#[inline]
pub fn schema(&self) -> ChunkColumnDescriptors {
self.engine
.with(|store, _cache| store.schema().chunk_column_descriptors())
}
#[inline]
pub fn schema_for_query(&self, query: &QueryExpression) -> ChunkColumnDescriptors {
self.engine
.with(|store, _cache| store.schema_for_query(query))
}
#[inline]
pub fn query(&self, query: QueryExpression) -> QueryHandle<E> {
QueryHandle::new(self.engine.clone(), query)
}
#[inline]
pub fn iter_entity_paths_sorted<'a>(
&self,
filter: &'a EntityPathFilter,
) -> impl Iterator<Item = EntityPath> + 'a + use<'a, E> {
let filter = filter.clone().resolve_without_substitutions();
self.engine.with(|store, _cache| {
store
.all_entities_sorted()
.into_iter()
.filter(move |entity_path| filter.matches(entity_path))
})
}
}