Store selectors in Arc early to avoid some copying.

This commit is contained in:
Simon Sapin 2014-01-08 15:08:27 +00:00
parent faeab3773e
commit 724fd7caaf
2 changed files with 26 additions and 15 deletions

View file

@ -281,8 +281,7 @@ impl Stylist {
Some(After) => &mut after_map, Some(After) => &mut after_map,
}; };
map.$priority.insert(Rule { map.$priority.insert(Rule {
// TODO: avoid copying? selector: selector.compound_selectors.clone(),
selector: Arc::new(selector.compound_selectors.clone()),
specificity: selector.specificity, specificity: selector.specificity,
declarations: style_rule.declarations.$priority.clone(), declarations: style_rule.declarations.$priority.clone(),
source_order: self.rules_source_order, source_order: self.rules_source_order,
@ -735,7 +734,7 @@ mod tests {
.unwrap().move_iter().map(|s| { .unwrap().move_iter().map(|s| {
Rule { Rule {
specificity: s.specificity, specificity: s.specificity,
selector: Arc::new(s.compound_selectors), selector: s.compound_selectors,
declarations: Arc::new(~[]), declarations: Arc::new(~[]),
source_order: i, source_order: i,
} }

View file

@ -4,14 +4,25 @@
use std::{vec, iter}; use std::{vec, iter};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use extra::arc::Arc;
use cssparser::ast::*; use cssparser::ast::*;
use cssparser::parse_nth; use cssparser::parse_nth;
use namespaces::NamespaceMap; use namespaces::NamespaceMap;
// Only used in tests
impl Eq for Arc<CompoundSelector> {
fn eq(&self, other: &Arc<CompoundSelector>) -> bool {
self.get() == other.get()
}
}
#[deriving(Eq, Clone)] #[deriving(Eq, Clone)]
pub struct Selector { pub struct Selector {
compound_selectors: CompoundSelector, compound_selectors: Arc<CompoundSelector>,
pseudo_element: Option<PseudoElement>, pseudo_element: Option<PseudoElement>,
specificity: u32, specificity: u32,
} }
@ -157,7 +168,7 @@ fn parse_selector(iter: &mut Iter, namespaces: &NamespaceMap)
} }
Some(Selector { Some(Selector {
specificity: compute_specificity(&compound, &pseudo_element), specificity: compute_specificity(&compound, &pseudo_element),
compound_selectors: compound, compound_selectors: Arc::new(compound),
pseudo_element: pseudo_element, pseudo_element: pseudo_element,
}) })
} }
@ -549,6 +560,7 @@ fn skip_whitespace(iter: &mut Iter) -> bool {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use extra::arc::Arc;
use cssparser; use cssparser;
use namespaces::NamespaceMap; use namespaces::NamespaceMap;
use super::*; use super::*;
@ -567,48 +579,48 @@ mod tests {
fn test_parsing() { fn test_parsing() {
assert_eq!(parse(""), None) assert_eq!(parse(""), None)
assert_eq!(parse("e"), Some(~[Selector{ assert_eq!(parse("e"), Some(~[Selector{
compound_selectors: CompoundSelector { compound_selectors: Arc::new(CompoundSelector {
simple_selectors: ~[LocalNameSelector(~"e")], simple_selectors: ~[LocalNameSelector(~"e")],
next: None, next: None,
}, }),
pseudo_element: None, pseudo_element: None,
specificity: specificity(0, 0, 1), specificity: specificity(0, 0, 1),
}])) }]))
assert_eq!(parse(".foo"), Some(~[Selector{ assert_eq!(parse(".foo"), Some(~[Selector{
compound_selectors: CompoundSelector { compound_selectors: Arc::new(CompoundSelector {
simple_selectors: ~[ClassSelector(~"foo")], simple_selectors: ~[ClassSelector(~"foo")],
next: None, next: None,
}, }),
pseudo_element: None, pseudo_element: None,
specificity: specificity(0, 1, 0), specificity: specificity(0, 1, 0),
}])) }]))
assert_eq!(parse("#bar"), Some(~[Selector{ assert_eq!(parse("#bar"), Some(~[Selector{
compound_selectors: CompoundSelector { compound_selectors: Arc::new(CompoundSelector {
simple_selectors: ~[IDSelector(~"bar")], simple_selectors: ~[IDSelector(~"bar")],
next: None, next: None,
}, }),
pseudo_element: None, pseudo_element: None,
specificity: specificity(1, 0, 0), specificity: specificity(1, 0, 0),
}])) }]))
assert_eq!(parse("e.foo#bar"), Some(~[Selector{ assert_eq!(parse("e.foo#bar"), Some(~[Selector{
compound_selectors: CompoundSelector { compound_selectors: Arc::new(CompoundSelector {
simple_selectors: ~[LocalNameSelector(~"e"), simple_selectors: ~[LocalNameSelector(~"e"),
ClassSelector(~"foo"), ClassSelector(~"foo"),
IDSelector(~"bar")], IDSelector(~"bar")],
next: None, next: None,
}, }),
pseudo_element: None, pseudo_element: None,
specificity: specificity(1, 1, 1), specificity: specificity(1, 1, 1),
}])) }]))
assert_eq!(parse("e.foo #bar"), Some(~[Selector{ assert_eq!(parse("e.foo #bar"), Some(~[Selector{
compound_selectors: CompoundSelector { compound_selectors: Arc::new(CompoundSelector {
simple_selectors: ~[IDSelector(~"bar")], simple_selectors: ~[IDSelector(~"bar")],
next: Some((~CompoundSelector { next: Some((~CompoundSelector {
simple_selectors: ~[LocalNameSelector(~"e"), simple_selectors: ~[LocalNameSelector(~"e"),
ClassSelector(~"foo")], ClassSelector(~"foo")],
next: None, next: None,
}, Descendant)), }, Descendant)),
}, }),
pseudo_element: None, pseudo_element: None,
specificity: specificity(1, 1, 1), specificity: specificity(1, 1, 1),
}])) }]))