Struct style::bloom::StyleBloom

source ·
pub struct StyleBloom<E: TElement> {
    filter: AtomicRefMut<'static, BloomFilter>,
    elements: SmallVec<[PushedElement<E>; 16]>,
    pushed_hashes: SmallVec<[u32; 64]>,
}
Expand description

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.

Fields§

§filter: AtomicRefMut<'static, BloomFilter>

A handle to the bloom filter from the thread upon which this StyleBloom was created. We use AtomicRefCell so that this is all |Send|, which allows StyleBloom to live in ThreadLocalStyleContext, which is dropped from the parent thread.

§elements: SmallVec<[PushedElement<E>; 16]>

The stack of elements that this bloom filter contains, along with the number of hashes pushed for each element.

§pushed_hashes: SmallVec<[u32; 64]>

Stack of hashes that have been pushed onto this filter.

Implementations§

source§

impl<E: TElement> StyleBloom<E>

source

pub fn new() -> Self

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.

source

pub fn filter(&self) -> &BloomFilter

Return the bloom filter used properly by the selectors crate.

source

pub fn push(&mut self, element: E)

Push an element to the bloom filter, knowing that it’s a child of the last element parent.

source

fn push_internal(&mut self, element: E)

Same as push, but without asserting, in order to use it from rebuild.

source

fn pop(&mut self) -> Option<E>

Pop the last element in the bloom filter and return it.

source

pub fn matching_depth(&self) -> usize

Returns the DOM depth of elements that can be correctly matched against the bloom filter (that is, the number of elements in our list).

source

pub fn clear(&mut self)

Clears the bloom filter.

source

pub fn rebuild(&mut self, element: E)

Rebuilds the bloom filter up to the parent of the given element.

source

pub fn assert_complete(&self, element: E)

In debug builds, asserts that all the parents of element are in the bloom filter.

Goes away in release builds.

source

pub fn current_parent(&self) -> Option<E>

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.

source

pub fn insert_parents_recovering(&mut self, element: E, element_depth: usize)

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.

Trait Implementations§

source§

impl<E: TElement> Drop for StyleBloom<E>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<E> Freeze for StyleBloom<E>
where E: Freeze,

§

impl<E> RefUnwindSafe for StyleBloom<E>
where E: RefUnwindSafe,

§

impl<E> Send for StyleBloom<E>

§

impl<E> Sync for StyleBloom<E>
where E: Sync,

§

impl<E> Unpin for StyleBloom<E>
where E: Unpin,

§

impl<E> !UnwindSafe for StyleBloom<E>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<T> MaybeBoxed<Box<T>> for T

source§

fn maybe_boxed(self) -> Box<T>

Convert
source§

impl<T> MaybeBoxed<T> for T

source§

fn maybe_boxed(self) -> T

Convert
source§

impl<T> Pointable for T

source§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> ErasedDestructor for T
where T: 'static,

source§

impl<T> MaybeSendSync for T