@@ -12,32 +12,48 @@ namespace Web::Layout {
12
12
13
13
FormattingState::NodeState& FormattingState::get_mutable (NodeWithStyleAndBoxModelMetrics const & box)
14
14
{
15
- if (auto it = nodes.find (&box); it != nodes.end ())
16
- return *it->value ;
17
-
18
- for (auto * ancestor = m_parent; ancestor; ancestor = ancestor->m_parent ) {
19
- if (auto it = ancestor->nodes .find (&box); it != ancestor->nodes .end ()) {
20
- auto cow_node_state = adopt_own (*new NodeState (*it->value ));
21
- auto * cow_node_state_ptr = cow_node_state.ptr ();
22
- nodes.set (&box, move (cow_node_state));
23
- return *cow_node_state_ptr;
15
+ if (m_lookup_cache.box == &box && m_lookup_cache.is_mutable )
16
+ return *m_lookup_cache.state ;
17
+
18
+ auto & node_state = [&]() -> NodeState& {
19
+ if (auto it = nodes.find (&box); it != nodes.end ())
20
+ return *it->value ;
21
+
22
+ for (auto const * ancestor = m_parent; ancestor; ancestor = ancestor->m_parent ) {
23
+ if (auto it = ancestor->nodes .find (&box); it != ancestor->nodes .end ()) {
24
+ auto cow_node_state = adopt_own (*new NodeState (*it->value ));
25
+ auto * cow_node_state_ptr = cow_node_state.ptr ();
26
+ nodes.set (&box, move (cow_node_state));
27
+ return *cow_node_state_ptr;
28
+ }
24
29
}
25
- }
26
30
27
- return *nodes.ensure (&box, [] { return adopt_own (*new NodeState); });
31
+ return *nodes.ensure (&box, [] { return adopt_own (*new NodeState); });
32
+ }();
33
+
34
+ m_lookup_cache = LookupCache { .box = &box, .state = &node_state, .is_mutable = true };
35
+
36
+ return node_state;
28
37
}
29
38
30
39
FormattingState::NodeState const & FormattingState::get (NodeWithStyleAndBoxModelMetrics const & box) const
31
40
{
32
- if (auto it = nodes. find (& box); it != nodes. end () )
33
- return *it-> value ;
41
+ if (m_lookup_cache. box == &box )
42
+ return *m_lookup_cache. state ;
34
43
35
- for ( auto * ancestor = m_parent; ancestor; ancestor = ancestor-> m_parent ) {
36
- if (auto it = ancestor-> nodes .find (&box); it != ancestor-> nodes .end ())
44
+ auto & node_state = [&]() -> NodeState const & {
45
+ if (auto it = nodes.find (&box); it != nodes.end ())
37
46
return *it->value ;
38
- }
39
47
40
- return *const_cast <FormattingState&>(*this ).nodes .ensure (&box, [] { return adopt_own (*new NodeState); });
48
+ for (auto * ancestor = m_parent; ancestor; ancestor = ancestor->m_parent ) {
49
+ if (auto it = ancestor->nodes .find (&box); it != ancestor->nodes .end ())
50
+ return *it->value ;
51
+ }
52
+ return *const_cast <FormattingState&>(*this ).nodes .ensure (&box, [] { return adopt_own (*new NodeState); });
53
+ }();
54
+
55
+ const_cast <FormattingState*>(this )->m_lookup_cache = LookupCache { .box = &box, .state = const_cast <NodeState*>(&node_state), .is_mutable = false };
56
+ return node_state;
41
57
}
42
58
43
59
void FormattingState::commit ()
0 commit comments