mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 17:40:27 +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
Notes:
sideshowbarker
2024-07-17 09:38:35 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/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)
|
||||
{
|
||||
if (auto it = nodes.find(&box); it != nodes.end())
|
||||
return *it->value;
|
||||
if (m_lookup_cache.box == &box && m_lookup_cache.is_mutable)
|
||||
return *m_lookup_cache.state;
|
||||
|
||||
for (auto* ancestor = m_parent; ancestor; ancestor = ancestor->m_parent) {
|
||||
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;
|
||||
auto& node_state = [&]() -> NodeState& {
|
||||
if (auto it = nodes.find(&box); it != nodes.end())
|
||||
return *it->value;
|
||||
|
||||
for (auto const* ancestor = m_parent; ancestor; ancestor = ancestor->m_parent) {
|
||||
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
|
||||
{
|
||||
if (auto it = nodes.find(&box); it != nodes.end())
|
||||
return *it->value;
|
||||
if (m_lookup_cache.box == &box)
|
||||
return *m_lookup_cache.state;
|
||||
|
||||
for (auto* ancestor = m_parent; ancestor; ancestor = ancestor->m_parent) {
|
||||
if (auto it = ancestor->nodes.find(&box); it != ancestor->nodes.end())
|
||||
auto& node_state = [&]() -> NodeState const& {
|
||||
if (auto it = nodes.find(&box); it != nodes.end())
|
||||
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()
|
||||
|
|
|
@ -111,6 +111,13 @@ struct FormattingState {
|
|||
|
||||
FormattingState const* m_parent { nullptr };
|
||||
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&);
|
||||
|
|
Loading…
Reference in a new issue