style/
custom_properties_map.rs1use crate::custom_properties::Name;
8use crate::properties_and_values::value::ComputedValue as ComputedRegisteredValue;
9use crate::selector_map::PrecomputedHasher;
10use indexmap::IndexMap;
11use servo_arc::Arc;
12use std::hash::BuildHasherDefault;
13use std::sync::LazyLock;
14
15#[derive(Clone, Debug, PartialEq)]
18pub struct CustomPropertiesMap(Arc<Inner>);
19
20impl Default for CustomPropertiesMap {
21 fn default() -> Self {
22 Self(EMPTY.clone())
23 }
24}
25
26type OwnMap =
28 IndexMap<Name, Option<ComputedRegisteredValue>, BuildHasherDefault<PrecomputedHasher>>;
29
30static EMPTY: LazyLock<Arc<Inner>> = LazyLock::new(|| {
31 Arc::new_leaked(Inner {
32 own_properties: Default::default(),
33 parent: None,
34 len: 0,
35 ancestor_count: 0,
36 })
37});
38
39#[derive(Debug, Clone)]
40struct Inner {
41 own_properties: OwnMap,
42 parent: Option<Arc<Inner>>,
43 len: usize,
46 ancestor_count: u8,
48}
49
50const ANCESTOR_COUNT_LIMIT: usize = 4;
52
53pub struct Iter<'a> {
55 current: &'a Inner,
56 current_iter: indexmap::map::Iter<'a, Name, Option<ComputedRegisteredValue>>,
57 descendants: smallvec::SmallVec<[&'a Inner; ANCESTOR_COUNT_LIMIT]>,
58}
59
60impl<'a> Iterator for Iter<'a> {
61 type Item = (&'a Name, &'a Option<ComputedRegisteredValue>);
62
63 fn next(&mut self) -> Option<Self::Item> {
64 loop {
65 let (name, value) = match self.current_iter.next() {
66 Some(v) => v,
67 None => {
68 let parent = self.current.parent.as_deref()?;
69 self.descendants.push(self.current);
70 self.current = parent;
71 self.current_iter = parent.own_properties.iter();
72 continue;
73 },
74 };
75 for descendant in &self.descendants {
77 if descendant.own_properties.contains_key(name) {
78 continue;
79 }
80 }
81 return Some((name, value));
82 }
83 }
84}
85
86impl PartialEq for Inner {
87 fn eq(&self, other: &Self) -> bool {
88 if self.len != other.len {
89 return false;
90 }
91 if self.own_properties.as_slice() != other.own_properties.as_slice() {
104 return false;
105 }
106 self.parent == other.parent
107 }
108}
109
110impl Inner {
111 fn iter(&self) -> Iter<'_> {
112 Iter {
113 current: self,
114 current_iter: self.own_properties.iter(),
115 descendants: Default::default(),
116 }
117 }
118
119 fn is_empty(&self) -> bool {
120 self.len == 0
121 }
122
123 fn len(&self) -> usize {
124 self.len
125 }
126
127 fn get(&self, name: &Name) -> Option<&ComputedRegisteredValue> {
128 if let Some(p) = self.own_properties.get(name) {
129 return p.as_ref();
130 }
131 self.parent.as_ref()?.get(name)
132 }
133
134 fn insert(&mut self, name: &Name, value: Option<ComputedRegisteredValue>) {
135 let new = self.own_properties.insert(name.clone(), value).is_none();
136 if new && self.parent.as_ref().map_or(true, |p| p.get(name).is_none()) {
137 self.len += 1;
138 }
139 }
140
141 fn should_expand_chain(&self) -> bool {
143 const SMALL_THRESHOLD: usize = 8;
144 if self.own_properties.len() <= SMALL_THRESHOLD {
145 return false; }
147 self.ancestor_count < ANCESTOR_COUNT_LIMIT as u8
148 }
149}
150
151impl CustomPropertiesMap {
152 pub fn is_empty(&self) -> bool {
154 self.0.is_empty()
155 }
156
157 pub fn len(&self) -> usize {
159 self.0.len()
160 }
161
162 pub fn get_index(&self, index: usize) -> Option<(&Name, &Option<ComputedRegisteredValue>)> {
164 if index >= self.len() {
165 return None;
166 }
167 self.0.iter().nth(index)
169 }
170
171 pub fn get(&self, name: &Name) -> Option<&ComputedRegisteredValue> {
173 self.0.get(name)
174 }
175
176 fn do_insert(&mut self, name: &Name, value: Option<ComputedRegisteredValue>) {
177 if let Some(inner) = Arc::get_mut(&mut self.0) {
178 return inner.insert(name, value);
179 }
180 if self.get(name) == value.as_ref() {
181 return;
182 }
183 if !self.0.should_expand_chain() {
184 return Arc::make_mut(&mut self.0).insert(name, value);
185 }
186 let len = self.0.len;
187 let ancestor_count = self.0.ancestor_count + 1;
188 let mut new_inner = Inner {
189 own_properties: Default::default(),
190 parent: Some(self.0.clone()),
192 len,
193 ancestor_count,
194 };
195 new_inner.insert(name, value);
196 self.0 = Arc::new(new_inner);
197 }
198
199 pub fn insert(&mut self, name: &Name, value: ComputedRegisteredValue) {
201 self.do_insert(name, Some(value))
202 }
203
204 pub fn remove(&mut self, name: &Name) {
206 self.do_insert(name, None)
207 }
208
209 pub fn shrink_to_fit(&mut self) {
211 if let Some(inner) = Arc::get_mut(&mut self.0) {
212 inner.own_properties.shrink_to_fit()
213 }
214 }
215
216 pub fn iter(&self) -> Iter<'_> {
218 self.0.iter()
219 }
220}