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;
13
14#[derive(Clone, Debug, PartialEq)]
17pub struct CustomPropertiesMap(Arc<Inner>);
18
19impl Default for CustomPropertiesMap {
20 fn default() -> Self {
21 Self(EMPTY.clone())
22 }
23}
24
25type OwnMap =
27 IndexMap<Name, Option<ComputedRegisteredValue>, BuildHasherDefault<PrecomputedHasher>>;
28
29lazy_static! {
30 static ref EMPTY: Arc<Inner> = {
31 Arc::new_leaked(Inner {
32 own_properties: Default::default(),
33 parent: None,
34 len: 0,
35 ancestor_count: 0,
36 })
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}