diff options
61 files changed, 547 insertions, 358 deletions
diff --git a/src/mongo/bson/bsonmisc.h b/src/mongo/bson/bsonmisc.h index 89a24015238..2ca9d39c805 100644 --- a/src/mongo/bson/bsonmisc.h +++ b/src/mongo/bson/bsonmisc.h @@ -54,38 +54,6 @@ private: const StringData::ComparatorInterface* _stringComparator; }; -class BSONObjCmp { -public: - /** - * If 'stringComparator' is null, the default binary comparator will be used for comparing - * string elements. A custom string comparator may be provided, but it must outlive the - * constructed BSONElementCmpWithoutField. - */ - BSONObjCmp(const BSONObj& order = BSONObj(), - const StringData::ComparatorInterface* stringComparator = nullptr) - : _order(order), _stringComparator(stringComparator) {} - bool operator()(const BSONObj& l, const BSONObj& r) const { - return l.woCompare(r, _order, true, _stringComparator) < 0; - } - BSONObj order() const { - return _order; - } - -private: - BSONObj _order; - const StringData::ComparatorInterface* _stringComparator; -}; - -typedef std::set<BSONObj, BSONObjCmp> BSONObjSet; - -enum FieldCompareResult { - LEFT_SUBFIELD = -2, - LEFT_BEFORE = -1, - SAME = 0, - RIGHT_BEFORE = 1, - RIGHT_SUBFIELD = 2 -}; - /** Use BSON macro to build a BSONObj from a stream e.g., diff --git a/src/mongo/bson/bsonobj_comparator.h b/src/mongo/bson/bsonobj_comparator.h new file mode 100644 index 00000000000..e5e2fd94e2b --- /dev/null +++ b/src/mongo/bson/bsonobj_comparator.h @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/base/string_data_comparator_interface.h" +#include "mongo/bson/bsonobj_comparator_interface.h" + +namespace mongo { + +/** + * A BSONObj comparator that supports: + * - Comparing with respect to an ordering spec such as {a: 1, b: -1}. + * - Ignoring field names during comparison. + * - Passing a custom string comparator. + */ +class BSONObjComparator final : public BSONObj::ComparatorInterface { +public: + enum class FieldNamesMode { + kConsider, + kIgnore, + }; + + /** + * Constructs a BSONObj comparator which will use the 'ordering' pattern for comparisons. + * + * Will not consider BSON field names in comparisons if 'fieldNamesMode' is kIgnore. + * + * If 'stringComparator' is null, uses default binary string comparison. Otherwise, + * 'stringComparator' is used for all string comparisons. + */ + BSONObjComparator(BSONObj ordering, + FieldNamesMode fieldNamesMode, + const StringData::ComparatorInterface* stringComparator) + : _ordering(std::move(ordering)), + _fieldNamesMode(fieldNamesMode), + _stringComparator(stringComparator) {} + + int compare(const BSONObj& lhs, const BSONObj& rhs) const final { + const bool considerFieldName = (_fieldNamesMode == FieldNamesMode::kConsider); + return lhs.woCompare(rhs, _ordering, considerFieldName, _stringComparator); + } + +private: + BSONObj _ordering; + FieldNamesMode _fieldNamesMode; + const StringData::ComparatorInterface* _stringComparator; +}; + +} // namespace mongo diff --git a/src/mongo/bson/bsonobj_comparator_interface.h b/src/mongo/bson/bsonobj_comparator_interface.h index 56fa736dab0..a063f638391 100644 --- a/src/mongo/bson/bsonobj_comparator_interface.h +++ b/src/mongo/bson/bsonobj_comparator_interface.h @@ -28,6 +28,7 @@ #pragma once +#include <initializer_list> #include <map> #include <set> #include <unordered_map> @@ -97,11 +98,11 @@ public: std::unordered_set<BSONObj, BSONObj::Hasher, BSONObj::ComparatorInterface::EqualTo>; template <typename T> - using BSONObjMap = std::map<BSONObj, T, BSONObj::ComparatorInterface::LessThan>; + using BSONObjIndexedMap = std::map<BSONObj, T, BSONObj::ComparatorInterface::LessThan>; // TODO SERVER-23990: Make the BSONObj hash collation-aware. template <typename T> - using BSONObjIndexedMap = + using BSONObjIndexedUnorderedMap = std::unordered_map<BSONObj, T, BSONObj::Hasher, BSONObj::ComparatorInterface::EqualTo>; virtual ~ComparatorInterface() = default; @@ -153,43 +154,55 @@ public: } /** - * Construct an empty BSONObjSet whose ordering is given by this comparator. This comparator - * must outlive the returned set. + * Constructs a BSONObjSet whose ordering is given by this comparator. This comparator must + * outlive the returned set. */ - BSONObjSet makeOrderedBSONObjSet() const { - return BSONObjSet(LessThan(this)); + BSONObjSet makeBSONObjSet(std::initializer_list<BSONObj> init = {}) const { + return BSONObjSet(init, LessThan(this)); } /** - * Construct an empty BSONObjUnorderedSet whose equivalence classes are given by this + * Constructs a BSONObjUnorderedSet whose equivalence classes are given by this * comparator. This comparator must outlive the returned set. */ - BSONObjUnorderedSet makeUnorderedBSONObjSet() const { + BSONObjUnorderedSet makeBSONObjUnorderedSet(std::initializer_list<BSONObj> init = {}) const { // TODO SERVER-23990: Make the BSONObj hash collation-aware. - return BSONObjUnorderedSet(0, BSONObj::Hasher(), EqualTo(this)); + return BSONObjUnorderedSet(init, 0, BSONObj::Hasher(), EqualTo(this)); } /** - * Construct an empty ordered map from BSONObj to type T whose ordering is given by this - * comparator. This comparator must outlive the returned map. + * Constructs an ordered map from BSONObj to type T whose ordering is given by this comparator. + * This comparator must outlive the returned map. */ template <typename T> - BSONObjMap<T> makeOrderedBSONObjMap() const { - return BSONObjMap<T>(LessThan(this)); + BSONObjIndexedMap<T> makeBSONObjIndexedMap( + std::initializer_list<std::pair<const BSONObj, T>> init = {}) const { + return BSONObjIndexedMap<T>(init, LessThan(this)); } /** - * Construct an empty unordered map from BSONObj to type T whose ordering is given by this + * Constructs an unordered map from BSONObj to type T whose ordering is given by this * comparator. This comparator must outlive the returned map. */ template <typename T> - BSONObjIndexedMap<T> makeBSONObjIndexedMap() const { + BSONObjIndexedUnorderedMap<T> makeBSONObjIndexedUnorderedMap( + std::initializer_list<std::pair<const BSONObj, T>> init = {}) const { // TODO SERVER-23990: Make the BSONObj hash collation-aware. - return BSONObjIndexedMap<T>(0, BSONObj::Hasher(), EqualTo(this)); + return BSONObjIndexedUnorderedMap<T>(init, 0, BSONObj::Hasher(), EqualTo(this)); } protected: constexpr ComparatorInterface() = default; }; +using BSONObjSet = BSONObj::ComparatorInterface::BSONObjSet; + +using BSONObjUnorderedSet = BSONObj::ComparatorInterface::BSONObjUnorderedSet; + +template <typename T> +using BSONObjIndexedMap = BSONObj::ComparatorInterface::BSONObjIndexedMap<T>; + +template <typename T> +using BSONObjIndexedUnorderedMap = BSONObj::ComparatorInterface::BSONObjIndexedUnorderedMap<T>; + } // namespace mongo diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp index 93e3a046fe6..de28926819a 100644 --- a/src/mongo/db/catalog/collection.cpp +++ b/src/mongo/db/catalog/collection.cpp @@ -39,6 +39,7 @@ #include "mongo/base/counter.h" #include "mongo/base/owned_pointer_map.h" #include "mongo/bson/ordering.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/background.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database_catalog_entry.h" @@ -1053,7 +1054,7 @@ public: } } - BSONObjSet documentKeySet; + BSONObjSet documentKeySet = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // There's no need to compute the prefixes of the indexed fields that cause the // index to be multikey when validating the index keys. MultikeyPaths* multikeyPaths = nullptr; diff --git a/src/mongo/db/commands/index_filter_commands.cpp b/src/mongo/db/commands/index_filter_commands.cpp index 5f8695713de..04a826b28d3 100644 --- a/src/mongo/db/commands/index_filter_commands.cpp +++ b/src/mongo/db/commands/index_filter_commands.cpp @@ -37,7 +37,7 @@ #include "mongo/base/init.h" #include "mongo/base/status.h" -#include "mongo/bson/bsonmisc.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/auth/authorization_session.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/database.h" @@ -386,7 +386,7 @@ Status SetFilter::set(OperationContext* txn, return Status(ErrorCodes::BadValue, "required field indexes must contain at least one index"); } - BSONObjSet indexes; + BSONObjSet indexes = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); std::unordered_set<std::string> indexNames; for (vector<BSONElement>::const_iterator i = indexesEltArray.begin(); i != indexesEltArray.end(); diff --git a/src/mongo/db/exec/group.cpp b/src/mongo/db/exec/group.cpp index 7acaebdf7fa..c4be03cdaad 100644 --- a/src/mongo/db/exec/group.cpp +++ b/src/mongo/db/exec/group.cpp @@ -86,7 +86,8 @@ GroupStage::GroupStage(OperationContext* txn, _specificStats(), _groupState(GroupState_Initializing), _reduceFunction(0), - _keyFunction(0) { + _keyFunction(0), + _groupMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<int>()) { _children.emplace_back(child); } diff --git a/src/mongo/db/exec/group.h b/src/mongo/db/exec/group.h index 355cab91b9d..7ec5efe647f 100644 --- a/src/mongo/db/exec/group.h +++ b/src/mongo/db/exec/group.h @@ -28,7 +28,7 @@ #pragma once - +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/exec/plan_stage.h" #include "mongo/scripting/engine.h" @@ -155,7 +155,7 @@ private: // Map from group key => group index. The group index is used to index into "$arr", a // variable owned by _scope which contains the group data for this key. - std::map<BSONObj, int, BSONObjCmp> _groupMap; + BSONObjIndexedMap<int> _groupMap; }; } // namespace mongo diff --git a/src/mongo/db/exec/sort_key_generator.cpp b/src/mongo/db/exec/sort_key_generator.cpp index acd4d6513ae..76e6ba70634 100644 --- a/src/mongo/db/exec/sort_key_generator.cpp +++ b/src/mongo/db/exec/sort_key_generator.cpp @@ -34,6 +34,7 @@ #include <vector> +#include "mongo/bson/bsonobj_comparator.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/exec/scoped_timer.h" #include "mongo/db/exec/working_set.h" @@ -178,8 +179,10 @@ StatusWith<BSONObj> SortKeyGenerator::getSortKeyFromObject(const WorkingSetMembe // We will sort '_data' in the same order an index over '_pattern' would have. This is // tricky. Consider the sort pattern {a:1} and the document {a:[1, 10]}. We have // potentially two keys we could use to sort on. Here we extract these keys. - BSONObjCmp patternCmp(_btreeObj); - BSONObjSet keys(patternCmp); + const StringData::ComparatorInterface* stringComparator = nullptr; + BSONObjComparator patternCmp( + _btreeObj, BSONObjComparator::FieldNamesMode::kConsider, stringComparator); + BSONObjSet keys = patternCmp.makeBSONObjSet(); try { // There's no need to compute the prefixes of the indexed fields that cause the index to be diff --git a/src/mongo/db/exec/working_set_common.cpp b/src/mongo/db/exec/working_set_common.cpp index a4052435d63..966e32eec61 100644 --- a/src/mongo/db/exec/working_set_common.cpp +++ b/src/mongo/db/exec/working_set_common.cpp @@ -30,6 +30,7 @@ #include "mongo/db/exec/working_set_common.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/exec/working_set.h" #include "mongo/db/index/index_access_method.h" @@ -113,7 +114,7 @@ bool WorkingSetCommon::fetch(OperationContext* txn, // unneeded due to the structure of the plan. invariant(!member->keyData.empty()); for (size_t i = 0; i < member->keyData.size(); i++) { - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // There's no need to compute the prefixes of the indexed fields that cause the index to // be multikey when ensuring the keyData is still valid. MultikeyPaths* multikeyPaths = nullptr; diff --git a/src/mongo/db/fts/fts_index_format.h b/src/mongo/db/fts/fts_index_format.h index 82be9ad03f5..4d936d463a7 100644 --- a/src/mongo/db/fts/fts_index_format.h +++ b/src/mongo/db/fts/fts_index_format.h @@ -33,6 +33,7 @@ #include <string> #include "mongo/base/string_data.h" +#include "mongo/bson/bsonobj_comparator_interface.h" #include "mongo/db/fts/fts_util.h" namespace mongo { diff --git a/src/mongo/db/fts/fts_index_format_test.cpp b/src/mongo/db/fts/fts_index_format_test.cpp index 03eb7406a79..c630f75ebd9 100644 --- a/src/mongo/db/fts/fts_index_format_test.cpp +++ b/src/mongo/db/fts/fts_index_format_test.cpp @@ -34,6 +34,7 @@ #include <set> +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/fts/fts_index_format.h" #include "mongo/db/fts/fts_spec.h" #include "mongo/unittest/unittest.h" @@ -50,7 +51,7 @@ using unittest::assertGet; TEST(FTSIndexFormat, Simple1) { FTSSpec spec(assertGet(FTSSpec::fixSpec(BSON("key" << BSON("data" << "text"))))); - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); FTSIndexFormat::getKeys(spec, BSON("data" << "cat sat"), @@ -69,7 +70,7 @@ TEST(FTSIndexFormat, ExtraBack1) { << "text" << "x" << 1))))); - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); FTSIndexFormat::getKeys(spec, BSON("data" << "cat" @@ -89,7 +90,7 @@ TEST(FTSIndexFormat, ExtraBack1) { TEST(FTSIndexFormat, ExtraFront1) { FTSSpec spec(assertGet(FTSSpec::fixSpec(BSON("key" << BSON("x" << 1 << "data" << "text"))))); - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); FTSIndexFormat::getKeys(spec, BSON("data" << "cat" @@ -110,14 +111,14 @@ TEST(FTSIndexFormat, StopWords1) { FTSSpec spec(assertGet(FTSSpec::fixSpec(BSON("key" << BSON("data" << "text"))))); - BSONObjSet keys1; + BSONObjSet keys1 = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); FTSIndexFormat::getKeys(spec, BSON("data" << "computer"), &keys1); ASSERT_EQUALS(1U, keys1.size()); - BSONObjSet keys2; + BSONObjSet keys2 = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); FTSIndexFormat::getKeys(spec, BSON("data" << "any computer"), @@ -159,7 +160,7 @@ TEST(FTSIndexFormat, LongWordsTextIndexVersion1) { << "text") << "textIndexVersion" << 1)))); - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); string longPrefix(1024U, 'a'); // "aaa...aaacat" string longWordCat = longPrefix + "cat"; @@ -189,7 +190,7 @@ TEST(FTSIndexFormat, LongWordTextIndexVersion2) { << "text") << "textIndexVersion" << 2)))); - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); string longPrefix(1024U, 'a'); // "aaa...aaacat" string longWordCat = longPrefix + "cat"; @@ -224,7 +225,7 @@ TEST(FTSIndexFormat, LongWordTextIndexVersion3) { << "text") << "textIndexVersion" << 3)))); - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); string longPrefix(1024U, 'a'); // "aaa...aaacat" string longWordCat = longPrefix + "cat"; diff --git a/src/mongo/db/index/2d_key_generator_test.cpp b/src/mongo/db/index/2d_key_generator_test.cpp index 9f6e3405fd1..136c3a5d16c 100644 --- a/src/mongo/db/index/2d_key_generator_test.cpp +++ b/src/mongo/db/index/2d_key_generator_test.cpp @@ -35,6 +35,7 @@ #include <algorithm> #include "mongo/bson/bsonobjbuilder.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/index/2d_common.h" #include "mongo/db/index/expression_params.h" #include "mongo/db/json.h" @@ -88,11 +89,11 @@ TEST(2dKeyGeneratorTest, TrailingField) { BSONObj infoObj = fromjson("{key: {a: '2d', b: 1}}"); TwoDIndexingParams params; ExpressionParams::parseTwoDParams(infoObj, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); std::vector<BSONObj> locs; ExpressionKeysPrivate::get2DKeys(obj, params, &actualKeys, &locs); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); BSONObj trailingFields = BSON("" << 5); expectedKeys.insert(make2DKey(params, 0, 0, trailingFields.firstElement())); @@ -104,11 +105,11 @@ TEST(2dKeyGeneratorTest, ArrayTrailingField) { BSONObj infoObj = fromjson("{key: {a: '2d', b: 1}}"); TwoDIndexingParams params; ExpressionParams::parseTwoDParams(infoObj, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); std::vector<BSONObj> locs; ExpressionKeysPrivate::get2DKeys(obj, params, &actualKeys, &locs); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); BSONObj trailingFields = BSON("" << BSON_ARRAY(5 << 6)); expectedKeys.insert(make2DKey(params, 0, 0, trailingFields.firstElement())); @@ -120,11 +121,11 @@ TEST(2dKeyGeneratorTest, ArrayOfObjectsTrailingField) { BSONObj infoObj = fromjson("{key: {a: '2d', 'b.c': 1}}"); TwoDIndexingParams params; ExpressionParams::parseTwoDParams(infoObj, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); std::vector<BSONObj> locs; ExpressionKeysPrivate::get2DKeys(obj, params, &actualKeys, &locs); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); BSONObj trailingFields = BSON("" << BSON_ARRAY(5 << 6)); expectedKeys.insert(make2DKey(params, 0, 0, trailingFields.firstElement())); diff --git a/src/mongo/db/index/btree_key_generator.h b/src/mongo/db/index/btree_key_generator.h index 76df5e7c810..382a55bc355 100644 --- a/src/mongo/db/index/btree_key_generator.h +++ b/src/mongo/db/index/btree_key_generator.h @@ -31,6 +31,7 @@ #include <set> #include <vector> +#include "mongo/bson/bsonobj_comparator_interface.h" #include "mongo/db/index/multikey_paths.h" #include "mongo/db/jsobj.h" diff --git a/src/mongo/db/index/btree_key_generator_test.cpp b/src/mongo/db/index/btree_key_generator_test.cpp index effeb192e9a..d8bb9e64024 100644 --- a/src/mongo/db/index/btree_key_generator_test.cpp +++ b/src/mongo/db/index/btree_key_generator_test.cpp @@ -35,6 +35,7 @@ #include <algorithm> #include <iostream> +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/json.h" #include "mongo/db/query/collation/collator_interface_mock.h" #include "mongo/unittest/unittest.h" @@ -124,7 +125,7 @@ bool testKeygen(const BSONObj& kp, // the indexed fields that would cause the index to be multikey as a result of inserting // 'actualKeys'. // - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; keyGen->getKeys(obj, &actualKeys, &actualMultikeyPaths); @@ -155,7 +156,7 @@ bool testKeygen(const BSONObj& kp, TEST(BtreeKeyGeneratorTest, GetIdKeyFromObject) { BSONObj keyPattern = fromjson("{_id: 1}"); BSONObj genKeysFrom = fromjson("{_id: 'foo', b: 4}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 'foo'}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -164,7 +165,7 @@ TEST(BtreeKeyGeneratorTest, GetIdKeyFromObject) { TEST(BtreeKeyGeneratorTest, GetKeysFromObjectSimple) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{b: 4, a: 5}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 5}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -173,7 +174,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromObjectSimple) { TEST(BtreeKeyGeneratorTest, GetKeysFromObjectDotted) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: {b: 4}, c: 'foo'}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 4}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -182,7 +183,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromObjectDotted) { TEST(BtreeKeyGeneratorTest, GetKeysFromArraySimple) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{a: [1, 2, 3]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -193,7 +194,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArraySimple) { TEST(BtreeKeyGeneratorTest, GetKeysFromArrayWithIdenticalValues) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{a: [0, 0, 0]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 0}")); MultikeyPaths expectedMultikeyPaths{{0U}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -202,7 +203,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArrayWithIdenticalValues) { TEST(BtreeKeyGeneratorTest, GetKeysFromArrayWithEquivalentValues) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{a: [0, NumberInt(0), NumberLong(0)]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 0}")); MultikeyPaths expectedMultikeyPaths{{0U}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -211,7 +212,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArrayWithEquivalentValues) { TEST(BtreeKeyGeneratorTest, GetKeysFromArrayFirstElement) { BSONObj keyPattern = fromjson("{a: 1, b: 1}"); BSONObj genKeysFrom = fromjson("{a: [1, 2, 3], b: 2}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1, '': 2}")); expectedKeys.insert(fromjson("{'': 2, '': 2}")); expectedKeys.insert(fromjson("{'': 3, '': 2}")); @@ -222,7 +223,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArrayFirstElement) { TEST(BtreeKeyGeneratorTest, GetKeysFromArraySecondElement) { BSONObj keyPattern = fromjson("{first: 1, a: 1}"); BSONObj genKeysFrom = fromjson("{first: 5, a: [1, 2, 3]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 5, '': 1}")); expectedKeys.insert(fromjson("{'': 5, '': 2}")); expectedKeys.insert(fromjson("{'': 5, '': 3}")); @@ -233,7 +234,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArraySecondElement) { TEST(BtreeKeyGeneratorTest, GetKeysFromSecondLevelArray) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: {b: [1, 2, 3]}}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -244,7 +245,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromSecondLevelArray) { TEST(BtreeKeyGeneratorTest, GetKeysFromParallelArraysBasic) { BSONObj keyPattern = fromjson("{'a': 1, 'b': 1}"); BSONObj genKeysFrom = fromjson("{a: [1, 2, 3], b: [1, 2, 3]}}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths(keyPattern.nFields()); ASSERT_THROWS(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths), UserException); @@ -253,7 +254,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromParallelArraysBasic) { TEST(BtreeKeyGeneratorTest, GetKeysFromArraySubobjectBasic) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [{b:1,c:4}, {b:2,c:4}, {b:3,c:4}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -264,7 +265,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArraySubobjectBasic) { TEST(BtreeKeyGeneratorTest, GetKeysFromSubobjectWithArrayOfSubobjects) { BSONObj keyPattern = fromjson("{'a.b.c': 1}"); BSONObj genKeysFrom = fromjson("{a: {b: [{c: 1}, {c: 2}]}}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); MultikeyPaths expectedMultikeyPaths{{1U}}; @@ -274,7 +275,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromSubobjectWithArrayOfSubobjects) { TEST(BtreeKeyGeneratorTest, GetKeysArraySubobjectCompoundIndex) { BSONObj keyPattern = fromjson("{'a.b': 1, d: 99}"); BSONObj genKeysFrom = fromjson("{a: [{b:1,c:4}, {b:2,c:4}, {b:3,c:4}], d: 99}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1, '': 99}")); expectedKeys.insert(fromjson("{'': 2, '': 99}")); expectedKeys.insert(fromjson("{'': 3, '': 99}")); @@ -285,7 +286,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysArraySubobjectCompoundIndex) { TEST(BtreeKeyGeneratorTest, GetKeysArraySubobjectSingleMissing) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [{foo: 41}, {b:1,c:4}, {b:2,c:4}, {b:3,c:4}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); @@ -297,7 +298,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysArraySubobjectSingleMissing) { TEST(BtreeKeyGeneratorTest, GetKeysFromArraySubobjectMissing) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [{foo: 41}, {foo: 41}, {foo: 41}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{{0U}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -306,7 +307,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArraySubobjectMissing) { TEST(BtreeKeyGeneratorTest, GetKeysMissingField) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{b: 1}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -315,7 +316,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysMissingField) { TEST(BtreeKeyGeneratorTest, GetKeysSubobjectMissing) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [1, 2]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{{0U}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -324,7 +325,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysSubobjectMissing) { TEST(BtreeKeyGeneratorTest, GetKeysFromCompound) { BSONObj keyPattern = fromjson("{x: 1, y: 1}"); BSONObj genKeysFrom = fromjson("{x: 'a', y: 'b'}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 'a', '': 'b'}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -333,7 +334,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromCompound) { TEST(BtreeKeyGeneratorTest, GetKeysFromCompoundMissing) { BSONObj keyPattern = fromjson("{x: 1, y: 1}"); BSONObj genKeysFrom = fromjson("{x: 'a'}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 'a', '': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -342,7 +343,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromCompoundMissing) { TEST(BtreeKeyGeneratorTest, GetKeysFromArraySubelementComplex) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:[{b:[2]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 2}")); // Both the 'a' and 'a.b' arrays contain a single element. MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; @@ -352,7 +353,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArraySubelementComplex) { TEST(BtreeKeyGeneratorTest, GetKeysFromParallelArraysComplex) { BSONObj keyPattern = fromjson("{'a.b': 1, 'a.c': 1}"); BSONObj genKeysFrom = fromjson("{a:[{b:[1],c:[2]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths(keyPattern.nFields()); ASSERT_THROWS(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths), UserException); @@ -361,7 +362,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromParallelArraysComplex) { TEST(BtreeKeyGeneratorTest, GetKeysAlternateMissing) { BSONObj keyPattern = fromjson("{'a.b': 1, 'a.c': 1}"); BSONObj genKeysFrom = fromjson("{a:[{b:1},{c:2}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null, '': 2}")); expectedKeys.insert(fromjson("{'': 1, '': null}")); MultikeyPaths expectedMultikeyPaths{{0U}, {0U}}; @@ -371,7 +372,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysAlternateMissing) { TEST(BtreeKeyGeneratorTest, GetKeysFromMultiComplex) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:[{b:1},{b:[1,2,3]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -382,7 +383,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromMultiComplex) { TEST(BtreeKeyGeneratorTest, GetKeysFromArrayOfSubobjectsWithArrayValues) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [{b: [1, 2]}, {b: [2, 3]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -393,7 +394,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArrayOfSubobjectsWithArrayValues) { TEST(BtreeKeyGeneratorTest, GetKeysFromArrayOfSubobjectsWithNonDistinctArrayValues) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [{b: [1, 2, 3]}, {b: [2]}, {b: [3, 1]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -404,7 +405,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArrayOfSubobjectsWithNonDistinctArrayValu TEST(BtreeKeyGeneratorTest, GetKeysArrayEmpty) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{a:[1,2]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); MultikeyPaths expectedMultikeyPaths{{0U}}; @@ -430,7 +431,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysArrayEmpty) { TEST(BtreeKeyGeneratorTest, GetKeysFromDoubleArray) { BSONObj keyPattern = fromjson("{a: 1, a: 1}"); BSONObj genKeysFrom = fromjson("{a:[1,2]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1, '': 1}")); expectedKeys.insert(fromjson("{'': 2, '': 2}")); MultikeyPaths expectedMultikeyPaths{{0U}, {0U}}; @@ -440,7 +441,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromDoubleArray) { TEST(BtreeKeyGeneratorTest, GetKeysFromDoubleEmptyArray) { BSONObj keyPattern = fromjson("{a: 1, a: 1}"); BSONObj genKeysFrom = fromjson("{a:[]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': undefined, '': undefined}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -449,7 +450,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromDoubleEmptyArray) { TEST(BtreeKeyGeneratorTest, GetKeysFromMultiEmptyArray) { BSONObj keyPattern = fromjson("{a: 1, b: 1}"); BSONObj genKeysFrom = fromjson("{a: 1, b: [1, 2]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1, '': 1}")); expectedKeys.insert(fromjson("{'': 1, '': 2}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, {0U}}; @@ -470,7 +471,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromMultiEmptyArray) { TEST(BtreeKeyGeneratorTest, GetKeysFromNestedEmptyArray) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:[]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -479,7 +480,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromNestedEmptyArray) { TEST(BtreeKeyGeneratorTest, GetKeysFromMultiNestedEmptyArray) { BSONObj keyPattern = fromjson("{'a.b': 1, 'a.c': 1}"); BSONObj genKeysFrom = fromjson("{a:[]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null, '': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -488,7 +489,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromMultiNestedEmptyArray) { TEST(BtreeKeyGeneratorTest, GetKeysFromUnevenNestedEmptyArray) { BSONObj keyPattern = fromjson("{'a': 1, 'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:[]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': undefined, '': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -507,7 +508,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromUnevenNestedEmptyArray) { TEST(BtreeKeyGeneratorTest, GetKeysFromReverseUnevenNestedEmptyArray) { BSONObj keyPattern = fromjson("{'a.b': 1, 'a': 1}"); BSONObj genKeysFrom = fromjson("{a:[]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null, '': undefined}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -517,7 +518,7 @@ TEST(BtreeKeyGeneratorTest, SparseReverseUnevenNestedEmptyArray) { const bool sparse = true; BSONObj keyPattern = fromjson("{'a.b': 1, 'a': 1}"); BSONObj genKeysFrom = fromjson("{a:[]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null, '': undefined}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, sparse)); @@ -527,7 +528,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromSparseEmptyArray) { const bool sparse = true; BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:1}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, sparse)); @@ -542,7 +543,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromSparseEmptyArraySecond) { const bool sparse = true; BSONObj keyPattern = fromjson("{z: 1, 'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:1}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, sparse)); @@ -557,7 +558,7 @@ TEST(BtreeKeyGeneratorTest, SparseNonObjectMissingNestedField) { const bool sparse = true; BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:[]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, sparse)); @@ -574,7 +575,7 @@ TEST(BtreeKeyGeneratorTest, SparseNonObjectMissingNestedField) { TEST(BtreeKeyGeneratorTest, GetKeysFromIndexedArrayIndex) { BSONObj keyPattern = fromjson("{'a.0': 1}"); BSONObj genKeysFrom = fromjson("{a:[1]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -612,7 +613,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromIndexedArrayIndex) { TEST(BtreeKeyGeneratorTest, GetKeysFromDoubleIndexedArrayIndex) { BSONObj keyPattern = fromjson("{'a.0.0': 1}"); BSONObj genKeysFrom = fromjson("{a:[[1]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -636,7 +637,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromDoubleIndexedArrayIndex) { TEST(BtreeKeyGeneratorTest, GetKeysFromObjectWithinArray) { BSONObj keyPattern = fromjson("{'a.0.b': 1}"); BSONObj genKeysFrom = fromjson("{a:[{b:1}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -675,7 +676,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromObjectWithinArray) { TEST(BtreeKeyGeneratorTest, GetKeysFromArrayWithinObjectWithinArray) { BSONObj keyPattern = fromjson("{'a.0.b.0': 1}"); BSONObj genKeysFrom = fromjson("{a:[{b:[1]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -684,7 +685,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArrayWithinObjectWithinArray) { TEST(BtreeKeyGeneratorTest, ParallelArraysInNestedObjects) { BSONObj keyPattern = fromjson("{'a.a': 1, 'b.a': 1}"); BSONObj genKeysFrom = fromjson("{a:{a:[1]}, b:{a:[1]}}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths(keyPattern.nFields()); ASSERT_THROWS(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths), UserException); @@ -693,7 +694,7 @@ TEST(BtreeKeyGeneratorTest, ParallelArraysInNestedObjects) { TEST(BtreeKeyGeneratorTest, ParallelArraysUneven) { BSONObj keyPattern = fromjson("{'b.a': 1, 'a': 1}"); BSONObj genKeysFrom = fromjson("{b:{a:[1]}, a:[1,2]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths(keyPattern.nFields()); ASSERT_THROWS(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths), UserException); @@ -702,7 +703,7 @@ TEST(BtreeKeyGeneratorTest, ParallelArraysUneven) { TEST(BtreeKeyGeneratorTest, MultipleArraysNotParallel) { BSONObj keyPattern = fromjson("{'a.b.c': 1}"); BSONObj genKeysFrom = fromjson("{a: [1, 2, {b: {c: [3, 4]}}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); expectedKeys.insert(fromjson("{'': 3}")); expectedKeys.insert(fromjson("{'': 4}")); @@ -713,7 +714,7 @@ TEST(BtreeKeyGeneratorTest, MultipleArraysNotParallel) { TEST(BtreeKeyGeneratorTest, MultipleArraysNotParallelCompound) { BSONObj keyPattern = fromjson("{'a.b.c': 1, 'a.b.d': 1}"); BSONObj genKeysFrom = fromjson("{a: [1, 2, {b: {c: [3, 4], d: 5}}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null, '': null}")); expectedKeys.insert(fromjson("{'': 3, '': 5}")); expectedKeys.insert(fromjson("{'': 4, '': 5}")); @@ -724,7 +725,7 @@ TEST(BtreeKeyGeneratorTest, MultipleArraysNotParallelCompound) { TEST(BtreeKeyGeneratorTest, GetKeysComplexNestedArrays) { BSONObj keyPattern = fromjson("{'a.b.c.d': 1, 'a.g': 1, 'a.b.f': 1, 'a.b.c': 1, 'a.b.e': 1}"); BSONObj genKeysFrom = fromjson("{a: [1, {b: [2, {c: [3, {d: 1}], e: 4}, 5, {f: 6}], g: 7}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'':null, '':null, '':null, '':null, '':null}")); expectedKeys.insert(fromjson("{'':null, '':7, '':null, '':null, '':null}")); expectedKeys.insert(fromjson("{'':null, '':7, '':null, '':3, '':4}")); @@ -738,7 +739,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysComplexNestedArrays) { TEST(BtreeKeyGeneratorTest, GetKeys2DArray) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{a: [[2]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': [2]}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -749,7 +750,7 @@ TEST(BtreeKeyGeneratorTest, GetKeys2DArray) { TEST(BtreeKeyGeneratorTest, GetKeysParallelEmptyArrays) { BSONObj keyPattern = fromjson("{a: 1, b: 1}"); BSONObj genKeysFrom = fromjson("{a: [], b: []}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths(keyPattern.nFields()); ASSERT_THROWS(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths), UserException); @@ -758,7 +759,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysParallelEmptyArrays) { TEST(BtreeKeyGeneratorTest, GetKeysParallelArraysOneArrayEmpty) { BSONObj keyPattern = fromjson("{a: 1, b: 1}"); BSONObj genKeysFrom = fromjson("{a: [], b: [1, 2, 3]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths(keyPattern.nFields()); ASSERT_THROWS(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths), UserException); @@ -767,7 +768,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysParallelArraysOneArrayEmpty) { TEST(BtreeKeyGeneratorTest, GetKeysParallelArraysOneArrayEmptyNested) { BSONObj keyPattern = fromjson("{'a.b.c': 1, 'a.b.d': 1}"); BSONObj genKeysFrom = fromjson("{a: [{b: [{c: [1, 2, 3], d: []}]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths(keyPattern.nFields()); ASSERT_THROWS(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths), UserException); @@ -777,7 +778,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysParallelArraysOneArrayEmptyNested) { TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternMissingElement) { BSONObj keyPattern = fromjson("{'a.2': 1}"); BSONObj genKeysFrom = fromjson("{a: [{'2': 5}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 5}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -787,7 +788,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternMissingElement) { TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray) { BSONObj keyPattern = fromjson("{'a.2': 1}"); BSONObj genKeysFrom = fromjson("{a: [[1, 2, 5]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -797,7 +798,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray) { TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray2) { BSONObj keyPattern = fromjson("{'a.2': 1}"); BSONObj genKeysFrom = fromjson("{a: [[1, 2, 5], [3, 4, 6], [0, 1, 2]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': [0, 1, 2]}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -807,7 +808,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray2) { TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray3) { BSONObj keyPattern = fromjson("{'a.2': 1}"); BSONObj genKeysFrom = fromjson("{a: [{'0': 1, '1': 2, '2': 5}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 5}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -817,7 +818,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray3) { TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray4) { BSONObj keyPattern = fromjson("{'a.b.2': 1}"); BSONObj genKeysFrom = fromjson("{a: [{b: [[1, 2, 5]]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -827,7 +828,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray4) { TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray5) { BSONObj keyPattern = fromjson("{'a.2': 1}"); BSONObj genKeysFrom = fromjson("{a: [[1, 2, 5], {'2': 6}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); expectedKeys.insert(fromjson("{'': 6}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{0U}}; @@ -837,7 +838,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray5) { TEST(BtreeKeyGeneratorTest, GetNullKeyNestedArray) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [[1, 2, 5]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -846,7 +847,7 @@ TEST(BtreeKeyGeneratorTest, GetNullKeyNestedArray) { TEST(BtreeKeyGeneratorTest, GetKeysUnevenNestedArrays) { BSONObj keyPattern = fromjson("{a: 1, 'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [1, {b: [2, 3, 4]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1, '': null}")); expectedKeys.insert(fromjson("{'': {b:[2,3,4]}, '': 2}")); expectedKeys.insert(fromjson("{'': {b:[2,3,4]}, '': 3}")); @@ -860,7 +861,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysUnevenNestedArrays) { TEST(BtreeKeyGeneratorTest, GetKeysRepeatedFieldName) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{a: 2, a: 3}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 2}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -871,7 +872,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysRepeatedFieldName) { TEST(BtreeKeyGeneratorTest, GetKeysEmptyPathPiece) { BSONObj keyPattern = fromjson("{'a..c': 1}"); BSONObj genKeysFrom = fromjson("{a: {'': [{c: 1}, {c: 2}]}}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); MultikeyPaths expectedMultikeyPaths{{1U}}; @@ -884,7 +885,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysLastPathPieceEmpty) { BSONObj keyPattern = fromjson("{'a.': 1}"); BSONObj genKeysFrom = fromjson("{a: 2}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 2}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -898,7 +899,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysLastPathPieceEmpty) { TEST(BtreeKeyGeneratorTest, GetKeysFirstPathPieceEmpty) { BSONObj keyPattern = fromjson("{'.a': 1}"); BSONObj genKeysFrom = fromjson("{a: 2}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -907,7 +908,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFirstPathPieceEmpty) { TEST(BtreeKeyGeneratorTest, GetKeysFirstPathPieceEmpty2) { BSONObj keyPattern = fromjson("{'.a': 1}"); BSONObj genKeysFrom = fromjson("{'': [{a: [1, 2, 3]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -918,7 +919,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFirstPathPieceEmpty2) { TEST(BtreeKeyGeneratorTest, PositionalKeyPatternParallelArrays) { BSONObj keyPattern = fromjson("{a: 1, 'b.0': 1}"); BSONObj genKeysFrom = fromjson("{a: [1], b: [2]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths expectedMultikeyPaths(keyPattern.nFields()); ASSERT_THROWS(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths), UserException); @@ -927,7 +928,7 @@ TEST(BtreeKeyGeneratorTest, PositionalKeyPatternParallelArrays) { TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_b_Extracts_b_ElementInsideSingleton2DArray) { BSONObj keyPattern = fromjson("{'a.0.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [[{b: 1}]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -936,7 +937,7 @@ TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_b_Extracts_b_ElementInsideSingleton2D TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_Extracts_b_ElementInsideSingleton2DArray) { BSONObj keyPattern = fromjson("{'a.0.0.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [[{b: 1}]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -946,7 +947,7 @@ TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_ExtractsEachValueFrom_b_ArrayInsideSingleton2DArray) { BSONObj keyPattern = fromjson("{'a.0.0.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [[{b: [1, 2, 3]}]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -957,7 +958,7 @@ TEST(BtreeKeyGeneratorTest, TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_Extracts_b_ElementInsideSingleton3DArray) { BSONObj keyPattern = fromjson("{'a.0.0.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [[[ {b: 1} ]]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -966,7 +967,7 @@ TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_Extracts_b_ElementInsideSingleton TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_ExtractsEach_b_ElementInside3DArray) { BSONObj keyPattern = fromjson("{'a.0.0.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [[[{b: 1}, {b: 2}, {b: 3}]]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 1}")); expectedKeys.insert(fromjson("{'': 2}")); expectedKeys.insert(fromjson("{'': 3}")); @@ -977,7 +978,7 @@ TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_ExtractsEach_b_ElementInside3DArr TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_ExtractsNullFrom4DArray) { BSONObj keyPattern = fromjson("{'a.0.0.b': 1}"); BSONObj genKeysFrom = fromjson("{a: [[[[ {b: 1} ]]]]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': null}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -986,7 +987,7 @@ TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_ExtractsNullFrom4DArray) { TEST(BtreeKeyGeneratorTest, PositionalKeyPatternNestedArrays5) { BSONObj keyPattern = fromjson("{'a.b.1': 1}"); BSONObj genKeysFrom = fromjson("{a: [{b: [1, 2]}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 2}")); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); @@ -996,7 +997,7 @@ TEST(BtreeKeyGeneratorTest, PositionalKeyPatternNestedArrays5) { TEST(BtreeKeyGeneratorTest, PositionalKeyPatternNestedArrays6) { BSONObj keyPattern = fromjson("{'a': 1, 'a.b': 1, 'a.0.b':1, 'a.b.0': 1, 'a.0.b.0': 1}"); BSONObj genKeysFrom = fromjson("{a: [{b: [1,2]}, {b: 3}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': {b:3}, '': 3, '': 1, '': null, '': 1}")); expectedKeys.insert(fromjson("{'': {b:3}, '': 3, '': 2, '': null, '': 1}")); expectedKeys.insert(fromjson("{'': {b:[1,2]}, '': 1, '': 1, '': 1, '': 1}")); @@ -1009,7 +1010,7 @@ TEST(BtreeKeyGeneratorTest, PositionalKeyPatternNestedArrays6) { TEST(BtreeKeyGeneratorTest, PositionalKeyPatternNestedArrays7) { BSONObj keyPattern = fromjson("{'a': 1, 'a.b': 1, 'a.0.b':1, 'a.b.0': 1, 'a.0.b.0': 1}"); BSONObj genKeysFrom = fromjson("{a: [{b: [1,2]}, {b: {'0': 3}}]}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': {b:{'0':3}}, '': {'0':3}, '': 1, '': 3, '': 1}")); expectedKeys.insert(fromjson("{'': {b:{'0':3}}, '': {'0':3}, '': 2, '': 3, '': 1}")); expectedKeys.insert(fromjson("{'': {b:[1,2]}, '': 1, '': 1, '': 1, '': 1}")); @@ -1021,7 +1022,7 @@ TEST(BtreeKeyGeneratorTest, PositionalKeyPatternNestedArrays7) { TEST(BtreeKeyGeneratorTest, GetCollationAwareIdKeyFromObject) { BSONObj keyPattern = fromjson("{_id: 1}"); BSONObj genKeysFrom = fromjson("{_id: 'foo', b: 4}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 'oof'}")); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; @@ -1032,7 +1033,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareIdKeyFromObject) { TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromObjectSimple) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{b: 4, a: 'foo'}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 'oof'}")); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; @@ -1043,7 +1044,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromObjectSimple) { TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromObjectDotted) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a: {b: 'foo'}, c: 4}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 'oof'}")); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; @@ -1054,7 +1055,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromObjectDotted) { TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromArraySimple) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{a: ['foo', 'bar', 'baz']}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 'oof'}")); expectedKeys.insert(fromjson("{'': 'rab'}")); expectedKeys.insert(fromjson("{'': 'zab'}")); @@ -1067,7 +1068,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromArraySimple) { TEST(BtreeKeyGeneratorTest, CollatorDoesNotAffectNonStringIdKey) { BSONObj keyPattern = fromjson("{_id: 1}"); BSONObj genKeysFrom = fromjson("{_id: 5, b: 4}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 5}")); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; @@ -1078,7 +1079,7 @@ TEST(BtreeKeyGeneratorTest, CollatorDoesNotAffectNonStringIdKey) { TEST(BtreeKeyGeneratorTest, CollatorDoesNotAffectNonStringKeys) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{b: 4, a: 5}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': 5}")); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; @@ -1089,7 +1090,7 @@ TEST(BtreeKeyGeneratorTest, CollatorDoesNotAffectNonStringKeys) { TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromNestedObject) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{b: 4, a: {c: 'foo'}}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': {c: 'oof'}}")); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; @@ -1100,7 +1101,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromNestedObject) { TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromNestedArray) { BSONObj keyPattern = fromjson("{a: 1}"); BSONObj genKeysFrom = fromjson("{b: 4, a: {c: ['foo', 'bar', 'baz']}}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(fromjson("{'': {c: ['oof', 'rab', 'zab']}}")); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; diff --git a/src/mongo/db/index/expression_keys_private.cpp b/src/mongo/db/index/expression_keys_private.cpp index 89f8614f0b2..00edf43e3ce 100644 --- a/src/mongo/db/index/expression_keys_private.cpp +++ b/src/mongo/db/index/expression_keys_private.cpp @@ -32,6 +32,7 @@ #include <utility> +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/bson/dotted_path_support.h" #include "mongo/db/field_ref.h" #include "mongo/db/fts/fts_index_format.h" @@ -460,7 +461,7 @@ void ExpressionKeysPrivate::getS2Keys(const BSONObj& obj, const S2IndexingParams& params, BSONObjSet* keys, MultikeyPaths* multikeyPaths) { - BSONObjSet keysToAdd; + BSONObjSet keysToAdd = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // Does one of our documents have a geo field? bool haveGeoField = false; @@ -490,7 +491,7 @@ void ExpressionKeysPrivate::getS2Keys(const BSONObj& obj, // (b) the last component of the indexed path ever refers to GeoJSON data that requires // multiple cells for its covering. bool lastPathComponentCausesIndexToBeMultikey; - BSONObjSet keysForThisField; + BSONObjSet keysForThisField = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); if (IndexNames::GEO_2DSPHERE == keyElem.valuestr()) { if (params.indexVersion >= S2_INDEX_VERSION_2) { // For >= V2, @@ -546,7 +547,7 @@ void ExpressionKeysPrivate::getS2Keys(const BSONObj& obj, continue; } - BSONObjSet updatedKeysToAdd; + BSONObjSet updatedKeysToAdd = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); for (BSONObjSet::const_iterator it = keysToAdd.begin(); it != keysToAdd.end(); ++it) { for (BSONObjSet::const_iterator newIt = keysForThisField.begin(); newIt != keysForThisField.end(); diff --git a/src/mongo/db/index/expression_keys_private.h b/src/mongo/db/index/expression_keys_private.h index a9b032ea97d..cbb8c9508ee 100644 --- a/src/mongo/db/index/expression_keys_private.h +++ b/src/mongo/db/index/expression_keys_private.h @@ -30,8 +30,8 @@ #include <vector> -#include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonobj.h" +#include "mongo/bson/bsonobj_comparator_interface.h" #include "mongo/db/hasher.h" #include "mongo/db/index/multikey_paths.h" diff --git a/src/mongo/db/index/external_key_generator.cpp b/src/mongo/db/index/external_key_generator.cpp index 192354dc7eb..ed62b1afe74 100644 --- a/src/mongo/db/index/external_key_generator.cpp +++ b/src/mongo/db/index/external_key_generator.cpp @@ -31,6 +31,7 @@ #include <cmath> #include <string> +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/fts/fts_spec.h" #include "mongo/db/index/2d_common.h" #include "mongo/db/index/btree_key_generator.h" @@ -194,7 +195,7 @@ int keyV1Size(const BSONObj& obj) { } // namespace bool isAnyIndexKeyTooLarge(const BSONObj& index, const BSONObj& doc) { - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); getKeysForUpgradeChecking(index, doc, &keys); int largestKeySize = 0; diff --git a/src/mongo/db/index/hash_key_generator_test.cpp b/src/mongo/db/index/hash_key_generator_test.cpp index a6f6600449a..07436bda0fd 100644 --- a/src/mongo/db/index/hash_key_generator_test.cpp +++ b/src/mongo/db/index/hash_key_generator_test.cpp @@ -35,6 +35,7 @@ #include <algorithm> #include "mongo/bson/bsonobjbuilder.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/hasher.h" #include "mongo/db/json.h" #include "mongo/db/query/collation/collator_interface_mock.h" @@ -84,13 +85,13 @@ BSONObj makeHashKey(BSONElement elt) { TEST(HashKeyGeneratorTest, CollationAppliedBeforeHashing) { BSONObj obj = fromjson("{a: 'string'}"); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionKeysPrivate::getHashKeys( obj, "a", kHashSeed, kHashVersion, false, &collator, &actualKeys); BSONObj backwardsObj = fromjson("{a: 'gnirts'}"); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(makeHashKey(backwardsObj["a"])); ASSERT(assertKeysetsEqual(expectedKeys, actualKeys)); @@ -98,12 +99,12 @@ TEST(HashKeyGeneratorTest, CollationAppliedBeforeHashing) { TEST(HashKeyGeneratorTest, CollationDoesNotAffectNonStringFields) { BSONObj obj = fromjson("{a: 5}"); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionKeysPrivate::getHashKeys( obj, "a", kHashSeed, kHashVersion, false, &collator, &actualKeys); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(makeHashKey(obj["a"])); ASSERT(assertKeysetsEqual(expectedKeys, actualKeys)); @@ -112,12 +113,12 @@ TEST(HashKeyGeneratorTest, CollationDoesNotAffectNonStringFields) { TEST(HashKeyGeneratorTest, CollatorAppliedBeforeHashingNestedObject) { BSONObj obj = fromjson("{a: {b: 'string'}}"); BSONObj backwardsObj = fromjson("{a: {b: 'gnirts'}}"); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionKeysPrivate::getHashKeys( obj, "a", kHashSeed, kHashVersion, false, &collator, &actualKeys); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(makeHashKey(backwardsObj["a"])); ASSERT(assertKeysetsEqual(expectedKeys, actualKeys)); @@ -125,11 +126,11 @@ TEST(HashKeyGeneratorTest, CollatorAppliedBeforeHashingNestedObject) { TEST(HashKeyGeneratorTest, NoCollation) { BSONObj obj = fromjson("{a: 'string'}"); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); ExpressionKeysPrivate::getHashKeys( obj, "a", kHashSeed, kHashVersion, false, nullptr, &actualKeys); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(makeHashKey(obj["a"])); ASSERT(assertKeysetsEqual(expectedKeys, actualKeys)); diff --git a/src/mongo/db/index/index_access_method.cpp b/src/mongo/db/index/index_access_method.cpp index 93decde8b15..86c045c0257 100644 --- a/src/mongo/db/index/index_access_method.cpp +++ b/src/mongo/db/index/index_access_method.cpp @@ -123,7 +123,7 @@ Status IndexAccessMethod::insert(OperationContext* txn, int64_t* numInserted) { invariant(numInserted); *numInserted = 0; - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths multikeyPaths; // Delegate to the subclass. getKeys(obj, &keys, &multikeyPaths); @@ -201,7 +201,7 @@ Status IndexAccessMethod::remove(OperationContext* txn, int64_t* numDeleted) { invariant(numDeleted); *numDeleted = 0; - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // There's no need to compute the prefixes of the indexed fields that cause the index to be // multikey when removing a document since the index metadata isn't updated when keys are // deleted. @@ -221,7 +221,7 @@ Status IndexAccessMethod::initializeAsEmpty(OperationContext* txn) { } Status IndexAccessMethod::touch(OperationContext* txn, const BSONObj& obj) { - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // There's no need to compute the prefixes of the indexed fields that cause the index to be // multikey when paging a document's index entries into memory. MultikeyPaths* multikeyPaths = nullptr; @@ -242,7 +242,7 @@ Status IndexAccessMethod::touch(OperationContext* txn) const { RecordId IndexAccessMethod::findSingle(OperationContext* txn, const BSONObj& key) const { // Generate the key for this index. - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths* multikeyPaths = nullptr; getKeys(key, &keys, multikeyPaths); invariant(keys.size() == 1); @@ -410,7 +410,7 @@ Status IndexAccessMethod::BulkBuilder::insert(OperationContext* txn, const RecordId& loc, const InsertDeleteOptions& options, int64_t* numInserted) { - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths multikeyPaths; _real->getKeys(obj, &keys, &multikeyPaths); diff --git a/src/mongo/db/index/index_access_method.h b/src/mongo/db/index/index_access_method.h index 35455f5425c..b3647ed3a09 100644 --- a/src/mongo/db/index/index_access_method.h +++ b/src/mongo/db/index/index_access_method.h @@ -32,6 +32,7 @@ #include <memory> #include "mongo/base/disallow_copying.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/jsobj.h" #include "mongo/db/operation_context.h" @@ -295,7 +296,10 @@ private: * validateUpdate fills out the UpdateStatus and update actually applies it. */ class UpdateTicket { - // No public interface +public: + UpdateTicket() + : oldKeys(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), newKeys(oldKeys) {} + private: friend class IndexAccessMethod; diff --git a/src/mongo/db/index/s2_key_generator_test.cpp b/src/mongo/db/index/s2_key_generator_test.cpp index fc126c0272c..82fdbd9c605 100644 --- a/src/mongo/db/index/s2_key_generator_test.cpp +++ b/src/mongo/db/index/s2_key_generator_test.cpp @@ -35,6 +35,7 @@ #include <algorithm> #include "mongo/bson/bsonobjbuilder.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/index/expression_params.h" #include "mongo/db/index/s2_common.h" #include "mongo/db/json.h" @@ -121,7 +122,7 @@ long long getCellID(int x, int y, bool multiPoint = false) { const CollatorInterface* collator = nullptr; ExpressionParams::initialize2dsphereParams(infoObj, collator, ¶ms); - BSONObjSet keys; + BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // There's no need to compute the prefixes of the indexed fields that cause the index to be // multikey when computing the cell id of the geo field. MultikeyPaths* multikeyPaths = nullptr; @@ -142,12 +143,12 @@ TEST(S2KeyGeneratorTest, GetS2KeysFromSubobjectWithArrayOfGeoAndNonGeoSubobjects CollatorInterfaceMock* collator = nullptr; ExpressionParams::initialize2dsphereParams(infoObj, collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys( genKeysFrom, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << 1 << "" << getCellID(0, 0))); expectedKeys.insert(BSON("" << 1 << "" << getCellID(3, 3))); expectedKeys.insert(BSON("" << 2 << "" << getCellID(0, 0))); @@ -168,12 +169,12 @@ TEST(S2KeyGeneratorTest, GetS2KeysFromArrayOfNonGeoSubobjectsWithArrayValues) { CollatorInterfaceMock* collator = nullptr; ExpressionParams::initialize2dsphereParams(infoObj, collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys( genKeysFrom, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << 1 << "" << getCellID(0, 0))); expectedKeys.insert(BSON("" << 2 << "" << getCellID(0, 0))); expectedKeys.insert(BSON("" << 3 << "" << getCellID(0, 0))); @@ -191,13 +192,13 @@ TEST(S2KeyGeneratorTest, GetS2KeysFromMultiPointInGeoField) { CollatorInterfaceMock* collator = nullptr; ExpressionParams::initialize2dsphereParams(infoObj, collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys( genKeysFrom, keyPattern, params, &actualKeys, &actualMultikeyPaths); const bool multiPoint = true; - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << 1 << "" << getCellID(0, 0, multiPoint))); expectedKeys.insert(BSON("" << 1 << "" << getCellID(1, 0, multiPoint))); expectedKeys.insert(BSON("" << 1 << "" << getCellID(1, 1, multiPoint))); @@ -214,11 +215,11 @@ TEST(S2KeyGeneratorTest, CollationAppliedToNonGeoStringFieldAfterGeoField) { CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionParams::initialize2dsphereParams(infoObj, &collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << getCellID(0, 0) << "" << "gnirts")); @@ -235,11 +236,11 @@ TEST(S2KeyGeneratorTest, CollationAppliedToNonGeoStringFieldBeforeGeoField) { CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionParams::initialize2dsphereParams(infoObj, &collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << "gnirts" << "" @@ -258,11 +259,11 @@ TEST(S2KeyGeneratorTest, CollationAppliedToAllNonGeoStringFields) { CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionParams::initialize2dsphereParams(infoObj, &collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << "gnirts" << "" @@ -284,11 +285,11 @@ TEST(S2KeyGeneratorTest, CollationAppliedToNonGeoStringFieldWithMultiplePathComp CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionParams::initialize2dsphereParams(infoObj, &collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << getCellID(0, 0) << "" << "gnirts")); @@ -305,11 +306,11 @@ TEST(S2KeyGeneratorTest, CollationAppliedToStringsInArray) { CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionParams::initialize2dsphereParams(infoObj, &collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << getCellID(0, 0) << "" << "gnirts")); expectedKeys.insert(BSON("" << getCellID(0, 0) << "" @@ -328,11 +329,11 @@ TEST(S2KeyGeneratorTest, CollationAppliedToStringsInAllArrays) { CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionParams::initialize2dsphereParams(infoObj, &collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << getCellID(0, 0) << "" << "gnirts" << "" @@ -362,11 +363,11 @@ TEST(S2KeyGeneratorTest, CollationDoesNotAffectNonStringFields) { CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionParams::initialize2dsphereParams(infoObj, &collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << getCellID(0, 0) << "" << 5)); assertKeysetsEqual(expectedKeys, actualKeys); @@ -382,11 +383,11 @@ TEST(S2KeyGeneratorTest, CollationAppliedToStringsInNestedObjects) { CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); ExpressionParams::initialize2dsphereParams(infoObj, &collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << getCellID(0, 0) << "" << BSON("c" << "gnirts"))); @@ -403,11 +404,11 @@ TEST(S2KeyGeneratorTest, NoCollation) { const CollatorInterface* collator = nullptr; ExpressionParams::initialize2dsphereParams(infoObj, collator, ¶ms); - BSONObjSet actualKeys; + BSONObjSet actualKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); MultikeyPaths actualMultikeyPaths; ExpressionKeysPrivate::getS2Keys(obj, keyPattern, params, &actualKeys, &actualMultikeyPaths); - BSONObjSet expectedKeys; + BSONObjSet expectedKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); expectedKeys.insert(BSON("" << getCellID(0, 0) << "" << "string")); diff --git a/src/mongo/db/pipeline/document_source.cpp b/src/mongo/db/pipeline/document_source.cpp index 5b9b3b39b3b..ae456bf035d 100644 --- a/src/mongo/db/pipeline/document_source.cpp +++ b/src/mongo/db/pipeline/document_source.cpp @@ -102,7 +102,7 @@ void DocumentSource::serializeToArray(vector<Value>& array, bool explain) const } BSONObjSet DocumentSource::allPrefixes(BSONObj obj) { - BSONObjSet out; + BSONObjSet out = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); BSONObj last = {}; for (auto&& field : obj) { @@ -118,7 +118,7 @@ BSONObjSet DocumentSource::allPrefixes(BSONObj obj) { BSONObjSet DocumentSource::truncateSortSet(const BSONObjSet& sorts, const std::set<std::string>& fields) { - BSONObjSet out; + BSONObjSet out = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); for (auto&& sort : sorts) { BSONObjBuilder outputSort; diff --git a/src/mongo/db/pipeline/document_source.h b/src/mongo/db/pipeline/document_source.h index 0af656be9c1..edf17b59a4c 100644 --- a/src/mongo/db/pipeline/document_source.h +++ b/src/mongo/db/pipeline/document_source.h @@ -39,6 +39,7 @@ #include <vector> #include "mongo/base/init.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/client/connpool.h" #include "mongo/db/clientcursor.h" #include "mongo/db/collection_index_usage_tracker.h" @@ -156,7 +157,7 @@ public: * Gets a BSONObjSet representing the sort order(s) of the output of the stage. */ virtual BSONObjSet getOutputSorts() { - return BSONObjSet(); + return SimpleBSONObjComparator::kInstance.makeBSONObjSet(); } /** @@ -765,7 +766,8 @@ public: Value serialize(bool explain = false) const final; boost::intrusive_ptr<DocumentSource> optimize() final; BSONObjSet getOutputSorts() final { - return pSource ? pSource->getOutputSorts() : BSONObjSet(); + return pSource ? pSource->getOutputSorts() + : SimpleBSONObjComparator::kInstance.makeBSONObjSet(); } /** * Attempts to combine with any subsequent $match stages, joining the query objects with a @@ -1250,8 +1252,10 @@ public: boost::optional<Document> getNext() final; const char* getSourceName() const final; BSONObjSet getOutputSorts() final { - return pSource ? pSource->getOutputSorts() : BSONObjSet(); + return pSource ? pSource->getOutputSorts() + : SimpleBSONObjComparator::kInstance.makeBSONObjSet(); } + /** * Attempts to combine with a subsequent $limit stage, setting 'limit' appropriately. */ @@ -1479,7 +1483,8 @@ public: Value serialize(bool explain = false) const final; boost::intrusive_ptr<DocumentSource> optimize() final; BSONObjSet getOutputSorts() final { - return pSource ? pSource->getOutputSorts() : BSONObjSet(); + return pSource ? pSource->getOutputSorts() + : SimpleBSONObjComparator::kInstance.makeBSONObjSet(); } GetDepsReturn getDependencies(DepsTracker* deps) const final { @@ -1612,7 +1617,8 @@ public: } Value serialize(bool explain = false) const final; BSONObjSet getOutputSorts() final { - return {BSON(distanceField->fullPath() << -1)}; + return SimpleBSONObjComparator::kInstance.makeBSONObjSet( + {BSON(distanceField->fullPath() << -1)}); } // Virtuals for SplittableDocumentSource diff --git a/src/mongo/db/pipeline/document_source_graph_lookup.cpp b/src/mongo/db/pipeline/document_source_graph_lookup.cpp index 553525ff6e8..69359b45ff0 100644 --- a/src/mongo/db/pipeline/document_source_graph_lookup.cpp +++ b/src/mongo/db/pipeline/document_source_graph_lookup.cpp @@ -148,7 +148,7 @@ void DocumentSourceGraphLookUp::doBreadthFirstSearch() { shouldPerformAnotherQuery = false; // Check whether each key in the frontier exists in the cache or needs to be queried. - BSONObjSet cached; + BSONObjSet cached = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); auto matchStage = makeMatchStageFromFrontier(&cached); ValueUnorderedSet queried = pExpCtx->getValueComparator().makeUnorderedValueSet(); diff --git a/src/mongo/db/pipeline/document_source_group.cpp b/src/mongo/db/pipeline/document_source_group.cpp index d10eb4dc513..c8da8a74e76 100644 --- a/src/mongo/db/pipeline/document_source_group.cpp +++ b/src/mongo/db/pipeline/document_source_group.cpp @@ -658,7 +658,7 @@ BSONObjSet DocumentSourceGroup::getOutputSorts() { } if (!(_streaming || _spilled)) { - return BSONObjSet(); + return SimpleBSONObjComparator::kInstance.makeBSONObjSet(); } BSONObjBuilder sortOrder; diff --git a/src/mongo/db/pipeline/document_source_mock.cpp b/src/mongo/db/pipeline/document_source_mock.cpp index 26152f07674..7c7170603e5 100644 --- a/src/mongo/db/pipeline/document_source_mock.cpp +++ b/src/mongo/db/pipeline/document_source_mock.cpp @@ -36,11 +36,15 @@ namespace mongo { using boost::intrusive_ptr; DocumentSourceMock::DocumentSourceMock(std::deque<Document> docs) - : DocumentSource(NULL), queue(std::move(docs)) {} + : DocumentSource(NULL), + queue(std::move(docs)), + sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()) {} DocumentSourceMock::DocumentSourceMock(std::deque<Document> docs, const boost::intrusive_ptr<ExpressionContext>& expCtx) - : DocumentSource(expCtx), queue(std::move(docs)) {} + : DocumentSource(expCtx), + queue(std::move(docs)), + sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()) {} const char* DocumentSourceMock::getSourceName() const { return "mock"; diff --git a/src/mongo/db/pipeline/document_source_test.cpp b/src/mongo/db/pipeline/document_source_test.cpp index ba326b9c82d..e4c337b0425 100644 --- a/src/mongo/db/pipeline/document_source_test.cpp +++ b/src/mongo/db/pipeline/document_source_test.cpp @@ -91,30 +91,38 @@ namespace DocumentSourceClass { using mongo::DocumentSource; TEST(TruncateSort, SortTruncatesNormalField) { + SimpleBSONObjComparator bsonComparator{}; BSONObj sortKey = BSON("a" << 1 << "b" << 1 << "c" << 1); - auto truncated = DocumentSource::truncateSortSet({sortKey}, {"b"}); + auto truncated = + DocumentSource::truncateSortSet(bsonComparator.makeBSONObjSet({sortKey}), {"b"}); ASSERT_EQUALS(truncated.size(), 1U); ASSERT_EQUALS(truncated.count(BSON("a" << 1)), 1U); } TEST(TruncateSort, SortTruncatesOnSubfield) { + SimpleBSONObjComparator bsonComparator{}; BSONObj sortKey = BSON("a" << 1 << "b.c" << 1 << "d" << 1); - auto truncated = DocumentSource::truncateSortSet({sortKey}, {"b"}); + auto truncated = + DocumentSource::truncateSortSet(bsonComparator.makeBSONObjSet({sortKey}), {"b"}); ASSERT_EQUALS(truncated.size(), 1U); ASSERT_EQUALS(truncated.count(BSON("a" << 1)), 1U); } TEST(TruncateSort, SortDoesNotTruncateOnParent) { + SimpleBSONObjComparator bsonComparator{}; BSONObj sortKey = BSON("a" << 1 << "b" << 1 << "d" << 1); - auto truncated = DocumentSource::truncateSortSet({sortKey}, {"b.c"}); + auto truncated = + DocumentSource::truncateSortSet(bsonComparator.makeBSONObjSet({sortKey}), {"b.c"}); ASSERT_EQUALS(truncated.size(), 1U); ASSERT_EQUALS(truncated.count(BSON("a" << 1 << "b" << 1 << "d" << 1)), 1U); } TEST(TruncateSort, TruncateSortDedupsSortCorrectly) { + SimpleBSONObjComparator bsonComparator{}; BSONObj sortKeyOne = BSON("a" << 1 << "b" << 1); BSONObj sortKeyTwo = BSON("a" << 1); - auto truncated = DocumentSource::truncateSortSet({sortKeyOne, sortKeyTwo}, {"b"}); + auto truncated = DocumentSource::truncateSortSet( + bsonComparator.makeBSONObjSet({sortKeyOne, sortKeyTwo}), {"b"}); ASSERT_EQUALS(truncated.size(), 1U); ASSERT_EQUALS(truncated.count(BSON("a" << 1)), 1U); } diff --git a/src/mongo/db/pipeline/document_source_unwind.cpp b/src/mongo/db/pipeline/document_source_unwind.cpp index 82bb8f3adbe..87097d6c4f8 100644 --- a/src/mongo/db/pipeline/document_source_unwind.cpp +++ b/src/mongo/db/pipeline/document_source_unwind.cpp @@ -203,7 +203,7 @@ boost::optional<Document> DocumentSourceUnwind::getNext() { } BSONObjSet DocumentSourceUnwind::getOutputSorts() { - BSONObjSet out; + BSONObjSet out = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); std::string unwoundPath = getUnwindPath(); BSONObjSet inputSort = pSource->getOutputSorts(); diff --git a/src/mongo/db/query/collation/collator_interface.h b/src/mongo/db/query/collation/collator_interface.h index 7d44a4c63ed..3bc54e552c7 100644 --- a/src/mongo/db/query/collation/collator_interface.h +++ b/src/mongo/db/query/collation/collator_interface.h @@ -47,8 +47,7 @@ namespace mongo { * * Does not throw exceptions. */ -class CollatorInterface : public StringData::ComparatorInterface, - public BSONObj::ComparatorInterface { +class CollatorInterface : public StringData::ComparatorInterface { MONGO_DISALLOW_COPYING(CollatorInterface); public: @@ -102,8 +101,6 @@ public: */ virtual int compare(StringData left, StringData right) const = 0; - virtual int compare(const BSONObj& left, const BSONObj& right) const = 0; - /** * Hashes the string such that strings which are equal under this collation also have equal * hashes. diff --git a/src/mongo/db/query/collation/collator_interface_icu.cpp b/src/mongo/db/query/collation/collator_interface_icu.cpp index 1040591fef5..12498d12712 100644 --- a/src/mongo/db/query/collation/collator_interface_icu.cpp +++ b/src/mongo/db/query/collation/collator_interface_icu.cpp @@ -71,10 +71,6 @@ int CollatorInterfaceICU::compare(StringData left, StringData right) const { MONGO_UNREACHABLE; } -int CollatorInterfaceICU::compare(const BSONObj& left, const BSONObj& right) const { - return left.woCompare(right, BSONObj(), true, this); -} - CollatorInterface::ComparisonKey CollatorInterfaceICU::getComparisonKey( StringData stringData) const { // A StringPiece is ICU's StringData. They are logically the same abstraction. diff --git a/src/mongo/db/query/collation/collator_interface_icu.h b/src/mongo/db/query/collation/collator_interface_icu.h index c35cc898c37..9bb83824891 100644 --- a/src/mongo/db/query/collation/collator_interface_icu.h +++ b/src/mongo/db/query/collation/collator_interface_icu.h @@ -50,8 +50,6 @@ public: int compare(StringData left, StringData right) const final; - int compare(const BSONObj& left, const BSONObj& right) const final; - ComparisonKey getComparisonKey(StringData stringData) const final; private: diff --git a/src/mongo/db/query/collation/collator_interface_mock.cpp b/src/mongo/db/query/collation/collator_interface_mock.cpp index 74fc7a26f4f..638427bcd99 100644 --- a/src/mongo/db/query/collation/collator_interface_mock.cpp +++ b/src/mongo/db/query/collation/collator_interface_mock.cpp @@ -92,10 +92,6 @@ int CollatorInterfaceMock::compare(StringData left, StringData right) const { MONGO_UNREACHABLE; } -int CollatorInterfaceMock::compare(const BSONObj& left, const BSONObj& right) const { - return left.woCompare(right, BSONObj(), true, this); -} - CollatorInterface::ComparisonKey CollatorInterfaceMock::getComparisonKey( StringData stringData) const { switch (_mockType) { diff --git a/src/mongo/db/query/collation/collator_interface_mock.h b/src/mongo/db/query/collation/collator_interface_mock.h index 6ab8a3d072b..8ef8d63fb83 100644 --- a/src/mongo/db/query/collation/collator_interface_mock.h +++ b/src/mongo/db/query/collation/collator_interface_mock.h @@ -65,8 +65,6 @@ public: int compare(StringData left, StringData right) const final; - int compare(const BSONObj& left, const BSONObj& right) const final; - ComparisonKey getComparisonKey(StringData stringData) const final; private: diff --git a/src/mongo/db/query/get_executor_test.cpp b/src/mongo/db/query/get_executor_test.cpp index 4ad667fc015..1979a178872 100644 --- a/src/mongo/db/query/get_executor_test.cpp +++ b/src/mongo/db/query/get_executor_test.cpp @@ -36,7 +36,7 @@ #include <string> #include <unordered_set> -#include "mongo/bson/bsonmisc.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/json.h" #include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/query_settings.h" @@ -101,7 +101,6 @@ void testAllowedIndices(std::vector<IndexEntry> indexes, ASSERT_FALSE(querySettings.getAllowedIndicesFilter(key)); querySettings.setAllowedIndices(*cq, key, keyPatterns, indexNames); - // Index entry vector should contain 1 entry after filtering. boost::optional<AllowedIndicesFilter> hasFilter = querySettings.getAllowedIndicesFilter(key); ASSERT_TRUE(hasFilter); @@ -120,24 +119,26 @@ void testAllowedIndices(std::vector<IndexEntry> indexes, // Use of index filters to select compound index over single key index. TEST(GetExecutorTest, GetAllowedIndices) { - testAllowedIndices({IndexEntry(fromjson("{a: 1}"), "a_1"), - IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"), - IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")}, - {fromjson("{a: 1, b: 1}")}, - {}, - {"a_1_b_1"}); + testAllowedIndices( + {IndexEntry(fromjson("{a: 1}"), "a_1"), + IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"), + IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")}, + SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{a: 1, b: 1}")}), + {}, + {"a_1_b_1"}); } // Setting index filter referring to non-existent indexes // will effectively disregard the index catalog and // result in the planner generating a collection scan. TEST(GetExecutorTest, GetAllowedIndicesNonExistentIndexKeyPatterns) { - testAllowedIndices({IndexEntry(fromjson("{a: 1}"), "a_1"), - IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"), - IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")}, - {fromjson("{nosuchfield: 1}")}, - {}, - {}); + testAllowedIndices( + {IndexEntry(fromjson("{a: 1}"), "a_1"), + IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"), + IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")}, + SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{nosuchfield: 1}")}), + {}, + {}); } // This test case shows how to force query execution to use @@ -145,7 +146,7 @@ TEST(GetExecutorTest, GetAllowedIndicesNonExistentIndexKeyPatterns) { TEST(GetExecutorTest, GetAllowedIndicesDescendingOrder) { testAllowedIndices( {IndexEntry(fromjson("{a: 1}"), "a_1"), IndexEntry(fromjson("{a: -1}"), "a_-1")}, - {fromjson("{a: -1}")}, + SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{a: -1}")}), {}, {"a_-1"}); } @@ -155,7 +156,7 @@ TEST(GetExecutorTest, GetAllowedIndicesMatchesByName) { {IndexEntry(fromjson("{a: 1}"), "a_1"), IndexEntry(fromjson("{a: 1}"), "a_1:en")}, // BSONObjSet default constructor is explicit, so we cannot copy-list-initialize until // C++14. - BSONObjSet(), + SimpleBSONObjComparator::kInstance.makeBSONObjSet(), {"a_1"}, {"a_1"}); } @@ -163,7 +164,7 @@ TEST(GetExecutorTest, GetAllowedIndicesMatchesByName) { TEST(GetExecutorTest, GetAllowedIndicesMatchesMultipleIndexesByKey) { testAllowedIndices( {IndexEntry(fromjson("{a: 1}"), "a_1"), IndexEntry(fromjson("{a: 1}"), "a_1:en")}, - {fromjson("{a: 1}")}, + SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{a: 1}")}), {}, {"a_1", "a_1:en"}); } diff --git a/src/mongo/db/query/plan_executor.cpp b/src/mongo/db/query/plan_executor.cpp index 3b4159facbc..ec4d3bf0c1d 100644 --- a/src/mongo/db/query/plan_executor.cpp +++ b/src/mongo/db/query/plan_executor.cpp @@ -26,9 +26,11 @@ * it in the license file. */ -#include "mongo/db/query/plan_executor.h" +#include "mongo/platform/basic.h" +#include "mongo/db/query/plan_executor.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop.h" @@ -268,7 +270,7 @@ BSONObjSet PlanExecutor::getOutputSorts() const { } } - return BSONObjSet(); + return SimpleBSONObjComparator::kInstance.makeBSONObjSet(); } OperationContext* PlanExecutor::getOpCtx() const { diff --git a/src/mongo/db/query/planner_access.cpp b/src/mongo/db/query/planner_access.cpp index fd53efbc3c0..b221210c035 100644 --- a/src/mongo/db/query/planner_access.cpp +++ b/src/mongo/db/query/planner_access.cpp @@ -36,6 +36,7 @@ #include <vector> #include "mongo/base/owned_pointer_vector.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/bson/dotted_path_support.h" #include "mongo/db/matcher/expression_array.h" #include "mongo/db/matcher/expression_geo.h" @@ -1093,13 +1094,14 @@ QuerySolutionNode* QueryPlannerAccess::buildIndexedOr(const CanonicalQuery& quer if (!sharedSortOrders.empty()) { for (size_t i = 1; i < ixscanNodes.size(); ++i) { ixscanNodes[i]->computeProperties(); - BSONObjSet isect; + const auto& bsonCmp = SimpleBSONObjComparator::kInstance; + BSONObjSet isect = bsonCmp.makeBSONObjSet(); set_intersection(sharedSortOrders.begin(), sharedSortOrders.end(), ixscanNodes[i]->getSort().begin(), ixscanNodes[i]->getSort().end(), std::inserter(isect, isect.end()), - BSONObjCmp()); + bsonCmp.makeLessThan()); sharedSortOrders = isect; if (sharedSortOrders.empty()) { break; diff --git a/src/mongo/db/query/query_settings.cpp b/src/mongo/db/query/query_settings.cpp index 9499e62a8ae..b5b5aa95473 100644 --- a/src/mongo/db/query/query_settings.cpp +++ b/src/mongo/db/query/query_settings.cpp @@ -39,7 +39,8 @@ namespace mongo { AllowedIndicesFilter::AllowedIndicesFilter(const BSONObjSet& indexKeyPatterns, const std::unordered_set<std::string>& indexNames) - : indexNames(indexNames) { + : indexKeyPatterns(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), + indexNames(indexNames) { for (BSONObjSet::const_iterator i = indexKeyPatterns.begin(); i != indexKeyPatterns.end(); ++i) { const BSONObj& indexKeyPattern = *i; @@ -61,6 +62,7 @@ AllowedIndexEntry::AllowedIndexEntry(const BSONObj& query, sort(sort.getOwned()), projection(projection.getOwned()), collation(collation.getOwned()), + indexKeyPatterns(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), indexNames(indexNames) { for (BSONObjSet::const_iterator i = indexKeyPatterns.begin(); i != indexKeyPatterns.end(); ++i) { diff --git a/src/mongo/db/query/query_settings.h b/src/mongo/db/query/query_settings.h index 24f71ae7e59..ec45629db31 100644 --- a/src/mongo/db/query/query_settings.h +++ b/src/mongo/db/query/query_settings.h @@ -32,8 +32,8 @@ #include <string> #include "mongo/base/disallow_copying.h" -#include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonobj.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/query/canonical_query.h" #include "mongo/db/query/index_entry.h" #include "mongo/db/query/plan_cache.h" diff --git a/src/mongo/db/query/query_settings_test.cpp b/src/mongo/db/query/query_settings_test.cpp index cd61ec241b1..ba54a60c998 100644 --- a/src/mongo/db/query/query_settings_test.cpp +++ b/src/mongo/db/query/query_settings_test.cpp @@ -34,17 +34,20 @@ #include "mongo/bson/bsonobj.h" #include "mongo/bson/json.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/query/index_entry.h" #include "mongo/unittest/unittest.h" using mongo::AllowedIndicesFilter; using mongo::BSONObj; using mongo::IndexEntry; +using mongo::SimpleBSONObjComparator; using mongo::fromjson; namespace { TEST(QuerySettingsTest, AllowedIndicesFilterAllowsIndexesByName) { - AllowedIndicesFilter filter({fromjson("{a:1}")}, {"a_1"}); + SimpleBSONObjComparator bsonCmp; + AllowedIndicesFilter filter(bsonCmp.makeBSONObjSet({fromjson("{a:1}")}), {"a_1"}); IndexEntry a_idx(fromjson("{a:1, b:1}"), false, false, false, "a_1", nullptr, BSONObj()); IndexEntry ab_idx(fromjson("{a:1, b:1}"), false, false, false, "a_1:2", nullptr, BSONObj()); @@ -53,7 +56,8 @@ TEST(QuerySettingsTest, AllowedIndicesFilterAllowsIndexesByName) { } TEST(QuerySettingsTest, AllowedIndicesFilterAllowsIndexesByKeyPattern) { - AllowedIndicesFilter filter({fromjson("{a:1}")}, {"a"}); + SimpleBSONObjComparator bsonCmp; + AllowedIndicesFilter filter(bsonCmp.makeBSONObjSet({fromjson("{a:1}")}), {"a"}); IndexEntry a_idx(fromjson("{a:1}"), false, false, false, "foo", nullptr, BSONObj()); IndexEntry ab_idx(fromjson("{a:1, b:1}"), false, false, false, "bar", nullptr, BSONObj()); diff --git a/src/mongo/db/query/query_solution.cpp b/src/mongo/db/query/query_solution.cpp index 2cf4dc81c36..ade1cf451b1 100644 --- a/src/mongo/db/query/query_solution.cpp +++ b/src/mongo/db/query/query_solution.cpp @@ -217,7 +217,11 @@ QuerySolutionNode* TextNode::clone() const { // CollectionScanNode // -CollectionScanNode::CollectionScanNode() : tailable(false), direction(1), maxScan(0) {} +CollectionScanNode::CollectionScanNode() + : _sort(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), + tailable(false), + direction(1), + maxScan(0) {} void CollectionScanNode::appendToString(mongoutils::str::stream* ss, int indent) const { addIndent(ss, indent); @@ -248,7 +252,7 @@ QuerySolutionNode* CollectionScanNode::clone() const { // AndHashNode // -AndHashNode::AndHashNode() {} +AndHashNode::AndHashNode() : _sort(SimpleBSONObjComparator::kInstance.makeBSONObjSet()) {} AndHashNode::~AndHashNode() {} @@ -302,7 +306,7 @@ QuerySolutionNode* AndHashNode::clone() const { // AndSortedNode // -AndSortedNode::AndSortedNode() {} +AndSortedNode::AndSortedNode() : _sort(SimpleBSONObjComparator::kInstance.makeBSONObjSet()) {} AndSortedNode::~AndSortedNode() {} @@ -352,7 +356,7 @@ QuerySolutionNode* AndSortedNode::clone() const { // OrNode // -OrNode::OrNode() : dedup(true) {} +OrNode::OrNode() : _sort(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), dedup(true) {} OrNode::~OrNode() {} @@ -412,7 +416,8 @@ QuerySolutionNode* OrNode::clone() const { // MergeSortNode // -MergeSortNode::MergeSortNode() : dedup(true) {} +MergeSortNode::MergeSortNode() + : _sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), dedup(true) {} MergeSortNode::~MergeSortNode() {} @@ -473,7 +478,7 @@ QuerySolutionNode* MergeSortNode::clone() const { // FetchNode // -FetchNode::FetchNode() {} +FetchNode::FetchNode() : _sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()) {} void FetchNode::appendToString(mongoutils::str::stream* ss, int indent) const { addIndent(ss, indent); @@ -505,7 +510,8 @@ QuerySolutionNode* FetchNode::clone() const { // IndexScanNode::IndexScanNode(IndexEntry index) - : index(std::move(index)), + : _sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), + index(std::move(index)), direction(1), maxScan(0), addKeyMetadata(false), diff --git a/src/mongo/db/query/query_solution.h b/src/mongo/db/query/query_solution.h index aca56fcded6..7e68378042d 100644 --- a/src/mongo/db/query/query_solution.h +++ b/src/mongo/db/query/query_solution.h @@ -30,6 +30,7 @@ #include <memory> +#include "mongo/bson/bsonobj_comparator_interface.h" #include "mongo/db/fts/fts_query.h" #include "mongo/db/jsobj.h" #include "mongo/db/matcher/expression.h" @@ -217,7 +218,9 @@ private: }; struct TextNode : public QuerySolutionNode { - TextNode(IndexEntry index) : index(std::move(index)) {} + TextNode(IndexEntry index) + : _sort(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), index(std::move(index)) {} + virtual ~TextNode() {} virtual StageType getType() const { @@ -501,7 +504,11 @@ struct ProjectionNode : public QuerySolutionNode { SIMPLE_DOC, }; - ProjectionNode(ParsedProjection proj) : fullExpression(NULL), projType(DEFAULT), parsed(proj) {} + ProjectionNode(ParsedProjection proj) + : _sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), + fullExpression(NULL), + projType(DEFAULT), + parsed(proj) {} virtual ~ProjectionNode() {} @@ -599,7 +606,8 @@ struct SortKeyGeneratorNode : public QuerySolutionNode { }; struct SortNode : public QuerySolutionNode { - SortNode() : limit(0) {} + SortNode() : _sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), limit(0) {} + virtual ~SortNode() {} virtual StageType getType() const { @@ -698,7 +706,11 @@ struct SkipNode : public QuerySolutionNode { // This is a standalone stage. struct GeoNear2DNode : public QuerySolutionNode { GeoNear2DNode(IndexEntry index) - : index(std::move(index)), addPointMeta(false), addDistMeta(false) {} + : _sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), + index(std::move(index)), + addPointMeta(false), + addDistMeta(false) {} + virtual ~GeoNear2DNode() {} virtual StageType getType() const { @@ -735,7 +747,11 @@ struct GeoNear2DNode : public QuerySolutionNode { // This is actually its own standalone stage. struct GeoNear2DSphereNode : public QuerySolutionNode { GeoNear2DSphereNode(IndexEntry index) - : index(std::move(index)), addPointMeta(false), addDistMeta(false) {} + : _sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), + index(std::move(index)), + addPointMeta(false), + addDistMeta(false) {} + virtual ~GeoNear2DSphereNode() {} virtual StageType getType() const { @@ -810,7 +826,8 @@ struct ShardingFilterNode : public QuerySolutionNode { * into the query result stream. */ struct KeepMutationsNode : public QuerySolutionNode { - KeepMutationsNode() {} + KeepMutationsNode() : sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()) {} + virtual ~KeepMutationsNode() {} virtual StageType getType() const { @@ -846,7 +863,9 @@ struct KeepMutationsNode : public QuerySolutionNode { * *always* skip over the current key to the next key. */ struct DistinctNode : public QuerySolutionNode { - DistinctNode(IndexEntry index) : index(std::move(index)) {} + DistinctNode(IndexEntry index) + : sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), index(std::move(index)) {} + virtual ~DistinctNode() {} virtual StageType getType() const { @@ -885,7 +904,9 @@ struct DistinctNode : public QuerySolutionNode { * Btree. */ struct CountScanNode : public QuerySolutionNode { - CountScanNode(IndexEntry index) : index(std::move(index)) {} + CountScanNode(IndexEntry index) + : sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()), index(std::move(index)) {} + virtual ~CountScanNode() {} virtual StageType getType() const { diff --git a/src/mongo/db/range_arithmetic.h b/src/mongo/db/range_arithmetic.h index 09682ada033..f15e955aeba 100644 --- a/src/mongo/db/range_arithmetic.h +++ b/src/mongo/db/range_arithmetic.h @@ -32,6 +32,7 @@ #include <string> #include <vector> +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/jsobj.h" namespace mongo { @@ -108,7 +109,7 @@ int compareRanges(const BSONObj& rangeMin1, * NOTE: For overlap testing to work correctly, there may be no overlaps present in the map * itself. */ -typedef std::map<BSONObj, BSONObj, BSONObjCmp> RangeMap; +typedef BSONObjIndexedMap<BSONObj> RangeMap; /** * A RangeVector is a list of [lower,upper) ranges. diff --git a/src/mongo/db/range_arithmetic_test.cpp b/src/mongo/db/range_arithmetic_test.cpp index 074e9efe0cb..afec7e05e36 100644 --- a/src/mongo/db/range_arithmetic_test.cpp +++ b/src/mongo/db/range_arithmetic_test.cpp @@ -31,12 +31,14 @@ namespace { -using mongo::MINKEY; +using mongo::BSONObj; using mongo::MAXKEY; -using mongo::rangeOverlaps; -using mongo::rangeMapOverlaps; +using mongo::MINKEY; using mongo::RangeMap; using mongo::RangeVector; +using mongo::SimpleBSONObjComparator; +using mongo::rangeMapOverlaps; +using mongo::rangeOverlaps; using std::make_pair; TEST(BSONRange, SmallerLowerRangeNonSubset) { @@ -76,7 +78,8 @@ TEST(BSONRange, EqualRange) { } TEST(RangeMap, RangeMapOverlap) { - RangeMap rangeMap; + SimpleBSONObjComparator bsonCmp; + RangeMap rangeMap = bsonCmp.makeBSONObjIndexedMap<BSONObj>(); rangeMap.insert(make_pair(BSON("x" << 100), BSON("x" << 200))); rangeMap.insert(make_pair(BSON("x" << 200), BSON("x" << 300))); rangeMap.insert(make_pair(BSON("x" << 300), BSON("x" << 400))); @@ -89,7 +92,8 @@ TEST(RangeMap, RangeMapOverlap) { } TEST(RangeMap, RangeMapOverlapPartial) { - RangeMap rangeMap; + SimpleBSONObjComparator bsonCmp; + RangeMap rangeMap = bsonCmp.makeBSONObjIndexedMap<BSONObj>(); rangeMap.insert(make_pair(BSON("x" << 100), BSON("x" << 200))); rangeMap.insert(make_pair(BSON("x" << 200), BSON("x" << 300))); @@ -101,7 +105,8 @@ TEST(RangeMap, RangeMapOverlapPartial) { } TEST(RangeMap, RangeMapOverlapInner) { - RangeMap rangeMap; + SimpleBSONObjComparator bsonCmp; + RangeMap rangeMap = bsonCmp.makeBSONObjIndexedMap<BSONObj>(); rangeMap.insert(make_pair(BSON("x" << 100), BSON("x" << 200))); RangeVector overlap; @@ -112,7 +117,8 @@ TEST(RangeMap, RangeMapOverlapInner) { } TEST(RangeMap, RangeMapNoOverlap) { - RangeMap rangeMap; + SimpleBSONObjComparator bsonCmp; + RangeMap rangeMap = bsonCmp.makeBSONObjIndexedMap<BSONObj>(); rangeMap.insert(make_pair(BSON("x" << 100), BSON("x" << 200))); rangeMap.insert(make_pair(BSON("x" << 300), BSON("x" << 400))); @@ -123,7 +129,8 @@ TEST(RangeMap, RangeMapNoOverlap) { } TEST(RangeMap, RangeMapOverlaps) { - RangeMap rangeMap; + SimpleBSONObjComparator bsonCmp; + RangeMap rangeMap = bsonCmp.makeBSONObjIndexedMap<BSONObj>(); rangeMap.insert(make_pair(BSON("x" << 100), BSON("x" << 200))); ASSERT(rangeMapOverlaps(rangeMap, BSON("x" << 100), BSON("x" << 200))); @@ -135,7 +142,8 @@ TEST(RangeMap, RangeMapOverlaps) { } TEST(RangeMap, RangeMapContains) { - RangeMap rangeMap; + SimpleBSONObjComparator bsonCmp; + RangeMap rangeMap = bsonCmp.makeBSONObjIndexedMap<BSONObj>(); rangeMap.insert(make_pair(BSON("x" << 100), BSON("x" << 200))); ASSERT(rangeMapContains(rangeMap, BSON("x" << 100), BSON("x" << 200))); @@ -144,7 +152,8 @@ TEST(RangeMap, RangeMapContains) { } TEST(RangeMap, RangeMapContainsMinMax) { - RangeMap rangeMap; + SimpleBSONObjComparator bsonCmp; + RangeMap rangeMap = bsonCmp.makeBSONObjIndexedMap<BSONObj>(); rangeMap.insert(make_pair(BSON("x" << MINKEY), BSON("x" << MAXKEY))); ASSERT(rangeMapContains(rangeMap, BSON("x" << MINKEY), BSON("x" << MAXKEY))); diff --git a/src/mongo/db/s/collection_metadata.cpp b/src/mongo/db/s/collection_metadata.cpp index 78815711446..4a644cfbbdb 100644 --- a/src/mongo/db/s/collection_metadata.cpp +++ b/src/mongo/db/s/collection_metadata.cpp @@ -47,12 +47,18 @@ using std::string; using std::vector; using str::stream; -CollectionMetadata::CollectionMetadata() = default; +CollectionMetadata::CollectionMetadata() + : _pendingMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>()), + _chunksMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>()), + _rangesMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>()) {} CollectionMetadata::CollectionMetadata(const BSONObj& keyPattern, ChunkVersion collectionVersion) : _collVersion(collectionVersion), _shardVersion(ChunkVersion(0, 0, collectionVersion.epoch())), - _keyPattern(keyPattern.getOwned()) {} + _keyPattern(keyPattern.getOwned()), + _pendingMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>()), + _chunksMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>()), + _rangesMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>()) {} CollectionMetadata::~CollectionMetadata() = default; diff --git a/src/mongo/db/s/metadata_manager.cpp b/src/mongo/db/s/metadata_manager.cpp index c51b4a4ba7a..72ee11d752c 100644 --- a/src/mongo/db/s/metadata_manager.cpp +++ b/src/mongo/db/s/metadata_manager.cpp @@ -46,7 +46,10 @@ using CallbackArgs = executor::TaskExecutor::CallbackArgs; MetadataManager::MetadataManager(ServiceContext* sc, NamespaceString nss) : _nss(std::move(nss)), _serviceContext(sc), - _activeMetadataTracker(stdx::make_unique<CollectionMetadataTracker>(nullptr)) {} + _activeMetadataTracker(stdx::make_unique<CollectionMetadataTracker>(nullptr)), + _receivingChunks(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>()), + _rangesToClean( + SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<RangeToCleanDescriptor>()) {} MetadataManager::~MetadataManager() { stdx::lock_guard<stdx::mutex> scopedLock(_managerLock); @@ -320,7 +323,7 @@ RangeMap MetadataManager::getCopyOfRangesToClean() { } RangeMap MetadataManager::_getCopyOfRangesToClean_inlock() { - RangeMap ranges; + RangeMap ranges = SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>(); for (auto it = _rangesToClean.begin(); it != _rangesToClean.end(); ++it) { ranges.insert(std::make_pair(it->first, it->second.getMax())); } diff --git a/src/mongo/db/s/metadata_manager.h b/src/mongo/db/s/metadata_manager.h index de672e89e65..868c48bcb9d 100644 --- a/src/mongo/db/s/metadata_manager.h +++ b/src/mongo/db/s/metadata_manager.h @@ -32,6 +32,7 @@ #include <memory> #include "mongo/base/disallow_copying.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/namespace_string.h" #include "mongo/db/s/collection_metadata.h" #include "mongo/db/service_context.h" @@ -220,7 +221,7 @@ private: RangeMap _receivingChunks; // Set of ranges to be deleted. Indexed by the min key of the range. - typedef std::map<BSONObj, RangeToCleanDescriptor, BSONObjCmp> RangeToCleanMap; + typedef BSONObjIndexedMap<RangeToCleanDescriptor> RangeToCleanMap; RangeToCleanMap _rangesToClean; }; diff --git a/src/mongo/db/s/split_vector_command.cpp b/src/mongo/db/s/split_vector_command.cpp index e00377e5a13..9e2ad5fde75 100644 --- a/src/mongo/db/s/split_vector_command.cpp +++ b/src/mongo/db/s/split_vector_command.cpp @@ -272,7 +272,7 @@ public: // Use every 'keyCount'-th key as a split point. We add the initial key as a sentinel, // to be removed at the end. If a key appears more times than entries allowed on a // chunk, we issue a warning and split on the following key. - auto tooFrequentKeys = SimpleBSONObjComparator::kInstance.makeOrderedBSONObjSet(); + auto tooFrequentKeys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); splitKeys.push_back(dps::extractElementsBasedOnTemplate( prettyKey(idx->keyPattern(), currKey.getOwned()), keyPattern)); diff --git a/src/mongo/db/storage/key_string_test.cpp b/src/mongo/db/storage/key_string_test.cpp index 662503223e9..07438866435 100644 --- a/src/mongo/db/storage/key_string_test.cpp +++ b/src/mongo/db/storage/key_string_test.cpp @@ -40,6 +40,9 @@ #include <vector> #include "mongo/base/owned_pointer_vector.h" +#include "mongo/base/simple_string_data_comparator.h" +#include "mongo/bson/bsonobj_comparator.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/config.h" #include "mongo/db/storage/key_string.h" #include "mongo/platform/decimal128.h" @@ -717,7 +720,10 @@ void testPermutation(KeyString::Version version, log() << "ordering: " << orderObj; std::vector<BSONObj> elements = elementsOrig; - std::stable_sort(elements.begin(), elements.end(), BSONObjCmp(orderObj)); + BSONObjComparator bsonCmp(orderObj, + BSONObjComparator::FieldNamesMode::kConsider, + &SimpleStringDataComparator::kInstance); + std::stable_sort(elements.begin(), elements.end(), bsonCmp.makeLessThan()); for (size_t i = 0; i < elements.size(); i++) { const BSONObj& o1 = elements[i]; diff --git a/src/mongo/dbtests/index_access_method_test.cpp b/src/mongo/dbtests/index_access_method_test.cpp index 59c769d6e87..44ee0eddabd 100644 --- a/src/mongo/dbtests/index_access_method_test.cpp +++ b/src/mongo/dbtests/index_access_method_test.cpp @@ -29,6 +29,7 @@ #include "mongo/platform/basic.h" #include "mongo/bson/bsonobj.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/index/index_access_method.h" #include "mongo/db/json.h" #include "mongo/unittest/unittest.h" @@ -39,38 +40,42 @@ namespace { using std::vector; TEST(IndexAccessMethodSetDifference, EmptyInputsShouldHaveNoDifference) { - BSONObjSet left{}; - BSONObjSet right{}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = bsonCmp.makeBSONObjSet(); + BSONObjSet right = bsonCmp.makeBSONObjSet(); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQ(0UL, diff.first.size()); ASSERT_EQ(0UL, diff.second.size()); } TEST(IndexAccessMethodSetDifference, EmptyLeftShouldHaveNoDifference) { - BSONObjSet left{}; - BSONObjSet right = {BSON("" << 0)}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = bsonCmp.makeBSONObjSet(); + BSONObjSet right = bsonCmp.makeBSONObjSet({BSON("" << 0)}); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQ(0UL, diff.first.size()); ASSERT_EQ(1UL, diff.second.size()); } TEST(IndexAccessMethodSetDifference, EmptyRightShouldReturnAllOfLeft) { - BSONObjSet left = {BSON("" << 0), BSON("" << 1)}; - BSONObjSet right{}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = bsonCmp.makeBSONObjSet({BSON("" << 0), BSON("" << 1)}); + BSONObjSet right = bsonCmp.makeBSONObjSet(); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQ(2UL, diff.first.size()); ASSERT_EQ(0UL, diff.second.size()); } TEST(IndexAccessMethodSetDifference, IdenticalSetsShouldHaveNoDifference) { - BSONObjSet left = {BSON("" << 0), - BSON("" - << "string"), - BSON("" << BSONNULL)}; - BSONObjSet right = {BSON("" << 0), - BSON("" - << "string"), - BSON("" << BSONNULL)}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = bsonCmp.makeBSONObjSet({BSON("" << 0), + BSON("" + << "string"), + BSON("" << BSONNULL)}); + BSONObjSet right = bsonCmp.makeBSONObjSet({BSON("" << 0), + BSON("" + << "string"), + BSON("" << BSONNULL)}); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQ(0UL, diff.first.size()); ASSERT_EQ(0UL, diff.second.size()); @@ -81,8 +86,9 @@ TEST(IndexAccessMethodSetDifference, IdenticalSetsShouldHaveNoDifference) { // void assertDistinct(BSONObj left, BSONObj right) { - BSONObjSet leftSet = {left}; - BSONObjSet rightSet = {right}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet leftSet = bsonCmp.makeBSONObjSet({left}); + BSONObjSet rightSet = bsonCmp.makeBSONObjSet({right}); auto diff = IndexAccessMethod::setDifference(leftSet, rightSet); ASSERT_EQ(1UL, diff.first.size()); ASSERT_EQ(1UL, diff.second.size()); @@ -120,46 +126,52 @@ TEST(IndexAccessMethodSetDifference, ZerosOfDifferentTypesAreNotEquivalent) { } TEST(IndexAccessMethodSetDifference, ShouldDetectOneDifferenceAmongManySimilarities) { - BSONObjSet left = {BSON("" << 0), - BSON("" - << "string"), - BSON("" << BSONNULL), - BSON("" << static_cast<long long>(1)), // This is different. - BSON("" << BSON("sub" - << "document")), - BSON("" << BSON_ARRAY(1 << "hi" << 42))}; - BSONObjSet right = {BSON("" << 0), - BSON("" - << "string"), - BSON("" << BSONNULL), - BSON("" << static_cast<double>(1.0)), // This is different. - BSON("" << BSON("sub" - << "document")), - BSON("" << BSON_ARRAY(1 << "hi" << 42))}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = + bsonCmp.makeBSONObjSet({BSON("" << 0), + BSON("" + << "string"), + BSON("" << BSONNULL), + BSON("" << static_cast<long long>(1)), // This is different. + BSON("" << BSON("sub" + << "document")), + BSON("" << BSON_ARRAY(1 << "hi" << 42))}); + BSONObjSet right = + bsonCmp.makeBSONObjSet({BSON("" << 0), + BSON("" + << "string"), + BSON("" << BSONNULL), + BSON("" << static_cast<double>(1.0)), // This is different. + BSON("" << BSON("sub" + << "document")), + BSON("" << BSON_ARRAY(1 << "hi" << 42))}); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQUALS(1UL, diff.first.size()); ASSERT_EQUALS(1UL, diff.second.size()); } TEST(IndexAccessMethodSetDifference, SingleObjInLeftShouldFindCorrespondingObjInRight) { - BSONObjSet left = {BSON("" << 2)}; - BSONObjSet right = {BSON("" << 1), BSON("" << 2), BSON("" << 3)}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = bsonCmp.makeBSONObjSet({BSON("" << 2)}); + BSONObjSet right = bsonCmp.makeBSONObjSet({BSON("" << 1), BSON("" << 2), BSON("" << 3)}); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQUALS(0UL, diff.first.size()); ASSERT_EQUALS(2UL, diff.second.size()); } TEST(IndexAccessMethodSetDifference, SingleObjInRightShouldFindCorrespondingObjInLeft) { - BSONObjSet left = {BSON("" << 1), BSON("" << 2), BSON("" << 3)}; - BSONObjSet right = {BSON("" << 2)}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = bsonCmp.makeBSONObjSet({BSON("" << 1), BSON("" << 2), BSON("" << 3)}); + BSONObjSet right = bsonCmp.makeBSONObjSet({BSON("" << 2)}); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQUALS(2UL, diff.first.size()); ASSERT_EQUALS(0UL, diff.second.size()); } TEST(IndexAccessMethodSetDifference, LeftSetAllSmallerThanRightShouldBeDisjoint) { - BSONObjSet left = {BSON("" << 1), BSON("" << 2), BSON("" << 3)}; - BSONObjSet right = {BSON("" << 4), BSON("" << 5), BSON("" << 6)}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = bsonCmp.makeBSONObjSet({BSON("" << 1), BSON("" << 2), BSON("" << 3)}); + BSONObjSet right = bsonCmp.makeBSONObjSet({BSON("" << 4), BSON("" << 5), BSON("" << 6)}); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQUALS(3UL, diff.first.size()); ASSERT_EQUALS(3UL, diff.second.size()); @@ -172,8 +184,9 @@ TEST(IndexAccessMethodSetDifference, LeftSetAllSmallerThanRightShouldBeDisjoint) } TEST(IndexAccessMethodSetDifference, LeftSetAllLargerThanRightShouldBeDisjoint) { - BSONObjSet left = {BSON("" << 4), BSON("" << 5), BSON("" << 6)}; - BSONObjSet right = {BSON("" << 1), BSON("" << 2), BSON("" << 3)}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = bsonCmp.makeBSONObjSet({BSON("" << 4), BSON("" << 5), BSON("" << 6)}); + BSONObjSet right = bsonCmp.makeBSONObjSet({BSON("" << 1), BSON("" << 2), BSON("" << 3)}); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQUALS(3UL, diff.first.size()); ASSERT_EQUALS(3UL, diff.second.size()); @@ -186,8 +199,11 @@ TEST(IndexAccessMethodSetDifference, LeftSetAllLargerThanRightShouldBeDisjoint) } TEST(IndexAccessMethodSetDifference, ShouldNotReportOverlapsFromNonDisjointSets) { - BSONObjSet left = {BSON("" << 0), BSON("" << 1), BSON("" << 4), BSON("" << 6)}; - BSONObjSet right = {BSON("" << -1), BSON("" << 1), BSON("" << 3), BSON("" << 4), BSON("" << 7)}; + SimpleBSONObjComparator bsonCmp; + BSONObjSet left = + bsonCmp.makeBSONObjSet({BSON("" << 0), BSON("" << 1), BSON("" << 4), BSON("" << 6)}); + BSONObjSet right = bsonCmp.makeBSONObjSet( + {BSON("" << -1), BSON("" << 1), BSON("" << 3), BSON("" << 4), BSON("" << 7)}); auto diff = IndexAccessMethod::setDifference(left, right); ASSERT_EQUALS(2UL, diff.first.size()); // 0, 6. ASSERT_EQUALS(3UL, diff.second.size()); // -1, 3, 7. diff --git a/src/mongo/dbtests/jsobjtests.cpp b/src/mongo/dbtests/jsobjtests.cpp index 34dff8ada09..72d18905a5f 100644 --- a/src/mongo/dbtests/jsobjtests.cpp +++ b/src/mongo/dbtests/jsobjtests.cpp @@ -36,6 +36,7 @@ #include <cmath> #include <iostream> +#include "mongo/bson/bsonobj_comparator.h" #include "mongo/bson/util/builder.h" #include "mongo/db/bson/dotted_path_support.h" #include "mongo/db/jsobj.h" @@ -59,6 +60,18 @@ using std::vector; namespace dps = ::mongo::dotted_path_support; +namespace { + +enum FieldCompareResult { + LEFT_SUBFIELD = -2, + LEFT_BEFORE = -1, + SAME = 0, + RIGHT_BEFORE = 1, + RIGHT_SUBFIELD = 2 +}; + +} // namespace + typedef std::map<std::string, BSONElement> BSONMap; BSONMap bson2map(const BSONObj& obj) { BSONMap m; @@ -1755,8 +1768,10 @@ public: } void test(BSONObj order, BSONObj l, BSONObj r, bool wanted) { - BSONObjCmp c(order); - bool got = c(l, r); + const StringData::ComparatorInterface* stringComparator = nullptr; + BSONObjComparator bsonCmp( + order, BSONObjComparator::FieldNamesMode::kConsider, stringComparator); + bool got = bsonCmp.makeLessThan()(l, r); if (got == wanted) return; cout << " order: " << order << " l: " << l << "r: " << r << " wanted: " << wanted diff --git a/src/mongo/dbtests/namespacetests.cpp b/src/mongo/dbtests/namespacetests.cpp index 479d7d2317c..7be6bdd1b24 100644 --- a/src/mongo/dbtests/namespacetests.cpp +++ b/src/mongo/dbtests/namespacetests.cpp @@ -35,6 +35,7 @@ #include <string> +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/client.h" @@ -100,7 +101,7 @@ public: BSONObj nullObj = BSON("a" << BSONNULL); // Call getKeys on the nullObj. - BSONObjSet nullFieldKeySet; + BSONObjSet nullFieldKeySet = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); const CollatorInterface* collator = nullptr; ExpressionKeysPrivate::getHashKeys(nullObj, "a", 0, 0, false, collator, &nullFieldKeySet); BSONElement nullFieldFromKey = nullFieldKeySet.begin()->firstElement(); @@ -129,7 +130,7 @@ public: << 0x5eed)); BSONObj nullObj = BSON("a" << BSONNULL); - BSONObjSet nullFieldKeySet; + BSONObjSet nullFieldKeySet = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); const CollatorInterface* collator = nullptr; ExpressionKeysPrivate::getHashKeys( nullObj, "a", 0x5eed, 0, false, collator, &nullFieldKeySet); diff --git a/src/mongo/s/balancer/balancer_chunk_selection_policy_impl.cpp b/src/mongo/s/balancer/balancer_chunk_selection_policy_impl.cpp index e2de583f254..b239932ae32 100644 --- a/src/mongo/s/balancer/balancer_chunk_selection_policy_impl.cpp +++ b/src/mongo/s/balancer/balancer_chunk_selection_policy_impl.cpp @@ -50,7 +50,7 @@ namespace mongo { -using ChunkMinimumsSet = BSONObj::ComparatorInterface::BSONObjSet; +using ChunkMinimumsSet = BSONObjSet; using MigrateInfoVector = BalancerChunkSelectionPolicy::MigrateInfoVector; using SplitInfoVector = BalancerChunkSelectionPolicy::SplitInfoVector; using std::shared_ptr; @@ -66,7 +66,7 @@ namespace { StatusWith<std::pair<DistributionStatus, ChunkMinimumsSet>> createCollectionDistributionInfo( OperationContext* txn, const ShardStatisticsVector& allShards, ChunkManager* chunkMgr) { ShardToChunksMap shardToChunksMap; - ChunkMinimumsSet chunkMinimums = SimpleBSONObjComparator::kInstance.makeOrderedBSONObjSet(); + ChunkMinimumsSet chunkMinimums = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // Makes sure there is an entry in shardToChunksMap for every shard, so empty shards will also // be accounted for diff --git a/src/mongo/s/balancer/balancer_policy.cpp b/src/mongo/s/balancer/balancer_policy.cpp index d50751c6974..6be352778aa 100644 --- a/src/mongo/s/balancer/balancer_policy.cpp +++ b/src/mongo/s/balancer/balancer_policy.cpp @@ -56,7 +56,9 @@ const size_t kAggressiveImbalanceThreshold = 1; } // namespace DistributionStatus::DistributionStatus(NamespaceString nss, ShardToChunksMap shardToChunksMap) - : _nss(std::move(nss)), _shardChunks(std::move(shardToChunksMap)) {} + : _nss(std::move(nss)), + _shardChunks(std::move(shardToChunksMap)), + _zoneRanges(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<ZoneRange>()) {} size_t DistributionStatus::totalChunks() const { size_t total = 0; diff --git a/src/mongo/s/balancer/balancer_policy.h b/src/mongo/s/balancer/balancer_policy.h index c6c4627f6a0..965e6519be5 100644 --- a/src/mongo/s/balancer/balancer_policy.h +++ b/src/mongo/s/balancer/balancer_policy.h @@ -30,6 +30,7 @@ #include "mongo/base/disallow_copying.h" #include "mongo/bson/bsonobj.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/s/balancer/cluster_statistics.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/client/shard.h" @@ -127,7 +128,7 @@ public: /** * Returns all tag ranges defined for the collection. */ - const std::map<BSONObj, ZoneRange, BSONObjCmp>& tagRanges() const { + const BSONObjIndexedMap<ZoneRange>& tagRanges() const { return _zoneRanges; } @@ -158,7 +159,7 @@ private: ShardToChunksMap _shardChunks; // Map of zone max key to the zone description - std::map<BSONObj, ZoneRange, BSONObjCmp> _zoneRanges; + BSONObjIndexedMap<ZoneRange> _zoneRanges; // Set of all zones defined for this collection std::set<std::string> _allTags; diff --git a/src/mongo/s/chunk_diff.h b/src/mongo/s/chunk_diff.h index 578ca7e51e9..96144a19ced 100644 --- a/src/mongo/s/chunk_diff.h +++ b/src/mongo/s/chunk_diff.h @@ -30,8 +30,8 @@ #include <string> -#include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonobj.h" +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/s/client/shard.h" namespace mongo { @@ -71,8 +71,8 @@ public: template <class ValType> class ConfigDiffTracker : public ConfigDiffTrackerBase { public: - // Stores ranges indexed by max or min key - typedef typename std::map<BSONObj, ValType, BSONObjCmp> RangeMap; + // Stores ranges indexed by max or min key. + typedef BSONObjIndexedMap<ValType> RangeMap; // Pair of iterators defining a subset of ranges typedef typename std::pair<typename RangeMap::iterator, typename RangeMap::iterator> diff --git a/src/mongo/s/chunk_diff_test.cpp b/src/mongo/s/chunk_diff_test.cpp index 51dd7ea1617..03f93e6c9bf 100644 --- a/src/mongo/s/chunk_diff_test.cpp +++ b/src/mongo/s/chunk_diff_test.cpp @@ -33,6 +33,7 @@ #include <utility> #include <vector> +#include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/jsobj.h" #include "mongo/db/operation_context_noop.h" #include "mongo/platform/random.h" @@ -104,7 +105,7 @@ void convertBSONArrayToChunkTypes(const vector<BSONObj>& chunksArray, class ChunkDiffUnitTest : public mongo::unittest::Test { protected: - typedef map<BSONObj, BSONObj, BSONObjCmp> RangeMap; + typedef BSONObjIndexedMap<BSONObj> RangeMap; typedef map<ShardId, ChunkVersion> VersionMap; ChunkDiffUnitTest() = default; @@ -163,7 +164,7 @@ protected: vector<BSONObj> chunks(std::move(chunksB)); // Setup the empty ranges and versions first - RangeMap ranges; + RangeMap ranges = SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<BSONObj>(); ChunkVersion maxVersion = ChunkVersion(0, 0, OID()); VersionMap maxShardVersions; diff --git a/src/mongo/s/chunk_manager.cpp b/src/mongo/s/chunk_manager.cpp index 4d5868ca8ae..cda67a18e06 100644 --- a/src/mongo/s/chunk_manager.cpp +++ b/src/mongo/s/chunk_manager.cpp @@ -173,13 +173,19 @@ ChunkManager::ChunkManager(const string& ns, _keyPattern(pattern.getKeyPattern()), _defaultCollator(std::move(defaultCollator)), _unique(unique), - _sequenceNumber(NextSequenceNumber.addAndFetch(1)) {} + _sequenceNumber(NextSequenceNumber.addAndFetch(1)), + _chunkMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<std::shared_ptr<Chunk>>()), + _chunkRangeMap( + SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<ShardAndChunkRange>()) {} ChunkManager::ChunkManager(OperationContext* txn, const CollectionType& coll) : _ns(coll.getNs().ns()), _keyPattern(coll.getKeyPattern()), _unique(coll.getUnique()), - _sequenceNumber(NextSequenceNumber.addAndFetch(1)) { + _sequenceNumber(NextSequenceNumber.addAndFetch(1)), + _chunkMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<std::shared_ptr<Chunk>>()), + _chunkRangeMap( + SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<ShardAndChunkRange>()) { // coll does not have correct version. Use same initial version as _load and createFirstChunks. _version = ChunkVersion(0, 0, coll.getEpoch()); @@ -198,7 +204,8 @@ void ChunkManager::loadExistingRanges(OperationContext* txn, const ChunkManager* int tries = 3; while (tries--) { - ChunkMap chunkMap; + ChunkMap chunkMap = + SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<std::shared_ptr<Chunk>>(); set<ShardId> shardIds; ShardVersionMap shardVersions; @@ -404,7 +411,7 @@ void ChunkManager::calcInitSplitsAndShards(OperationContext* txn, shardIds->push_back(primaryShardId); } else { // make sure points are unique and ordered - auto orderedPts = SimpleBSONObjComparator::kInstance.makeOrderedBSONObjSet(); + auto orderedPts = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); for (unsigned i = 0; i < initPoints->size(); ++i) { BSONObj pt = (*initPoints)[i]; orderedPts.insert(pt); @@ -766,7 +773,8 @@ string ChunkManager::toString() const { } ChunkManager::ChunkRangeMap ChunkManager::_constructRanges(const ChunkMap& chunkMap) { - ChunkRangeMap chunkRangeMap; + ChunkRangeMap chunkRangeMap = + SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<ShardAndChunkRange>(); if (chunkMap.empty()) { return chunkRangeMap; diff --git a/src/mongo/s/chunk_manager.h b/src/mongo/s/chunk_manager.h index 35b16ace0da..0dd74ba1711 100644 --- a/src/mongo/s/chunk_manager.h +++ b/src/mongo/s/chunk_manager.h @@ -54,7 +54,7 @@ class OperationContext; typedef std::shared_ptr<ChunkManager> ChunkManagerPtr; // The key for the map is max for each Chunk or ChunkRange -typedef std::map<BSONObj, std::shared_ptr<Chunk>, BSONObjCmp> ChunkMap; +typedef BSONObjIndexedMap<std::shared_ptr<Chunk>> ChunkMap; class ChunkManager { public: @@ -237,7 +237,7 @@ private: // Contains a compressed map of what range of keys resides on which shard. The index is the max // key of the respective range and the union of all ranges in a such constructed map must cover // the complete space from [MinKey, MaxKey). - using ChunkRangeMap = std::map<BSONObj, ShardAndChunkRange, BSONObjCmp>; + using ChunkRangeMap = BSONObjIndexedMap<ShardAndChunkRange>; /** * If load was successful, returns true and it is guaranteed that the _chunkMap and diff --git a/src/mongo/s/chunk_manager_targeter.h b/src/mongo/s/chunk_manager_targeter.h index 25ad4b417b4..949718f0258 100644 --- a/src/mongo/s/chunk_manager_targeter.h +++ b/src/mongo/s/chunk_manager_targeter.h @@ -46,11 +46,11 @@ struct ChunkVersion; struct TargeterStats { TargeterStats() - : chunkSizeDelta(SimpleBSONObjComparator::kInstance.makeOrderedBSONObjMap<int>()) {} + : chunkSizeDelta(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<int>()) {} // Map of chunk shard minKey -> approximate delta. This is used for deciding // whether a chunk might need splitting or not. - BSONObj::ComparatorInterface::BSONObjMap<int> chunkSizeDelta; + BSONObjIndexedMap<int> chunkSizeDelta; }; /** diff --git a/src/mongo/s/commands/cluster_map_reduce_cmd.cpp b/src/mongo/s/commands/cluster_map_reduce_cmd.cpp index efae5d2c4d1..e398609c9e9 100644 --- a/src/mongo/s/commands/cluster_map_reduce_cmd.cpp +++ b/src/mongo/s/commands/cluster_map_reduce_cmd.cpp @@ -326,7 +326,7 @@ public: BSONObjBuilder shardResultsB; BSONObjBuilder shardCountsB; map<string, int64_t> countsMap; - auto splitPts = SimpleBSONObjComparator::kInstance.makeOrderedBSONObjSet(); + auto splitPts = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); { bool ok = true; @@ -510,7 +510,7 @@ public: confOut->getChunkManager(txn, outputCollNss.ns(), true /* force */); } - auto chunkSizes = SimpleBSONObjComparator::kInstance.makeOrderedBSONObjMap<int>(); + auto chunkSizes = SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<int>(); { // Take distributed lock to prevent split / migration. auto scopedDistLock = grid.catalogClient(txn)->distLock( diff --git a/src/mongo/s/commands/commands_public.cpp b/src/mongo/s/commands/commands_public.cpp index a8babdb81d8..cff2718e5c4 100644 --- a/src/mongo/s/commands/commands_public.cpp +++ b/src/mongo/s/commands/commands_public.cpp @@ -30,6 +30,7 @@ #include "mongo/platform/basic.h" +#include "mongo/bson/bsonobj_comparator.h" #include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/bson/util/bson_extract.h" #include "mongo/client/connpool.h" @@ -1213,9 +1214,11 @@ public: set<ShardId> shardIds; cm->getShardIdsForQuery(txn, query, queryCollation.getValue(), &shardIds); - BSONObjSet all(BSONObjCmp(BSONObj(), + BSONObjComparator bsonCmp(BSONObj(), + BSONObjComparator::FieldNamesMode::kConsider, !queryCollation.getValue().isEmpty() ? collator.get() - : cm->getDefaultCollator())); + : cm->getDefaultCollator()); + BSONObjSet all = bsonCmp.makeBSONObjSet(); for (const ShardId& shardId : shardIds) { const auto shard = Grid::get(txn)->shardRegistry()->getShard(txn, shardId); @@ -1244,8 +1247,8 @@ public: BSONObjBuilder b(32); int n = 0; - for (set<BSONObj, BSONObjCmp>::iterator i = all.begin(); i != all.end(); i++) { - b.appendAs(i->firstElement(), b.numStr(n++)); + for (auto&& obj : all) { + b.appendAs(obj.firstElement(), b.numStr(n++)); } result.appendArray("values", b.obj()); |