Skip to content

Commit 15fdf44

Browse files
committed
perf: Simplify iteration over nodes
1 parent 5004947 commit 15fdf44

File tree

7 files changed

+33
-18
lines changed

7 files changed

+33
-18
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Performance
6+
7+
- Use a simpler way for HTML tree traversal.
8+
59
## [0.10.0] - 2023-06-16
610

711
### Added

bindings/python/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Performance
6+
7+
- Use a simpler way for HTML tree traversal.
8+
59
## [0.10.0] - 2023-06-16
610

711
### Added

bindings/ruby/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Performance
6+
7+
- Use a simpler way for HTML tree traversal.
8+
59
## 0.10.0 - 2023-06-17
610

711
- Initial public release

bindings/wasm/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Performance
6+
7+
- Use a simpler way for HTML tree traversal.
8+
59
## [0.10.0] - 2023-06-16
610

711
### Added

css-inline/src/html/document.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ impl Document {
6161
}
6262
}
6363

64+
#[inline]
65+
pub(super) fn next_node_id(&self, node_id: NodeId) -> Option<NodeId> {
66+
node_id.next().filter(|&next| next.get() < self.nodes.len())
67+
}
68+
69+
#[inline]
6470
pub(super) fn as_element(&self, node_id: NodeId) -> Option<Element<'_>> {
6571
if let NodeData::Element { element, .. } = &self[node_id].data {
6672
Some(Element::new(self, node_id, element))
@@ -246,17 +252,6 @@ impl Document {
246252
successors(self[node].first_child, |&node| self[node].next_sibling)
247253
}
248254

249-
pub(crate) fn node_and_ancestors(&self, node: NodeId) -> impl Iterator<Item = NodeId> + '_ {
250-
successors(Some(node), move |&node| self[node].parent)
251-
}
252-
253-
pub(crate) fn next_in_tree_order(&self, node: NodeId) -> Option<NodeId> {
254-
self[node].first_child.or_else(|| {
255-
self.node_and_ancestors(node)
256-
.find_map(|ancestor| self[ancestor].next_sibling)
257-
})
258-
}
259-
260255
/// Serialize the document to HTML string.
261256
pub(crate) fn serialize<W: Write>(
262257
&self,

css-inline/src/html/iter.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ pub(crate) fn select<'a, 'b>(
1515
Selectors::compile(selectors).map(|selectors| Select {
1616
traverse: Traverse {
1717
document,
18-
current: Some(NodeId::document_id()),
18+
current: NodeId::document_id(),
1919
},
2020
selectors,
2121
})
2222
}
2323

24-
/// An internal iterator that traverses a document in tree order.
24+
/// An internal iterator that traverses a document.
2525
struct Traverse<'a> {
2626
document: &'a Document,
2727
// Current node being processed
28-
current: Option<NodeId>,
28+
current: NodeId,
2929
}
3030

3131
impl<'a> Iterator for Traverse<'a> {
@@ -34,11 +34,10 @@ impl<'a> Iterator for Traverse<'a> {
3434
fn next(&mut self) -> Option<Self::Item> {
3535
// Loop until we either run out of nodes or find an element node
3636
loop {
37-
if let Some(current) = self.current {
38-
// Advance to the next node in tree order
39-
self.current = self.document.next_in_tree_order(current);
37+
if let Some(next) = self.document.next_node_id(self.current) {
38+
self.current = next;
4039
// If the current node is an element node, return it, else continue with the loop
41-
if let Some(element) = self.document.as_element(current) {
40+
if let Some(element) = self.document.as_element(next) {
4241
return Some(element);
4342
}
4443
} else {

css-inline/src/html/node.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,14 @@ impl NodeId {
6565
pub(super) fn document_id() -> NodeId {
6666
NodeId::new(1)
6767
}
68+
#[inline]
6869
pub(super) fn get(self) -> usize {
6970
self.0.get()
7071
}
72+
#[inline]
73+
pub(super) fn next(self) -> Option<NodeId> {
74+
self.get().checked_add(1).map(NodeId::new)
75+
}
7176
}
7277

7378
/// Data associated with a `Node`.

0 commit comments

Comments
 (0)