mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:17:45 +00:00
LibWeb: Add a 1-entry lookup cache to FormattingState
This makes repeated lookups of the state for the same box much faster by bypassing the HashMap.
This commit is contained in:
parent
e7370443f2
commit
83a6be593c
2 changed files with 39 additions and 16 deletions
|
@ -12,32 +12,48 @@ namespace Web::Layout {
|
||||||
|
|
||||||
FormattingState::NodeState& FormattingState::get_mutable(NodeWithStyleAndBoxModelMetrics const& box)
|
FormattingState::NodeState& FormattingState::get_mutable(NodeWithStyleAndBoxModelMetrics const& box)
|
||||||
{
|
{
|
||||||
if (auto it = nodes.find(&box); it != nodes.end())
|
if (m_lookup_cache.box == &box && m_lookup_cache.is_mutable)
|
||||||
return *it->value;
|
return *m_lookup_cache.state;
|
||||||
|
|
||||||
for (auto* ancestor = m_parent; ancestor; ancestor = ancestor->m_parent) {
|
auto& node_state = [&]() -> NodeState& {
|
||||||
if (auto it = ancestor->nodes.find(&box); it != ancestor->nodes.end()) {
|
if (auto it = nodes.find(&box); it != nodes.end())
|
||||||
auto cow_node_state = adopt_own(*new NodeState(*it->value));
|
return *it->value;
|
||||||
auto* cow_node_state_ptr = cow_node_state.ptr();
|
|
||||||
nodes.set(&box, move(cow_node_state));
|
for (auto const* ancestor = m_parent; ancestor; ancestor = ancestor->m_parent) {
|
||||||
return *cow_node_state_ptr;
|
if (auto it = ancestor->nodes.find(&box); it != ancestor->nodes.end()) {
|
||||||
|
auto cow_node_state = adopt_own(*new NodeState(*it->value));
|
||||||
|
auto* cow_node_state_ptr = cow_node_state.ptr();
|
||||||
|
nodes.set(&box, move(cow_node_state));
|
||||||
|
return *cow_node_state_ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return *nodes.ensure(&box, [] { return adopt_own(*new NodeState); });
|
return *nodes.ensure(&box, [] { return adopt_own(*new NodeState); });
|
||||||
|
}();
|
||||||
|
|
||||||
|
m_lookup_cache = LookupCache { .box = &box, .state = &node_state, .is_mutable = true };
|
||||||
|
|
||||||
|
return node_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormattingState::NodeState const& FormattingState::get(NodeWithStyleAndBoxModelMetrics const& box) const
|
FormattingState::NodeState const& FormattingState::get(NodeWithStyleAndBoxModelMetrics const& box) const
|
||||||
{
|
{
|
||||||
if (auto it = nodes.find(&box); it != nodes.end())
|
if (m_lookup_cache.box == &box)
|
||||||
return *it->value;
|
return *m_lookup_cache.state;
|
||||||
|
|
||||||
for (auto* ancestor = m_parent; ancestor; ancestor = ancestor->m_parent) {
|
auto& node_state = [&]() -> NodeState const& {
|
||||||
if (auto it = ancestor->nodes.find(&box); it != ancestor->nodes.end())
|
if (auto it = nodes.find(&box); it != nodes.end())
|
||||||
return *it->value;
|
return *it->value;
|
||||||
}
|
|
||||||
|
|
||||||
return *const_cast<FormattingState&>(*this).nodes.ensure(&box, [] { return adopt_own(*new NodeState); });
|
for (auto* ancestor = m_parent; ancestor; ancestor = ancestor->m_parent) {
|
||||||
|
if (auto it = ancestor->nodes.find(&box); it != ancestor->nodes.end())
|
||||||
|
return *it->value;
|
||||||
|
}
|
||||||
|
return *const_cast<FormattingState&>(*this).nodes.ensure(&box, [] { return adopt_own(*new NodeState); });
|
||||||
|
}();
|
||||||
|
|
||||||
|
const_cast<FormattingState*>(this)->m_lookup_cache = LookupCache { .box = &box, .state = const_cast<NodeState*>(&node_state), .is_mutable = false };
|
||||||
|
return node_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormattingState::commit()
|
void FormattingState::commit()
|
||||||
|
|
|
@ -111,6 +111,13 @@ struct FormattingState {
|
||||||
|
|
||||||
FormattingState const* m_parent { nullptr };
|
FormattingState const* m_parent { nullptr };
|
||||||
FormattingState const& m_root;
|
FormattingState const& m_root;
|
||||||
|
|
||||||
|
struct LookupCache {
|
||||||
|
NodeWithStyleAndBoxModelMetrics const* box { nullptr };
|
||||||
|
NodeState* state { nullptr };
|
||||||
|
bool is_mutable { false };
|
||||||
|
};
|
||||||
|
LookupCache m_lookup_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
Gfx::FloatRect absolute_content_rect(Box const&, FormattingState const&);
|
Gfx::FloatRect absolute_content_rect(Box const&, FormattingState const&);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue