Commit eba04950 by Maarten L. Hekkelman

Optimised erase II

parent 0c70df27
...@@ -411,13 +411,13 @@ namespace detail ...@@ -411,13 +411,13 @@ namespace detail
{ {
and_condition_impl(condition &&a, condition &&b) and_condition_impl(condition &&a, condition &&b)
{ {
mSub.emplace_back(std::exchange(a.m_impl, nullptr)); m_sub.emplace_back(std::exchange(a.m_impl, nullptr));
mSub.emplace_back(std::exchange(b.m_impl, nullptr)); m_sub.emplace_back(std::exchange(b.m_impl, nullptr));
} }
~and_condition_impl() ~and_condition_impl()
{ {
for (auto sub : mSub) for (auto sub : m_sub)
delete sub; delete sub;
} }
...@@ -427,7 +427,7 @@ namespace detail ...@@ -427,7 +427,7 @@ namespace detail
{ {
bool result = true; bool result = true;
for (auto sub : mSub) for (auto sub : m_sub)
{ {
if (sub->test(r)) if (sub->test(r))
continue; continue;
...@@ -444,7 +444,7 @@ namespace detail ...@@ -444,7 +444,7 @@ namespace detail
os << '('; os << '(';
bool first = true; bool first = true;
for (auto sub : mSub) for (auto sub : m_sub)
{ {
if (first) if (first)
first = false; first = false;
...@@ -461,7 +461,7 @@ namespace detail ...@@ -461,7 +461,7 @@ namespace detail
{ {
std::optional<row_handle> result; std::optional<row_handle> result;
for (auto sub : mSub) for (auto sub : m_sub)
{ {
auto s = sub->single(); auto s = sub->single();
...@@ -481,56 +481,97 @@ namespace detail ...@@ -481,56 +481,97 @@ namespace detail
return result; return result;
} }
std::vector<condition_impl *> mSub; std::vector<condition_impl *> m_sub;
}; };
struct or_condition_impl : public condition_impl struct or_condition_impl : public condition_impl
{ {
or_condition_impl(condition &&a, condition &&b) or_condition_impl(condition &&a, condition &&b)
: mA(nullptr)
, mB(nullptr)
{ {
std::swap(mA, a.m_impl); if (typeid(*a.m_impl) == typeid(*this))
std::swap(mB, b.m_impl); {
or_condition_impl *ai = static_cast<or_condition_impl *>(a.m_impl);
std::swap(m_sub, ai->m_sub);
m_sub.emplace_back(std::exchange(b.m_impl, nullptr));
}
else if (typeid(*b.m_impl) == typeid(*this))
{
or_condition_impl *bi = static_cast<or_condition_impl *>(b.m_impl);
std::swap(m_sub, bi->m_sub);
m_sub.emplace_back(std::exchange(a.m_impl, nullptr));
}
else
{
m_sub.emplace_back(std::exchange(a.m_impl, nullptr));
m_sub.emplace_back(std::exchange(b.m_impl, nullptr));
}
} }
~or_condition_impl() ~or_condition_impl()
{ {
delete mA; for (auto sub : m_sub)
delete mB; delete sub;
} }
condition_impl *prepare(const category &c) override; condition_impl *prepare(const category &c) override;
bool test(row_handle r) const override bool test(row_handle r) const override
{ {
return mA->test(r) or mB->test(r); bool result = false;
for (auto sub : m_sub)
{
if (not sub->test(r))
continue;
result = true;
break;
}
return result;
} }
void str(std::ostream &os) const override void str(std::ostream &os) const override
{ {
bool first = true;
for (auto sub : m_sub)
{
if (first)
first = false;
else
os << " OR ";
os << '('; os << '(';
mA->str(os); sub->str(os);
os << ") OR (";
mB->str(os);
os << ')'; os << ')';
} }
}
virtual std::optional<row_handle> single() const override virtual std::optional<row_handle> single() const override
{ {
auto sa = mA->single(); std::optional<row_handle> result;
auto sb = mB->single();
for (auto sub : m_sub)
{
auto s = sub->single();
if (not result.has_value())
{
result = s;
continue;
}
if (s == result)
continue;
if (sa.has_value() and sb.has_value() and sa != sb) result.reset();
sa.reset(); break;
else if (not sa.has_value()) }
sa = sb;
return sa; return result;
} }
condition_impl *mA; std::vector<condition_impl *> m_sub;
condition_impl *mB;
}; };
struct not_condition_impl : public condition_impl struct not_condition_impl : public condition_impl
......
...@@ -78,21 +78,21 @@ namespace detail ...@@ -78,21 +78,21 @@ namespace detail
condition_impl *and_condition_impl::prepare(const category &c) condition_impl *and_condition_impl::prepare(const category &c)
{ {
for (auto &sub : mSub) for (auto &sub : m_sub)
sub = sub->prepare(c); sub = sub->prepare(c);
for (;;) for (;;)
{ {
auto si = find_if(mSub.begin(), mSub.end(), [](condition_impl *sub) { return dynamic_cast<and_condition_impl *>(sub) != nullptr; }); auto si = find_if(m_sub.begin(), m_sub.end(), [](condition_impl *sub) { return dynamic_cast<and_condition_impl *>(sub) != nullptr; });
if (si == mSub.end()) if (si == m_sub.end())
break; break;
and_condition_impl *sub_and = static_cast<and_condition_impl *>(*si); and_condition_impl *sub_and = static_cast<and_condition_impl *>(*si);
mSub.erase(si); m_sub.erase(si);
mSub.insert(mSub.end(), sub_and->mSub.begin(), sub_and->mSub.end()); m_sub.insert(m_sub.end(), sub_and->m_sub.begin(), sub_and->m_sub.end());
sub_and->mSub.clear(); sub_and->m_sub.clear();
delete sub_and; delete sub_and;
} }
...@@ -103,16 +103,21 @@ namespace detail ...@@ -103,16 +103,21 @@ namespace detail
{ {
condition_impl *result = this; condition_impl *result = this;
mA = mA->prepare(c); for (auto &sub : m_sub)
mB = mB->prepare(c); sub = sub->prepare(c);
if (m_sub.size() == 2)
{
auto a = m_sub.front();
auto b = m_sub.back();
key_equals_condition_impl *equals = dynamic_cast<key_equals_condition_impl*>(mA); key_equals_condition_impl *equals = dynamic_cast<key_equals_condition_impl*>(a);
key_is_empty_condition_impl *empty = dynamic_cast<key_is_empty_condition_impl*>(mB); key_is_empty_condition_impl *empty = dynamic_cast<key_is_empty_condition_impl*>(b);
if (equals == nullptr and empty == nullptr) if (equals == nullptr and empty == nullptr)
{ {
equals = dynamic_cast<key_equals_condition_impl*>(mB); equals = dynamic_cast<key_equals_condition_impl*>(b);
empty = dynamic_cast<key_is_empty_condition_impl*>(mA); empty = dynamic_cast<key_is_empty_condition_impl*>(a);
} }
if (equals != nullptr and empty != nullptr and equals->m_item_tag == empty->m_item_tag) if (equals != nullptr and empty != nullptr and equals->m_item_tag == empty->m_item_tag)
...@@ -121,6 +126,7 @@ namespace detail ...@@ -121,6 +126,7 @@ namespace detail
result = result->prepare(c); result = result->prepare(c);
delete this; delete this;
} }
}
return result; return result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment