mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
style: Hash less stuff in the bloom filter, using the precomputed hashes we have.
This commit is contained in:
parent
65ebbb7c56
commit
e29b84de18
10 changed files with 129 additions and 63 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2392,6 +2392,7 @@ dependencies = [
|
||||||
"cssparser 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2753,6 +2754,7 @@ dependencies = [
|
||||||
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"selectors 0.18.0",
|
"selectors 0.18.0",
|
||||||
|
|
|
@ -20,3 +20,4 @@ bitflags = "0.7"
|
||||||
matches = "0.1"
|
matches = "0.1"
|
||||||
cssparser = "0.12.1"
|
cssparser = "0.12.1"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
|
precomputed-hash = "0.1"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#[macro_use] extern crate cssparser;
|
#[macro_use] extern crate cssparser;
|
||||||
#[macro_use] extern crate matches;
|
#[macro_use] extern crate matches;
|
||||||
extern crate fnv;
|
extern crate fnv;
|
||||||
|
extern crate precomputed_hash;
|
||||||
|
|
||||||
pub mod bloom;
|
pub mod bloom;
|
||||||
pub mod matching;
|
pub mod matching;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
use bloom::BloomFilter;
|
use bloom::BloomFilter;
|
||||||
use parser::{CaseSensitivity, Combinator, ComplexSelector, LocalName};
|
use parser::{CaseSensitivity, Combinator, ComplexSelector, LocalName};
|
||||||
use parser::{SimpleSelector, Selector, SelectorImpl};
|
use parser::{SimpleSelector, Selector, SelectorImpl};
|
||||||
|
use precomputed_hash::PrecomputedHash;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use tree::Element;
|
use tree::Element;
|
||||||
|
|
||||||
|
@ -135,23 +136,23 @@ fn may_match<E>(mut selector: &ComplexSelector<E::Impl>,
|
||||||
for ss in selector.compound_selector.iter() {
|
for ss in selector.compound_selector.iter() {
|
||||||
match *ss {
|
match *ss {
|
||||||
SimpleSelector::LocalName(LocalName { ref name, ref lower_name }) => {
|
SimpleSelector::LocalName(LocalName { ref name, ref lower_name }) => {
|
||||||
if !bf.might_contain(name) &&
|
if !bf.might_contain_hash(name.precomputed_hash()) &&
|
||||||
!bf.might_contain(lower_name) {
|
!bf.might_contain_hash(lower_name.precomputed_hash()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SimpleSelector::Namespace(ref namespace) => {
|
SimpleSelector::Namespace(ref namespace) => {
|
||||||
if !bf.might_contain(&namespace.url) {
|
if !bf.might_contain_hash(namespace.url.precomputed_hash()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SimpleSelector::ID(ref id) => {
|
SimpleSelector::ID(ref id) => {
|
||||||
if !bf.might_contain(id) {
|
if !bf.might_contain_hash(id.precomputed_hash()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SimpleSelector::Class(ref class) => {
|
SimpleSelector::Class(ref class) => {
|
||||||
if !bf.might_contain(class) {
|
if !bf.might_contain_hash(class.precomputed_hash()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter};
|
use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter};
|
||||||
|
use precomputed_hash::PrecomputedHash;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::{Borrow, Cow};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
@ -39,10 +40,10 @@ macro_rules! with_all_bounds {
|
||||||
/// of pseudo-classes/elements
|
/// of pseudo-classes/elements
|
||||||
pub trait SelectorImpl: Sized {
|
pub trait SelectorImpl: Sized {
|
||||||
type AttrValue: $($InSelector)*;
|
type AttrValue: $($InSelector)*;
|
||||||
type Identifier: $($InSelector)*;
|
type Identifier: $($InSelector)* + PrecomputedHash;
|
||||||
type ClassName: $($InSelector)*;
|
type ClassName: $($InSelector)* + PrecomputedHash;
|
||||||
type LocalName: $($InSelector)* + Borrow<Self::BorrowedLocalName>;
|
type LocalName: $($InSelector)* + Borrow<Self::BorrowedLocalName> + PrecomputedHash;
|
||||||
type NamespaceUrl: $($CommonBounds)* + Default + Borrow<Self::BorrowedNamespaceUrl>;
|
type NamespaceUrl: $($CommonBounds)* + Default + Borrow<Self::BorrowedNamespaceUrl> + PrecomputedHash;
|
||||||
type NamespacePrefix: $($InSelector)* + Default;
|
type NamespacePrefix: $($InSelector)* + Default;
|
||||||
type BorrowedNamespaceUrl: ?Sized + Eq;
|
type BorrowedNamespaceUrl: ?Sized + Eq;
|
||||||
type BorrowedLocalName: ?Sized + Eq + Hash;
|
type BorrowedLocalName: ?Sized + Eq + Hash;
|
||||||
|
@ -1184,24 +1185,49 @@ pub mod tests {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DummyParser {
|
pub struct DummyParser {
|
||||||
default_ns: Option<String>,
|
default_ns: Option<DummyAtom>,
|
||||||
ns_prefixes: HashMap<String, String>,
|
ns_prefixes: HashMap<DummyAtom, DummyAtom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SelectorImpl for DummySelectorImpl {
|
impl SelectorImpl for DummySelectorImpl {
|
||||||
type AttrValue = String;
|
type AttrValue = DummyAtom;
|
||||||
type Identifier = String;
|
type Identifier = DummyAtom;
|
||||||
type ClassName = String;
|
type ClassName = DummyAtom;
|
||||||
type LocalName = String;
|
type LocalName = DummyAtom;
|
||||||
type NamespaceUrl = String;
|
type NamespaceUrl = DummyAtom;
|
||||||
type NamespacePrefix = String;
|
type NamespacePrefix = DummyAtom;
|
||||||
type BorrowedLocalName = str;
|
type BorrowedLocalName = DummyAtom;
|
||||||
type BorrowedNamespaceUrl = str;
|
type BorrowedNamespaceUrl = DummyAtom;
|
||||||
type NonTSPseudoClass = PseudoClass;
|
type NonTSPseudoClass = PseudoClass;
|
||||||
type PseudoElement = PseudoElement;
|
type PseudoElement = PseudoElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShutUpTidy = String;
|
#[derive(Default, Debug, Hash, Clone, PartialEq, Eq)]
|
||||||
|
pub struct DummyAtom(String);
|
||||||
|
|
||||||
|
impl fmt::Display for DummyAtom {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
<String as fmt::Display>::fmt(&self.0, fmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for DummyAtom {
|
||||||
|
fn from(string: String) -> Self {
|
||||||
|
DummyAtom(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a str> for DummyAtom {
|
||||||
|
fn from(string: &'a str) -> Self {
|
||||||
|
DummyAtom(string.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrecomputedHash for DummyAtom {
|
||||||
|
fn precomputed_hash(&self) -> u32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Parser for DummyParser {
|
impl Parser for DummyParser {
|
||||||
type Impl = DummySelectorImpl;
|
type Impl = DummySelectorImpl;
|
||||||
|
@ -1232,11 +1258,11 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_namespace(&self) -> Option<String> {
|
fn default_namespace(&self) -> Option<DummyAtom> {
|
||||||
self.default_ns.clone()
|
self.default_ns.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn namespace_for_prefix(&self, prefix: &ShutUpTidy) -> Option<String> {
|
fn namespace_for_prefix(&self, prefix: &DummyAtom) -> Option<DummyAtom> {
|
||||||
self.ns_prefixes.get(prefix).cloned()
|
self.ns_prefixes.get(prefix).cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1276,8 +1302,8 @@ pub mod tests {
|
||||||
assert_eq!(parse("EeÉ"), Ok(SelectorList(vec!(Selector {
|
assert_eq!(parse("EeÉ"), Ok(SelectorList(vec!(Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(SimpleSelector::LocalName(LocalName {
|
compound_selector: vec!(SimpleSelector::LocalName(LocalName {
|
||||||
name: String::from("EeÉ"),
|
name: DummyAtom::from("EeÉ"),
|
||||||
lower_name: String::from("eeÉ") })),
|
lower_name: DummyAtom::from("eeÉ") })),
|
||||||
next: None,
|
next: None,
|
||||||
}),
|
}),
|
||||||
pseudo_element: None,
|
pseudo_element: None,
|
||||||
|
@ -1286,7 +1312,7 @@ pub mod tests {
|
||||||
assert_eq!(parse(".foo:lang(en-US)"), Ok(SelectorList(vec!(Selector {
|
assert_eq!(parse(".foo:lang(en-US)"), Ok(SelectorList(vec!(Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec![
|
compound_selector: vec![
|
||||||
SimpleSelector::Class(String::from("foo")),
|
SimpleSelector::Class(DummyAtom::from("foo")),
|
||||||
SimpleSelector::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned()))
|
SimpleSelector::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned()))
|
||||||
],
|
],
|
||||||
next: None,
|
next: None,
|
||||||
|
@ -1296,7 +1322,7 @@ pub mod tests {
|
||||||
}))));
|
}))));
|
||||||
assert_eq!(parse("#bar"), Ok(SelectorList(vec!(Selector {
|
assert_eq!(parse("#bar"), Ok(SelectorList(vec!(Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(SimpleSelector::ID(String::from("bar"))),
|
compound_selector: vec!(SimpleSelector::ID(DummyAtom::from("bar"))),
|
||||||
next: None,
|
next: None,
|
||||||
}),
|
}),
|
||||||
pseudo_element: None,
|
pseudo_element: None,
|
||||||
|
@ -1305,10 +1331,10 @@ pub mod tests {
|
||||||
assert_eq!(parse("e.foo#bar"), Ok(SelectorList(vec!(Selector {
|
assert_eq!(parse("e.foo#bar"), Ok(SelectorList(vec!(Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(SimpleSelector::LocalName(LocalName {
|
compound_selector: vec!(SimpleSelector::LocalName(LocalName {
|
||||||
name: String::from("e"),
|
name: DummyAtom::from("e"),
|
||||||
lower_name: String::from("e") }),
|
lower_name: DummyAtom::from("e") }),
|
||||||
SimpleSelector::Class(String::from("foo")),
|
SimpleSelector::Class(DummyAtom::from("foo")),
|
||||||
SimpleSelector::ID(String::from("bar"))),
|
SimpleSelector::ID(DummyAtom::from("bar"))),
|
||||||
next: None,
|
next: None,
|
||||||
}),
|
}),
|
||||||
pseudo_element: None,
|
pseudo_element: None,
|
||||||
|
@ -1316,12 +1342,12 @@ pub mod tests {
|
||||||
}))));
|
}))));
|
||||||
assert_eq!(parse("e.foo #bar"), Ok(SelectorList(vec!(Selector {
|
assert_eq!(parse("e.foo #bar"), Ok(SelectorList(vec!(Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(SimpleSelector::ID(String::from("bar"))),
|
compound_selector: vec!(SimpleSelector::ID(DummyAtom::from("bar"))),
|
||||||
next: Some((Arc::new(ComplexSelector {
|
next: Some((Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(SimpleSelector::LocalName(LocalName {
|
compound_selector: vec!(SimpleSelector::LocalName(LocalName {
|
||||||
name: String::from("e"),
|
name: DummyAtom::from("e"),
|
||||||
lower_name: String::from("e") }),
|
lower_name: DummyAtom::from("e") }),
|
||||||
SimpleSelector::Class(String::from("foo"))),
|
SimpleSelector::Class(DummyAtom::from("foo"))),
|
||||||
next: None,
|
next: None,
|
||||||
}), Combinator::Descendant)),
|
}), Combinator::Descendant)),
|
||||||
}),
|
}),
|
||||||
|
@ -1334,8 +1360,8 @@ pub mod tests {
|
||||||
assert_eq!(parse_ns("[Foo]", &parser), Ok(SelectorList(vec!(Selector {
|
assert_eq!(parse_ns("[Foo]", &parser), Ok(SelectorList(vec!(Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(SimpleSelector::AttrExists(AttrSelector {
|
compound_selector: vec!(SimpleSelector::AttrExists(AttrSelector {
|
||||||
name: String::from("Foo"),
|
name: DummyAtom::from("Foo"),
|
||||||
lower_name: String::from("foo"),
|
lower_name: DummyAtom::from("foo"),
|
||||||
namespace: NamespaceConstraint::Specific(Namespace {
|
namespace: NamespaceConstraint::Specific(Namespace {
|
||||||
prefix: None,
|
prefix: None,
|
||||||
url: "".into(),
|
url: "".into(),
|
||||||
|
@ -1347,17 +1373,17 @@ pub mod tests {
|
||||||
specificity: specificity(0, 1, 0),
|
specificity: specificity(0, 1, 0),
|
||||||
}))));
|
}))));
|
||||||
assert_eq!(parse_ns("svg|circle", &parser), Err(()));
|
assert_eq!(parse_ns("svg|circle", &parser), Err(()));
|
||||||
parser.ns_prefixes.insert("svg".into(), SVG.into());
|
parser.ns_prefixes.insert(DummyAtom("svg".into()), DummyAtom(SVG.into()));
|
||||||
assert_eq!(parse_ns("svg|circle", &parser), Ok(SelectorList(vec![Selector {
|
assert_eq!(parse_ns("svg|circle", &parser), Ok(SelectorList(vec![Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec![
|
compound_selector: vec![
|
||||||
SimpleSelector::Namespace(Namespace {
|
SimpleSelector::Namespace(Namespace {
|
||||||
prefix: Some("svg".into()),
|
prefix: Some(DummyAtom("svg".into())),
|
||||||
url: SVG.into(),
|
url: SVG.into(),
|
||||||
}),
|
}),
|
||||||
SimpleSelector::LocalName(LocalName {
|
SimpleSelector::LocalName(LocalName {
|
||||||
name: String::from("circle"),
|
name: DummyAtom::from("circle"),
|
||||||
lower_name: String::from("circle")
|
lower_name: DummyAtom::from("circle"),
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
next: None,
|
next: None,
|
||||||
|
@ -1378,8 +1404,8 @@ pub mod tests {
|
||||||
url: MATHML.into(),
|
url: MATHML.into(),
|
||||||
}),
|
}),
|
||||||
SimpleSelector::AttrExists(AttrSelector {
|
SimpleSelector::AttrExists(AttrSelector {
|
||||||
name: String::from("Foo"),
|
name: DummyAtom::from("Foo"),
|
||||||
lower_name: String::from("foo"),
|
lower_name: DummyAtom::from("foo"),
|
||||||
namespace: NamespaceConstraint::Specific(Namespace {
|
namespace: NamespaceConstraint::Specific(Namespace {
|
||||||
prefix: None,
|
prefix: None,
|
||||||
url: "".into(),
|
url: "".into(),
|
||||||
|
@ -1400,8 +1426,8 @@ pub mod tests {
|
||||||
url: MATHML.into(),
|
url: MATHML.into(),
|
||||||
}),
|
}),
|
||||||
SimpleSelector::LocalName(LocalName {
|
SimpleSelector::LocalName(LocalName {
|
||||||
name: String::from("e"),
|
name: DummyAtom::from("e"),
|
||||||
lower_name: String::from("e") }),
|
lower_name: DummyAtom::from("e") }),
|
||||||
),
|
),
|
||||||
next: None,
|
next: None,
|
||||||
}),
|
}),
|
||||||
|
@ -1412,13 +1438,13 @@ pub mod tests {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec![
|
compound_selector: vec![
|
||||||
SimpleSelector::AttrDashMatch(AttrSelector {
|
SimpleSelector::AttrDashMatch(AttrSelector {
|
||||||
name: String::from("attr"),
|
name: DummyAtom::from("attr"),
|
||||||
lower_name: String::from("attr"),
|
lower_name: DummyAtom::from("attr"),
|
||||||
namespace: NamespaceConstraint::Specific(Namespace {
|
namespace: NamespaceConstraint::Specific(Namespace {
|
||||||
prefix: None,
|
prefix: None,
|
||||||
url: "".into(),
|
url: "".into(),
|
||||||
}),
|
}),
|
||||||
}, "foo".to_owned())
|
}, DummyAtom::from("foo"))
|
||||||
],
|
],
|
||||||
next: None,
|
next: None,
|
||||||
}),
|
}),
|
||||||
|
@ -1441,8 +1467,8 @@ pub mod tests {
|
||||||
compound_selector: vec!(),
|
compound_selector: vec!(),
|
||||||
next: Some((Arc::new(ComplexSelector {
|
next: Some((Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(SimpleSelector::LocalName(LocalName {
|
compound_selector: vec!(SimpleSelector::LocalName(LocalName {
|
||||||
name: String::from("div"),
|
name: DummyAtom::from("div"),
|
||||||
lower_name: String::from("div") })),
|
lower_name: DummyAtom::from("div") })),
|
||||||
next: None,
|
next: None,
|
||||||
}), Combinator::Descendant)),
|
}), Combinator::Descendant)),
|
||||||
}),
|
}),
|
||||||
|
@ -1452,11 +1478,11 @@ pub mod tests {
|
||||||
assert_eq!(parse("#d1 > .ok"), Ok(SelectorList(vec![Selector {
|
assert_eq!(parse("#d1 > .ok"), Ok(SelectorList(vec![Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
compound_selector: vec![
|
compound_selector: vec![
|
||||||
SimpleSelector::Class(String::from("ok")),
|
SimpleSelector::Class(DummyAtom::from("ok")),
|
||||||
],
|
],
|
||||||
next: Some((Arc::new(ComplexSelector {
|
next: Some((Arc::new(ComplexSelector {
|
||||||
compound_selector: vec![
|
compound_selector: vec![
|
||||||
SimpleSelector::ID(String::from("d1")),
|
SimpleSelector::ID(DummyAtom::from("d1")),
|
||||||
],
|
],
|
||||||
next: None,
|
next: None,
|
||||||
}), Combinator::Child)),
|
}), Combinator::Child)),
|
||||||
|
@ -1469,13 +1495,13 @@ pub mod tests {
|
||||||
compound_selector: vec!(SimpleSelector::Negation(
|
compound_selector: vec!(SimpleSelector::Negation(
|
||||||
vec!(
|
vec!(
|
||||||
Arc::new(ComplexSelector {
|
Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(SimpleSelector::Class(String::from("babybel"))),
|
compound_selector: vec!(SimpleSelector::Class(DummyAtom::from("babybel"))),
|
||||||
next: None
|
next: None
|
||||||
}),
|
}),
|
||||||
Arc::new(ComplexSelector {
|
Arc::new(ComplexSelector {
|
||||||
compound_selector: vec!(
|
compound_selector: vec!(
|
||||||
SimpleSelector::ID(String::from("provel")),
|
SimpleSelector::ID(DummyAtom::from("provel")),
|
||||||
SimpleSelector::Class(String::from("old")),
|
SimpleSelector::Class(DummyAtom::from("old")),
|
||||||
),
|
),
|
||||||
next: None
|
next: None
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -44,6 +44,7 @@ num-traits = "0.1.32"
|
||||||
ordered-float = "0.4"
|
ordered-float = "0.4"
|
||||||
parking_lot = "0.3.3"
|
parking_lot = "0.3.3"
|
||||||
pdqsort = "0.1.0"
|
pdqsort = "0.1.0"
|
||||||
|
precomputed-hash = "0.1"
|
||||||
rayon = "0.6"
|
rayon = "0.6"
|
||||||
selectors = { path = "../selectors" }
|
selectors = { path = "../selectors" }
|
||||||
serde = {version = "0.9", optional = true}
|
serde = {version = "0.9", optional = true}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use gecko_bindings::bindings::Gecko_AddRefAtom;
|
||||||
use gecko_bindings::bindings::Gecko_Atomize;
|
use gecko_bindings::bindings::Gecko_Atomize;
|
||||||
use gecko_bindings::bindings::Gecko_ReleaseAtom;
|
use gecko_bindings::bindings::Gecko_ReleaseAtom;
|
||||||
use gecko_bindings::structs::nsIAtom;
|
use gecko_bindings::structs::nsIAtom;
|
||||||
|
use precomputed_hash::PrecomputedHash;
|
||||||
use std::borrow::{Cow, Borrow};
|
use std::borrow::{Cow, Borrow};
|
||||||
use std::char::{self, DecodeUtf16};
|
use std::char::{self, DecodeUtf16};
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
@ -56,6 +57,13 @@ impl Deref for Atom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PrecomputedHash for Atom {
|
||||||
|
#[inline]
|
||||||
|
fn precomputed_hash(&self) -> u32 {
|
||||||
|
self.get_hash()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Borrow<WeakAtom> for Atom {
|
impl Borrow<WeakAtom> for Atom {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn borrow(&self) -> &WeakAtom {
|
fn borrow(&self) -> &WeakAtom {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
//! A type to represent a namespace.
|
//! A type to represent a namespace.
|
||||||
|
|
||||||
use gecko_bindings::structs::nsIAtom;
|
use gecko_bindings::structs::nsIAtom;
|
||||||
|
use precomputed_hash::PrecomputedHash;
|
||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::{Borrow, Cow};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -19,10 +20,27 @@ macro_rules! ns {
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Default, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Default, Hash)]
|
||||||
pub struct Namespace(pub Atom);
|
pub struct Namespace(pub Atom);
|
||||||
|
|
||||||
|
impl PrecomputedHash for Namespace {
|
||||||
|
#[inline]
|
||||||
|
fn precomputed_hash(&self) -> u32 {
|
||||||
|
self.0.precomputed_hash()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A Gecko WeakNamespace is a wrapped WeakAtom.
|
/// A Gecko WeakNamespace is a wrapped WeakAtom.
|
||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
pub struct WeakNamespace(WeakAtom);
|
pub struct WeakNamespace(WeakAtom);
|
||||||
|
|
||||||
|
impl Deref for WeakNamespace {
|
||||||
|
type Target = WeakAtom;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn deref(&self) -> &WeakAtom {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Deref for Namespace {
|
impl Deref for Namespace {
|
||||||
type Target = WeakNamespace;
|
type Target = WeakNamespace;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ extern crate num_traits;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
extern crate pdqsort;
|
extern crate pdqsort;
|
||||||
|
#[cfg(feature = "gecko")] extern crate precomputed_hash;
|
||||||
extern crate rayon;
|
extern crate rayon;
|
||||||
extern crate selectors;
|
extern crate selectors;
|
||||||
#[cfg(feature = "servo")] #[macro_use] extern crate serde_derive;
|
#[cfg(feature = "servo")] #[macro_use] extern crate serde_derive;
|
||||||
|
|
|
@ -1175,23 +1175,30 @@ pub trait MatchMethods : TElement {
|
||||||
/// Therefore, each node must have its matching selectors inserted _after_
|
/// Therefore, each node must have its matching selectors inserted _after_
|
||||||
/// its own selector matching and _before_ its children start.
|
/// its own selector matching and _before_ its children start.
|
||||||
fn insert_into_bloom_filter(&self, bf: &mut BloomFilter) {
|
fn insert_into_bloom_filter(&self, bf: &mut BloomFilter) {
|
||||||
bf.insert(&*self.get_local_name());
|
bf.insert_hash(self.get_local_name().get_hash());
|
||||||
bf.insert(&*self.get_namespace());
|
bf.insert_hash(self.get_namespace().get_hash());
|
||||||
self.get_id().map(|id| bf.insert(&id));
|
if let Some(id) = self.get_id() {
|
||||||
|
bf.insert_hash(id.get_hash());
|
||||||
|
}
|
||||||
// TODO: case-sensitivity depends on the document type and quirks mode
|
// TODO: case-sensitivity depends on the document type and quirks mode
|
||||||
self.each_class(|class| bf.insert(class));
|
self.each_class(|class| {
|
||||||
|
bf.insert_hash(class.get_hash())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// After all the children are done css selector matching, this must be
|
/// After all the children are done css selector matching, this must be
|
||||||
/// called to reset the bloom filter after an `insert`.
|
/// called to reset the bloom filter after an `insert`.
|
||||||
fn remove_from_bloom_filter(&self, bf: &mut BloomFilter) {
|
fn remove_from_bloom_filter(&self, bf: &mut BloomFilter) {
|
||||||
bf.remove(&*self.get_local_name());
|
bf.remove_hash(self.get_local_name().get_hash());
|
||||||
bf.remove(&*self.get_namespace());
|
bf.remove_hash(self.get_namespace().get_hash());
|
||||||
self.get_id().map(|id| bf.remove(&id));
|
if let Some(id) = self.get_id() {
|
||||||
|
bf.remove_hash(id.get_hash());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: case-sensitivity depends on the document type and quirks mode
|
// TODO: case-sensitivity depends on the document type and quirks mode
|
||||||
self.each_class(|class| bf.remove(class));
|
self.each_class(|class| {
|
||||||
|
bf.remove_hash(class.get_hash())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the old and new style of this element, and whether it's a
|
/// Given the old and new style of this element, and whether it's a
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue