rustc_type_ir/data_structures/
delayed_map.rs1use std::hash::Hash;
2
3use crate::data_structures::{HashMap, HashSet};
4
5const CACHE_CUTOFF: u32 = 32;
6
7#[derive(Debug)]
13pub struct DelayedMap<K, V> {
14 cache: HashMap<K, V>,
15 count: u32,
16}
17
18impl<K, V> Default for DelayedMap<K, V> {
19 fn default() -> Self {
20 DelayedMap { cache: Default::default(), count: 0 }
21 }
22}
23
24impl<K: Hash + Eq, V> DelayedMap<K, V> {
25 #[inline(always)]
26 pub fn insert(&mut self, key: K, value: V) -> bool {
27 if self.count >= CACHE_CUTOFF {
28 self.cold_insert(key, value)
29 } else {
30 self.count += 1;
31 true
32 }
33 }
34
35 #[cold]
36 #[inline(never)]
37 fn cold_insert(&mut self, key: K, value: V) -> bool {
38 self.cache.insert(key, value).is_none()
39 }
40
41 #[inline(always)]
42 pub fn get(&self, key: &K) -> Option<&V> {
43 if self.cache.is_empty() { None } else { self.cold_get(key) }
44 }
45
46 #[cold]
47 #[inline(never)]
48 fn cold_get(&self, key: &K) -> Option<&V> {
49 self.cache.get(key)
50 }
51}
52
53#[derive(Debug)]
54pub struct DelayedSet<T> {
55 cache: HashSet<T>,
56 count: u32,
57}
58
59impl<T> Default for DelayedSet<T> {
60 fn default() -> Self {
61 DelayedSet { cache: Default::default(), count: 0 }
62 }
63}
64
65impl<T: Hash + Eq> DelayedSet<T> {
66 #[inline(always)]
67 pub fn insert(&mut self, value: T) -> bool {
68 if self.count >= CACHE_CUTOFF {
69 self.cold_insert(value)
70 } else {
71 self.count += 1;
72 true
73 }
74 }
75
76 #[cold]
77 #[inline(never)]
78 fn cold_insert(&mut self, value: T) -> bool {
79 self.cache.insert(value)
80 }
81
82 #[inline(always)]
83 pub fn contains(&self, value: &T) -> bool {
84 !self.cache.is_empty() && self.cold_contains(value)
85 }
86
87 #[cold]
88 #[inline(never)]
89 fn cold_contains(&self, value: &T) -> bool {
90 self.cache.contains(value)
91 }
92}