diff options
author | Alison Lu <alison.lu@mongodb.com> | 2021-06-21 20:36:23 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-06-25 20:31:55 +0000 |
commit | faa111304a5301eb321b016029766104de6d9272 (patch) | |
tree | e4f9cd28993ecb25938d04e6dd5b6cb3cb34eee1 | |
parent | b13cd8a982b9f2598ba34a1e40cfe78738ef1c90 (diff) | |
download | mongo-faa111304a5301eb321b016029766104de6d9272.tar.gz |
SERVER-56717 Update naming and comment, simplify comparisons
-rw-r--r-- | src/mongo/bson/bsonelement.cpp | 92 | ||||
-rw-r--r-- | src/mongo/bson/bsonelement.h | 9 | ||||
-rw-r--r-- | src/mongo/db/timeseries/minmax.cpp | 26 |
3 files changed, 113 insertions, 14 deletions
diff --git a/src/mongo/bson/bsonelement.cpp b/src/mongo/bson/bsonelement.cpp index d93f928861c..d6eb1af0830 100644 --- a/src/mongo/bson/bsonelement.cpp +++ b/src/mongo/bson/bsonelement.cpp @@ -482,6 +482,88 @@ int BSONElement::woCompare(const BSONElement& elem, return compareElements(*this, elem, rules, comparator); } +template <typename Comparator> +bool BSONElement::compare(const BSONElement& other, + Comparator comp, + const StringData::ComparatorInterface* stringComp) const { + if (type() != other.type()) + return comp((int)canonicalType(), other.canonicalType()); + switch (other.type()) { + case BSONType::EOO: + case BSONType::Undefined: + case BSONType::jstNULL: + case BSONType::MaxKey: + case BSONType::MinKey: + return comp(canonicalType(), other.canonicalType()); + case BSONType::Bool: + return comp(*value(), *other.value()); + case BSONType::bsonTimestamp: + return comp(timestamp(), other.timestamp()); + case BSONType::Date: + return comp(Date(), other.Date()); + case BSONType::NumberInt: + return comp(_numberInt(), other._numberInt()); + case BSONType::NumberLong: + return comp(_numberLong(), other._numberLong()); + case BSONType::NumberDouble: + return comp(_numberDouble(), other._numberDouble()); + case BSONType::NumberDecimal: + return comp(_numberDecimal(), other._numberDecimal()); + case BSONType::jstOID: + return comp(memcmp(value(), other.value(), OID::kOIDSize), 0); + case BSONType::Code: + return comp(compareElementStringValues(*this, other), 0); + case BSONType::Symbol: + case BSONType::String: + return comp(stringComp ? stringComp->compare(valueStringData(), other.valueStringData()) + : compareElementStringValues(*this, other), + 0); + case BSONType::Object: + case BSONType::Array: + return embeddedObject().woCompare(other.embeddedObject(), + BSONObj(), + BSONElement::ComparisonRules::kConsiderFieldName, + stringComp); + case BSONType::DBRef: { + int size = valuesize(); + int diff = size - other.valuesize(); + if (diff != 0) { + diff = memcmp(value(), other.value(), size); + } + return comp(diff, 0); + } + case BSONType::BinData: { + int size = objsize(); + int diff = size - other.objsize(); + if (diff != 0) { + diff = memcmp(value() + 4, other.value() + 4, size + 1); + } + return comp(diff, 0); + } + case BSONType::RegEx: { + int diff = strcmp(regex(), other.regex()); + if (diff != 0) { + diff = strcmp(regexFlags(), other.regexFlags()); + } + return comp(diff, 0); + } + case BSONType::CodeWScope: { + int diff = + StringData(codeWScopeCode(), codeWScopeCodeLen() - 1) + .compare(StringData(other.codeWScopeCode(), other.codeWScopeCodeLen() - 1)); + if (diff != 0) { + return codeWScopeObject().woCompare( + other.codeWScopeObject(), + BSONObj(), + BSONElement::ComparisonRules::kConsiderFieldName); + } + return comp(diff, 0); + } + } + + MONGO_UNREACHABLE; +} + bool BSONElement::binaryEqual(const BSONElement& rhs) const { const int elemSize = size(); @@ -992,4 +1074,14 @@ struct BSONElementCodeWithScopeType { } bsonElementCodeWithScopeType; #endif // defined(_MSC_VER) && defined(_DEBUG) +template bool BSONElement::compare<std::less<>>( + const BSONElement& other, + std::less<> comp, + const StringData::ComparatorInterface* stringComp) const; + +template bool BSONElement::compare<std::greater<>>( + const BSONElement& other, + std::greater<> comp, + const StringData::ComparatorInterface* stringComp) const; + } // namespace mongo diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h index b3a39c04ce3..e83ca647e30 100644 --- a/src/mongo/bson/bsonelement.h +++ b/src/mongo/bson/bsonelement.h @@ -624,6 +624,15 @@ public: ComparisonRulesSet rules = ComparisonRules::kConsiderFieldName, const StringData::ComparatorInterface* comparator = nullptr) const; + /** + * Returns a boolean for how, using the given comparison functions 'comp' or + * 'stringComp', this BSONElement compares with 'other'. Ignores the field name. + */ + template <typename Comparator> + bool compare(const BSONElement& other, + Comparator comp, + const StringData::ComparatorInterface* stringComp = nullptr) const; + DeferredComparison operator<(const BSONElement& other) const { return DeferredComparison(DeferredComparison::Type::kLT, *this, other); } diff --git a/src/mongo/db/timeseries/minmax.cpp b/src/mongo/db/timeseries/minmax.cpp index f59c7f0d7e6..77fe8ea2a5f 100644 --- a/src/mongo/db/timeseries/minmax.cpp +++ b/src/mongo/db/timeseries/minmax.cpp @@ -417,12 +417,11 @@ std::pair<MinMaxStore::Iterator, MinMaxStore::Iterator> MinMax::_update( }; if (elem.type() == Object) { - auto shouldUpdateObject = [&](MinMaxStore::Data& data, auto compare) { + auto shouldUpdateObject = [&](MinMaxStore::Data& data, auto comp) { return data.type() == MinMaxStore::Type::kObject || data.type() == MinMaxStore::Type::kUnset || - (data.type() == MinMaxStore::Type::kArray && compare(typeComp(Array), 0)) || - (data.type() == MinMaxStore::Type::kValue && - compare(typeComp(data.valueType()), 0)); + (data.type() == MinMaxStore::Type::kArray && comp(typeComp(Array), 0)) || + (data.type() == MinMaxStore::Type::kValue && comp(typeComp(data.valueType()), 0)); }; bool updateMin = updateMinValues && shouldUpdateObject(obj.element().min(), std::less<int>{}); @@ -446,12 +445,11 @@ std::pair<MinMaxStore::Iterator, MinMaxStore::Iterator> MinMax::_update( } if (elem.type() == Array) { - auto shouldUpdateArray = [&](MinMaxStore::Data& data, auto compare) { + auto shouldUpdateArray = [&](MinMaxStore::Data& data, auto comp) { return data.type() == MinMaxStore::Type::kArray || data.type() == MinMaxStore::Type::kUnset || - (data.type() == MinMaxStore::Type::kObject && compare(typeComp(Object), 0)) || - (data.type() == MinMaxStore::Type::kValue && - compare(typeComp(data.valueType()), 0)); + (data.type() == MinMaxStore::Type::kObject && comp(typeComp(Object), 0)) || + (data.type() == MinMaxStore::Type::kValue && comp(typeComp(data.valueType()), 0)); }; bool updateMin = updateMinValues && shouldUpdateArray(obj.element().min(), std::less<int>{}); @@ -485,21 +483,21 @@ std::pair<MinMaxStore::Iterator, MinMaxStore::Iterator> MinMax::_update( return {obj.iterator(), obj.parent().end()}; } - auto maybeUpdateValue = [&](MinMaxStore::Data& data, auto compare) { + auto maybeUpdateValue = [&](MinMaxStore::Data& data, auto comp) { if (data.type() == MinMaxStore::Type::kUnset || - (data.type() == MinMaxStore::Type::kObject && compare(typeComp(Object), 0)) || - (data.type() == MinMaxStore::Type::kArray && compare(typeComp(Array), 0)) || + (data.type() == MinMaxStore::Type::kObject && comp(typeComp(Object), 0)) || + (data.type() == MinMaxStore::Type::kArray && comp(typeComp(Array), 0)) || (data.type() == MinMaxStore::Type::kValue && - compare(elem.woCompare(data.value(), false, stringComparator), 0))) { + elem.compare(data.value(), comp, stringComparator))) { data.setValue(elem); } }; if (updateMinValues) { - maybeUpdateValue(obj.element().min(), std::less<int>{}); + maybeUpdateValue(obj.element().min(), std::less<>{}); } if (updateMaxValues) { - maybeUpdateValue(obj.element().max(), std::greater<int>{}); + maybeUpdateValue(obj.element().max(), std::greater<>{}); } return {obj.iterator(), obj.parent().end()}; |