Skip to main content

TreeOrderedIndexMap

Struct TreeOrderedIndexMap 

Source
pub(crate) struct TreeOrderedIndexMap {
    map: DomRefCell<HashMapTracedValues<Atom, TreeOrderedIndexMapEntry, FxBuildHasher>>,
    might_need_rebuild_for_layout: Cell<bool>,
    index_type: IndexType,
}
Expand description

A data structure that tracks the use of an identifier type in the DOM. Currently this is meant for tracking elements that share an id or name attribute.

The core problem this structure is trying to solve is that elements with the same id and ‘name’ often need to be accessed in document order, yet calculating the order of elements is expensive. This structure makes calculation of that ordering as cheap as possible by delaying it until the last moment before it is needed.

The goal here is to mitigate the situation where many elements on a page share the same identifier. Maintaining an in-order map in that case has very negative performance characteristics. This map solves that problem, making the optimal case still O(1). It’s actually not very common that a normal page needs the elements in order during script execution.

Each entry in the map holds a cached ordering, initially valid if there is only a single element that has a particular id or name. When another element is added to the map which shares that identifier, the cache is invalidated and count of elements is maintained. Only when needing to access the ordered representation of the elements with the identifier do we walk the DOM, collecting the various elements in order.

There is one unfortunate penalty we have to pay due to Servo’s rooting design: layout that might match elements by id does need elements in order. Before layout or running any query selectors, we need to resolve all unresolved entries in the map. In the end though, this is still just a single walk over the DOM. This is only run when a map entry becomes invalid due to to an element sharing an id being added or removed.

Fields§

§map: DomRefCell<HashMapTracedValues<Atom, TreeOrderedIndexMapEntry, FxBuildHasher>>

It is safe to use FxHash for these maps as Atoms are string_cache items that will have the hash computed from a u32.

§might_need_rebuild_for_layout: Cell<bool>

Whether or not this map might need to be resolved for layout or for calls to Self::for_each.

§index_type: IndexType

The IndexType that this TreeOrderedIndexMap uses, which is either the id or name attribute.

Implementations§

Source§

impl TreeOrderedIndexMap

Source

pub(crate) fn name() -> Self

Source

pub(crate) fn id() -> Self

Source

pub(crate) fn add(&self, key: &Atom, element: &Element)

Add an entry to this map from the key (an id or name attribute value) to Element. If this is the first time this key is used, then the map will be able to map to the entry without having to resolve ordering.

Source

pub(crate) fn remove(&self, key: &Atom)

Remove an entry from the map with key (an id or name attribute value). If there are more elements that share the same key, the entry will need resoluton before use. Removal of the last element for an entry will remove it from the map.

Source

pub(crate) fn get( &self, no_gc: &NoGC, scope: &Node, key: &Atom, ) -> Option<DomRoot<Element>>

Get the first element that has this key from the DOM, possibly resolving the ordering of unresolved entries.

Note: This should never be used during layout as it does rooting and unrooting.

Source

pub(crate) fn get_all( &self, no_gc: &NoGC, scope: &Node, key: &Atom, ) -> Ref<'_, [Dom<Element>]>

Get all of the entries in the map, in DOM order that share a particular key. If the entry for this key is unresolved, it will be resolved.

Note: This should never be used during layout as it does rooting and unrooting.

Source

pub(crate) fn for_each( &self, no_gc: &NoGC, scope: &Node, callback: impl FnMut(&Atom, &[Dom<Element>]), )

Run the given callback against every (key, elements) tuple in this map. This will resolve all unresolved entries in the map.

Note: This should never be used during layout as it does rooting and unrooting.

Source

pub(crate) fn get_all_for_layout(&self, key: &Atom) -> &[LayoutDom<'_, Element>]

Get all of the entries in the map, in DOM order that share a particular key. This will not resolve any entries. It is an error to call this before an entry is resolved.

Source

fn resolve_one( no_gc: &NoGC, scope: &Node, key: &Atom, entry: &mut TreeOrderedIndexMapEntry, index_type: IndexType, )

Resolve a single entry in the map that has more than one element associated with it. This will walk the DOM and gather all of the elements that have this id/name associated with them in DOM order.

Source

pub(crate) fn resolve_all(&self, no_gc: &NoGC, scope: &Node)

Resolve all entries in the map, meaning the next access will not need any resolution. This should be called before any layout activity that accesses the map.

Trait Implementations§

Source§

impl MallocSizeOf for TreeOrderedIndexMap

Source§

fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize

Measure the heap usage of all descendant heap-allocated structures, but not the space taken up by the value itself.
Source§

impl Traceable for TreeOrderedIndexMap

Source§

unsafe fn trace(&self, tracer: *mut JSTracer)

Trace self.

Auto Trait Implementations§

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> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> Filterable for T

Source§

fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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.
Source§

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

Source§

type Output = T

Should always be Self
Source§

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

Source§

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>,

Source§

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> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

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

Source§

impl<T> MaybeSendSync for T

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,