use rustc_hash::FxHashMap;
use std::sync::Arc;
use super::EntityDecoder;
use crate::DecodedEntity;
impl EntityDecoder<'_> {
pub(crate) fn decode_string_by_id_transient(
&mut self, id: u32, attribute: usize,
) -> crate::Result<Option<String>> {
if let Some(entity) = self.cache.get(&id) {
return Ok(entity.get_string(attribute).map(str::to_owned));
}
self.build_index();
let (start, end) = self.entity_index.as_ref().and_then(|index| index.lookup(id))
.ok_or_else(|| crate::Error::parse(0, format!("Entity #{} not found", id)))?;
let (parsed_id, _, tokens) = self.parse_at(start, end, "decode_at_uncached")?;
if let Some(entity) = self.cache.get(&parsed_id) {
return Ok(entity.get_string(attribute).map(str::to_owned));
}
Ok(match tokens.get(attribute) {
Some(token @ crate::parser::Token::String(_)) => {
match crate::AttributeValue::from_token(token) {
crate::AttributeValue::String(value) => Some(value),
_ => None,
}
}
_ => None,
})
}
pub fn drain_cache(&mut self) -> FxHashMap<u32, Arc<DecodedEntity>> {
std::mem::take(&mut self.cache)
}
pub fn clear_cache(&mut self) {
self.cache.clear();
self.point_cache.clear();
self.placement_transform_cache.clear();
}
pub fn clear_entity_cache(&mut self) {
self.cache.clear();
}
pub fn clear_point_cache(&mut self) {
self.point_cache.clear();
}
pub fn take_point_cache(&mut self) -> FxHashMap<u32, (f64, f64, f64)> {
std::mem::take(&mut self.point_cache)
}
pub fn set_point_cache(&mut self, cache: FxHashMap<u32, (f64, f64, f64)>) {
self.point_cache = cache;
}
pub fn point_cache_stats(&self) -> (u64, u64) {
(self.point_cache_hits, self.point_cache_misses)
}
pub fn take_placement_transform_cache(&mut self) -> FxHashMap<u32, [f64; 16]> {
std::mem::take(&mut self.placement_transform_cache)
}
pub fn set_placement_transform_cache(&mut self, cache: FxHashMap<u32, [f64; 16]>) {
self.placement_transform_cache = cache;
}
pub fn get_placement_transform_cached(&self, id: u32) -> Option<[f64; 16]> {
self.placement_transform_cache.get(&id).copied()
}
pub fn cache_placement_transform(&mut self, id: u32, transform: [f64; 16]) {
self.placement_transform_cache.insert(id, transform);
}
pub fn cache_size(&self) -> usize {
self.cache.len()
}
}
#[cfg(test)]
#[path = "transient_projection_tests.rs"]
mod transient_projection_tests;