1use crate::custom_properties::{Name, SubstitutionFunctionKind};
8use crate::properties_and_values::value::ComputedValue as ComputedRegisteredValue;
9use crate::selector_map::PrecomputedHasher;
10use indexmap::{Equivalent, IndexMap};
11use rustc_hash::FxBuildHasher;
12use servo_arc::Arc;
13use std::hash::{BuildHasherDefault, Hash};
14use std::sync::LazyLock;
15
16#[derive(Clone, Debug, PartialEq)]
19pub struct CustomPropertiesMap(Arc<Inner>);
20
21impl Default for CustomPropertiesMap {
22 fn default() -> Self {
23 Self(EMPTY.clone())
24 }
25}
26
27pub type OwnMap =
29 IndexMap<Name, Option<ComputedRegisteredValue>, BuildHasherDefault<PrecomputedHasher>>;
30
31static EMPTY: LazyLock<Arc<Inner>> = LazyLock::new(|| {
32 Arc::new_leaked(Inner {
33 own_properties: Default::default(),
34 parent: None,
35 len: 0,
36 ancestor_count: 0,
37 })
38});
39
40#[derive(Debug, Clone)]
41struct Inner {
42 own_properties: OwnMap,
43 parent: Option<Arc<Inner>>,
44 len: usize,
47 ancestor_count: u8,
49}
50
51const ANCESTOR_COUNT_LIMIT: usize = 4;
53
54pub struct Iter<'a> {
56 current: &'a Inner,
57 current_iter: indexmap::map::Iter<'a, Name, Option<ComputedRegisteredValue>>,
58 descendants: smallvec::SmallVec<[&'a Inner; ANCESTOR_COUNT_LIMIT]>,
59}
60
61impl<'a> Iterator for Iter<'a> {
62 type Item = (&'a Name, &'a Option<ComputedRegisteredValue>);
63
64 fn next(&mut self) -> Option<Self::Item> {
65 loop {
66 let (name, value) = match self.current_iter.next() {
67 Some(v) => v,
68 None => {
69 let parent = self.current.parent.as_deref()?;
70 self.descendants.push(self.current);
71 self.current = parent;
72 self.current_iter = parent.own_properties.iter();
73 continue;
74 },
75 };
76 for descendant in &self.descendants {
78 if descendant.own_properties.contains_key(name) {
79 continue;
80 }
81 }
82 return Some((name, value));
83 }
84 }
85}
86
87impl PartialEq for Inner {
88 fn eq(&self, other: &Self) -> bool {
89 if self.len != other.len {
90 return false;
91 }
92 if self.own_properties.as_slice() != other.own_properties.as_slice() {
105 return false;
106 }
107 self.parent == other.parent
108 }
109}
110
111impl Inner {
112 fn iter(&self) -> Iter<'_> {
113 Iter {
114 current: self,
115 current_iter: self.own_properties.iter(),
116 descendants: Default::default(),
117 }
118 }
119
120 fn is_empty(&self) -> bool {
121 self.len == 0
122 }
123
124 fn len(&self) -> usize {
125 self.len
126 }
127
128 fn get(&self, name: &Name) -> Option<&ComputedRegisteredValue> {
129 if let Some(p) = self.own_properties.get(name) {
130 return p.as_ref();
131 }
132 self.parent.as_ref()?.get(name)
133 }
134
135 fn insert(&mut self, name: &Name, value: Option<ComputedRegisteredValue>) {
136 let new = self.own_properties.insert(name.clone(), value).is_none();
137 if new && self.parent.as_ref().map_or(true, |p| p.get(name).is_none()) {
138 self.len += 1;
139 }
140 }
141
142 fn should_expand_chain(&self) -> bool {
144 const SMALL_THRESHOLD: usize = 8;
145 if self.own_properties.len() <= SMALL_THRESHOLD {
146 return false; }
148 self.ancestor_count < ANCESTOR_COUNT_LIMIT as u8
149 }
150}
151
152impl CustomPropertiesMap {
153 pub fn is_empty(&self) -> bool {
155 self.0.is_empty()
156 }
157
158 pub fn len(&self) -> usize {
160 self.0.len()
161 }
162
163 pub fn get_index(&self, index: usize) -> Option<(&Name, &Option<ComputedRegisteredValue>)> {
165 if index >= self.len() {
166 return None;
167 }
168 self.0.iter().nth(index)
170 }
171
172 pub fn get(&self, name: &Name) -> Option<&ComputedRegisteredValue> {
174 self.0.get(name)
175 }
176
177 fn do_insert(&mut self, name: &Name, value: Option<ComputedRegisteredValue>) {
178 if let Some(inner) = Arc::get_mut(&mut self.0) {
179 return inner.insert(name, value);
180 }
181 if self.get(name) == value.as_ref() {
182 return;
183 }
184 if !self.0.should_expand_chain() {
185 return Arc::make_mut(&mut self.0).insert(name, value);
186 }
187 let len = self.0.len;
188 let ancestor_count = self.0.ancestor_count + 1;
189 let mut new_inner = Inner {
190 own_properties: Default::default(),
191 parent: Some(self.0.clone()),
193 len,
194 ancestor_count,
195 };
196 new_inner.insert(name, value);
197 self.0 = Arc::new(new_inner);
198 }
199
200 pub fn insert(&mut self, name: &Name, value: ComputedRegisteredValue) {
202 self.do_insert(name, Some(value))
203 }
204
205 pub fn remove(&mut self, name: &Name) {
207 self.do_insert(name, None)
208 }
209
210 pub fn shrink_to_fit(&mut self) {
212 if let Some(inner) = Arc::get_mut(&mut self.0) {
213 inner.own_properties.shrink_to_fit()
214 }
215 }
216
217 pub fn iter(&self) -> Iter<'_> {
219 self.0.iter()
220 }
221}
222
223#[derive(Clone, Debug, Default, PartialEq)]
225pub struct AllSubstitutionFunctions(IndexMap<Key, ComputedRegisteredValue, FxBuildHasher>);
226
227#[derive(Clone, Debug, Hash, Eq, PartialEq)]
228struct Key(Name, SubstitutionFunctionKind);
229
230#[derive(Clone, Debug, Hash, Eq, PartialEq)]
231struct KeyRef<'a>(&'a Name, SubstitutionFunctionKind);
232
233impl<'a> Equivalent<Key> for KeyRef<'a> {
234 fn equivalent(&self, key: &Key) -> bool {
235 *self.0 == key.0 && self.1 == key.1
236 }
237}
238
239impl AllSubstitutionFunctions {
240 #[inline(always)]
242 pub fn is_empty(&self) -> bool {
243 self.0.is_empty()
244 }
245
246 #[inline(always)]
248 pub fn get(
249 &self,
250 name: &Name,
251 kind: SubstitutionFunctionKind,
252 ) -> Option<&ComputedRegisteredValue> {
253 debug_assert_ne!(kind, SubstitutionFunctionKind::Env);
254 self.0.get(&KeyRef(name, kind))
255 }
256
257 #[inline(always)]
259 pub fn insert(
260 &mut self,
261 name: &Name,
262 kind: SubstitutionFunctionKind,
263 value: ComputedRegisteredValue,
264 ) {
265 debug_assert_ne!(kind, SubstitutionFunctionKind::Env);
266 let k = Key(name.clone(), kind);
267 self.0.insert(k, value);
268 }
269
270 #[inline(always)]
272 pub fn iter(
273 &self,
274 ) -> impl Iterator<Item = (&Name, SubstitutionFunctionKind, &ComputedRegisteredValue)> {
275 self.0.iter().map(|(k, v)| (&k.0, k.1, v))
276 }
277}