diff options
author | Rui Liu <lriuui0x0@gmail.com> | 2021-07-28 11:24:27 +0100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-08-06 08:51:59 +0000 |
commit | 0df1ecc5133a17f8af0b58079f6ef8c910970739 (patch) | |
tree | 07f21094a1a60058a308051d8edc290ab66753c8 /src/mongo | |
parent | 67a48464b946e4398948185c849a90f14614b555 (diff) | |
download | mongo-0df1ecc5133a17f8af0b58079f6ef8c910970739.tar.gz |
SERVER-58587 Improve performance of $setIsSubset by replacing std::set with an unordered set
(cherry picked from commit f0defdba5d5839e4cbfd3b0fa69fb8369419ded4)
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/pipeline/expression.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp index de1434b0fcc..2cc52c45bdc 100644 --- a/src/mongo/db/pipeline/expression.cpp +++ b/src/mongo/db/pipeline/expression.cpp @@ -4090,6 +4090,13 @@ ValueSet arrayToSet(const Value& val, const ValueComparator& valueComparator) { valueSet.insert(array.begin(), array.end()); return valueSet; } + +ValueUnorderedSet arrayToUnorderedSet(const Value& val, const ValueComparator& valueComparator) { + const vector<Value>& array = val.getArray(); + ValueUnorderedSet valueSet = valueComparator.makeUnorderedValueSet(); + valueSet.insert(array.begin(), array.end()); + return valueSet; +} } // namespace /* ----------------------- ExpressionSetDifference ---------------------------- */ @@ -4219,7 +4226,7 @@ const char* ExpressionSetIntersection::getOpName() const { /* ----------------------- ExpressionSetIsSubset ---------------------------- */ namespace { -Value setIsSubsetHelper(const vector<Value>& lhs, const ValueSet& rhs) { +Value setIsSubsetHelper(const vector<Value>& lhs, const ValueUnorderedSet& rhs) { // do not shortcircuit when lhs.size() > rhs.size() // because lhs can have redundant entries for (vector<Value>::const_iterator it = lhs.begin(); it != lhs.end(); ++it) { @@ -4244,8 +4251,8 @@ Value ExpressionSetIsSubset::evaluate(const Document& root, Variables* variables << "argument is of type: " << typeName(rhs.getType()), rhs.isArray()); - return setIsSubsetHelper(lhs.getArray(), - arrayToSet(rhs, getExpressionContext()->getValueComparator())); + return setIsSubsetHelper( + lhs.getArray(), arrayToUnorderedSet(rhs, getExpressionContext()->getValueComparator())); } /** @@ -4258,7 +4265,7 @@ Value ExpressionSetIsSubset::evaluate(const Document& root, Variables* variables class ExpressionSetIsSubset::Optimized : public ExpressionSetIsSubset { public: Optimized(const boost::intrusive_ptr<ExpressionContext>& expCtx, - const ValueSet& cachedRhsSet, + const ValueUnorderedSet& cachedRhsSet, const ExpressionVector& operands) : ExpressionSetIsSubset(expCtx), _cachedRhsSet(cachedRhsSet) { _children = operands; @@ -4276,7 +4283,7 @@ public: } private: - const ValueSet _cachedRhsSet; + const ValueUnorderedSet _cachedRhsSet; }; intrusive_ptr<Expression> ExpressionSetIsSubset::optimize() { @@ -4296,7 +4303,7 @@ intrusive_ptr<Expression> ExpressionSetIsSubset::optimize() { intrusive_ptr<Expression> optimizedWithConstant( new Optimized(this->getExpressionContext(), - arrayToSet(rhs, getExpressionContext()->getValueComparator()), + arrayToUnorderedSet(rhs, getExpressionContext()->getValueComparator()), _children)); return optimizedWithConstant; } |