Skip to content

Commit 184448a

Browse files
committed
perf(OverlayObjectImpl): fold empty overlays
1 parent 12ceade commit 184448a

File tree

1 file changed

+102
-6
lines changed

1 file changed

+102
-6
lines changed

src/lib/Support/Handlebars.cpp

Lines changed: 102 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,55 @@ isEmpty(dom::Value const& arg)
8989

9090
class OverlayObjectImpl : public dom::ObjectImpl
9191
{
92+
std::vector<dom::Object> grandParents_;
9293
dom::Object parent_;
9394
dom::Object child_;
9495

9596
public:
9697
~OverlayObjectImpl() override = default;
9798

9899
OverlayObjectImpl(dom::Object parent)
99-
: parent_(std::move(parent))
100-
{}
100+
{
101+
auto* parImpl = parent.impl().get();
102+
auto* parOverlay = dynamic_cast<OverlayObjectImpl*>(parImpl);
103+
if (parOverlay == nullptr)
104+
{
105+
parent_ = std::move(parent);
106+
}
107+
else if (parOverlay->child_.empty())
108+
{
109+
grandParents_ = parOverlay->grandParents_;
110+
parent_ = parOverlay->parent_;
111+
}
112+
else
113+
{
114+
grandParents_.push_back(parOverlay->parent_);
115+
grandParents_.insert(
116+
grandParents_.end(),
117+
parOverlay->grandParents_.begin(),
118+
parOverlay->grandParents_.end());
119+
parent_ = parOverlay->child_;
120+
}
121+
}
101122

102123
OverlayObjectImpl(dom::Object child, dom::Object parent)
103-
: parent_(std::move(parent))
104-
, child_(std::move(child))
105-
{}
124+
: OverlayObjectImpl(std::move(parent))
125+
{
126+
child_ = std::move(child);
127+
auto* childOverlay = dynamic_cast<OverlayObjectImpl*>(child_.impl().get());
128+
if (childOverlay != nullptr)
129+
{
130+
grandParents_.insert(
131+
grandParents_.begin(),
132+
parent_);
133+
grandParents_.insert(
134+
grandParents_.end(),
135+
childOverlay->grandParents_.begin(),
136+
childOverlay->grandParents_.end());
137+
parent_ = childOverlay->parent_;
138+
child_ = childOverlay->child_;
139+
}
140+
}
106141

107142
std::size_t size() const override
108143
{
@@ -113,6 +148,17 @@ class OverlayObjectImpl : public dom::ObjectImpl
113148
{
114149
--n;
115150
}
151+
else
152+
{
153+
for (auto const& grandParent : grandParents_)
154+
{
155+
if (grandParent.exists(key))
156+
{
157+
--n;
158+
break;
159+
}
160+
}
161+
}
116162
});
117163
return n;
118164
};
@@ -127,6 +173,13 @@ class OverlayObjectImpl : public dom::ObjectImpl
127173
{
128174
return parent_.get(key);
129175
}
176+
for (auto const& grandParent : grandParents_)
177+
{
178+
if (grandParent.exists(key))
179+
{
180+
return grandParent.get(key);
181+
}
182+
}
130183
return dom::Kind::Undefined;
131184
}
132185

@@ -154,12 +207,55 @@ class OverlayObjectImpl : public dom::ObjectImpl
154207
{
155208
return false;
156209
}
210+
211+
for (std::size_t i = 0; i < grandParents_.size(); ++i)
212+
{
213+
auto visit_if_not_in_prev = [&](
214+
dom::String const& key, dom::Value const& value)
215+
{
216+
if (child_.exists(key))
217+
{
218+
return true;
219+
}
220+
if (parent_.exists(key))
221+
{
222+
return true;
223+
}
224+
for (std::size_t j = 0; j < i; ++j)
225+
{
226+
if (grandParents_[j].exists(key))
227+
{
228+
return true;
229+
}
230+
}
231+
return fn(key, value);
232+
};
233+
if (!grandParents_[i].visit(visit_if_not_in_prev))
234+
{
235+
return false;
236+
}
237+
}
157238
return true;
158239
}
159240

160241
bool exists(std::string_view key) const override
161242
{
162-
return child_.exists(key) || parent_.exists(key);
243+
if (child_.exists(key))
244+
{
245+
return true;
246+
}
247+
if (parent_.exists(key))
248+
{
249+
return true;
250+
}
251+
for (auto const& grandParent : grandParents_)
252+
{
253+
if (grandParent.exists(key))
254+
{
255+
return true;
256+
}
257+
}
258+
return false;
163259
}
164260
};
165261

0 commit comments

Comments
 (0)