mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-15 19:20:13 +00:00
Bug 1519269 - Remove OrderedMap in favor of IndexMap. r=emilio
This cherry-picks https://github.com/servo/servo/pull/22656.
This commit is contained in:
parent
f32fd66363
commit
03d98acfa8
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2425,6 +2425,7 @@ dependencies = [
|
||||
"fallible 0.0.1",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashglobe 0.1.0",
|
||||
"indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -38,6 +38,7 @@ fallible = { path = "../fallible" }
|
||||
fxhash = "0.2"
|
||||
hashglobe = { path = "../hashglobe" }
|
||||
html5ever = {version = "0.22", optional = true}
|
||||
indexmap = "1.0"
|
||||
itertools = "0.7.6"
|
||||
itoa = "0.4"
|
||||
lazy_static = "1"
|
||||
|
@ -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() {
|
||||
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,
|
||||
|
@ -48,6 +48,7 @@ extern crate hashglobe;
|
||||
#[cfg(feature = "servo")]
|
||||
#[macro_use]
|
||||
extern crate html5ever;
|
||||
extern crate indexmap;
|
||||
extern crate itertools;
|
||||
extern crate itoa;
|
||||
#[macro_use]
|
||||
|
@ -5792,8 +5792,8 @@ pub extern "C" fn Servo_GetCustomPropertyNameAt(
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let property_name = match custom_properties.get_key_at(index) {
|
||||
Some(n) => n,
|
||||
let property_name = match custom_properties.get_index(index as usize) {
|
||||
Some((key, _value)) => key,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user