mirror of
https://github.com/servo/servo.git
synced 2025-06-20 15:18:58 +01:00
Cache the number of children of each node
This commit is contained in:
parent
a54404c921
commit
a49eb14615
3 changed files with 46 additions and 17 deletions
|
@ -123,8 +123,7 @@ pub trait ParallelPreorderDomTraversal : PreorderDomTraversal {
|
||||||
// Perform the appropriate traversal.
|
// Perform the appropriate traversal.
|
||||||
self.process(node);
|
self.process(node);
|
||||||
|
|
||||||
// NB: O(n).
|
let child_count = node.children_count();
|
||||||
let child_count = node.children().count();
|
|
||||||
|
|
||||||
// Reset the count of children.
|
// Reset the count of children.
|
||||||
{
|
{
|
||||||
|
|
|
@ -237,6 +237,10 @@ impl<'ln> LayoutNode<'ln> {
|
||||||
self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
|
self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn children_count(&self) -> u32 {
|
||||||
|
unsafe { self.node.children_count() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ln> LayoutNode<'ln> {
|
impl<'ln> LayoutNode<'ln> {
|
||||||
|
|
|
@ -106,6 +106,9 @@ pub struct Node {
|
||||||
/// The live list of children return by .childNodes.
|
/// The live list of children return by .childNodes.
|
||||||
child_list: MutNullableHeap<JS<NodeList>>,
|
child_list: MutNullableHeap<JS<NodeList>>,
|
||||||
|
|
||||||
|
/// The live count of children of this node.
|
||||||
|
children_count: Cell<u32>,
|
||||||
|
|
||||||
/// A bitfield of flags for node items.
|
/// A bitfield of flags for node items.
|
||||||
flags: Cell<NodeFlags>,
|
flags: Cell<NodeFlags>,
|
||||||
|
|
||||||
|
@ -430,6 +433,7 @@ pub trait NodeHelpers {
|
||||||
fn type_id(self) -> NodeTypeId;
|
fn type_id(self) -> NodeTypeId;
|
||||||
fn len(self) -> u32;
|
fn len(self) -> u32;
|
||||||
fn index(self) -> u32;
|
fn index(self) -> u32;
|
||||||
|
fn children_count(self) -> u32;
|
||||||
|
|
||||||
fn owner_doc(self) -> Root<Document>;
|
fn owner_doc(self) -> Root<Document>;
|
||||||
fn set_owner_doc(self, document: &Document);
|
fn set_owner_doc(self, document: &Document);
|
||||||
|
@ -567,7 +571,7 @@ impl<'a> NodeHelpers for &'a Node {
|
||||||
NodeTypeId::CharacterData(_) => {
|
NodeTypeId::CharacterData(_) => {
|
||||||
CharacterDataCast::to_ref(self).unwrap().Length()
|
CharacterDataCast::to_ref(self).unwrap().Length()
|
||||||
},
|
},
|
||||||
_ => self.children().count() as u32
|
_ => self.children_count(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,6 +580,10 @@ impl<'a> NodeHelpers for &'a Node {
|
||||||
self.preceding_siblings().count() as u32
|
self.preceding_siblings().count() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn children_count(self) -> u32 {
|
||||||
|
self.children_count.get()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_anchor_element(self) -> bool {
|
fn is_anchor_element(self) -> bool {
|
||||||
self.type_id == NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement))
|
self.type_id == NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement))
|
||||||
|
@ -1076,36 +1084,26 @@ pub fn from_untrusted_node_address(_runtime: *mut JSRuntime, candidate: Untruste
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub trait LayoutNodeHelpers {
|
pub trait LayoutNodeHelpers {
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn type_id_for_layout(&self) -> NodeTypeId;
|
unsafe fn type_id_for_layout(&self) -> NodeTypeId;
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn parent_node_ref(&self) -> Option<LayoutJS<Node>>;
|
unsafe fn parent_node_ref(&self) -> Option<LayoutJS<Node>>;
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn first_child_ref(&self) -> Option<LayoutJS<Node>>;
|
unsafe fn first_child_ref(&self) -> Option<LayoutJS<Node>>;
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn last_child_ref(&self) -> Option<LayoutJS<Node>>;
|
unsafe fn last_child_ref(&self) -> Option<LayoutJS<Node>>;
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn prev_sibling_ref(&self) -> Option<LayoutJS<Node>>;
|
unsafe fn prev_sibling_ref(&self) -> Option<LayoutJS<Node>>;
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn next_sibling_ref(&self) -> Option<LayoutJS<Node>>;
|
unsafe fn next_sibling_ref(&self) -> Option<LayoutJS<Node>>;
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn owner_doc_for_layout(&self) -> LayoutJS<Document>;
|
unsafe fn owner_doc_for_layout(&self) -> LayoutJS<Document>;
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn is_element_for_layout(&self) -> bool;
|
unsafe fn is_element_for_layout(&self) -> bool;
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn get_flag(&self, flag: NodeFlags) -> bool;
|
unsafe fn get_flag(&self, flag: NodeFlags) -> bool;
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn set_flag(&self, flag: NodeFlags, value: bool);
|
unsafe fn set_flag(&self, flag: NodeFlags, value: bool);
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
unsafe fn children_count(&self) -> u32;
|
||||||
|
|
||||||
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>>;
|
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>>;
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn layout_data_mut(&self) -> RefMut<Option<LayoutData>>;
|
unsafe fn layout_data_mut(&self) -> RefMut<Option<LayoutData>>;
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData>;
|
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData>;
|
||||||
|
|
||||||
fn get_hover_state_for_layout(&self) -> bool;
|
fn get_hover_state_for_layout(&self) -> bool;
|
||||||
|
@ -1184,6 +1182,12 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
|
||||||
(*this).flags.set(flags);
|
(*this).flags.set(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
unsafe fn children_count(&self) -> u32 {
|
||||||
|
(*self.unsafe_get()).children_count.get()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>> {
|
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>> {
|
||||||
|
@ -1482,6 +1486,7 @@ impl Node {
|
||||||
prev_sibling: Default::default(),
|
prev_sibling: Default::default(),
|
||||||
owner_doc: MutNullableHeap::new(doc.map(JS::from_ref)),
|
owner_doc: MutNullableHeap::new(doc.map(JS::from_ref)),
|
||||||
child_list: Default::default(),
|
child_list: Default::default(),
|
||||||
|
children_count: Cell::new(0u32),
|
||||||
flags: Cell::new(NodeFlags::new(type_id)),
|
flags: Cell::new(NodeFlags::new(type_id)),
|
||||||
|
|
||||||
layout_data: LayoutDataRef::new(),
|
layout_data: LayoutDataRef::new(),
|
||||||
|
@ -2404,7 +2409,7 @@ impl<'a> NodeMethods for &'a Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5.
|
// Step 5.
|
||||||
if this.children().count() != node.children().count() {
|
if this.children_count() != node.children_count() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2557,6 +2562,27 @@ impl<'a> VirtualMethods for &'a Node {
|
||||||
let eventtarget: &&EventTarget = EventTargetCast::from_borrowed_ref(self);
|
let eventtarget: &&EventTarget = EventTargetCast::from_borrowed_ref(self);
|
||||||
Some(eventtarget as &VirtualMethods)
|
Some(eventtarget as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn children_changed(&self, mutation: &ChildrenMutation) {
|
||||||
|
if let Some(ref s) = self.super_type() {
|
||||||
|
s.children_changed(mutation);
|
||||||
|
}
|
||||||
|
match *mutation {
|
||||||
|
ChildrenMutation::Append { added, .. } |
|
||||||
|
ChildrenMutation::Insert { added, .. } |
|
||||||
|
ChildrenMutation::Prepend { added, .. } => {
|
||||||
|
self.children_count.set(
|
||||||
|
self.children_count.get() + added.len() as u32);
|
||||||
|
},
|
||||||
|
ChildrenMutation::Replace { added, .. } => {
|
||||||
|
self.children_count.set(
|
||||||
|
self.children_count.get() - 1u32 + added.len() as u32);
|
||||||
|
},
|
||||||
|
ChildrenMutation::ReplaceAll { added, .. } => {
|
||||||
|
self.children_count.set(added.len() as u32);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DisabledStateHelpers {
|
pub trait DisabledStateHelpers {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue