diff options
author | Alan Jeffrey <ajeffrey@mozilla.com> | 2015-11-06 09:48:32 -0600 |
---|---|---|
committer | Alan Jeffrey <ajeffrey@mozilla.com> | 2015-11-06 17:23:16 -0600 |
commit | 64a50bcf5640fe202e37e7b93c4932e27ce08c98 (patch) | |
tree | eb7163f0a9441c73026ef126cc550011eae48bb9 | |
parent | 4aa6a76f5714fa945f1883ae2d658750cc91d6e3 (diff) | |
download | servo-64a50bcf5640fe202e37e7b93c4932e27ce08c98.tar.gz servo-64a50bcf5640fe202e37e7b93c4932e27ce08c98.zip |
Added versioning to DOM nodes.
There is now an inclusive_descendants_version field of each node, which
increases each time the node, or any of its descendants, is dirtied.
This can be used for cache invalidation, by caching a version number
and comparting the current version number against the cached version number.
-rw-r--r-- | components/script/dom/node.rs | 23 | ||||
-rw-r--r-- | tests/unit/script/size_of.rs | 14 |
2 files changed, 30 insertions, 7 deletions
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index d3eb716d05d..49bb441e21e 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -57,6 +57,7 @@ use selectors::parser::Selector; use selectors::parser::parse_author_origin_selector_list_from_str; use std::borrow::ToOwned; use std::cell::{Cell, Ref, RefCell, RefMut}; +use std::cmp::max; use std::default::Default; use std::iter::{self, FilterMap, Peekable}; use std::mem; @@ -105,6 +106,9 @@ pub struct Node { /// A bitfield of flags for node items. flags: Cell<NodeFlags>, + /// The maximum version of any inclusive descendant of this node. + inclusive_descendants_version: Cell<u64>, + /// Layout information. Only the layout task may touch this data. /// /// Must be sent back to the layout task to be destroyed when this @@ -489,6 +493,19 @@ impl Node { } pub fn dirty_impl(&self, damage: NodeDamage, force_ancestors: bool) { + + // 0. Set version counter + // The new version counter is 1 plus the max of the node's current version counter, + // its descendants version, and the document's version. Normally, this will just be + // the document's version, but we do have to deal with the case where the node has moved + // document, so may have a higher version count than its owning document. + let doc: Root<Node> = Root::upcast(self.owner_doc()); + let version = max(self.get_inclusive_descendants_version(), doc.get_inclusive_descendants_version()) + 1; + for ancestor in self.inclusive_ancestors() { + ancestor.inclusive_descendants_version.set(version); + } + doc.inclusive_descendants_version.set(version); + // 1. Dirty self. match damage { NodeDamage::NodeStyleDamaged => {} @@ -520,6 +537,11 @@ impl Node { } } + /// The maximum version number of this node's descendants, including itself + pub fn get_inclusive_descendants_version(&self) -> u64 { + self.inclusive_descendants_version.get() + } + /// Iterates over this node and all its descendants, in preorder. pub fn traverse_preorder(&self) -> TreeIterator { TreeIterator::new(self) @@ -1284,6 +1306,7 @@ impl Node { child_list: Default::default(), children_count: Cell::new(0u32), flags: Cell::new(flags), + inclusive_descendants_version: Cell::new(0), layout_data: LayoutDataRef::new(), diff --git a/tests/unit/script/size_of.rs b/tests/unit/script/size_of.rs index b89ca9dd837..16154bdcc91 100644 --- a/tests/unit/script/size_of.rs +++ b/tests/unit/script/size_of.rs @@ -38,10 +38,10 @@ macro_rules! sizeof_checker ( // Update the sizes here sizeof_checker!(size_event_target, EventTarget, 40); -sizeof_checker!(size_node, Node, 168); -sizeof_checker!(size_element, Element, 312); -sizeof_checker!(size_htmlelement, HTMLElement, 328); -sizeof_checker!(size_div, HTMLDivElement, 328); -sizeof_checker!(size_span, HTMLSpanElement, 328); -sizeof_checker!(size_text, Text, 200); -sizeof_checker!(size_characterdata, CharacterData, 200); +sizeof_checker!(size_node, Node, 176); +sizeof_checker!(size_element, Element, 320); +sizeof_checker!(size_htmlelement, HTMLElement, 336); +sizeof_checker!(size_div, HTMLDivElement, 336); +sizeof_checker!(size_span, HTMLSpanElement, 336); +sizeof_checker!(size_text, Text, 208); +sizeof_checker!(size_characterdata, CharacterData, 208); |