mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Diagnostic map semantics.
MozReview-Commit-ID: C0a5g6xMPY0
This commit is contained in:
parent
438b9df00c
commit
f5c5be00a7
11 changed files with 296 additions and 69 deletions
|
@ -10,8 +10,7 @@ use applicable_declarations::ApplicableDeclarationBlock;
|
|||
use context::QuirksMode;
|
||||
use dom::TElement;
|
||||
use fallible::FallibleVec;
|
||||
use hash::{HashMap, HashSet};
|
||||
use hash::map as hash_map;
|
||||
use hash::{HashMap, HashSet, DiagnosticHashMap};
|
||||
use hashglobe::FailedAllocationError;
|
||||
use pdqsort::sort_by;
|
||||
use precomputed_hash::PrecomputedHash;
|
||||
|
@ -38,6 +37,9 @@ impl Default for PrecomputedHasher {
|
|||
/// A simple alias for a hashmap using PrecomputedHasher.
|
||||
pub type PrecomputedHashMap<K, V> = HashMap<K, V, BuildHasherDefault<PrecomputedHasher>>;
|
||||
|
||||
/// A simple alias for a hashmap using PrecomputedHasher.
|
||||
pub type PrecomputedDiagnosticHashMap<K, V> = DiagnosticHashMap<K, V, BuildHasherDefault<PrecomputedHasher>>;
|
||||
|
||||
/// A simple alias for a hashset using PrecomputedHasher.
|
||||
pub type PrecomputedHashSet<K> = HashSet<K, BuildHasherDefault<PrecomputedHasher>>;
|
||||
|
||||
|
@ -102,7 +104,7 @@ pub struct SelectorMap<T: 'static> {
|
|||
/// 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: PrecomputedHashMap<LocalName, SmallVec<[T; 1]>>,
|
||||
pub local_name_hash: PrecomputedDiagnosticHashMap<LocalName, SmallVec<[T; 1]>>,
|
||||
/// Rules that don't have ID, class, or element selectors.
|
||||
pub other: SmallVec<[T; 1]>,
|
||||
/// The number of entries in this map.
|
||||
|
@ -123,7 +125,7 @@ impl<T: 'static> SelectorMap<T> {
|
|||
SelectorMap {
|
||||
id_hash: MaybeCaseInsensitiveHashMap::new(),
|
||||
class_hash: MaybeCaseInsensitiveHashMap::new(),
|
||||
local_name_hash: HashMap::default(),
|
||||
local_name_hash: DiagnosticHashMap::default(),
|
||||
other: SmallVec::new(),
|
||||
count: 0,
|
||||
}
|
||||
|
@ -147,6 +149,20 @@ impl<T: 'static> SelectorMap<T> {
|
|||
pub fn len(&self) -> usize {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Allows mutation of this SelectorMap.
|
||||
pub fn begin_mutation(&mut self) {
|
||||
self.id_hash.begin_mutation();
|
||||
self.class_hash.begin_mutation();
|
||||
self.local_name_hash.begin_mutation();
|
||||
}
|
||||
|
||||
/// Disallows mutation of this SelectorMap.
|
||||
pub fn end_mutation(&mut self) {
|
||||
self.id_hash.end_mutation();
|
||||
self.class_hash.end_mutation();
|
||||
self.local_name_hash.end_mutation();
|
||||
}
|
||||
}
|
||||
|
||||
impl SelectorMap<Rule> {
|
||||
|
@ -251,12 +267,10 @@ impl<T: SelectorMapEntry> SelectorMap<T> {
|
|||
|
||||
let vector = match find_bucket(entry.selector()) {
|
||||
Bucket::ID(id) => {
|
||||
self.id_hash.try_entry(id.clone(), quirks_mode)?
|
||||
.or_insert_with(SmallVec::new)
|
||||
self.id_hash.try_get_or_insert_with(id.clone(), quirks_mode, SmallVec::new)?
|
||||
}
|
||||
Bucket::Class(class) => {
|
||||
self.class_hash.try_entry(class.clone(), quirks_mode)?
|
||||
.or_insert_with(SmallVec::new)
|
||||
self.class_hash.try_get_or_insert_with(class.clone(), quirks_mode, SmallVec::new)?
|
||||
}
|
||||
Bucket::LocalName { name, lower_name } => {
|
||||
// If the local name in the selector isn't lowercase, insert it
|
||||
|
@ -272,12 +286,10 @@ impl<T: SelectorMapEntry> SelectorMap<T> {
|
|||
// subsequent selector matching work will filter them out.
|
||||
if name != lower_name {
|
||||
self.local_name_hash
|
||||
.try_entry(lower_name.clone())?
|
||||
.or_insert_with(SmallVec::new)
|
||||
.try_get_or_insert_with(lower_name.clone(), SmallVec::new)?
|
||||
.try_push(entry.clone())?;
|
||||
}
|
||||
self.local_name_hash.try_entry(name.clone())?
|
||||
.or_insert_with(SmallVec::new)
|
||||
self.local_name_hash.try_get_or_insert_with(name.clone(), SmallVec::new)?
|
||||
}
|
||||
Bucket::Universal => {
|
||||
&mut self.other
|
||||
|
@ -463,7 +475,7 @@ fn find_bucket<'a>(mut iter: SelectorIter<'a, SelectorImpl>) -> Bucket<'a> {
|
|||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V: 'static>(PrecomputedHashMap<K, V>);
|
||||
pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V: 'static>(PrecomputedDiagnosticHashMap<K, V>);
|
||||
|
||||
// FIXME(Manishearth) the 'static bound can be removed when
|
||||
// our HashMap fork (hashglobe) is able to use NonZero,
|
||||
|
@ -471,32 +483,20 @@ pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V: 'stati
|
|||
impl<V: 'static> MaybeCaseInsensitiveHashMap<Atom, V> {
|
||||
/// Empty map
|
||||
pub fn new() -> Self {
|
||||
MaybeCaseInsensitiveHashMap(PrecomputedHashMap::default())
|
||||
MaybeCaseInsensitiveHashMap(PrecomputedDiagnosticHashMap::default())
|
||||
}
|
||||
|
||||
/// HashMap::entry
|
||||
pub fn entry(&mut self, mut key: Atom, quirks_mode: QuirksMode) -> hash_map::Entry<Atom, V> {
|
||||
if quirks_mode == QuirksMode::Quirks {
|
||||
key = key.to_ascii_lowercase()
|
||||
}
|
||||
self.0.entry(key)
|
||||
}
|
||||
|
||||
/// HashMap::try_entry
|
||||
pub fn try_entry(
|
||||
/// DiagnosticHashMap::try_get_or_insert_with
|
||||
pub fn try_get_or_insert_with<F: FnOnce() -> V>(
|
||||
&mut self,
|
||||
mut key: Atom,
|
||||
quirks_mode: QuirksMode
|
||||
) -> Result<hash_map::Entry<Atom, V>, FailedAllocationError> {
|
||||
quirks_mode: QuirksMode,
|
||||
default: F,
|
||||
) -> Result<&mut V, FailedAllocationError> {
|
||||
if quirks_mode == QuirksMode::Quirks {
|
||||
key = key.to_ascii_lowercase()
|
||||
}
|
||||
self.0.try_entry(key)
|
||||
}
|
||||
|
||||
/// HashMap::iter
|
||||
pub fn iter(&self) -> hash_map::Iter<Atom, V> {
|
||||
self.0.iter()
|
||||
self.0.try_get_or_insert_with(key, default)
|
||||
}
|
||||
|
||||
/// HashMap::clear
|
||||
|
@ -512,5 +512,15 @@ impl<V: 'static> MaybeCaseInsensitiveHashMap<Atom, V> {
|
|||
self.0.get(key)
|
||||
}
|
||||
}
|
||||
|
||||
/// DiagnosticHashMap::begin_mutation
|
||||
pub fn begin_mutation(&mut self) {
|
||||
self.0.begin_mutation();
|
||||
}
|
||||
|
||||
/// DiagnosticHashMap::end_mutation
|
||||
pub fn end_mutation(&mut self) {
|
||||
self.0.end_mutation();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue