diff options
-rw-r--r-- | Cargo.lock | 8 | ||||
-rw-r--r-- | components/style/lib.rs | 2 | ||||
-rw-r--r-- | components/style/selector_map.rs | 53 |
3 files changed, 50 insertions, 13 deletions
diff --git a/Cargo.lock b/Cargo.lock index 9485e216d00..7b40353a4f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1678,7 +1678,7 @@ dependencies = [ "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2814,7 +2814,7 @@ dependencies = [ name = "servo_atoms" version = "0.0.1" dependencies = [ - "string_cache 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2966,7 +2966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "string_cache" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3873,7 +3873,7 @@ dependencies = [ "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" -"checksum string_cache 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23429a3aca80e7cc7f0060853a97fbba9a90e30ef36b29d13e22559cd7f3dc54" +"checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" diff --git a/components/style/lib.rs b/components/style/lib.rs index e1453706977..fcf48752530 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -71,7 +71,7 @@ extern crate ordered_float; extern crate owning_ref; extern crate parking_lot; extern crate pdqsort; -#[cfg(feature = "gecko")] extern crate precomputed_hash; +extern crate precomputed_hash; extern crate rayon; extern crate selectors; #[cfg(feature = "servo")] #[macro_use] extern crate serde; diff --git a/components/style/selector_map.rs b/components/style/selector_map.rs index c4bc3dcadb0..193196c488a 100644 --- a/components/style/selector_map.rs +++ b/components/style/selector_map.rs @@ -9,19 +9,56 @@ use {Atom, LocalName}; use applicable_declarations::ApplicableDeclarationBlock; use context::QuirksMode; use dom::TElement; -use fnv::FnvHashMap; use pdqsort::sort_by; +use precomputed_hash::PrecomputedHash; use rule_tree::CascadeLevel; use selector_parser::SelectorImpl; use selectors::matching::{matches_selector, MatchingContext, ElementSelectorFlags}; use selectors::parser::{Component, Combinator, SelectorIter}; use selectors::parser::LocalName as LocalNameSelector; use smallvec::{SmallVec, VecLike}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::collections::hash_map; -use std::hash::Hash; +use std::hash::{BuildHasherDefault, Hash, Hasher}; use stylist::Rule; +/// A hasher implementation that doesn't hash anything, because it expects its +/// input to be a suitable u32 hash. +pub struct PrecomputedHasher { + hash: Option<u32>, +} + +impl Default for PrecomputedHasher { + fn default() -> Self { + Self { hash: None } + } +} + +/// A simple alias for a hashmap using PrecomputedHasher. +pub type PrecomputedHashMap<K, V> = HashMap<K, V, BuildHasherDefault<PrecomputedHasher>>; + +/// A simple alias for a hashset using PrecomputedHasher. +pub type PrecomputedHashSet<K> = HashSet<K, BuildHasherDefault<PrecomputedHasher>>; + +impl Hasher for PrecomputedHasher { + #[inline] + fn write(&mut self, _: &[u8]) { + unreachable!("Called into PrecomputedHasher with something that isn't \ + a u32") + } + + #[inline] + fn write_u32(&mut self, i: u32) { + debug_assert!(self.hash.is_none()); + self.hash = Some(i); + } + + #[inline] + fn finish(&self) -> u64 { + self.hash.expect("PrecomputedHasher wasn't fed?") as u64 + } +} + /// A trait to abstract over a given selector map entry. pub trait SelectorMapEntry : Sized + Clone { /// Gets the selector we should use to index in the selector map. @@ -63,7 +100,7 @@ pub struct SelectorMap<T> { /// A hash from a class name to rules which contain that class selector. pub class_hash: MaybeCaseInsensitiveHashMap<Atom, SmallVec<[T; 1]>>, /// A hash from local name to rules which contain that local name selector. - pub local_name_hash: FnvHashMap<LocalName, SmallVec<[T; 1]>>, + pub local_name_hash: PrecomputedHashMap<LocalName, SmallVec<[T; 1]>>, /// Rules that don't have ID, class, or element selectors. pub other: Vec<T>, /// The number of entries in this map. @@ -434,7 +471,7 @@ pub fn get_local_name(iter: SelectorIter<SelectorImpl>) } #[inline] -fn find_push<Str: Eq + Hash, V, VL>(map: &mut FnvHashMap<Str, VL>, +fn find_push<Str: Eq + Hash, V, VL>(map: &mut PrecomputedHashMap<Str, VL>, key: Str, value: V) where VL: VecLike<V> + Default @@ -442,15 +479,15 @@ fn find_push<Str: Eq + Hash, V, VL>(map: &mut FnvHashMap<Str, VL>, map.entry(key).or_insert_with(VL::default).push(value) } -/// Wrapper for FnvHashMap that does ASCII-case-insensitive lookup in quirks mode. +/// Wrapper for PrecomputedHashMap that does ASCII-case-insensitive lookup in quirks mode. #[derive(Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub struct MaybeCaseInsensitiveHashMap<K: Hash + Eq, V>(FnvHashMap<K, V>); +pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V>(PrecomputedHashMap<K, V>); impl<V> MaybeCaseInsensitiveHashMap<Atom, V> { /// Empty map pub fn new() -> Self { - MaybeCaseInsensitiveHashMap(FnvHashMap::default()) + MaybeCaseInsensitiveHashMap(PrecomputedHashMap::default()) } /// HashMap::entry |