micromegas_tracing/
static_set_cache.rs1use crate::property_set::{Property, PropertySet, apply_pairs};
3use rustc_hash::FxBuildHasher;
4use std::{
5 collections::HashMap,
6 sync::{PoisonError, RwLock},
7};
8
9type Key<const M: usize> = (usize, [(usize, usize); M]);
12
13pub struct StaticSetCache<const M: usize> {
16 map: RwLock<HashMap<Key<M>, &'static PropertySet, FxBuildHasher>>,
17}
18
19impl<const M: usize> Default for StaticSetCache<M> {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl<const M: usize> StaticSetCache<M> {
26 pub const fn new() -> Self {
27 Self {
28 map: RwLock::new(HashMap::with_hasher(FxBuildHasher)),
29 }
30 }
31
32 pub fn get(
34 &self,
35 base: &'static PropertySet,
36 pairs: [(&'static str, &'static str); M],
37 ) -> &'static PropertySet {
38 let key: Key<M> = (
39 base as *const PropertySet as usize,
40 pairs.map(|(_, v)| (v.as_ptr() as usize, v.len())),
41 );
42 let hit = self
45 .map
46 .read()
47 .unwrap_or_else(PoisonError::into_inner)
48 .get(&key)
49 .copied();
50 if let Some(set) = hit {
51 return set;
52 }
53 let mut properties: Vec<Property> = base.get_properties().to_vec();
54 apply_pairs(&mut properties, pairs);
55 let set = PropertySet::find_or_create(properties);
58 self.map
59 .write()
60 .unwrap_or_else(PoisonError::into_inner)
61 .entry(key)
62 .or_insert(set)
63 }
64}