Struct style::bloom::StyleBloom
[−]
[src]
pub struct StyleBloom<E: TElement> { /* fields omitted */ }
A struct that allows us to fast-reject deep descendant selectors avoiding selector-matching.
This is implemented using a counting bloom filter, and it's a standard
optimization. See Gecko's AncestorFilter
, and Blink's and WebKit's
SelectorFilter
.
The constraints for Servo's style system are a bit different compared to traditional style systems given Servo does a parallel breadth-first traversal instead of a sequential depth-first traversal.
This implies that we need to track a bit more state than other browsers to ensure we're doing the correct thing during the traversal, and being able to apply this optimization effectively.
Concretely, we have a bloom filter instance per worker thread, and we track the current DOM depth in order to find a common ancestor when it doesn't match the previous element we've styled.
This is usually a pretty fast operation (we use to be one level deeper than the previous one), but in the case of work-stealing, we may needed to push and pop multiple elements.
See the insert_parents_recovering
, where most of the magic happens.
Regarding thread-safety, this struct is safe because:
- We clear this after a restyle.
- The DOM shape and attributes (and every other thing we access here) are immutable during a restyle.
Methods
impl<E: TElement> StyleBloom<E>
[src]
pub fn new() -> Self
[src]
Create an empty StyleBloom
. Because StyleBloom acquires the thread-
local filter buffer, creating multiple live StyleBloom instances at
the same time on the same thread will panic.
pub fn filter(&self) -> &BloomFilter
[src]
Return the bloom filter used properly by the selectors
crate.
pub fn push(&mut self, element: E)
[src]
Push an element to the bloom filter, knowing that it's a child of the last element parent.
pub fn is_empty(&self) -> bool
[src]
Returns true if the bloom filter is empty.
pub fn matching_depth(&self) -> usize
[src]
Returns the DOM depth of elements that can be correctly matched against the bloom filter (that is, the number of elements in our list).
pub fn clear(&mut self)
[src]
Clears the bloom filter.
pub fn rebuild(&mut self, element: E)
[src]
Rebuilds the bloom filter up to the parent of the given element.
pub fn assert_complete(&self, element: E)
[src]
In debug builds, asserts that all the parents of element
are in the
bloom filter.
Goes away in release builds.
pub fn current_parent(&self) -> Option<E>
[src]
Get the element that represents the chain of things inserted into the filter right now. That chain is the given element (if any) and its ancestors.
pub fn insert_parents_recovering(&mut self, element: E, element_depth: usize)
[src]
Insert the parents of an element in the bloom filter, trying to recover the filter if the last element inserted doesn't match.
Gets the element depth in the dom, to make it efficient, or if not provided always rebuilds the filter from scratch.
Returns the new bloom filter depth, that the traversal code is responsible to keep around if it wants to get an effective filter.