New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove OrderedMap in favor of IndexMap #22656
Changes from all commits
File filter...
Jump to…
Remove OrderedMap in favor of IndexMap
- Loading branch information
Some generated files are not rendered by default. Learn more.
| @@ -8,17 +8,17 @@ | ||
|
|
||
| use crate::hash::map::Entry; | ||
| use crate::properties::{CSSWideKeyword, CustomDeclarationValue}; | ||
| use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet}; | ||
| use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet, PrecomputedHasher}; | ||
| use crate::Atom; | ||
| use cssparser::{Delimiter, Parser, ParserInput, SourcePosition, Token, TokenSerializationType}; | ||
| use precomputed_hash::PrecomputedHash; | ||
| use indexmap::IndexMap; | ||
| use selectors::parser::SelectorParseErrorKind; | ||
| use servo_arc::Arc; | ||
| use smallvec::SmallVec; | ||
| use std::borrow::{Borrow, Cow}; | ||
| use std::borrow::Cow; | ||
| use std::cmp; | ||
| use std::fmt::{self, Write}; | ||
| use std::hash::Hash; | ||
| use std::hash::BuildHasherDefault; | ||
| use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; | ||
|
|
||
| /// The environment from which to get `env` function values. | ||
| @@ -131,7 +131,8 @@ impl ToCss for SpecifiedValue { | ||
| /// | ||
| /// The variable values are guaranteed to not have references to other | ||
| /// properties. | ||
| pub type CustomPropertiesMap = OrderedMap<Name, Arc<VariableValue>>; | ||
| pub type CustomPropertiesMap = | ||
| IndexMap<Name, Arc<VariableValue>, BuildHasherDefault<PrecomputedHasher>>; | ||
|
|
||
| /// Both specified and computed values are VariableValues, the difference is | ||
| /// whether var() functions are expanded. | ||
| @@ -140,130 +141,6 @@ pub type SpecifiedValue = VariableValue; | ||
| /// whether var() functions are expanded. | ||
| pub type ComputedValue = VariableValue; | ||
|
|
||
| /// A map that preserves order for the keys, and that is easily indexable. | ||
| #[derive(Clone, Debug, Eq, PartialEq)] | ||
| pub struct OrderedMap<K, V> | ||
| where | ||
| K: PrecomputedHash + Hash + Eq + Clone, | ||
| { | ||
| /// Key index. | ||
| index: Vec<K>, | ||
| /// Key-value map. | ||
| values: PrecomputedHashMap<K, V>, | ||
| } | ||
|
|
||
| impl<K, V> OrderedMap<K, V> | ||
| where | ||
| K: Eq + PrecomputedHash + Hash + Clone, | ||
| { | ||
| /// Creates a new ordered map. | ||
| pub fn new() -> Self { | ||
| OrderedMap { | ||
| index: Vec::new(), | ||
| values: PrecomputedHashMap::default(), | ||
| } | ||
| } | ||
|
|
||
| /// Insert a new key-value pair. | ||
| /// | ||
| /// TODO(emilio): Remove unused_mut when Gecko and Servo agree in whether | ||
| /// it's necessary. | ||
| #[allow(unused_mut)] | ||
| pub fn insert(&mut self, key: K, value: V) { | ||
| let OrderedMap { | ||
| ref mut index, | ||
| ref mut values, | ||
| } = *self; | ||
| match values.entry(key) { | ||
| Entry::Vacant(mut entry) => { | ||
| index.push(entry.key().clone()); | ||
| entry.insert(value); | ||
| }, | ||
| Entry::Occupied(mut entry) => { | ||
| entry.insert(value); | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| /// Get a value given its key. | ||
| pub fn get(&self, key: &K) -> Option<&V> { | ||
| let value = self.values.get(key); | ||
| debug_assert_eq!(value.is_some(), self.index.contains(key)); | ||
| value | ||
| } | ||
|
|
||
| /// Get whether there's a value on the map for `key`. | ||
| pub fn contains_key(&self, key: &K) -> bool { | ||
| self.values.contains_key(key) | ||
| } | ||
|
|
||
| /// Get the key located at the given index. | ||
| pub fn get_key_at(&self, index: u32) -> Option<&K> { | ||
| self.index.get(index as usize) | ||
| } | ||
|
|
||
| /// Get an ordered map iterator. | ||
| pub fn iter<'a>(&'a self) -> OrderedMapIterator<'a, K, V> { | ||
| OrderedMapIterator { | ||
| inner: self, | ||
| pos: 0, | ||
| } | ||
| } | ||
|
|
||
| /// Get the count of items in the map. | ||
| pub fn len(&self) -> usize { | ||
| debug_assert_eq!(self.values.len(), self.index.len()); | ||
| self.values.len() | ||
| } | ||
|
|
||
| /// Returns whether this map is empty. | ||
| pub fn is_empty(&self) -> bool { | ||
| self.len() == 0 | ||
| } | ||
|
|
||
| /// Remove an item given its key. | ||
| fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> | ||
| where | ||
| K: Borrow<Q>, | ||
| Q: PrecomputedHash + Hash + Eq, | ||
| { | ||
| let index = self.index.iter().position(|k| k.borrow() == key)?; | ||
| self.index.remove(index); | ||
| self.values.remove(key) | ||
| } | ||
| } | ||
|
|
||
| /// An iterator for OrderedMap. | ||
| /// | ||
| /// The iteration order is determined by the order that the values are | ||
| /// added to the key-value map. | ||
| pub struct OrderedMapIterator<'a, K, V> | ||
| where | ||
| K: 'a + Eq + PrecomputedHash + Hash + Clone, | ||
| V: 'a, | ||
| { | ||
| /// The OrderedMap itself. | ||
| inner: &'a OrderedMap<K, V>, | ||
| /// The position of the iterator. | ||
| pos: usize, | ||
| } | ||
|
|
||
| impl<'a, K, V> Iterator for OrderedMapIterator<'a, K, V> | ||
| where | ||
| K: Eq + PrecomputedHash + Hash + Clone, | ||
| { | ||
| type Item = (&'a K, &'a V); | ||
|
|
||
| fn next(&mut self) -> Option<Self::Item> { | ||
| let key = self.inner.index.get(self.pos)?; | ||
|
|
||
| self.pos += 1; | ||
| let value = &self.inner.values[key]; | ||
|
|
||
| Some((key, value)) | ||
| } | ||
| } | ||
|
|
||
| /// A struct holding information about the external references to that a custom | ||
| /// property value may have. | ||
| #[derive(Default)] | ||
| @@ -648,7 +525,7 @@ impl<'a> CustomPropertiesBuilder<'a> { | ||
| if self.custom_properties.is_none() { | ||
| self.custom_properties = Some(match self.inherited { | ||
| Some(inherited) => (**inherited).clone(), | ||
| None => CustomPropertiesMap::new(), | ||
| None => CustomPropertiesMap::default(), | ||
| }); | ||
| } | ||
|
|
||
| @@ -933,7 +810,7 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment: | ||
|
|
||
| // We have to clone the names so that we can mutably borrow the map | ||
| // in the context we create for traversal. | ||
| let names = custom_properties_map.index.clone(); | ||
| let names: Vec<_> = custom_properties_map.keys().cloned().collect(); | ||
| for name in names.into_iter() { | ||
|
This conversation was marked as resolved
by CYBAI
shanavas786
Author
Contributor
|
||
| let mut context = Context { | ||
| count: 0, | ||
| @@ -1112,7 +989,7 @@ pub fn substitute<'i>( | ||
| let mut input = ParserInput::new(input); | ||
| let mut input = Parser::new(&mut input); | ||
| let mut position = (input.position(), first_token_type); | ||
| let empty_map = CustomPropertiesMap::new(); | ||
| let empty_map = CustomPropertiesMap::default(); | ||
| let custom_properties = match computed_values_map { | ||
| Some(m) => &**m, | ||
| None => &empty_map, | ||
Could we just iterate with
keys()or maybekeys().into_iter()?