From ef3aadfd69600e6f48bb42366d909ed57c4e6a9b Mon Sep 17 00:00:00 2001 From: madschemas <155993105+MadSchemas@users.noreply.github.com> Date: Fri, 16 Aug 2024 12:19:12 +0300 Subject: [PATCH] [fix] Reduce expression tree stack --- .../comparator/comparator_indexed.cc | 109 +++--- .../comparator/comparator_indexed.h | 321 +++--------------- .../comparator/comparator_indexed_distinct.h | 6 +- .../comparator/comparator_not_indexed.cc | 9 +- .../comparator/comparator_not_indexed.h | 239 ++++++++----- .../comparator_not_indexed_distinct.h | 31 +- .../comparator/equalposition_comparator.cc | 15 +- .../comparator/equalposition_comparator.h | 46 ++- .../equalposition_comparator_impl.h | 81 +++-- .../nsselecter/comparator/fieldscomparator.cc | 8 +- .../nsselecter/comparator/fieldscomparator.h | 31 +- .../nsselecter/selectiteratorcontainer.cc | 56 ++- cpp_src/estl/charset.h | 2 +- cpp_src/estl/intrusive_ptr.h | 38 ++- 14 files changed, 471 insertions(+), 521 deletions(-) diff --git a/cpp_src/core/nsselecter/comparator/comparator_indexed.cc b/cpp_src/core/nsselecter/comparator/comparator_indexed.cc index d6b6ace4d..513c81ac8 100644 --- a/cpp_src/core/nsselecter/comparator/comparator_indexed.cc +++ b/cpp_src/core/nsselecter/comparator/comparator_indexed.cc @@ -103,10 +103,6 @@ void initComparator(const reindexer::VariantArray& from, typename reindexer::com template void initComparator(CondType cond, const reindexer::VariantArray& from, reindexer::comparators::DataHolder& to) { using namespace reindexer::comparators; - using SingleType = typename DataHolder::SingleType; - using RangeType = typename DataHolder::RangeType; - using SetPtrType = typename DataHolder::SetPtrType; - using AllSetPtrType = typename DataHolder::AllSetPtrType; using SetWrpType = typename DataHolder::SetWrpType; using AllSetWrpType = typename DataHolder::AllSetWrpType; switch (cond) { @@ -118,17 +114,15 @@ void initComparator(CondType cond, const reindexer::VariantArray& from, reindexe to.value_ = GetValue(cond, from, 0); break; case CondRange: - to.value_.~SingleType(); - new (&to.range_) RangeType{GetValue(cond, from, 0), GetValue(cond, from, 1)}; + to.value_ = GetValue(cond, from, 0); + to.value2_ = GetValue(cond, from, 1); break; case CondSet: - to.value_.~SingleType(); - new (&to.setPtr_) SetPtrType{make_intrusive()}; + to.setPtr_ = make_intrusive(); initComparator(from, *to.setPtr_); break; case CondAllSet: - to.value_.~SingleType(); - new (&to.allSetPtr_) AllSetPtrType{make_intrusive()}; + to.allSetPtr_ = make_intrusive(); initComparator(from, *to.allSetPtr_); break; case CondAny: @@ -143,12 +137,8 @@ void initComparator(CondType cond, const reindexer::VariantArray& from, reindexe void initStringComparator(CondType cond, const reindexer::VariantArray& from, reindexer::comparators::DataHolder& to, const CollateOpts& collate) { using namespace reindexer::comparators; - using SingleType = DataHolder::SingleType; - using RangeType = DataHolder::RangeType; using SetType = DataHolder::SetType; using AllSetType = DataHolder::AllSetType; - using SetPtrType = DataHolder::SetPtrType; - using AllSetPtrType = DataHolder::AllSetPtrType; using SetWrpType = DataHolder::SetWrpType; using AllSetWrpType = DataHolder::AllSetWrpType; switch (cond) { @@ -161,17 +151,15 @@ void initStringComparator(CondType cond, const reindexer::VariantArray& from, re to.value_ = GetValue(cond, from, 0); break; case CondRange: - to.value_.~SingleType(); - new (&to.range_) RangeType{GetValue(cond, from, 0), GetValue(cond, from, 1)}; + to.value_ = GetValue(cond, from, 0); + to.value2_ = GetValue(cond, from, 1); break; case CondSet: - to.value_.~SingleType(); - new (&to.setPtr_) SetPtrType{make_intrusive(SetType{collate})}; + to.setPtr_ = make_intrusive(SetType{collate}); initComparator(from, *to.setPtr_); break; case CondAllSet: - to.value_.~SingleType(); - new (&to.allSetPtr_) AllSetPtrType{make_intrusive(AllSetType{collate, {}})}; + to.allSetPtr_ = make_intrusive(AllSetType{collate, {}}); initComparator(from, *to.allSetPtr_); break; case CondAny: @@ -185,13 +173,8 @@ void initStringComparator(CondType cond, const reindexer::VariantArray& from, re template [[nodiscard]] std::string comparatorCondStr(const V& values) { using namespace std::string_literals; - if constexpr (Cond == CondRange) { - if constexpr (std::is_same_v) { - return fmt::sprintf("RANGE(%s, %s)", values.value1_.valueView_, values.value2_.valueView_); - } else { - return fmt::format("RANGE({}, {})", values.first, values.second); - } - } else if constexpr (Cond == CondSet) { + static_assert(Cond != CondRange, "Incorrect specialization"); + if constexpr (Cond == CondSet) { if (values.empty()) { return "IN []"s; } else { @@ -205,12 +188,25 @@ template } } else if constexpr (Cond == CondEq || Cond == CondLt || Cond == CondLe || Cond == CondGt || Cond == CondGe) { if constexpr (std::is_same_v) { - return fmt::sprintf("%s %s", reindexer::comparators::CondToStr(), values.valueView_); + return fmt::format("{} {}", reindexer::comparators::CondToStr(), values.valueView_); } else { return fmt::format("{} {}", reindexer::comparators::CondToStr(), values); } } else if constexpr (Cond == CondLike && std::is_same_v) { - return fmt::sprintf("LIKE \"%s\"", values.valueView_); + return fmt::format("LIKE \"{}\"", values.valueView_); + } + abort(); +} + +template +[[nodiscard]] std::string comparatorCondStr(const V& value, const V& value2) { + using namespace std::string_literals; + if constexpr (Cond == CondRange) { + if constexpr (std::is_same_v) { + return fmt::format("RANGE({}, {})", value.valueView_, value2.valueView_); + } else { + return fmt::format("RANGE({}, {})", value, value2); + } } abort(); } @@ -229,7 +225,7 @@ template case CondGe: return comparatorCondStr(data.value_); case CondRange: - return comparatorCondStr(data.range_); + return comparatorCondStr(data.value_, data.value2_); case CondSet: assertrx_dbg(data.setPtr_); return comparatorCondStr(*data.setPtr_); @@ -251,27 +247,33 @@ template const typename reindexer::comparators::ValuesHolder::Type& values, const reindexer::PayloadType& payloadType, const reindexer::FieldsSet& fields) { using namespace std::string_literals; - if constexpr (Cond == CondRange) { - return fmt::sprintf("RANGE(%s, %s)", reindexer::Variant{values.first}.As(payloadType, fields), - reindexer::Variant{values.second}.As(payloadType, fields)); - } else if constexpr (Cond == CondSet) { + static_assert(Cond != CondRange, "Incorrect specialization"); + if constexpr (Cond == CondSet) { if (values.empty()) { return "IN []"s; } else { - return fmt::sprintf("IN [%s, ...]", reindexer::Variant{*values.begin()}.As(payloadType, fields)); + return fmt::format("IN [{}, ...]", reindexer::Variant{*values.begin()}.As(payloadType, fields)); } } else if constexpr (Cond == CondAllSet) { if (values.values_.empty()) { return "ALLSET []"s; } else { - return fmt::sprintf("ALLSET [%s, ...]", reindexer::Variant{values.values_.begin()->first}.As(payloadType, fields)); + return fmt::format("ALLSET [{}, ...]", reindexer::Variant{values.values_.begin()->first}.As(payloadType, fields)); } } else if constexpr (Cond == CondEq || Cond == CondLt || Cond == CondLe || Cond == CondGt || Cond == CondGe) { - return fmt::sprintf("%s %s", reindexer::comparators::CondToStr(), - reindexer::Variant{values}.As(payloadType, fields)); + return fmt::format("{} {}", reindexer::comparators::CondToStr(), + reindexer::Variant{values}.As(payloadType, fields)); } } +template +[[nodiscard]] std::string compositeRangeComparatorCondStr(const V& value, const V& value2, const reindexer::PayloadType& payloadType, + const reindexer::FieldsSet& fields) { + using namespace std::string_literals; + return fmt::format("RANGE({}, {})", reindexer::Variant{value}.As(payloadType, fields), + reindexer::Variant{value2}.As(payloadType, fields)); +} + [[nodiscard]] std::string anyComparatorCondStr() { using namespace std::string_literals; return "IS NOT NULL"s; @@ -483,7 +485,7 @@ ComparatorIndexedJsonPathStringDistinct::ComparatorIndexedJsonPathStringDistinct ComparatorIndexedComposite::ComparatorIndexedComposite(const VariantArray& values, const CollateOpts& collate, const FieldsSet& fields, const PayloadType& payloadType, CondType cond) - : collateOpts_{&collate}, fields_{fields}, payloadType_{payloadType} { + : collateOpts_{&collate}, fields_{make_intrusive(fields)}, payloadType_{payloadType} { switch (cond) { case CondEq: case CondLt: @@ -493,19 +495,16 @@ ComparatorIndexedComposite::ComparatorIndexedComposite(const VariantArray& value value_ = GetValue(cond, values, 0); break; case CondRange: - value_.~PayloadValue(); - new (&range_) RangeType{GetValue(cond, values, 0), GetValue(cond, values, 1)}; + value_ = GetValue(cond, values, 0); + value2_ = GetValue(cond, values, 1); break; case CondSet: - value_.~PayloadValue(); - new (&setPtr_) SetPtrType{make_intrusive(SetType{values.size(), reindexer::hash_composite_ref{payloadType, fields}, - reindexer::equal_composite_ref{payloadType, fields}})}; + setPtr_ = make_intrusive(SetType{values.size(), reindexer::hash_composite_ref{payloadType, fields}, + reindexer::equal_composite_ref{payloadType, fields}}); initComparator(values, *setPtr_); break; case CondAllSet: - value_.~PayloadValue(); - new (&allSetPtr_) AllSetPtrType{ - make_intrusive(AllSetType{{reindexer::PayloadType{payloadType}, reindexer::FieldsSet{fields}}, {}})}; + allSetPtr_ = make_intrusive(AllSetType{{reindexer::PayloadType{payloadType}, reindexer::FieldsSet{fields}}, {}}); initComparator(values, *allSetPtr_); break; case CondAny: @@ -520,23 +519,23 @@ ComparatorIndexedComposite::ComparatorIndexedComposite(const VariantArray& value [[nodiscard]] std::string ComparatorIndexedComposite::ConditionStr() const { switch (cond_) { case CondEq: - return compositeComparatorCondStr(value_, payloadType_, fields_); + return compositeComparatorCondStr(value_, payloadType_, *fields_); case CondLt: - return compositeComparatorCondStr(value_, payloadType_, fields_); + return compositeComparatorCondStr(value_, payloadType_, *fields_); case CondLe: - return compositeComparatorCondStr(value_, payloadType_, fields_); + return compositeComparatorCondStr(value_, payloadType_, *fields_); case CondGt: - return compositeComparatorCondStr(value_, payloadType_, fields_); + return compositeComparatorCondStr(value_, payloadType_, *fields_); case CondGe: - return compositeComparatorCondStr(value_, payloadType_, fields_); + return compositeComparatorCondStr(value_, payloadType_, *fields_); case CondRange: - return compositeComparatorCondStr(range_, payloadType_, fields_); + return compositeRangeComparatorCondStr(value_, value2_, payloadType_, *fields_); case CondSet: assertrx_dbg(setPtr_); - return compositeComparatorCondStr(*setPtr_, payloadType_, fields_); + return compositeComparatorCondStr(*setPtr_, payloadType_, *fields_); case CondAllSet: assertrx_dbg(allSetPtr_); - return compositeComparatorCondStr(*allSetPtr_, payloadType_, fields_); + return compositeComparatorCondStr(*allSetPtr_, payloadType_, *fields_); case CondLike: case CondAny: case CondEmpty: diff --git a/cpp_src/core/nsselecter/comparator/comparator_indexed.h b/cpp_src/core/nsselecter/comparator/comparator_indexed.h index 2f78efd8b..254dbf02e 100644 --- a/cpp_src/core/nsselecter/comparator/comparator_indexed.h +++ b/cpp_src/core/nsselecter/comparator/comparator_indexed.h @@ -15,7 +15,6 @@ #include "estl/fast_hash_set.h" #include "helpers.h" #include "tools/string_regexp_functions.h" -#include "vendor/sparse-map/sparse_set.h" namespace reindexer { @@ -51,41 +50,14 @@ struct ValuesHolder { }; }; -// TODO: fast_hash_map here somehow causes crashes in the centos 7 asan CI builds -template -using LowSparsityMap = tsl::sparse_map, std::allocator>, - tsl::sh::power_of_two_growth_policy<2>, tsl::sh::exception_safety::basic, tsl::sh::sparsity::low>; - -template -using LowSparsitySet = tsl::sparse_set, std::allocator, tsl::sh::power_of_two_growth_policy<2>, - tsl::sh::exception_safety::basic, tsl::sh::sparsity::low>; - template struct ValuesHolder { - using Type = std::pair; -}; - -template <> -struct ValuesHolder { - struct Type { - ValuesHolder::Type value1_; - ValuesHolder::Type value2_; - }; -}; - -template <> -struct ValuesHolder { - using Type = LowSparsitySet>; -}; - -template <> -struct ValuesHolder { - using Type = LowSparsitySet>; + // Empty }; template struct ValuesHolder { - using Type = LowSparsitySet>; + using Type = fast_hash_set; }; template <> @@ -98,26 +70,10 @@ struct ValuesHolder { using Type = unordered_payload_ref_set; }; -template <> -struct ValuesHolder { - struct Type { - LowSparsityMap> values_; - fast_hash_set allSetValues_; - }; -}; - -template <> -struct ValuesHolder { - struct Type { - LowSparsityMap> values_; - fast_hash_set allSetValues_; - }; -}; - template struct ValuesHolder { struct Type { - LowSparsityMap> values_; + fast_hash_map values_; fast_hash_set allSetValues_; }; }; @@ -141,7 +97,6 @@ struct ValuesHolder { template struct DataHolder { using SingleType = typename ValuesHolder::Type; - using RangeType = typename ValuesHolder::Type; using SetType = typename ValuesHolder::Type; using SetWrpType = intrusive_rc_wrapper; using SetPtrType = intrusive_ptr; @@ -149,188 +104,16 @@ struct DataHolder { using AllSetWrpType = intrusive_rc_wrapper; using AllSetPtrType = intrusive_ptr; - DataHolder() noexcept : cond_{CondEq}, value_{} {} - DataHolder(DataHolder&& other) noexcept : cond_{other.cond_} { - switch (other.cond_) { - case CondEq: - case CondLt: - case CondLe: - case CondGt: - case CondGe: - case CondLike: - new (&this->value_) SingleType{std::move(other.value_)}; - break; - case CondRange: - new (&this->range_) RangeType{std::move(other.range_)}; - break; - case CondSet: - new (&this->setPtr_) SetPtrType{std::move(other.setPtr_)}; - break; - case CondAllSet: - new (&this->allSetPtr_) AllSetPtrType{std::move(other.allSetPtr_)}; - break; - case CondAny: - case CondEmpty: - case CondDWithin: - new (&this->value_) SingleType{}; - break; - } - } - DataHolder(const DataHolder& other) : cond_{CondAny} { - switch (other.cond_) { - case CondEq: - case CondLt: - case CondLe: - case CondGt: - case CondGe: - case CondLike: - new (&this->value_) SingleType{other.value_}; - break; - case CondRange: - new (&this->range_) RangeType{other.range_}; - break; - case CondSet: - new (&this->setPtr_) SetPtrType{other.setPtr_}; - break; - case CondAllSet: - new (&this->allSetPtr_) AllSetPtrType{other.allSetPtr_}; - break; - case CondAny: - case CondEmpty: - case CondDWithin: - new (&this->value_) SingleType{}; - break; - } - cond_ = other.cond_; - } - DataHolder& operator=(DataHolder&& other) noexcept { - if (this == &other) { - return *this; - } - if (cond_ != other.cond_) { - clear(); - switch (other.cond_) { - case CondEq: - case CondLt: - case CondLe: - case CondGt: - case CondGe: - case CondLike: - new (&this->value_) SingleType{std::move(other.value_)}; - break; - case CondRange: - new (&this->range_) RangeType{std::move(other.range_)}; - break; - case CondSet: - new (&this->setPtr_) SetPtrType{std::move(other.setPtr_)}; - break; - case CondAllSet: - new (&this->allSetPtr_) AllSetPtrType{std::move(other.allSetPtr_)}; - break; - case CondAny: - case CondEmpty: - case CondDWithin: - break; - } - this->cond_ = other.cond_; - } else { - switch (other.cond_) { - case CondEq: - case CondLt: - case CondLe: - case CondGt: - case CondGe: - case CondLike: - this->value_ = std::move(other.value_); - break; - case CondRange: - this->range_ = std::move(other.range_); - break; - case CondSet: - this->setPtr_ = std::move(other.setPtr_); - break; - case CondAllSet: - this->allSetPtr_ = std::move(other.allSetPtr_); - break; - case CondAny: - case CondEmpty: - case CondDWithin: - break; - } - } - return *this; - } - DataHolder& operator=(const DataHolder& other) { - if (this == &other) { - return *this; - } - if (cond_ != other.cond_) { - clear(); - switch (other.cond_) { - case CondEq: - case CondLt: - case CondLe: - case CondGt: - case CondGe: - case CondLike: - new (&this->value_) SingleType{other.value_}; - break; - case CondRange: - new (&this->range_) RangeType{other.range_}; - break; - case CondSet: - new (&this->setPtr_) SetPtrType{other.setPtr_}; - break; - case CondAllSet: - new (&this->allSetPtr_) AllSetPtrType{other.allSetPtr_}; - break; - case CondAny: - case CondEmpty: - case CondDWithin: - break; - } - this->cond_ = other.cond_; - } else { - DataHolder tmp{other}; - *this = std::move(tmp); - } - return *this; - } - ~DataHolder() { clear(); } - void clear() noexcept { - switch (cond_) { - case CondEq: - case CondLt: - case CondLe: - case CondGt: - case CondGe: - case CondLike: - value_.~SingleType(); - break; - case CondRange: - range_.~RangeType(); - break; - case CondSet: - setPtr_.~SetPtrType(); - break; - case CondAllSet: - allSetPtr_.~AllSetPtrType(); - break; - case CondDWithin: - case CondAny: - case CondEmpty: - default: - break; - } - cond_ = CondAny; - } + DataHolder() noexcept : cond_{CondEq} {} + DataHolder(DataHolder&& other) noexcept = default; + DataHolder(const DataHolder& other) = default; + DataHolder& operator=(DataHolder&& other) noexcept = default; + DataHolder& operator=(const DataHolder& other) = default; CondType cond_; - union { - SingleType value_; - RangeType range_; - SetPtrType setPtr_; - AllSetPtrType allSetPtr_; - }; + SingleType value_{}; // Either single value or right range boundry + SingleType value2_{}; // Left range boundry + SetPtrType setPtr_{}; + AllSetPtrType allSetPtr_{}; }; template @@ -351,7 +134,7 @@ class ComparatorIndexedOffsetScalar : private DataHolder { case CondGe: return *ptr >= this->value_; case CondRange: - return this->range_.first <= *ptr && *ptr <= this->range_.second; + return this->value_ <= *ptr && *ptr <= this->value2_; case CondSet: assertrx_dbg(this->setPtr_); return this->setPtr_->find(*ptr) != this->setPtr_->cend(); @@ -393,7 +176,7 @@ class ComparatorIndexedColumnScalar : private DataHolder { case CondGe: return v >= this->value_; case CondRange: - return this->range_.first <= v && v <= this->range_.second; + return this->value_ <= v && v <= this->value2_; case CondSet: assertrx_dbg(this->setPtr_); return this->setPtr_->find(v) != this->setPtr_->cend(); @@ -435,7 +218,7 @@ class ComparatorIndexedOffsetScalarDistinct : private DataHolder { case CondGe: return value >= this->value_ && distinct_.Compare(value); case CondRange: - return this->range_.first <= value && value <= this->range_.second && distinct_.Compare(value); + return this->value_ <= value && value <= this->value2_ && distinct_.Compare(value); case CondSet: assertrx_dbg(this->setPtr_); return this->setPtr_->find(value) != this->setPtr_->cend() && distinct_.Compare(value); @@ -481,7 +264,7 @@ class ComparatorIndexedColumnScalarDistinct : private DataHolder { case CondGe: return value >= this->value_ && distinct_.Compare(value); case CondRange: - return this->range_.first <= value && value <= this->range_.second && distinct_.Compare(value); + return this->value_ <= value && value <= this->value2_ && distinct_.Compare(value); case CondSet: assertrx_dbg(this->setPtr_); return this->setPtr_->find(value) != this->setPtr_->cend() && distinct_.Compare(value); @@ -546,7 +329,7 @@ class ComparatorIndexedOffsetArray : private DataHolder { } continue; case CondRange: - if (this->range_.first <= *ptr && *ptr <= this->range_.second) { + if (this->value_ <= *ptr && *ptr <= this->value2_) { return true; } continue; @@ -625,7 +408,7 @@ class ComparatorIndexedOffsetArrayDistinct : private DataHolder { } continue; case CondRange: - if (this->range_.first <= *ptr && *ptr <= this->range_.second && distinct_.Compare(*ptr)) { + if (this->value_ <= *ptr && *ptr <= this->value2_ && distinct_.Compare(*ptr)) { return true; } continue; @@ -720,7 +503,7 @@ class ComparatorIndexedJsonPath : private DataHolder { continue; case CondRange: { const auto v = value.As(); - if (this->range_.first <= v && v <= this->range_.second) { + if (this->value_ <= v && v <= this->value2_) { return true; } } @@ -810,7 +593,7 @@ class ComparatorIndexedJsonPathDistinct : private DataHolder { continue; case CondRange: { const auto v = value; - if (this->range_.first <= v && v <= this->range_.second && distinct_.Compare(value)) { + if (this->value_ <= v && v <= this->value2_ && distinct_.Compare(value)) { return true; } } @@ -875,8 +658,8 @@ class ComparatorIndexedOffsetScalarString : private DataHolder { assertrx_dbg(this->setPtr_); return setPtr_->find(value) != setPtr_->cend(); case CondRange: - return (collateCompare(value, range_.value1_.valueView_, *collateOpts_) & ComparationResult::Ge) && - (collateCompare(value, range_.value2_.valueView_, *collateOpts_) & ComparationResult::Le); + return (collateCompare(value, value_.valueView_, *collateOpts_) & ComparationResult::Ge) && + (collateCompare(value, value2_.valueView_, *collateOpts_) & ComparationResult::Le); case CondAllSet: assertrx_dbg(this->allSetPtr_); return allSetPtr_->values_.size() == 1 && allSetPtr_->values_.find(value) != allSetPtr_->values_.cend(); @@ -920,8 +703,8 @@ class ComparatorIndexedColumnScalarString : private DataHolder { assertrx_dbg(this->setPtr_); return setPtr_->find(value) != setPtr_->cend(); case CondRange: - return (collateCompare(value, range_.value1_.valueView_, *collateOpts_) & ComparationResult::Ge) && - (collateCompare(value, range_.value2_.valueView_, *collateOpts_) & ComparationResult::Le); + return (collateCompare(value, value_.valueView_, *collateOpts_) & ComparationResult::Ge) && + (collateCompare(value, value2_.valueView_, *collateOpts_) & ComparationResult::Le); case CondAllSet: assertrx_dbg(this->allSetPtr_); return allSetPtr_->values_.size() == 1 && allSetPtr_->values_.find(value) != allSetPtr_->values_.cend(); @@ -964,9 +747,8 @@ class ComparatorIndexedOffsetScalarStringDistinct : private DataHoldersetPtr_); return setPtr_->find(value) != setPtr_->cend() && distinct_.Compare(value); case CondRange: - return (collateCompare(value, range_.value1_.valueView_, *collateOpts_) & ComparationResult::Ge) && - (collateCompare(value, range_.value2_.valueView_, *collateOpts_) & ComparationResult::Le) && - distinct_.Compare(value); + return (collateCompare(value, value_.valueView_, *collateOpts_) & ComparationResult::Ge) && + (collateCompare(value, value2_.valueView_, *collateOpts_) & ComparationResult::Le) && distinct_.Compare(value); case CondAllSet: assertrx_dbg(this->allSetPtr_); return allSetPtr_->values_.size() == 1 && allSetPtr_->values_.find(value) != allSetPtr_->values_.cend() && @@ -1013,9 +795,8 @@ class ComparatorIndexedColumnScalarStringDistinct : private DataHoldersetPtr_); return setPtr_->find(value) != setPtr_->cend() && distinct_.Compare(value); case CondRange: - return (collateCompare(value, range_.value1_.valueView_, *collateOpts_) & ComparationResult::Ge) && - (collateCompare(value, range_.value2_.valueView_, *collateOpts_) & ComparationResult::Le) && - distinct_.Compare(value); + return (collateCompare(value, value_.valueView_, *collateOpts_) & ComparationResult::Ge) && + (collateCompare(value, value2_.valueView_, *collateOpts_) & ComparationResult::Le) && distinct_.Compare(value); case CondAllSet: assertrx_dbg(this->allSetPtr_); return allSetPtr_->values_.size() == 1 && allSetPtr_->values_.find(value) != allSetPtr_->values_.cend() && @@ -1069,8 +850,8 @@ class ComparatorIndexedOffsetArrayString : private DataHolder { } continue; case CondRange: - if ((collateCompare(value, range_.value1_.valueView_, *collateOpts_) & ComparationResult::Ge) && - (collateCompare(value, range_.value2_.valueView_, *collateOpts_) & ComparationResult::Le)) { + if ((collateCompare(value, value_.valueView_, *collateOpts_) & ComparationResult::Ge) && + (collateCompare(value, value2_.valueView_, *collateOpts_) & ComparationResult::Le)) { return true; } continue; @@ -1154,9 +935,8 @@ class ComparatorIndexedOffsetArrayStringDistinct : private DataHolder { } break; case CondRange: - if ((collateCompare(value, range_.value1_.valueView_, *collateOpts_) & ComparationResult::Ge) && - (collateCompare(value, range_.value2_.valueView_, *collateOpts_) & ComparationResult::Le)) { + if ((collateCompare(value, value_.valueView_, *collateOpts_) & ComparationResult::Ge) && + (collateCompare(value, value2_.valueView_, *collateOpts_) & ComparationResult::Le)) { return true; } break; @@ -1339,9 +1119,8 @@ class ComparatorIndexedJsonPathStringDistinct : private DataHolder { } break; case CondRange: - if ((collateCompare(value, range_.value1_.valueView_, *collateOpts_) & ComparationResult::Ge) && - (collateCompare(value, range_.value2_.valueView_, *collateOpts_) & ComparationResult::Le) && - distinct_.Compare(value)) { + if ((collateCompare(value, value_.valueView_, *collateOpts_) & ComparationResult::Ge) && + (collateCompare(value, value2_.valueView_, *collateOpts_) & ComparationResult::Le) && distinct_.Compare(value)) { return true; } break; @@ -1427,26 +1206,26 @@ class ComparatorIndexedComposite : private DataHolder { return setPtr_->find(item) != setPtr_->cend(); case CondRange: { ConstPayload pv{payloadType_, item}; - return (pv.Compare(range_.first, fields_, *collateOpts_) & ComparationResult::Ge) && - (pv.Compare(range_.second, fields_, *collateOpts_) & ComparationResult::Le); + return (pv.Compare(value_, *fields_, *collateOpts_) & ComparationResult::Ge) && + (pv.Compare(value2_, *fields_, *collateOpts_) & ComparationResult::Le); } case CondAllSet: assertrx_dbg(this->allSetPtr_); return allSetPtr_->values_.size() == 1 && allSetPtr_->values_.find(item) != allSetPtr_->values_.end(); case CondEq: - return ConstPayload{payloadType_, item}.Compare(value_, fields_, *collateOpts_) == + return ConstPayload{payloadType_, item}.Compare(value_, *fields_, *collateOpts_) == ComparationResult::Eq; case CondLt: - return ConstPayload{payloadType_, item}.Compare(value_, fields_, *collateOpts_) == + return ConstPayload{payloadType_, item}.Compare(value_, *fields_, *collateOpts_) == ComparationResult::Lt; case CondLe: - return ConstPayload{payloadType_, item}.Compare(value_, fields_, *collateOpts_) & + return ConstPayload{payloadType_, item}.Compare(value_, *fields_, *collateOpts_) & ComparationResult::Le; case CondGt: - return ConstPayload{payloadType_, item}.Compare(value_, fields_, *collateOpts_) == + return ConstPayload{payloadType_, item}.Compare(value_, *fields_, *collateOpts_) == ComparationResult::Gt; case CondGe: - return ConstPayload{payloadType_, item}.Compare(value_, fields_, *collateOpts_) & + return ConstPayload{payloadType_, item}.Compare(value_, *fields_, *collateOpts_) & ComparationResult::Ge; case CondAny: case CondEmpty: @@ -1462,8 +1241,11 @@ class ComparatorIndexedComposite : private DataHolder { void ClearDistinctValues() const noexcept {} private: + // Using pointer for cheap copying and ExpressionTree size reduction + using FieldsSetWrp = intrusive_rc_wrapper; + const CollateOpts* collateOpts_; - FieldsSet fields_; + intrusive_ptr fields_; PayloadType payloadType_; }; @@ -1514,7 +1296,7 @@ class ComparatorIndexedOffsetArrayDWithinDistinct { void ClearDistinctValues() noexcept { distinct_.ClearValues(); } private: - ComparatorIndexedDistinct distinct_; + ComparatorIndexedDistinct> distinct_; Point point_; double distance_; size_t offset_; @@ -1569,7 +1351,7 @@ class ComparatorIndexedJsonPathDWithinDistinct { void ClearDistinctValues() noexcept { distinct_.ClearValues(); } private: - ComparatorIndexedDistinct distinct_; + ComparatorIndexedDistinct> distinct_; PayloadType payloadType_; TagsPath tagsPath_; VariantArray buffer_; @@ -1674,7 +1456,10 @@ class ComparatorIndexedOffsetArrayAnyDistinct { void ClearDistinctValues() noexcept { distinct_.ClearValues(); } private: - ComparatorIndexedDistinct distinct_; + using ComparatoristincType = std::conditional_t, ComparatorIndexedDistinct>, + ComparatorIndexedDistinct>; + + ComparatoristincType distinct_; size_t offset_; }; diff --git a/cpp_src/core/nsselecter/comparator/comparator_indexed_distinct.h b/cpp_src/core/nsselecter/comparator/comparator_indexed_distinct.h index 615443cb9..5a0fd6ae9 100644 --- a/cpp_src/core/nsselecter/comparator/comparator_indexed_distinct.h +++ b/cpp_src/core/nsselecter/comparator/comparator_indexed_distinct.h @@ -2,15 +2,14 @@ #include #include -#include #include +#include "estl/fast_hash_set.h" #include "tools/stringstools.h" -#include "vendor/hopscotch/hopscotch_sc_set.h" namespace reindexer { -template +template > class ComparatorIndexedDistinct { public: ComparatorIndexedDistinct() : values_{make_intrusive()} {} @@ -28,7 +27,6 @@ class ComparatorIndexedDistinct { } private: - using SetType = std::unordered_set; using SetWrpType = intrusive_rc_wrapper; using SetPtrType = intrusive_ptr; diff --git a/cpp_src/core/nsselecter/comparator/comparator_not_indexed.cc b/cpp_src/core/nsselecter/comparator/comparator_not_indexed.cc index ce24c7ddc..1f9350ed1 100644 --- a/cpp_src/core/nsselecter/comparator/comparator_not_indexed.cc +++ b/cpp_src/core/nsselecter/comparator/comparator_not_indexed.cc @@ -76,12 +76,13 @@ template } // namespace comparators [[nodiscard]] std::string ComparatorNotIndexed::ConditionStr() const { - return std::visit([&](const auto& impl) { return impl.ConditionStr(); }, impl_); + assertrx_dbg(dynamic_cast(impl_.get())); + return std::visit([&](const auto& impl) { return impl.ConditionStr(); }, *static_cast(impl_.get())); } -comparators::ComparatorNotIndexedVariant ComparatorNotIndexed::createImpl(CondType cond, const VariantArray& values, - const PayloadType& payloadType, const TagsPath& fieldPath, - bool distinct) { +ComparatorNotIndexed::ImplVariantType ComparatorNotIndexed::createImpl(CondType cond, const VariantArray& values, + const PayloadType& payloadType, const TagsPath& fieldPath, + bool distinct) { using namespace comparators; if (distinct) { switch (cond) { diff --git a/cpp_src/core/nsselecter/comparator/comparator_not_indexed.h b/cpp_src/core/nsselecter/comparator/comparator_not_indexed.h index 149fc9e1d..097dff18f 100644 --- a/cpp_src/core/nsselecter/comparator/comparator_not_indexed.h +++ b/cpp_src/core/nsselecter/comparator/comparator_not_indexed.h @@ -1,6 +1,5 @@ #pragma once -#include #include "comparator_not_indexed_distinct.h" #include "const.h" #include "core/keyvalue/geometry.h" @@ -19,6 +18,11 @@ template class ComparatorNotIndexedImplBase { protected: ComparatorNotIndexedImplBase(const VariantArray&); + ComparatorNotIndexedImplBase(const ComparatorNotIndexedImplBase&) = delete; + ComparatorNotIndexedImplBase& operator=(const ComparatorNotIndexedImplBase&) = delete; + ComparatorNotIndexedImplBase(ComparatorNotIndexedImplBase&&) = default; + ComparatorNotIndexedImplBase& operator=(ComparatorNotIndexedImplBase&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const Variant& v) const { if constexpr (Cond == CondEq) { @@ -44,6 +48,11 @@ template <> class ComparatorNotIndexedImplBase { protected: ComparatorNotIndexedImplBase(const VariantArray&); + ComparatorNotIndexedImplBase(const ComparatorNotIndexedImplBase&) = delete; + ComparatorNotIndexedImplBase& operator=(const ComparatorNotIndexedImplBase&) = delete; + ComparatorNotIndexedImplBase(ComparatorNotIndexedImplBase&&) = default; + ComparatorNotIndexedImplBase& operator=(ComparatorNotIndexedImplBase&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const Variant& v) const { return (v.RelaxCompare(value1_) & ComparationResult::Ge) && @@ -62,6 +71,11 @@ class ComparatorNotIndexedImplBase { values_.insert(v); } } + ComparatorNotIndexedImplBase(const ComparatorNotIndexedImplBase&) = delete; + ComparatorNotIndexedImplBase& operator=(const ComparatorNotIndexedImplBase&) = delete; + ComparatorNotIndexedImplBase(ComparatorNotIndexedImplBase&&) = default; + ComparatorNotIndexedImplBase& operator=(ComparatorNotIndexedImplBase&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const Variant& v) const { return values_.find(v) != values_.cend(); } @@ -75,6 +89,11 @@ template <> class ComparatorNotIndexedImplBase { protected: ComparatorNotIndexedImplBase(const VariantArray&); + ComparatorNotIndexedImplBase(const ComparatorNotIndexedImplBase&) = delete; + ComparatorNotIndexedImplBase& operator=(const ComparatorNotIndexedImplBase&) = delete; + ComparatorNotIndexedImplBase(ComparatorNotIndexedImplBase&&) = default; + ComparatorNotIndexedImplBase& operator=(ComparatorNotIndexedImplBase&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const Variant& v) const { if (!v.Type().Is()) { @@ -98,6 +117,11 @@ class ComparatorNotIndexedImpl : private ComparatorNotIndexedImplBa public: ComparatorNotIndexedImpl(const VariantArray& values, const PayloadType& payloadType, const TagsPath& fieldPath) : Base{values}, payloadType_{payloadType}, fieldPath_{fieldPath} {} + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { ConstPayload{payloadType_, item}.GetByJsonPath(fieldPath_, buffer_, KeyValueType::Undefined{}); for (const Variant& v : buffer_) { @@ -125,6 +149,11 @@ class ComparatorNotIndexedImpl : private ComparatorNotIndexedImplBas public: ComparatorNotIndexedImpl(const VariantArray& values, const PayloadType& payloadType, const TagsPath& fieldPath) : Base{values}, distinct_{}, payloadType_{payloadType}, fieldPath_{fieldPath} {} + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { ConstPayload{payloadType_, item}.GetByJsonPath(fieldPath_, buffer_, KeyValueType::Undefined{}); for (const Variant& v : buffer_) { @@ -156,6 +185,11 @@ class ComparatorNotIndexedImpl { public: ComparatorNotIndexedImpl(const PayloadType& payloadType, const TagsPath& fieldPath) : payloadType_{payloadType}, fieldPath_{fieldPath} {} + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { ConstPayload{payloadType_, item}.GetByJsonPath(fieldPath_, buffer_, KeyValueType::Undefined{}); @@ -181,6 +215,11 @@ class ComparatorNotIndexedImpl { public: ComparatorNotIndexedImpl(const PayloadType& payloadType, const TagsPath& fieldPath) : payloadType_{payloadType}, fieldPath_{fieldPath} {} + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { ConstPayload{payloadType_, item}.GetByJsonPath(fieldPath_, buffer_, KeyValueType::Undefined{}); @@ -212,6 +251,11 @@ class ComparatorNotIndexedImpl { public: ComparatorNotIndexedImpl(const PayloadType& payloadType, const TagsPath& fieldPath) : payloadType_{payloadType}, fieldPath_{fieldPath} {} + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { ConstPayload{payloadType_, item}.GetByJsonPath(fieldPath_, buffer_, KeyValueType::Undefined{}); @@ -238,6 +282,11 @@ class ComparatorNotIndexedImpl : private ComparatorNotIndexedIm public: ComparatorNotIndexedImpl(const PayloadType& payloadType, const TagsPath& fieldPath) : Base{payloadType, fieldPath} {} + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] bool IsDistinct() const noexcept { return true; } using Base::ClearDistinctValues; using Base::ExcludeDistinctValues; @@ -249,6 +298,11 @@ template <> class ComparatorNotIndexedImpl { public: ComparatorNotIndexedImpl(const VariantArray& values, const PayloadType& payloadType, const TagsPath& fieldPath); + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { ConstPayload{payloadType_, item}.GetByJsonPath(fieldPath_, buffer_, KeyValueType::Undefined{}); @@ -276,6 +330,11 @@ class ComparatorNotIndexedImpl : private ComparatorNotIndexed public: ComparatorNotIndexedImpl(const VariantArray& values, const PayloadType& payloadType, const TagsPath& fieldPath) : Base{values, payloadType, fieldPath} {} + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { ConstPayload{payloadType_, item}.GetByJsonPath(fieldPath_, buffer_, KeyValueType::Undefined{}); if (buffer_.size() != 2 || !buffer_[0].Type().Is() || !buffer_[0].Type().Is()) { @@ -311,6 +370,11 @@ class ComparatorNotIndexedImpl { ++i; } } + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] std::string ConditionStr() const; [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { allSetValues_.clear(); @@ -337,7 +401,7 @@ class ComparatorNotIndexedImpl { MultiHashMap::indexesCount, RelaxedHasher, RelaxedComparator> values_; - std::unordered_set allSetValues_; + fast_hash_set allSetValues_; }; template <> @@ -347,6 +411,11 @@ class ComparatorNotIndexedImpl : private ComparatorNotIndexedI public: ComparatorNotIndexedImpl(const VariantArray& values, const PayloadType& payloadType, const TagsPath& fieldPath) : Base{values, payloadType, fieldPath} {} + ComparatorNotIndexedImpl(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl& operator=(const ComparatorNotIndexedImpl&) = delete; + ComparatorNotIndexedImpl(ComparatorNotIndexedImpl&&) = default; + ComparatorNotIndexedImpl& operator=(ComparatorNotIndexedImpl&&) = default; + [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType /*rowId*/) { allSetValues_.clear(); ConstPayload{payloadType_, item}.GetByJsonPath(fieldPath_, buffer_, KeyValueType::Undefined{}); @@ -384,13 +453,17 @@ using ComparatorNotIndexedVariant = std::variant< ComparatorNotIndexedImpl, ComparatorNotIndexedImpl, ComparatorNotIndexedImpl, ComparatorNotIndexedImpl, ComparatorNotIndexedImpl, ComparatorNotIndexedImpl, ComparatorNotIndexedImpl, ComparatorNotIndexedImpl, ComparatorNotIndexedImpl>; + +using ComparatorNotIndexedVariantWrp = intrusive_rc_wrapper; + } // namespace comparators class ComparatorNotIndexed { public: ComparatorNotIndexed(std::string_view fieldName, CondType cond, const VariantArray& values, const PayloadType& payloadType, const TagsPath& fieldPath, bool distinct) - : impl_{createImpl(cond, values, payloadType, fieldPath, distinct)}, fieldName_{fieldName} {} + : impl_{make_intrusive(createImpl(cond, values, payloadType, fieldPath, distinct))}, + fieldName_{fieldName} {} [[nodiscard]] const std::string& Name() const& noexcept { return fieldName_; } auto Name() const&& = delete; [[nodiscard]] std::string ConditionStr() const; @@ -405,78 +478,78 @@ class ComparatorNotIndexed { [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const PayloadValue& item, IdType rowId) { static_assert(std::variant_size_v == 24); bool res; - switch (impl_.index()) { + switch (impl_->index()) { case 0: - res = std::get_if<0>(&impl_)->Compare(item, rowId); + res = std::get_if<0>(impl_.get())->Compare(item, rowId); break; case 1: - res = std::get_if<1>(&impl_)->Compare(item, rowId); + res = std::get_if<1>(impl_.get())->Compare(item, rowId); break; case 2: - res = std::get_if<2>(&impl_)->Compare(item, rowId); + res = std::get_if<2>(impl_.get())->Compare(item, rowId); break; case 3: - res = std::get_if<3>(&impl_)->Compare(item, rowId); + res = std::get_if<3>(impl_.get())->Compare(item, rowId); break; case 4: - res = std::get_if<4>(&impl_)->Compare(item, rowId); + res = std::get_if<4>(impl_.get())->Compare(item, rowId); break; case 5: - res = std::get_if<5>(&impl_)->Compare(item, rowId); + res = std::get_if<5>(impl_.get())->Compare(item, rowId); break; case 6: - res = std::get_if<6>(&impl_)->Compare(item, rowId); + res = std::get_if<6>(impl_.get())->Compare(item, rowId); break; case 7: - res = std::get_if<7>(&impl_)->Compare(item, rowId); + res = std::get_if<7>(impl_.get())->Compare(item, rowId); break; case 8: - res = std::get_if<8>(&impl_)->Compare(item, rowId); + res = std::get_if<8>(impl_.get())->Compare(item, rowId); break; case 9: - res = std::get_if<9>(&impl_)->Compare(item, rowId); + res = std::get_if<9>(impl_.get())->Compare(item, rowId); break; case 10: - res = std::get_if<10>(&impl_)->Compare(item, rowId); + res = std::get_if<10>(impl_.get())->Compare(item, rowId); break; case 11: - res = std::get_if<11>(&impl_)->Compare(item, rowId); + res = std::get_if<11>(impl_.get())->Compare(item, rowId); break; case 12: - res = std::get_if<12>(&impl_)->Compare(item, rowId); + res = std::get_if<12>(impl_.get())->Compare(item, rowId); break; case 13: - res = std::get_if<13>(&impl_)->Compare(item, rowId); + res = std::get_if<13>(impl_.get())->Compare(item, rowId); break; case 14: - res = std::get_if<14>(&impl_)->Compare(item, rowId); + res = std::get_if<14>(impl_.get())->Compare(item, rowId); break; case 15: - res = std::get_if<15>(&impl_)->Compare(item, rowId); + res = std::get_if<15>(impl_.get())->Compare(item, rowId); break; case 16: - res = std::get_if<16>(&impl_)->Compare(item, rowId); + res = std::get_if<16>(impl_.get())->Compare(item, rowId); break; case 17: - res = std::get_if<17>(&impl_)->Compare(item, rowId); + res = std::get_if<17>(impl_.get())->Compare(item, rowId); break; case 18: - res = std::get_if<18>(&impl_)->Compare(item, rowId); + res = std::get_if<18>(impl_.get())->Compare(item, rowId); break; case 19: - res = std::get_if<19>(&impl_)->Compare(item, rowId); + res = std::get_if<19>(impl_.get())->Compare(item, rowId); break; case 20: - res = std::get_if<20>(&impl_)->Compare(item, rowId); + res = std::get_if<20>(impl_.get())->Compare(item, rowId); break; case 21: - res = std::get_if<21>(&impl_)->Compare(item, rowId); + res = std::get_if<21>(impl_.get())->Compare(item, rowId); break; case 22: - res = std::get_if<22>(&impl_)->Compare(item, rowId); + res = std::get_if<22>(impl_.get())->Compare(item, rowId); break; case 23: - res = std::get_if<23>(&impl_)->Compare(item, rowId); + res = std::get_if<23>(impl_.get())->Compare(item, rowId); break; default: abort(); @@ -486,122 +559,124 @@ class ComparatorNotIndexed { } void ClearDistinctValues() noexcept { static_assert(std::variant_size_v == 24); - switch (impl_.index()) { + switch (impl_->index()) { case 0: - return std::get_if<0>(&impl_)->ClearDistinctValues(); + return std::get_if<0>(impl_.get())->ClearDistinctValues(); case 1: - return std::get_if<1>(&impl_)->ClearDistinctValues(); + return std::get_if<1>(impl_.get())->ClearDistinctValues(); case 2: - return std::get_if<2>(&impl_)->ClearDistinctValues(); + return std::get_if<2>(impl_.get())->ClearDistinctValues(); case 3: - return std::get_if<3>(&impl_)->ClearDistinctValues(); + return std::get_if<3>(impl_.get())->ClearDistinctValues(); case 4: - return std::get_if<4>(&impl_)->ClearDistinctValues(); + return std::get_if<4>(impl_.get())->ClearDistinctValues(); case 5: - return std::get_if<5>(&impl_)->ClearDistinctValues(); + return std::get_if<5>(impl_.get())->ClearDistinctValues(); case 6: - return std::get_if<6>(&impl_)->ClearDistinctValues(); + return std::get_if<6>(impl_.get())->ClearDistinctValues(); case 7: - return std::get_if<7>(&impl_)->ClearDistinctValues(); + return std::get_if<7>(impl_.get())->ClearDistinctValues(); case 8: - return std::get_if<8>(&impl_)->ClearDistinctValues(); + return std::get_if<8>(impl_.get())->ClearDistinctValues(); case 9: - return std::get_if<9>(&impl_)->ClearDistinctValues(); + return std::get_if<9>(impl_.get())->ClearDistinctValues(); case 10: - return std::get_if<10>(&impl_)->ClearDistinctValues(); + return std::get_if<10>(impl_.get())->ClearDistinctValues(); case 11: - return std::get_if<11>(&impl_)->ClearDistinctValues(); + return std::get_if<11>(impl_.get())->ClearDistinctValues(); case 12: - return std::get_if<12>(&impl_)->ClearDistinctValues(); + return std::get_if<12>(impl_.get())->ClearDistinctValues(); case 13: - return std::get_if<13>(&impl_)->ClearDistinctValues(); + return std::get_if<13>(impl_.get())->ClearDistinctValues(); case 14: - return std::get_if<14>(&impl_)->ClearDistinctValues(); + return std::get_if<14>(impl_.get())->ClearDistinctValues(); case 15: - return std::get_if<15>(&impl_)->ClearDistinctValues(); + return std::get_if<15>(impl_.get())->ClearDistinctValues(); case 16: - return std::get_if<16>(&impl_)->ClearDistinctValues(); + return std::get_if<16>(impl_.get())->ClearDistinctValues(); case 17: - return std::get_if<17>(&impl_)->ClearDistinctValues(); + return std::get_if<17>(impl_.get())->ClearDistinctValues(); case 18: - return std::get_if<18>(&impl_)->ClearDistinctValues(); + return std::get_if<18>(impl_.get())->ClearDistinctValues(); case 19: - return std::get_if<19>(&impl_)->ClearDistinctValues(); + return std::get_if<19>(impl_.get())->ClearDistinctValues(); case 20: - return std::get_if<20>(&impl_)->ClearDistinctValues(); + return std::get_if<20>(impl_.get())->ClearDistinctValues(); case 21: - return std::get_if<21>(&impl_)->ClearDistinctValues(); + return std::get_if<21>(impl_.get())->ClearDistinctValues(); case 22: - return std::get_if<22>(&impl_)->ClearDistinctValues(); + return std::get_if<22>(impl_.get())->ClearDistinctValues(); case 23: - return std::get_if<23>(&impl_)->ClearDistinctValues(); + return std::get_if<23>(impl_.get())->ClearDistinctValues(); default: abort(); } } void ExcludeDistinctValues(const PayloadValue& item, IdType rowId) { static_assert(std::variant_size_v == 24); - switch (impl_.index()) { + switch (impl_->index()) { case 0: - return std::get_if<0>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<0>(impl_.get())->ExcludeDistinctValues(item, rowId); case 1: - return std::get_if<1>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<1>(impl_.get())->ExcludeDistinctValues(item, rowId); case 2: - return std::get_if<2>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<2>(impl_.get())->ExcludeDistinctValues(item, rowId); case 3: - return std::get_if<3>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<3>(impl_.get())->ExcludeDistinctValues(item, rowId); case 4: - return std::get_if<4>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<4>(impl_.get())->ExcludeDistinctValues(item, rowId); case 5: - return std::get_if<5>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<5>(impl_.get())->ExcludeDistinctValues(item, rowId); case 6: - return std::get_if<6>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<6>(impl_.get())->ExcludeDistinctValues(item, rowId); case 7: - return std::get_if<7>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<7>(impl_.get())->ExcludeDistinctValues(item, rowId); case 8: - return std::get_if<8>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<8>(impl_.get())->ExcludeDistinctValues(item, rowId); case 9: - return std::get_if<9>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<9>(impl_.get())->ExcludeDistinctValues(item, rowId); case 10: - return std::get_if<10>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<10>(impl_.get())->ExcludeDistinctValues(item, rowId); case 11: - return std::get_if<11>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<11>(impl_.get())->ExcludeDistinctValues(item, rowId); case 12: - return std::get_if<12>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<12>(impl_.get())->ExcludeDistinctValues(item, rowId); case 13: - return std::get_if<13>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<13>(impl_.get())->ExcludeDistinctValues(item, rowId); case 14: - return std::get_if<14>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<14>(impl_.get())->ExcludeDistinctValues(item, rowId); case 15: - return std::get_if<15>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<15>(impl_.get())->ExcludeDistinctValues(item, rowId); case 16: - return std::get_if<16>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<16>(impl_.get())->ExcludeDistinctValues(item, rowId); case 17: - return std::get_if<17>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<17>(impl_.get())->ExcludeDistinctValues(item, rowId); case 18: - return std::get_if<18>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<18>(impl_.get())->ExcludeDistinctValues(item, rowId); case 19: - return std::get_if<19>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<19>(impl_.get())->ExcludeDistinctValues(item, rowId); case 20: - return std::get_if<20>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<20>(impl_.get())->ExcludeDistinctValues(item, rowId); case 21: - return std::get_if<21>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<21>(impl_.get())->ExcludeDistinctValues(item, rowId); case 22: - return std::get_if<22>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<22>(impl_.get())->ExcludeDistinctValues(item, rowId); case 23: - return std::get_if<23>(&impl_)->ExcludeDistinctValues(item, rowId); + return std::get_if<23>(impl_.get())->ExcludeDistinctValues(item, rowId); default: abort(); } } [[nodiscard]] bool IsDistinct() const noexcept { - return std::visit([](auto& impl) { return impl.IsDistinct(); }, impl_); + assertrx_dbg(dynamic_cast(impl_.get())); + return std::visit([](auto& impl) { return impl.IsDistinct(); }, *static_cast(impl_.get())); } private: - static comparators::ComparatorNotIndexedVariant createImpl(CondType, const VariantArray& values, const PayloadType&, const TagsPath&, - bool distinct); - comparators::ComparatorNotIndexedVariant impl_; + using ImplVariantType = comparators::ComparatorNotIndexedVariant; + static ImplVariantType createImpl(CondType, const VariantArray& values, const PayloadType&, const TagsPath&, bool distinct); + // Using pointer to reduce ExpressionTree Node size + intrusive_ptr impl_; int matchedCount_{0}; bool isNotOperation_{false}; std::string fieldName_; diff --git a/cpp_src/core/nsselecter/comparator/comparator_not_indexed_distinct.h b/cpp_src/core/nsselecter/comparator/comparator_not_indexed_distinct.h index e41f790f4..fa00b3095 100644 --- a/cpp_src/core/nsselecter/comparator/comparator_not_indexed_distinct.h +++ b/cpp_src/core/nsselecter/comparator/comparator_not_indexed_distinct.h @@ -1,33 +1,26 @@ #pragma once -#include -#include #include "core/keyvalue/variant.h" +#include "estl/fast_hash_set.h" namespace reindexer { class ComparatorNotIndexedDistinct { public: - ComparatorNotIndexedDistinct() : values_{make_intrusive()} {} - [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const Variant& v) const { - assertrx_dbg(values_); - return values_->find(v) == values_->cend(); - } - void ExcludeValues(Variant&& v) { - assertrx_dbg(values_); - values_->emplace(std::move(v)); - } - void ClearValues() noexcept { - assertrx_dbg(values_); - values_->clear(); - } + ComparatorNotIndexedDistinct() = default; + ComparatorNotIndexedDistinct(const ComparatorNotIndexedDistinct&) = delete; + ComparatorNotIndexedDistinct& operator=(const ComparatorNotIndexedDistinct&) = delete; + ComparatorNotIndexedDistinct(ComparatorNotIndexedDistinct&&) = default; + ComparatorNotIndexedDistinct& operator=(ComparatorNotIndexedDistinct&&) = default; + + [[nodiscard]] RX_ALWAYS_INLINE bool Compare(const Variant& v) const { return values_.find(v) == values_.cend(); } + void ExcludeValues(Variant&& v) { values_.emplace(std::move(v)); } + void ClearValues() noexcept { values_.clear(); } private: - using SetType = std::unordered_set; - using SetWrpType = intrusive_rc_wrapper; - using SetPtrType = intrusive_ptr; + using SetType = fast_hash_set; - SetPtrType values_; + SetType values_; }; } // namespace reindexer diff --git a/cpp_src/core/nsselecter/comparator/equalposition_comparator.cc b/cpp_src/core/nsselecter/comparator/equalposition_comparator.cc index e280835c2..4cd3e775e 100644 --- a/cpp_src/core/nsselecter/comparator/equalposition_comparator.cc +++ b/cpp_src/core/nsselecter/comparator/equalposition_comparator.cc @@ -6,18 +6,19 @@ namespace reindexer { -void EqualPositionComparator::BindField(const std::string& name, int field, const VariantArray& values, CondType cond, - const CollateOpts& collate) { +void EqualPositionComparatorImpl::BindField(const std::string& name, int field, const VariantArray& values, CondType cond, + const CollateOpts& collate) { bindField(name, field, values, cond, collate); } -void EqualPositionComparator::BindField(const std::string& name, const FieldsPath& fieldPath, const VariantArray& values, CondType cond) { +void EqualPositionComparatorImpl::BindField(const std::string& name, const FieldsPath& fieldPath, const VariantArray& values, + CondType cond) { bindField(name, fieldPath, values, cond, CollateOpts{}); } template -void EqualPositionComparator::bindField(const std::string& name, F field, const VariantArray& values, CondType cond, - const CollateOpts& collate) { +void EqualPositionComparatorImpl::bindField(const std::string& name, F field, const VariantArray& values, CondType cond, + const CollateOpts& collate) { fields_.push_back(field); Context& ctx = ctx_.emplace_back(collate); @@ -33,7 +34,7 @@ void EqualPositionComparator::bindField(const std::string& name, F field, const name_ += ' ' + name; } -bool EqualPositionComparator::Compare(const PayloadValue& pv, IdType /*rowId*/) { +bool EqualPositionComparatorImpl::Compare(const PayloadValue& pv, IdType /*rowId*/) { ConstPayload pl(payloadType_, pv); size_t len = INT_MAX; @@ -72,7 +73,7 @@ bool EqualPositionComparator::Compare(const PayloadValue& pv, IdType /*rowId*/) return false; } -bool EqualPositionComparator::compareField(size_t field, const Variant& v) { +bool EqualPositionComparatorImpl::compareField(size_t field, const Variant& v) { return v.Type().EvaluateOneOf( [&](KeyValueType::Bool) { return ctx_[field].cmpBool.Compare(ctx_[field].cond, static_cast(v)); }, [&](KeyValueType::Int) { return ctx_[field].cmpInt.Compare(ctx_[field].cond, static_cast(v)); }, diff --git a/cpp_src/core/nsselecter/comparator/equalposition_comparator.h b/cpp_src/core/nsselecter/comparator/equalposition_comparator.h index cefde2e48..f5942efcc 100644 --- a/cpp_src/core/nsselecter/comparator/equalposition_comparator.h +++ b/cpp_src/core/nsselecter/comparator/equalposition_comparator.h @@ -7,9 +7,13 @@ namespace reindexer { -class EqualPositionComparator { +class EqualPositionComparatorImpl : public intrusive_rc_base { public: - EqualPositionComparator(const PayloadType& payloadType) : payloadType_{payloadType}, name_{"EqualPositions"} {} + EqualPositionComparatorImpl(const PayloadType& payloadType) : payloadType_{payloadType}, name_{"EqualPositions"} {} + EqualPositionComparatorImpl(const EqualPositionComparatorImpl&) = delete; + EqualPositionComparatorImpl(EqualPositionComparatorImpl&&) = delete; + EqualPositionComparatorImpl& operator=(const EqualPositionComparatorImpl&) = delete; + EqualPositionComparatorImpl& operator=(EqualPositionComparatorImpl&&) = delete; void BindField(const std::string& name, int field, const VariantArray&, CondType, const CollateOpts&); void BindField(const std::string& name, const FieldsPath&, const VariantArray&, CondType); @@ -38,12 +42,12 @@ class EqualPositionComparator { struct Context { Context(const CollateOpts& collate) : cmpString{collate} {} CondType cond; - EqualPositionComparatorImpl cmpBool; - EqualPositionComparatorImpl cmpInt; - EqualPositionComparatorImpl cmpInt64; - EqualPositionComparatorImpl cmpDouble; - EqualPositionComparatorImpl cmpString; - EqualPositionComparatorImpl cmpUuid; + EqualPositionComparatorTypeImpl cmpBool; + EqualPositionComparatorTypeImpl cmpInt; + EqualPositionComparatorTypeImpl cmpInt64; + EqualPositionComparatorTypeImpl cmpDouble; + EqualPositionComparatorTypeImpl cmpString; + EqualPositionComparatorTypeImpl cmpUuid; }; std::vector ctx_; @@ -53,4 +57,30 @@ class EqualPositionComparator { int matchedCount_{0}; }; +class EqualPositionComparator { +public: + EqualPositionComparator(const PayloadType& payloadType) : impl_{make_intrusive(payloadType)} {} + + void BindField(const std::string& name, int field, const VariantArray& values, CondType cond, const CollateOpts& opts) { + return impl_->BindField(name, field, values, cond, opts); + } + void BindField(const std::string& name, const FieldsPath& fields, const VariantArray& values, CondType cond) { + return impl_->BindField(name, fields, values, cond); + } + bool Compare(const PayloadValue& pv, IdType id) { return impl_->Compare(pv, id); } + bool IsBinded() noexcept { return impl_->IsBinded(); } + [[nodiscard]] int GetMatchedCount() const noexcept { return impl_->GetMatchedCount(); } + [[nodiscard]] int FieldsCount() const noexcept { return impl_->FieldsCount(); } + [[nodiscard]] const std::string& Name() const& noexcept { return impl_->Name(); } + [[nodiscard]] const std::string& Dump() const& noexcept { return impl_->Name(); } + [[nodiscard]] double Cost(int expectedIterations) const noexcept { return impl_->Cost(expectedIterations); } + + auto Name() const&& = delete; + auto Dump() const&& = delete; + +private: + // Using pointer to reduce ExpressionTree Node size + intrusive_ptr impl_; +}; + } // namespace reindexer diff --git a/cpp_src/core/nsselecter/comparator/equalposition_comparator_impl.h b/cpp_src/core/nsselecter/comparator/equalposition_comparator_impl.h index 1bb3cf5b8..0eb935e2f 100644 --- a/cpp_src/core/nsselecter/comparator/equalposition_comparator_impl.h +++ b/cpp_src/core/nsselecter/comparator/equalposition_comparator_impl.h @@ -1,11 +1,10 @@ #pragma once #include -#include #include "core/index/string_map.h" #include "core/keyvalue/geometry.h" #include "core/keyvalue/p_string.h" -#include "estl/intrusive_ptr.h" +#include "estl/fast_hash_set.h" #include "estl/one_of.h" #include "tools/string_regexp_functions.h" #include "vendor/hopscotch/hopscotch_sc_set.h" @@ -13,19 +12,23 @@ namespace reindexer { template -class EqualPositionComparatorImpl { - using ValuesSet = intrusive_atomic_rc_wrapper>; - using AllSetValuesSet = intrusive_atomic_rc_wrapper>; +class EqualPositionComparatorTypeImpl { + using ValuesSet = fast_hash_set; + using AllSetValuesSet = fast_hash_set; public: - EqualPositionComparatorImpl() noexcept = default; + EqualPositionComparatorTypeImpl() noexcept = default; + EqualPositionComparatorTypeImpl(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl& operator=(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl(EqualPositionComparatorTypeImpl&&) = default; + EqualPositionComparatorTypeImpl& operator=(EqualPositionComparatorTypeImpl&&) = default; void SetValues(CondType cond, const VariantArray& values) { if (cond == CondSet) { - valuesS_.reset(new ValuesSet{}); + valuesS_ = std::make_unique(); } else if (cond == CondAllSet) { - valuesS_.reset(new ValuesSet{}); - allSetValuesS_.reset(new AllSetValuesSet{}); + valuesS_ = std::make_unique(); + allSetValuesS_ = std::make_unique(); } for (Variant key : values) { @@ -85,8 +88,8 @@ class EqualPositionComparatorImpl { } h_vector values_; - intrusive_ptr valuesS_; - intrusive_ptr allSetValuesS_; + std::unique_ptr valuesS_; + std::unique_ptr allSetValuesS_; private: KeyValueType type() { @@ -115,19 +118,23 @@ class EqualPositionComparatorImpl { }; template <> -class EqualPositionComparatorImpl { - using ValuesSet = intrusive_atomic_rc_wrapper>; - using AllSetValuesSet = intrusive_atomic_rc_wrapper>; +class EqualPositionComparatorTypeImpl { + using ValuesSet = fast_hash_set; + using AllSetValuesSet = fast_hash_set; public: - EqualPositionComparatorImpl() noexcept = default; + EqualPositionComparatorTypeImpl() noexcept = default; + EqualPositionComparatorTypeImpl(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl& operator=(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl(EqualPositionComparatorTypeImpl&&) = default; + EqualPositionComparatorTypeImpl& operator=(EqualPositionComparatorTypeImpl&&) = default; void SetValues(CondType cond, const VariantArray& values) { if (cond == CondSet) { - valuesS_.reset(new ValuesSet{}); + valuesS_ = std::make_unique(); } else if (cond == CondAllSet) { - valuesS_.reset(new ValuesSet{}); - allSetValuesS_.reset(new AllSetValuesSet{}); + valuesS_ = std::make_unique(); + allSetValuesS_ = std::make_unique(); } for (const Variant& key : values) { @@ -190,8 +197,8 @@ class EqualPositionComparatorImpl { } h_vector values_; - intrusive_ptr valuesS_; - intrusive_ptr allSetValuesS_; + std::unique_ptr valuesS_; + std::unique_ptr allSetValuesS_; private: void addValue(CondType cond, Uuid value) { @@ -204,16 +211,20 @@ class EqualPositionComparatorImpl { }; template <> -class EqualPositionComparatorImpl { +class EqualPositionComparatorTypeImpl { public: - EqualPositionComparatorImpl(const CollateOpts& collate) : collate_{collate} {} + EqualPositionComparatorTypeImpl(const CollateOpts& collate) : collate_{collate} {} + EqualPositionComparatorTypeImpl(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl& operator=(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl(EqualPositionComparatorTypeImpl&&) = default; + EqualPositionComparatorTypeImpl& operator=(EqualPositionComparatorTypeImpl&&) = default; void SetValues(CondType cond, const VariantArray& values) { if (cond == CondSet) { - valuesS_ = make_intrusive>(collate_); + valuesS_ = std::make_unique(collate_); } else if (cond == CondAllSet) { - valuesS_ = make_intrusive>(collate_); - allSetValuesS_ = make_intrusive>>(); + valuesS_ = std::make_unique(collate_); + allSetValuesS_ = std::make_unique>(); } for (Variant key : values) { @@ -279,8 +290,8 @@ class EqualPositionComparatorImpl { less_key_string(opts)) {} }; - intrusive_ptr> valuesS_; - intrusive_ptr>> allSetValuesS_; + std::unique_ptr valuesS_; + std::unique_ptr> allSetValuesS_; private: void addValue(CondType cond, const key_string& value) { @@ -297,15 +308,23 @@ class EqualPositionComparatorImpl { }; template <> -class EqualPositionComparatorImpl { +class EqualPositionComparatorTypeImpl { public: - EqualPositionComparatorImpl() = delete; + EqualPositionComparatorTypeImpl() = delete; + EqualPositionComparatorTypeImpl(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl& operator=(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl(EqualPositionComparatorTypeImpl&&) = default; + EqualPositionComparatorTypeImpl& operator=(EqualPositionComparatorTypeImpl&&) = default; }; template <> -class EqualPositionComparatorImpl { +class EqualPositionComparatorTypeImpl { public: - EqualPositionComparatorImpl() noexcept = default; + EqualPositionComparatorTypeImpl() noexcept = default; + EqualPositionComparatorTypeImpl(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl& operator=(const EqualPositionComparatorTypeImpl&) = delete; + EqualPositionComparatorTypeImpl(EqualPositionComparatorTypeImpl&&) = default; + EqualPositionComparatorTypeImpl& operator=(EqualPositionComparatorTypeImpl&&) = default; void SetValues(const VariantArray& values) { if (values.size() != 2) { diff --git a/cpp_src/core/nsselecter/comparator/fieldscomparator.cc b/cpp_src/core/nsselecter/comparator/fieldscomparator.cc index 6b84de8c0..54edeba82 100644 --- a/cpp_src/core/nsselecter/comparator/fieldscomparator.cc +++ b/cpp_src/core/nsselecter/comparator/fieldscomparator.cc @@ -68,7 +68,7 @@ class ArrayAdapter { namespace reindexer { -FieldsComparator::FieldsComparator(std::string_view lField, CondType cond, std::string_view rField, PayloadType plType) +FieldsComparatorImpl::FieldsComparatorImpl(std::string_view lField, CondType cond, std::string_view rField, PayloadType plType) : condition_{cond}, payloadType_{std::move(plType)} { switch (condition_) { case CondEq: @@ -92,7 +92,7 @@ FieldsComparator::FieldsComparator(std::string_view lField, CondType cond, std:: } template -bool FieldsComparator::compare(const LArr& lhs, const RArr& rhs) { +bool FieldsComparatorImpl::compare(const LArr& lhs, const RArr& rhs) { static constexpr bool needCompareTypes{std::is_same_v || std::is_same_v}; switch (condition_) { case CondRange: @@ -214,7 +214,7 @@ bool FieldsComparator::compare(const LArr& lhs, const RArr& rhs) { } } -bool FieldsComparator::compare(const PayloadValue& item, const Context& ctx) { +bool FieldsComparatorImpl::compare(const PayloadValue& item, const Context& ctx) { bool result; if (ctx.lCtx_.fields_.getTagsPathsLength() > 0) { VariantArray lhs; @@ -262,7 +262,7 @@ bool FieldsComparator::compare(const PayloadValue& item, const Context& ctx) { return result; } -void FieldsComparator::validateTypes(KeyValueType lType, KeyValueType rType) const { +void FieldsComparatorImpl::validateTypes(KeyValueType lType, KeyValueType rType) const { if (lType.IsSame(rType) || lType.Is() || rType.Is()) { return; } diff --git a/cpp_src/core/nsselecter/comparator/fieldscomparator.h b/cpp_src/core/nsselecter/comparator/fieldscomparator.h index 41a6fbd8f..d785b48c9 100644 --- a/cpp_src/core/nsselecter/comparator/fieldscomparator.h +++ b/cpp_src/core/nsselecter/comparator/fieldscomparator.h @@ -10,9 +10,14 @@ namespace reindexer { -class FieldsComparator { +class FieldsComparatorImpl : public intrusive_rc_base { public: - FieldsComparator(std::string_view lField, CondType cond, std::string_view rField, PayloadType plType); + FieldsComparatorImpl(std::string_view lField, CondType cond, std::string_view rField, PayloadType plType); + FieldsComparatorImpl(const FieldsComparatorImpl&) = delete; + FieldsComparatorImpl(FieldsComparatorImpl&&) = delete; + FieldsComparatorImpl& operator=(const FieldsComparatorImpl&) = delete; + FieldsComparatorImpl& operator=(FieldsComparatorImpl&&) = delete; + bool Compare(const PayloadValue& item, IdType /*rowId*/) { if (ctx_.size() > 1) { for (const auto& c : ctx_) { @@ -155,4 +160,26 @@ class FieldsComparator { bool leftFieldSet = false; }; +class FieldsComparator { +public: + FieldsComparator(std::string_view lField, CondType cond, std::string_view rField, PayloadType plType) + : impl_{make_intrusive(lField, cond, rField, plType)} {} + bool Compare(const PayloadValue& item, IdType rowId) { return impl_->Compare(item, rowId); } + double Cost(int expectedIterations) const noexcept { return impl_->Cost(expectedIterations); } + const std::string& Name() const& noexcept { return impl_->Name(); } + const std::string& Name() const&& = delete; + const std::string& Dump() const& noexcept { return impl_->Dump(); } + const std::string& Dump() const&& = delete; + int GetMatchedCount() const noexcept { return impl_->GetMatchedCount(); } + void SetLeftField(const FieldsSet& fields) { return impl_->SetLeftField(fields); } + void SetRightField(const FieldsSet& fields) { return impl_->SetRightField(fields); } + void SetLeftField(const FieldsSet& fset, KeyValueType type, bool isArray) { return impl_->SetLeftField(fset, type, isArray); } + void SetRightField(const FieldsSet& fset, KeyValueType type, bool isArray) { return impl_->SetRightField(fset, type, isArray); } + void SetCollateOpts(const CollateOpts& cOpts) { impl_->SetCollateOpts(cOpts); } + +private: + // Using pointer to reduce ExpressionTree Node size + intrusive_ptr impl_; +}; + } // namespace reindexer diff --git a/cpp_src/core/nsselecter/selectiteratorcontainer.cc b/cpp_src/core/nsselecter/selectiteratorcontainer.cc index 6121cb5d0..070ffebbb 100644 --- a/cpp_src/core/nsselecter/selectiteratorcontainer.cc +++ b/cpp_src/core/nsselecter/selectiteratorcontainer.cc @@ -647,13 +647,13 @@ bool SelectIteratorContainer::checkIfSatisfyAllConditions(iterator begin, iterat // suggest that all JOINs in chain of OR ... OR ... OR ... OR will be before all not JOINs (see SortByCost) if (result) { // check what it does not holds join - if (it->Visit([] RX_PRE_LMBD_ALWAYS_INLINE(const SelectIteratorsBracket& b) - RX_POST_LMBD_ALWAYS_INLINE noexcept { return !b.haveJoins; }, - [] RX_PRE_LMBD_ALWAYS_INLINE(const JoinSelectIterator&) RX_POST_LMBD_ALWAYS_INLINE noexcept { return false; }, - [] RX_PRE_LMBD_ALWAYS_INLINE( - OneOf>) - RX_POST_LMBD_ALWAYS_INLINE noexcept { return true; })) { + if (it->Visit( + [](const SelectIteratorsBracket& b) noexcept { return !b.haveJoins; }, + [](const JoinSelectIterator&) noexcept { return false; }, + [](OneOf>) noexcept { + return true; + })) { continue; } } @@ -664,18 +664,16 @@ bool SelectIteratorContainer::checkIfSatisfyAllConditions(iterator begin, iterat } bool lastFinish = false; const bool lastResult = it->Visit( - [&] RX_PRE_LMBD_ALWAYS_INLINE(SelectIteratorsBracket&) RX_POST_LMBD_ALWAYS_INLINE { + [&](SelectIteratorsBracket&) { return checkIfSatisfyAllConditions(it.begin(), it.end(), pv, &lastFinish, rowId, properRowId, match); }, - [&] RX_PRE_LMBD_ALWAYS_INLINE(SelectIterator & sit) - RX_POST_LMBD_ALWAYS_INLINE { return checkIfSatisfyCondition(sit, &lastFinish, rowId); }, - [&] RX_PRE_LMBD_ALWAYS_INLINE(JoinSelectIterator & jit) - RX_POST_LMBD_ALWAYS_INLINE { return checkIfSatisfyCondition(jit, pv, properRowId, match); }, + [&](SelectIterator& sit) { return checkIfSatisfyCondition(sit, &lastFinish, rowId); }, + [&](JoinSelectIterator& jit) { return checkIfSatisfyCondition(jit, pv, properRowId, match); }, Restricted>{}( - [&pv, properRowId] RX_PRE_LMBD_ALWAYS_INLINE(auto& c) RX_POST_LMBD_ALWAYS_INLINE { return c.Compare(pv, properRowId); }), - [] RX_PRE_LMBD_ALWAYS_INLINE(AlwaysTrue&) RX_POST_LMBD_ALWAYS_INLINE noexcept { return true; }); + [&pv, properRowId](auto& c) { return c.Compare(pv, properRowId); }), + [](AlwaysTrue&) noexcept { return true; }); if (op == OpOr) { result |= lastResult; currentFinish &= (!result && lastFinish); @@ -700,9 +698,8 @@ IdType SelectIteratorContainer::getNextItemId(const_iterator begin, const_iterat switch (it->operation) { case OpOr: { auto next = it->Visit( - [it, from] RX_PRE_LMBD_ALWAYS_INLINE(const SelectIteratorsBracket&) - RX_POST_LMBD_ALWAYS_INLINE { return getNextItemId(it.cbegin(), it.cend(), from); }, - [from] RX_PRE_LMBD_ALWAYS_INLINE(const SelectIterator& sit) RX_POST_LMBD_ALWAYS_INLINE { + [it, from](const SelectIteratorsBracket&) { return getNextItemId(it.cbegin(), it.cend(), from); }, + [from](const SelectIterator& sit) { if constexpr (reverse) { if (sit.End()) { return std::numeric_limits::lowest(); @@ -720,11 +717,11 @@ IdType SelectIteratorContainer::getNextItemId(const_iterator begin, const_iterat } return from; }, - [from] RX_PRE_LMBD_ALWAYS_INLINE( - const OneOf>) - RX_POST_LMBD_ALWAYS_INLINE { return from; }, - [] RX_PRE_LMBD_ALWAYS_INLINE(const AlwaysFalse&) RX_POST_LMBD_ALWAYS_INLINE { + [from](const OneOf>) { + return from; + }, + [](const AlwaysFalse&) { return reverse ? std::numeric_limits::lowest() : std::numeric_limits::max(); }); if constexpr (reverse) { @@ -736,9 +733,8 @@ IdType SelectIteratorContainer::getNextItemId(const_iterator begin, const_iterat case OpAnd: from = result; result = it->Visit( - [it, from] RX_PRE_LMBD_ALWAYS_INLINE(const SelectIteratorsBracket&) - RX_POST_LMBD_ALWAYS_INLINE { return getNextItemId(it.cbegin(), it.cend(), from); }, - [from] RX_PRE_LMBD_ALWAYS_INLINE(const SelectIterator& sit) RX_POST_LMBD_ALWAYS_INLINE { + [it, from](const SelectIteratorsBracket&) { return getNextItemId(it.cbegin(), it.cend(), from); }, + [from](const SelectIterator& sit) { if constexpr (reverse) { if (sit.End()) { return std::numeric_limits::lowest(); @@ -756,11 +752,11 @@ IdType SelectIteratorContainer::getNextItemId(const_iterator begin, const_iterat } return from; }, - [from] RX_PRE_LMBD_ALWAYS_INLINE( - const OneOf>) - RX_POST_LMBD_ALWAYS_INLINE { return from; }, - [] RX_PRE_LMBD_ALWAYS_INLINE(const AlwaysFalse&) RX_POST_LMBD_ALWAYS_INLINE { + [from](const OneOf>) { + return from; + }, + [](const AlwaysFalse&) { return reverse ? std::numeric_limits::lowest() : std::numeric_limits::max(); }); break; diff --git a/cpp_src/estl/charset.h b/cpp_src/estl/charset.h index b10cf80ef..43037bfc5 100644 --- a/cpp_src/estl/charset.h +++ b/cpp_src/estl/charset.h @@ -37,7 +37,7 @@ class Charset { WordT set_[kWordsCount] = {0}; }; -static_assert(std::numeric_limits::max() - std::numeric_limits::min() + 1 == Charset::max_values_count(), +static_assert(size_t(std::numeric_limits::max() - std::numeric_limits::min() + 1) == Charset::max_values_count(), "Expecting max uint8_t range of [0, 255] for the simplicity"); } // namespace reindexer::estl diff --git a/cpp_src/estl/intrusive_ptr.h b/cpp_src/estl/intrusive_ptr.h index 957150578..ea19a4a46 100644 --- a/cpp_src/estl/intrusive_ptr.h +++ b/cpp_src/estl/intrusive_ptr.h @@ -187,11 +187,11 @@ template class intrusive_atomic_rc_wrapper : public T { public: template - intrusive_atomic_rc_wrapper(Args&&... args) : T(std::forward(args)...), refcount(0) {} + intrusive_atomic_rc_wrapper(Args&&... args) : T(std::forward(args)...) {} intrusive_atomic_rc_wrapper& operator=(const intrusive_atomic_rc_wrapper&) = delete; protected: - std::atomic refcount; + std::atomic refcount{0}; friend void intrusive_ptr_add_ref<>(intrusive_atomic_rc_wrapper* x) noexcept; friend void intrusive_ptr_release<>(intrusive_atomic_rc_wrapper* x) noexcept; @@ -224,11 +224,11 @@ template class intrusive_rc_wrapper : public T { public: template - intrusive_rc_wrapper(Args&&... args) : T(std::forward(args)...), refcount(0) {} + intrusive_rc_wrapper(Args&&... args) : T(std::forward(args)...) {} intrusive_rc_wrapper& operator=(const intrusive_rc_wrapper&) = delete; protected: - int refcount; + int refcount{0}; friend void intrusive_ptr_add_ref<>(intrusive_rc_wrapper* x) noexcept; friend void intrusive_ptr_release<>(intrusive_rc_wrapper* x) noexcept; @@ -237,12 +237,11 @@ class intrusive_rc_wrapper : public T { class intrusive_atomic_rc_base { public: - intrusive_atomic_rc_base() noexcept : refcount(0) {} intrusive_atomic_rc_base& operator=(const intrusive_atomic_rc_base&) = delete; virtual ~intrusive_atomic_rc_base() = default; protected: - std::atomic refcount; + std::atomic refcount{0}; friend void intrusive_ptr_add_ref(intrusive_atomic_rc_base* x) noexcept; friend void intrusive_ptr_release(intrusive_atomic_rc_base* x) noexcept; @@ -266,6 +265,33 @@ inline bool intrusive_ptr_is_unique(intrusive_atomic_rc_base* x) noexcept { return !x || (x->refcount.load(std::memory_order_acquire) == 1); } +class intrusive_rc_base { +public: + intrusive_rc_base& operator=(const intrusive_rc_base&) = delete; + virtual ~intrusive_rc_base() = default; + +protected: + int refcount{0}; + + friend void intrusive_ptr_add_ref(intrusive_rc_base* x) noexcept; + friend void intrusive_ptr_release(intrusive_rc_base* x) noexcept; + friend bool intrusive_ptr_is_unique(intrusive_rc_base* x) noexcept; +}; + +inline void intrusive_ptr_add_ref(intrusive_rc_base* x) noexcept { + if (x) { + ++x->refcount; + } +} + +inline void intrusive_ptr_release(intrusive_rc_base* x) noexcept { + if (x && --x->refcount == 0) { + delete x; + } +} + +inline bool intrusive_ptr_is_unique(intrusive_rc_base* x) noexcept { return !x || (x->refcount == 1); } + template intrusive_ptr make_intrusive(Args&&... args) { return intrusive_ptr(new T(std::forward(args)...));