diff options
author | Henrik Edin <henrik.edin@mongodb.com> | 2020-04-06 10:05:56 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-04-08 21:33:40 +0000 |
commit | 6ef4109428abf1afe7ee73d42155d20cf1966fc0 (patch) | |
tree | e80d4aa1bfe76b9eea600e82b71bb008d82a37ad /src | |
parent | f79261579283f48d186925e7e9450917a8622e5c (diff) | |
download | mongo-6ef4109428abf1afe7ee73d42155d20cf1966fc0.tar.gz |
SERVER-47349 Use flat_set instead of set for KeyStringSet and MultikeyPaths
So we can reduce the amount of small memory allocations and re-use allocated memory.
Diffstat (limited to 'src')
24 files changed, 176 insertions, 169 deletions
diff --git a/src/mongo/db/bson/dotted_path_support.cpp b/src/mongo/db/bson/dotted_path_support.cpp index 53b1e41fa96..4860e5dfd66 100644 --- a/src/mongo/db/bson/dotted_path_support.cpp +++ b/src/mongo/db/bson/dotted_path_support.cpp @@ -53,7 +53,7 @@ void _extractAllElementsAlongPath(const BSONObj& obj, BSONElementColl& elements, bool expandArrayOnTrailingField, size_t depth, - std::set<size_t>* arrayComponents) { + MultikeyComponents* arrayComponents) { BSONElement e = obj.getField(path); if (e.eoo()) { @@ -165,7 +165,7 @@ void extractAllElementsAlongPath(const BSONObj& obj, StringData path, BSONElementSet& elements, bool expandArrayOnTrailingField, - std::set<size_t>* arrayComponents) { + MultikeyComponents* arrayComponents) { const size_t initialDepth = 0; _extractAllElementsAlongPath( obj, path, elements, expandArrayOnTrailingField, initialDepth, arrayComponents); @@ -175,7 +175,7 @@ void extractAllElementsAlongPath(const BSONObj& obj, StringData path, BSONElementMultiSet& elements, bool expandArrayOnTrailingField, - std::set<size_t>* arrayComponents) { + MultikeyComponents* arrayComponents) { const size_t initialDepth = 0; _extractAllElementsAlongPath( obj, path, elements, expandArrayOnTrailingField, initialDepth, arrayComponents); diff --git a/src/mongo/db/bson/dotted_path_support.h b/src/mongo/db/bson/dotted_path_support.h index e4a3f0c407f..b41dd3df3ba 100644 --- a/src/mongo/db/bson/dotted_path_support.h +++ b/src/mongo/db/bson/dotted_path_support.h @@ -30,10 +30,10 @@ #pragma once #include <cstddef> -#include <set> #include "mongo/bson/bsonelement_comparator_interface.h" #include "mongo/bson/bsonobj.h" +#include "mongo/db/index/multikey_paths.h" namespace mongo { namespace dotted_path_support { @@ -102,13 +102,13 @@ void extractAllElementsAlongPath(const BSONObj& obj, StringData path, BSONElementSet& elements, bool expandArrayOnTrailingField = true, - std::set<std::size_t>* arrayComponents = nullptr); + MultikeyComponents* arrayComponents = nullptr); void extractAllElementsAlongPath(const BSONObj& obj, StringData path, BSONElementMultiSet& elements, bool expandArrayOnTrailingField = true, - std::set<std::size_t>* arrayComponents = nullptr); + MultikeyComponents* arrayComponents = nullptr); /** * Returns an owned BSONObj with elements in the same order as they appear in the 'pattern' object diff --git a/src/mongo/db/bson/dotted_path_support_test.cpp b/src/mongo/db/bson/dotted_path_support_test.cpp index bbaac5c6a0f..b41eab52c2f 100644 --- a/src/mongo/db/bson/dotted_path_support_test.cpp +++ b/src/mongo/db/bson/dotted_path_support_test.cpp @@ -147,7 +147,7 @@ void assertBSONElementSetsAreEqual(const std::vector<BSONObj>& expectedObjs, } } -void dumpArrayComponents(const std::set<size_t>& arrayComponents, StringBuilder* sb) { +void dumpArrayComponents(const MultikeyComponents& arrayComponents, StringBuilder* sb) { *sb << "[ "; bool firstIteration = true; for (const auto pos : arrayComponents) { @@ -160,8 +160,8 @@ void dumpArrayComponents(const std::set<size_t>& arrayComponents, StringBuilder* *sb << " ]"; } -void assertArrayComponentsAreEqual(const std::set<size_t>& expectedArrayComponents, - const std::set<size_t>& actualArrayComponents) { +void assertArrayComponentsAreEqual(const MultikeyComponents& expectedArrayComponents, + const MultikeyComponents& actualArrayComponents) { if (expectedArrayComponents != actualArrayComponents) { StringBuilder sb; sb << "Expected: "; @@ -177,12 +177,12 @@ TEST(ExtractAllElementsAlongPath, NestedObjectWithScalarValue) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << 1)}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, NestedObjectWithEmptyArrayValue) { @@ -190,12 +190,12 @@ TEST(ExtractAllElementsAlongPath, NestedObjectWithEmptyArrayValue) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual(std::vector<BSONObj>{}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{1U}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{1U}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, NestedObjectWithEmptyArrayValueAndExpandParamIsFalse) { @@ -203,12 +203,12 @@ TEST(ExtractAllElementsAlongPath, NestedObjectWithEmptyArrayValueAndExpandParamI BSONElementSet actualElements; const bool expandArrayOnTrailingField = false; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << BSONArray())}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, NestedObjectWithSingletonArrayValue) { @@ -216,12 +216,12 @@ TEST(ExtractAllElementsAlongPath, NestedObjectWithSingletonArrayValue) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << 1)}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{1U}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{1U}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, NestedObjectWithSingletonArrayValueAndExpandParamIsFalse) { @@ -229,12 +229,12 @@ TEST(ExtractAllElementsAlongPath, NestedObjectWithSingletonArrayValueAndExpandPa BSONElementSet actualElements; const bool expandArrayOnTrailingField = false; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b.c", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << BSON_ARRAY(3))}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, NestedObjectWithArrayValue) { @@ -242,7 +242,7 @@ TEST(ExtractAllElementsAlongPath, NestedObjectWithArrayValue) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -255,7 +255,7 @@ TEST(ExtractAllElementsAlongPath, ObjectWithArrayOfSubobjectsWithScalarValue) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -270,7 +270,7 @@ TEST(ExtractAllElementsAlongPath, ObjectWithArrayOfSubobjectsWithArrayValues) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -285,7 +285,7 @@ TEST(ExtractAllElementsAlongPath, BSONElementSet actualElements; const bool expandArrayOnTrailingField = false; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -300,7 +300,7 @@ TEST(ExtractAllElementsAlongPath, DoesNotExpandArrayWithinTrailingArray) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -315,7 +315,7 @@ TEST(ExtractAllElementsAlongPath, ObjectWithTwoDimensionalArrayOfSubobjects) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -335,7 +335,7 @@ TEST(ExtractAllElementsAlongPath, ObjectWithDiverseStructure) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b.c", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -348,12 +348,12 @@ TEST(ExtractAllElementsAlongPath, AcceptsNumericFieldNames) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.0", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << 1)}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, UsesNumericFieldNameToExtractElementFromArray) { @@ -361,12 +361,12 @@ TEST(ExtractAllElementsAlongPath, UsesNumericFieldNameToExtractElementFromArray) BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.0", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << 1)}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, TreatsNegativeIndexAsFieldName) { @@ -374,7 +374,7 @@ TEST(ExtractAllElementsAlongPath, TreatsNegativeIndexAsFieldName) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.-1", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -387,12 +387,12 @@ TEST(ExtractAllElementsAlongPath, ExtractsNoValuesFromOutOfBoundsIndex) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.10", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, DoesNotTreatHexStringAsIndexSpecification) { @@ -400,7 +400,7 @@ TEST(ExtractAllElementsAlongPath, DoesNotTreatHexStringAsIndexSpecification) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.0x2", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -413,7 +413,7 @@ TEST(ExtractAllElementsAlongPath, DoesNotAcceptLeadingPlusAsArrayIndex) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.+2", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -426,7 +426,7 @@ TEST(ExtractAllElementsAlongPath, DoesNotAcceptTrailingCharactersForArrayIndex) BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.2xyz", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -439,7 +439,7 @@ TEST(ExtractAllElementsAlongPath, DoesNotAcceptNonDigitsForArrayIndex) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.2x4", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -453,12 +453,12 @@ TEST(ExtractAllElementsAlongPath, BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.2.target", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << 3)}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, DoesExpandMultiplePositionalPathSpecifications) { @@ -466,14 +466,14 @@ TEST(ExtractAllElementsAlongPath, DoesExpandMultiplePositionalPathSpecifications BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.1.0.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << "(1, 0)")}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, DoesAcceptNumericInitialField) { @@ -481,12 +481,12 @@ TEST(ExtractAllElementsAlongPath, DoesAcceptNumericInitialField) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "0", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << 2)}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, DoesExpandArrayFoundAfterPositionalSpecification) { @@ -494,7 +494,7 @@ TEST(ExtractAllElementsAlongPath, DoesExpandArrayFoundAfterPositionalSpecificati BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.1.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -511,12 +511,12 @@ TEST(ExtractAllElementsAlongPath, PositionalElementsNotConsideredArrayComponents BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.0.b.1", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << 2)}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, TrailingArrayIsExpandedEvenIfPositional) { @@ -524,7 +524,7 @@ TEST(ExtractAllElementsAlongPath, TrailingArrayIsExpandedEvenIfPositional) { BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b.1", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -537,12 +537,12 @@ TEST(ExtractAllElementsAlongPath, PositionalTrailingArrayNotExpandedIfExpandPara BSONElementSet actualElements; const bool expandArrayOnTrailingField = false; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b.1", actualElements, expandArrayOnTrailingField, &actualArrayComponents); assertBSONElementSetsAreEqual({BSON("" << BSON_ARRAY(1 << 2))}, actualElements); - assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); + assertArrayComponentsAreEqual(MultikeyComponents{}, actualArrayComponents); } TEST(ExtractAllElementsAlongPath, MidPathEmptyArrayIsConsideredAnArrayComponent) { @@ -550,7 +550,7 @@ TEST(ExtractAllElementsAlongPath, MidPathEmptyArrayIsConsideredAnArrayComponent) BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b.c", actualElements, expandArrayOnTrailingField, &actualArrayComponents); @@ -563,7 +563,7 @@ TEST(ExtractAllElementsAlongPath, MidPathSingletonArrayIsConsideredAnArrayCompon BSONElementSet actualElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> actualArrayComponents; + MultikeyComponents actualArrayComponents; dps::extractAllElementsAlongPath( obj, "a.b.c", actualElements, expandArrayOnTrailingField, &actualArrayComponents); diff --git a/src/mongo/db/fts/fts_index_format.cpp b/src/mongo/db/fts/fts_index_format.cpp index 75d343ccedb..f6f5e379c02 100644 --- a/src/mongo/db/fts/fts_index_format.cpp +++ b/src/mongo/db/fts/fts_index_format.cpp @@ -88,7 +88,7 @@ const size_t termKeyLengthV3 = termKeyPrefixLengthV3 + termKeySuffixLengthV3; BSONElement extractNonFTSKeyElement(const BSONObj& obj, StringData path) { BSONElementSet indexedElements; const bool expandArrayOnTrailingField = true; - std::set<size_t> arrayComponents; + MultikeyComponents arrayComponents; dps::extractAllElementsAlongPath( obj, path, indexedElements, expandArrayOnTrailingField, &arrayComponents); uassert(ErrorCodes::CannotBuildIndexKeys, diff --git a/src/mongo/db/index/btree_key_generator.cpp b/src/mongo/db/index/btree_key_generator.cpp index 0b41e8a7451..bcb44c7caf7 100644 --- a/src/mongo/db/index/btree_key_generator.cpp +++ b/src/mongo/db/index/btree_key_generator.cpp @@ -162,7 +162,7 @@ BSONElement BtreeKeyGenerator::_extractNextElement(const BSONObj& obj, void BtreeKeyGenerator::_getKeysArrEltFixed(std::vector<const char*>* fieldNames, std::vector<BSONElement>* fixed, const BSONElement& arrEntry, - KeyStringSet* keys, + KeyStringSet::sequence_type* keys, unsigned numNotFound, const BSONElement& arrObjElt, const std::set<size_t>& arrIdxs, @@ -236,10 +236,16 @@ void BtreeKeyGenerator::getKeys(const BSONObj& obj, invariant(multikeyPaths->empty()); multikeyPaths->resize(_fieldNames.size()); } + // Extract the underlying sequence and insert elements unsorted to avoid O(N^2) when + // inserting element by element if array + auto seq = keys->extract_sequence(); // '_fieldNames' and '_fixed' are passed by value so that their copies can be mutated as // part of the _getKeysWithArray method. _getKeysWithArray( - _fieldNames, _fixed, obj, keys, 0, _emptyPositionalInfo, multikeyPaths, id); + _fieldNames, _fixed, obj, &seq, 0, _emptyPositionalInfo, multikeyPaths, id); + // Put the sequence back into the set, it will sort and guarantee uniqueness, this is + // O(NlogN) + keys->adopt_sequence(std::move(seq)); } if (keys->empty() && !_isSparse) { @@ -282,7 +288,7 @@ void BtreeKeyGenerator::_getKeysWithoutArray(const BSONObj& obj, void BtreeKeyGenerator::_getKeysWithArray(std::vector<const char*> fieldNames, std::vector<BSONElement> fixed, const BSONObj& obj, - KeyStringSet* keys, + KeyStringSet::sequence_type* keys, unsigned numNotFound, const std::vector<PositionalPathInfo>& positionalInfo, MultikeyPaths* multikeyPaths, @@ -368,7 +374,7 @@ void BtreeKeyGenerator::_getKeysWithArray(std::vector<const char*> fieldNames, if (id) { keyString.appendRecordId(*id); } - keys->insert(keyString.release()); + keys->push_back(keyString.release()); } else if (arrElt.embeddedObject().firstElement().eoo()) { // We've encountered an empty array. if (multikeyPaths && mayExpandArrayUnembedded) { diff --git a/src/mongo/db/index/btree_key_generator.h b/src/mongo/db/index/btree_key_generator.h index 1b1b5d53584..d3afa8c5100 100644 --- a/src/mongo/db/index/btree_key_generator.h +++ b/src/mongo/db/index/btree_key_generator.h @@ -150,7 +150,7 @@ private: void _getKeysWithArray(std::vector<const char*> fieldNames, std::vector<BSONElement> fixed, const BSONObj& obj, - KeyStringSet* keys, + KeyStringSet::sequence_type* keys, unsigned numNotFound, const std::vector<PositionalPathInfo>& positionalInfo, MultikeyPaths* multikeyPaths, @@ -210,7 +210,7 @@ private: void _getKeysArrEltFixed(std::vector<const char*>* fieldNames, std::vector<BSONElement>* fixed, const BSONElement& arrEntry, - KeyStringSet* keys, + KeyStringSet::sequence_type* keys, unsigned numNotFound, const BSONElement& arrObjElt, const std::set<size_t>& arrIdxs, diff --git a/src/mongo/db/index/btree_key_generator_test.cpp b/src/mongo/db/index/btree_key_generator_test.cpp index b25f24a8b35..15cae440526 100644 --- a/src/mongo/db/index/btree_key_generator_test.cpp +++ b/src/mongo/db/index/btree_key_generator_test.cpp @@ -192,7 +192,7 @@ TEST(BtreeKeyGeneratorTest, GetIdKeyFromObject) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': 'foo'}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -202,7 +202,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromObjectSimple) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': 5}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -212,7 +212,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromObjectDotted) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': 4}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -260,7 +260,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArrayFirstElement) { KeyString::HeapBuilder keyString3( KeyString::Version::kLatestVersion, fromjson("{'': 3, '': 2}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.release(), keyString2.release(), keyString3.release()}; - MultikeyPaths expectedMultikeyPaths{{0U}, std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{{0U}, MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -274,7 +274,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArraySecondElement) { KeyString::HeapBuilder keyString3( KeyString::Version::kLatestVersion, fromjson("{'': 5, '': 3}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.release(), keyString2.release(), keyString3.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, {0U}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}, {0U}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -337,7 +337,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysArraySubobjectCompoundIndex) { KeyString::HeapBuilder keyString3( KeyString::Version::kLatestVersion, fromjson("{'': 3, '': 99}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.release(), keyString2.release(), keyString3.release()}; - MultikeyPaths expectedMultikeyPaths{{0U}, std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{{0U}, MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -374,7 +374,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysMissingField) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': null}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -395,7 +395,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromCompound) { fromjson("{'': 'a', '': 'b'}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -406,7 +406,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromCompoundMissing) { fromjson("{'': 'a', '': null}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -552,7 +552,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromMultiEmptyArray) { fromjson("{'': 1, '': undefined}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.getValueCopy(), keyString2.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, {0U}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}, {0U}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); genKeysFrom = fromjson("{a: 1, b: [1]}"); @@ -643,7 +643,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromSparseEmptyArray) { BSONObj keyPattern = fromjson("{'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:1}"); KeyStringSet expectedKeys; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, sparse)); genKeysFrom = fromjson("{a:[]}"); @@ -659,7 +659,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromSparseEmptyArraySecond) { BSONObj keyPattern = fromjson("{z: 1, 'a.b': 1}"); BSONObj genKeysFrom = fromjson("{a:1}"); KeyStringSet expectedKeys; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, sparse)); genKeysFrom = fromjson("{a:[]}"); @@ -699,7 +699,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromIndexedArrayIndex) { KeyString::HeapBuilder keyString3( KeyString::Version::kLatestVersion, fromjson("{'': undefined}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.getValueCopy()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); genKeysFrom = fromjson("{a:[[1]]}"); @@ -742,7 +742,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromDoubleIndexedArrayIndex) { KeyString::HeapBuilder keyString3( KeyString::Version::kLatestVersion, fromjson("{'': undefined}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); genKeysFrom = fromjson("{a:[[]]}"); @@ -762,7 +762,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromDoubleIndexedArrayIndex) { genKeysFrom = fromjson("{a:[[[]]]}"); expectedKeys.clear(); expectedKeys.insert(keyString3.release()); - expectedMultikeyPaths = {std::set<size_t>{}}; + expectedMultikeyPaths = {MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -776,7 +776,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromObjectWithinArray) { KeyString::HeapBuilder keyString3( KeyString::Version::kLatestVersion, fromjson("{'': undefined}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.getValueCopy()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); genKeysFrom = fromjson("{a:[{b:[1]}]}"); @@ -832,7 +832,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysTrailingPositionalElementIsSingletonArray) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': [3]}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -842,7 +842,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysTrailingPositionalElementIsEmptyArray) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': undefined}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -862,7 +862,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFromArrayWithinObjectWithinArray) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': 1}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -1009,7 +1009,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray2) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': [0, 1, 2]}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -1044,7 +1044,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysPositionalKeyPatternNestedArray5) { KeyString::HeapBuilder keyString2( KeyString::Version::kLatestVersion, fromjson("{'': 6}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.release(), keyString2.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{0U}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{0U}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -1087,7 +1087,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysRepeatedFieldName) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': 2}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -1115,7 +1115,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysLastPathPieceEmpty) { KeyString::HeapBuilder keyString2( KeyString::Version::kLatestVersion, fromjson("{'': {'': 2}}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString1.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); genKeysFrom = fromjson("{a: {'': 2}}"); @@ -1130,7 +1130,7 @@ TEST(BtreeKeyGeneratorTest, GetKeysFirstPathPieceEmpty) { KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': null}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -1173,7 +1173,7 @@ TEST(BtreeKeyGeneratorTest, KeyPattern_a_0_0_b_Extracts_b_ElementInsideSingleton KeyString::HeapBuilder keyString( KeyString::Version::kLatestVersion, fromjson("{'': 1}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -1254,7 +1254,7 @@ TEST(BtreeKeyGeneratorTest, PositionalKeyPatternNestedArrays6) { Ordering::make(BSONObj())); KeyStringSet expectedKeys{ keyString1.release(), keyString2.release(), keyString3.release(), keyString4.release()}; - MultikeyPaths expectedMultikeyPaths{{0U}, {0U, 1U}, {2U}, {0U}, std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{{0U}, {0U, 1U}, {2U}, {0U}, MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -1278,7 +1278,7 @@ TEST(BtreeKeyGeneratorTest, PositionalKeyPatternNestedArrays7) { Ordering::make(BSONObj())); KeyStringSet expectedKeys{ keyString1.release(), keyString2.release(), keyString3.release(), keyString4.release()}; - MultikeyPaths expectedMultikeyPaths{{0U}, {0U, 1U}, {2U}, {0U}, std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{{0U}, {0U, 1U}, {2U}, {0U}, MultikeyComponents{}}; ASSERT(testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths)); } @@ -1289,7 +1289,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareIdKeyFromObject) { KeyString::Version::kLatestVersion, fromjson("{'': 'oof'}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT( testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, false, &collator)); } @@ -1301,7 +1301,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromObjectSimple) { KeyString::Version::kLatestVersion, fromjson("{'': 'oof'}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT( testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, false, &collator)); } @@ -1313,7 +1313,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromObjectDotted) { KeyString::Version::kLatestVersion, fromjson("{'': 'oof'}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT( testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, false, &collator)); } @@ -1341,7 +1341,7 @@ TEST(BtreeKeyGeneratorTest, CollatorDoesNotAffectNonStringIdKey) { KeyString::Version::kLatestVersion, fromjson("{'': 5}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT( testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, false, &collator)); } @@ -1353,7 +1353,7 @@ TEST(BtreeKeyGeneratorTest, CollatorDoesNotAffectNonStringKeys) { KeyString::Version::kLatestVersion, fromjson("{'': 5}"), Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT( testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, false, &collator)); } @@ -1366,7 +1366,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromNestedObject) { Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT( testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, false, &collator)); } @@ -1379,7 +1379,7 @@ TEST(BtreeKeyGeneratorTest, GetCollationAwareKeysFromNestedArray) { Ordering::make(BSONObj())); KeyStringSet expectedKeys{keyString.release()}; CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString); - MultikeyPaths expectedMultikeyPaths{std::set<size_t>{}}; + MultikeyPaths expectedMultikeyPaths{MultikeyComponents{}}; ASSERT( testKeygen(keyPattern, genKeysFrom, expectedKeys, expectedMultikeyPaths, false, &collator)); } diff --git a/src/mongo/db/index/expression_keys_private.cpp b/src/mongo/db/index/expression_keys_private.cpp index ce38e6d0092..b0e1570dd7c 100644 --- a/src/mongo/db/index/expression_keys_private.cpp +++ b/src/mongo/db/index/expression_keys_private.cpp @@ -555,7 +555,7 @@ void ExpressionKeysPrivate::getS2Keys(const BSONObj& obj, // the value of the field, or they're transformed if the field is geo. BSONElementSet fieldElements; const bool expandArrayOnTrailingField = false; - std::set<size_t>* arrayComponents = multikeyPaths ? &(*multikeyPaths)[posInIdx] : nullptr; + MultikeyComponents* arrayComponents = multikeyPaths ? &(*multikeyPaths)[posInIdx] : nullptr; dps::extractAllElementsAlongPath( obj, keyElem.fieldName(), fieldElements, expandArrayOnTrailingField, arrayComponents); diff --git a/src/mongo/db/index/index_access_method.cpp b/src/mongo/db/index/index_access_method.cpp index 67483da9ec7..6945c2babc7 100644 --- a/src/mongo/db/index/index_access_method.cpp +++ b/src/mongo/db/index/index_access_method.cpp @@ -80,7 +80,7 @@ static const RecordId kMultikeyMetadataKeyId = bool isMultikeyFromPaths(const MultikeyPaths& multikeyPaths) { return std::any_of(multikeyPaths.cbegin(), multikeyPaths.cend(), - [](const std::set<std::size_t>& components) { return !components.empty(); }); + [](const MultikeyComponents& components) { return !components.empty(); }); } std::vector<KeyString::Value> asVector(const KeyStringSet& keySet) { diff --git a/src/mongo/db/index/multikey_paths.h b/src/mongo/db/index/multikey_paths.h index b772ecf0d50..4ab25690529 100644 --- a/src/mongo/db/index/multikey_paths.h +++ b/src/mongo/db/index/multikey_paths.h @@ -29,8 +29,8 @@ #pragma once +#include <boost/container/flat_set.hpp> #include <cstddef> -#include <set> #include <vector> namespace mongo { @@ -53,7 +53,8 @@ namespace mongo { // {a: 1, b: 1} none {{}, {}} // {a: 1, b: 1} no multikey metadata {} // +using MultikeyComponents = boost::container::flat_set<std::size_t>; // An empty vector is used to represent that the index doesn't support path-level multikey tracking. -using MultikeyPaths = std::vector<std::set<std::size_t>>; +using MultikeyPaths = std::vector<MultikeyComponents>; } // namespace mongo diff --git a/src/mongo/db/index/s2_key_generator_test.cpp b/src/mongo/db/index/s2_key_generator_test.cpp index f5c24fb1687..5f986b1e1d6 100644 --- a/src/mongo/db/index/s2_key_generator_test.cpp +++ b/src/mongo/db/index/s2_key_generator_test.cpp @@ -212,7 +212,7 @@ TEST(S2KeyGeneratorTest, GetS2KeysFromArrayOfNonGeoSubobjectsWithArrayValues) { KeyStringSet expectedKeys{keyString1.release(), keyString2.release(), keyString3.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{{0U, 1U}, std::set<size_t>{}}, actualMultikeyPaths); + assertMultikeyPathsEqual(MultikeyPaths{{0U, 1U}, MultikeyComponents{}}, actualMultikeyPaths); } TEST(S2KeyGeneratorTest, GetS2KeysFromMultiPointInGeoField) { @@ -247,7 +247,7 @@ TEST(S2KeyGeneratorTest, GetS2KeysFromMultiPointInGeoField) { KeyStringSet expectedKeys{keyString1.release(), keyString2.release(), keyString3.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, {0U}}, actualMultikeyPaths); + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, {0U}}, actualMultikeyPaths); } TEST(S2KeyGeneratorTest, CollationAppliedToNonGeoStringFieldAfterGeoField) { @@ -275,7 +275,7 @@ TEST(S2KeyGeneratorTest, CollationAppliedToNonGeoStringFieldAfterGeoField) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}, + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}, actualMultikeyPaths); } @@ -305,7 +305,7 @@ TEST(S2KeyGeneratorTest, CollationAppliedToNonGeoStringFieldBeforeGeoField) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}, + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}, actualMultikeyPaths); } @@ -337,7 +337,7 @@ TEST(S2KeyGeneratorTest, CollationAppliedToAllNonGeoStringFields) { ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); assertMultikeyPathsEqual( - MultikeyPaths{std::set<size_t>{}, std::set<size_t>{}, std::set<size_t>{}}, + MultikeyPaths{MultikeyComponents{}, MultikeyComponents{}, MultikeyComponents{}}, actualMultikeyPaths); } @@ -366,7 +366,7 @@ TEST(S2KeyGeneratorTest, CollationAppliedToNonGeoStringFieldWithMultiplePathComp KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}, + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}, actualMultikeyPaths); } @@ -399,7 +399,7 @@ TEST(S2KeyGeneratorTest, CollationAppliedToStringsInArray) { KeyStringSet expectedKeys{keyString1.release(), keyString2.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, {0U}}, actualMultikeyPaths); + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, {0U}}, actualMultikeyPaths); } TEST(S2KeyGeneratorTest, CollationAppliedToStringsInAllArrays) { @@ -449,7 +449,7 @@ TEST(S2KeyGeneratorTest, CollationAppliedToStringsInAllArrays) { keyString1.release(), keyString2.release(), keyString3.release(), keyString4.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, {0U}, {0U}}, actualMultikeyPaths); + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, {0U}, {0U}}, actualMultikeyPaths); } TEST(S2KeyGeneratorTest, CollationDoesNotAffectNonStringFields) { @@ -476,7 +476,7 @@ TEST(S2KeyGeneratorTest, CollationDoesNotAffectNonStringFields) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}, + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}, actualMultikeyPaths); } @@ -506,7 +506,7 @@ TEST(S2KeyGeneratorTest, CollationAppliedToStringsInNestedObjects) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}, + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}, actualMultikeyPaths); } @@ -535,7 +535,7 @@ TEST(S2KeyGeneratorTest, NoCollation) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, std::set<size_t>{}}, + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, MultikeyComponents{}}, actualMultikeyPaths); } @@ -563,7 +563,7 @@ TEST(S2KeyGeneratorTest, EmptyArrayForLeadingFieldIsConsideredMultikey) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{{0U}, std::set<size_t>{}}, actualMultikeyPaths); + assertMultikeyPathsEqual(MultikeyPaths{{0U}, MultikeyComponents{}}, actualMultikeyPaths); } TEST(S2KeyGeneratorTest, EmptyArrayForTrailingFieldIsConsideredMultikey) { @@ -590,7 +590,7 @@ TEST(S2KeyGeneratorTest, EmptyArrayForTrailingFieldIsConsideredMultikey) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{std::set<size_t>{}, {0U}}, actualMultikeyPaths); + assertMultikeyPathsEqual(MultikeyPaths{MultikeyComponents{}, {0U}}, actualMultikeyPaths); } TEST(S2KeyGeneratorTest, SingleElementTrailingArrayIsConsideredMultikey) { @@ -617,7 +617,7 @@ TEST(S2KeyGeneratorTest, SingleElementTrailingArrayIsConsideredMultikey) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{{1U}, std::set<size_t>{}}, actualMultikeyPaths); + assertMultikeyPathsEqual(MultikeyPaths{{1U}, MultikeyComponents{}}, actualMultikeyPaths); } TEST(S2KeyGeneratorTest, MidPathSingleElementArrayIsConsideredMultikey) { @@ -644,7 +644,7 @@ TEST(S2KeyGeneratorTest, MidPathSingleElementArrayIsConsideredMultikey) { KeyStringSet expectedKeys{keyString.release()}; ASSERT_TRUE(areKeysetsEqual(expectedKeys, actualKeys)); - assertMultikeyPathsEqual(MultikeyPaths{{0U}, std::set<size_t>{}}, actualMultikeyPaths); + assertMultikeyPathsEqual(MultikeyPaths{{0U}, MultikeyComponents{}}, actualMultikeyPaths); } } // namespace diff --git a/src/mongo/db/query/plan_enumerator.cpp b/src/mongo/db/query/plan_enumerator.cpp index 87535d59bd5..8953465327b 100644 --- a/src/mongo/db/query/plan_enumerator.cpp +++ b/src/mongo/db/query/plan_enumerator.cpp @@ -166,7 +166,7 @@ void getPossibleFirstAssignments(const IndexEntry& thisIndex, * will be assigned to the index. */ bool canAssignPredToIndex(const RelevantTag* rt, - const std::set<size_t>& multikeyComponents, + const MultikeyComponents& multikeyComponents, StringMap<MatchExpression*>* used) { invariant(used); const FieldRef path(rt->path); diff --git a/src/mongo/db/query/planner_ixselect_test.cpp b/src/mongo/db/query/planner_ixselect_test.cpp index 84ba3f704d0..868b23b4357 100644 --- a/src/mongo/db/query/planner_ixselect_test.cpp +++ b/src/mongo/db/query/planner_ixselect_test.cpp @@ -1392,7 +1392,7 @@ TEST(QueryPlannerIXSelectTest, ExpandedIndexEntriesAreCorrectlyMarkedAsMultikeyO if (SimpleBSONObjComparator::kInstance.evaluate(entry.keyPattern == BSON("a.b" << 1))) { ASSERT_TRUE(entry.multikey); - ASSERT(entry.multikeyPaths[0] == std::set<std::size_t>{0u}); + ASSERT(entry.multikeyPaths[0] == MultikeyComponents{0u}); } else { ASSERT_BSONOBJ_EQ(entry.keyPattern, BSON("c.d" << 1)); ASSERT_FALSE(entry.multikey); diff --git a/src/mongo/db/query/planner_wildcard_helpers.cpp b/src/mongo/db/query/planner_wildcard_helpers.cpp index c65c5ae28ec..29f16df060a 100644 --- a/src/mongo/db/query/planner_wildcard_helpers.cpp +++ b/src/mongo/db/query/planner_wildcard_helpers.cpp @@ -54,7 +54,7 @@ namespace { */ bool fieldNameOrArrayIndexPathMatches(const FieldRef& fieldNameOrArrayIndexPath, const FieldRef& staticComparisonPath, - const std::set<size_t>& multikeyPathComponents) { + const MultikeyComponents& multikeyPathComponents) { // Can't be equal if 'staticComparisonPath' has more parts than 'fieldNameOrArrayIndexPath'. if (staticComparisonPath.numParts() > fieldNameOrArrayIndexPath.numParts()) { return false; @@ -82,7 +82,7 @@ bool fieldNameOrArrayIndexPathMatches(const FieldRef& fieldNameOrArrayIndexPath, * matches 'pathToLookup' when the latter's array indices are ignored. */ bool fieldNameOrArrayIndexPathSetContains(const std::set<FieldRef>& multikeyPathSet, - const std::set<std::size_t>& multikeyPathComponents, + const MultikeyComponents& multikeyPathComponents, const FieldRef& pathToLookup) { // Fast-path check for an exact match. If there is no exact match and 'pathToLookup' has no // numeric path components, then 'multikeyPathSet' does not contain the path. @@ -107,7 +107,7 @@ bool fieldNameOrArrayIndexPathSetContains(const std::set<FieldRef>& multikeyPath * prefix of the full path used to generate 'multikeyPaths', and so we must avoid checking path * components beyond the end of 'queryPath'. */ -std::vector<size_t> findArrayIndexPathComponents(const std::set<std::size_t>& multikeyPaths, +std::vector<size_t> findArrayIndexPathComponents(const MultikeyComponents& multikeyPaths, const FieldRef& queryPath) { std::vector<size_t> arrayIndices; for (auto i : multikeyPaths) { @@ -144,7 +144,7 @@ FieldRef pathWithoutSpecifiedComponents(const FieldRef& path, MultikeyPaths buildMultiKeyPathsForExpandedWildcardIndexEntry( const FieldRef& indexedPath, const std::set<FieldRef>& multikeyPathSet) { FieldRef pathToLookup; - std::set<std::size_t> multikeyPaths; + MultikeyComponents multikeyPaths; for (size_t i = 0; i < indexedPath.numParts(); ++i) { pathToLookup.appendPart(indexedPath.getPart(i)); if (fieldNameOrArrayIndexPathSetContains(multikeyPathSet, multikeyPaths, pathToLookup)) { @@ -154,7 +154,7 @@ MultikeyPaths buildMultiKeyPathsForExpandedWildcardIndexEntry( return {multikeyPaths}; } -std::set<FieldRef> generateFieldNameOrArrayIndexPathSet(const std::set<std::size_t>& multikeyPaths, +std::set<FieldRef> generateFieldNameOrArrayIndexPathSet(const MultikeyComponents& multikeyPaths, const FieldRef& queryPath, bool requiresSubpathBounds) { // We iterate over the power set of array index positions to generate all necessary paths. @@ -466,7 +466,7 @@ void finalizeWildcardIndexScanConfiguration(IndexScanNode* scan) { // field in each key is 'path.to.field'. We push a new entry into the bounds vector for the // leading '$_path' bound here. We also push corresponding fields into the IndexScanNode's // keyPattern and its multikeyPaths vector. - index->multikeyPaths.insert(index->multikeyPaths.begin(), std::set<std::size_t>{}); + index->multikeyPaths.insert(index->multikeyPaths.begin(), MultikeyComponents{}); bounds->fields.insert(bounds->fields.begin(), {"$_path"}); index->keyPattern = BSON("$_path" << index->keyPattern.firstElement() << index->keyPattern.firstElement()); diff --git a/src/mongo/db/query/planner_wildcard_helpers.h b/src/mongo/db/query/planner_wildcard_helpers.h index a709272a100..d152ce18cd2 100644 --- a/src/mongo/db/query/planner_wildcard_helpers.h +++ b/src/mongo/db/query/planner_wildcard_helpers.h @@ -29,8 +29,6 @@ #pragma once -#include <set> - #include "mongo/db/field_ref.h" #include "mongo/db/index/multikey_paths.h" #include "mongo/db/query/index_bounds_builder.h" diff --git a/src/mongo/db/query/query_planner_array_test.cpp b/src/mongo/db/query/query_planner_array_test.cpp index a50165637dc..e4a95c9a1ce 100644 --- a/src/mongo/db/query/query_planner_array_test.cpp +++ b/src/mongo/db/query/query_planner_array_test.cpp @@ -1137,7 +1137,7 @@ TEST_F(QueryPlannerTest, MultikeyElemMatchAllCompound3) { } TEST_F(QueryPlannerTest, CanIntersectBoundsWhenFirstFieldIsNotMultikey) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: {$gte: 0, $lt: 10}}")); @@ -1149,7 +1149,7 @@ TEST_F(QueryPlannerTest, CanIntersectBoundsWhenFirstFieldIsNotMultikey) { } TEST_F(QueryPlannerTest, CanIntersectBoundsOnFirstFieldWhenItAndSharedPrefixAreNotMultikey) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {1U}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {1U}}; addIndex(BSON("a.b" << 1 << "a.c" << 1), multikeyPaths); runQuery(fromjson("{'a.b': {$gte: 0, $lt: 10}}")); @@ -1161,7 +1161,7 @@ TEST_F(QueryPlannerTest, CanIntersectBoundsOnFirstFieldWhenItAndSharedPrefixAreN } TEST_F(QueryPlannerTest, CannotIntersectBoundsWhenFirstFieldIsMultikey) { - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: {$gte: 0, $lt: 10}}")); @@ -1176,7 +1176,7 @@ TEST_F(QueryPlannerTest, CannotIntersectBoundsWhenFirstFieldIsMultikey) { } TEST_F(QueryPlannerTest, CanIntersectBoundsWhenFirstFieldIsMultikeyButHasElemMatch) { - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: {$elemMatch: {$gte: 0, $lt: 10}}}")); @@ -1190,7 +1190,7 @@ TEST_F(QueryPlannerTest, CanIntersectBoundsWhenFirstFieldIsMultikeyButHasElemMat TEST_F(QueryPlannerTest, CanComplementBoundsOnFirstFieldWhenItIsMultikeyAndHasNotEqualExpr) { params.options = QueryPlannerParams::NO_TABLE_SCAN; - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: {$ne: 3}, b: 2}")); @@ -1204,7 +1204,7 @@ TEST_F(QueryPlannerTest, CanComplementBoundsOnFirstFieldWhenItIsMultikeyAndHasNo TEST_F(QueryPlannerTest, CanIntersectBoundsWhenFirstFieldIsMultikeyAndHasNotInsideElemMatch) { params.options = QueryPlannerParams::NO_TABLE_SCAN; - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: {$elemMatch: {$not: {$gte: 10}, $gte: 0}}, b: 2}")); @@ -1243,7 +1243,7 @@ TEST_F(QueryPlannerTest, CannotIntersectBoundsOnFirstFieldWhenItAndSharedPrefixA } TEST_F(QueryPlannerTest, CanIntersectBoundsWhenSecondFieldIsNotMultikey) { - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: 2, b: {$gte: 0, $lt: 10}}")); @@ -1255,7 +1255,7 @@ TEST_F(QueryPlannerTest, CanIntersectBoundsWhenSecondFieldIsNotMultikey) { } TEST_F(QueryPlannerTest, CanIntersectBoundsOnSecondFieldWhenItAndSharedPrefixAreNotMultikey) { - MultikeyPaths multikeyPaths{{1U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{1U}, MultikeyComponents{}}; addIndex(BSON("a.b" << 1 << "a.c" << 1), multikeyPaths); runQuery(fromjson("{'a.b': 2, 'a.c': {$gte: 0, $lt: 10}}")); @@ -1267,7 +1267,7 @@ TEST_F(QueryPlannerTest, CanIntersectBoundsOnSecondFieldWhenItAndSharedPrefixAre } TEST_F(QueryPlannerTest, CannotIntersectBoundsWhenSecondFieldIsMultikey) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: 2, b: {$gte: 0, $lt: 10}}")); @@ -1279,7 +1279,7 @@ TEST_F(QueryPlannerTest, CannotIntersectBoundsWhenSecondFieldIsMultikey) { } TEST_F(QueryPlannerTest, CanIntersectBoundsWhenSecondFieldIsMultikeyButHasElemMatch) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: 2, b: {$elemMatch: {$gte: 0, $lt: 10}}}")); @@ -1293,7 +1293,7 @@ TEST_F(QueryPlannerTest, CanIntersectBoundsWhenSecondFieldIsMultikeyButHasElemMa TEST_F(QueryPlannerTest, CanComplementBoundsOnSecondFieldWhenItIsMultikeyAndHasNotEqualExpr) { params.options = QueryPlannerParams::NO_TABLE_SCAN; - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: 2, b: {$ne: 3}}")); @@ -1307,7 +1307,7 @@ TEST_F(QueryPlannerTest, CanComplementBoundsOnSecondFieldWhenItIsMultikeyAndHasN TEST_F(QueryPlannerTest, CanIntersectBoundsWhenSecondFieldIsMultikeyAndHasNotInsideElemMatch) { params.options = QueryPlannerParams::NO_TABLE_SCAN; - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}}; addIndex(BSON("a" << 1 << "b" << 1), multikeyPaths); runQuery(fromjson("{a: 2, b: {$elemMatch: {$not: {$gte: 10}, $gte: 0}}}")); @@ -2391,7 +2391,7 @@ TEST_F(QueryPlannerTest, CantExplodeMultikeyIxscanForSort) { TEST_F(QueryPlannerTest, CantExplodeMultikeyIxscanForSortWithPathLevelMultikeyMetadata) { params.options &= ~QueryPlannerParams::INCLUDE_COLLSCAN; - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}}; addIndex(BSON("a" << 1 << "b.c" << 1), multikeyPaths); runQueryAsCommand(fromjson("{find: 'testns', filter: {a: {$in: [1, 2]}}, sort: {'b.c': 1}}")); @@ -2405,7 +2405,7 @@ TEST_F(QueryPlannerTest, CantExplodeMultikeyIxscanForSortWithPathLevelMultikeyMe TEST_F(QueryPlannerTest, CanExplodeMultikeyIndexScanForSortWhenSortFieldsAreNotMultikey) { params.options &= ~QueryPlannerParams::INCLUDE_COLLSCAN; - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b.c" << 1), multikeyPaths); runQueryAsCommand(fromjson("{find: 'testns', filter: {a: {$in: [1, 2]}}, sort: {'b.c': 1}}")); diff --git a/src/mongo/db/query/query_planner_geo_test.cpp b/src/mongo/db/query/query_planner_geo_test.cpp index cc4e46c2e72..7028e4d57a7 100644 --- a/src/mongo/db/query/query_planner_geo_test.cpp +++ b/src/mongo/db/query/query_planner_geo_test.cpp @@ -885,7 +885,7 @@ TEST_F(QueryPlannerTest, Negation2DSphereGeoNearMultikey) { using QueryPlannerGeo2dsphereTest = QueryPlannerTest; TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenFirstFieldIsNotMultikey) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -900,7 +900,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenFirstFieldIsNotMultike TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsOnFirstFieldWhenItAndSharedPrefixAreNotMultikey) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {1U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {1U}, MultikeyComponents{}}; addIndex(BSON("a.b" << 1 << "a.c" << 1 << "a.geo" << "2dsphere"), multikeyPaths); @@ -914,7 +914,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, } TEST_F(QueryPlannerGeo2dsphereTest, CannotIntersectBoundsWhenFirstFieldIsMultikey) { - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -928,7 +928,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, CannotIntersectBoundsWhenFirstFieldIsMultike } TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenFirstFieldIsMultikeyButHasElemMatch) { - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -943,7 +943,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenFirstFieldIsMultikeyBu TEST_F(QueryPlannerGeo2dsphereTest, CannotComplementBoundsOnFirstFieldWhenItIsMultikeyAndHasNotEqualExpr) { - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -954,7 +954,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenFirstFieldIsMultikeyAndHasNotInsideElemMatch) { - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -1001,7 +1001,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, } TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenSecondFieldIsNotMultikey) { - MultikeyPaths multikeyPaths{{0U}, std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{0U}, MultikeyComponents{}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -1016,7 +1016,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenSecondFieldIsNotMultik TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsOnSecondFieldWhenItAndSharedPrefixAreNotMultikey) { - MultikeyPaths multikeyPaths{{1U}, std::set<size_t>{}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{{1U}, MultikeyComponents{}, MultikeyComponents{}}; addIndex(BSON("a.b" << 1 << "a.c" << 1 << "a.geo" << "2dsphere"), multikeyPaths); @@ -1030,7 +1030,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, } TEST_F(QueryPlannerGeo2dsphereTest, CannotIntersectBoundsWhenSecondFieldIsMultikey) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -1044,7 +1044,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, CannotIntersectBoundsWhenSecondFieldIsMultik } TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenSecondFieldIsMultikeyButHasElemMatch) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -1059,7 +1059,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenSecondFieldIsMultikeyB TEST_F(QueryPlannerGeo2dsphereTest, CannotComplementBoundsOnSecondFieldWhenItIsMultikeyAndHasNotEqualExpr) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -1074,7 +1074,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsWhenSecondFieldIsMultikeyAndHasNotInsideElemMatch) { - MultikeyPaths multikeyPaths{std::set<size_t>{}, {0U}, std::set<size_t>{}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}, {0U}, MultikeyComponents{}}; addIndex(BSON("a" << 1 << "b" << 1 << "geo" << "2dsphere"), multikeyPaths); @@ -1264,7 +1264,7 @@ TEST_F(QueryPlannerGeo2dsphereTest, } TEST_F(QueryPlannerGeo2dsphereTest, CanIntersectBoundsOn2dsphereFieldWhenItIsNotMultikey) { - MultikeyPaths multikeyPaths{std::set<size_t>{}}; + MultikeyPaths multikeyPaths{MultikeyComponents{}}; addIndex(BSON("geo" << "2dsphere"), multikeyPaths); diff --git a/src/mongo/db/query/query_planner_test_fixture.cpp b/src/mongo/db/query/query_planner_test_fixture.cpp index 805fccdbc1f..d522a108f58 100644 --- a/src/mongo/db/query/query_planner_test_fixture.cpp +++ b/src/mongo/db/query/query_planner_test_fixture.cpp @@ -151,7 +151,7 @@ void QueryPlannerTest::addIndex(BSONObj keyPattern, const MultikeyPaths& multike const bool multikey = std::any_of(multikeyPaths.cbegin(), multikeyPaths.cend(), - [](const std::set<size_t>& components) { return !components.empty(); }); + [](const MultikeyComponents& components) { return !components.empty(); }); const bool sparse = false; const bool unique = false; const char name[] = "my_index_with_path_level_multikey_info"; diff --git a/src/mongo/db/storage/bson_collection_catalog_entry.cpp b/src/mongo/db/storage/bson_collection_catalog_entry.cpp index 976c8123afc..95290131e9c 100644 --- a/src/mongo/db/storage/bson_collection_catalog_entry.cpp +++ b/src/mongo/db/storage/bson_collection_catalog_entry.cpp @@ -84,7 +84,7 @@ void appendMultikeyPathsAsBytes(BSONObj keyPattern, void parseMultikeyPathsFromBytes(BSONObj multikeyPathsObj, MultikeyPaths* multikeyPaths) { invariant(multikeyPaths); for (auto elem : multikeyPathsObj) { - std::set<size_t> multikeyComponents; + MultikeyComponents multikeyComponents; int len; const char* data = elem.binData(len); invariant(len > 0); diff --git a/src/mongo/db/storage/durable_catalog_impl.cpp b/src/mongo/db/storage/durable_catalog_impl.cpp index 1d70e3383db..46e4f3ce5ad 100644 --- a/src/mongo/db/storage/durable_catalog_impl.cpp +++ b/src/mongo/db/storage/durable_catalog_impl.cpp @@ -1097,7 +1097,7 @@ bool DurableCatalogImpl::setIndexIsMultikey(OperationContext* opCtx, // Store new path components that cause this index to be multikey in catalog's index // metadata. for (size_t i = 0; i < multikeyPaths.size(); ++i) { - std::set<size_t>& indexMultikeyComponents = md.indexes[offset].multikeyPaths[i]; + MultikeyComponents& indexMultikeyComponents = md.indexes[offset].multikeyPaths[i]; for (const auto multikeyComponent : multikeyPaths[i]) { auto result = indexMultikeyComponents.insert(multikeyComponent); newPathIsMultikey = newPathIsMultikey || result.second; diff --git a/src/mongo/db/storage/key_string.h b/src/mongo/db/storage/key_string.h index 33a57c2853a..303ec83c06f 100644 --- a/src/mongo/db/storage/key_string.h +++ b/src/mongo/db/storage/key_string.h @@ -44,6 +44,8 @@ #include "mongo/platform/decimal128.h" #include "mongo/util/assert_util.h" +#include <boost/container/flat_set.hpp> + namespace mongo { namespace KeyString { @@ -905,6 +907,6 @@ int Value::compareWithoutRecordId(const T& other) const { } // namespace KeyString -using KeyStringSet = std::set<KeyString::Value>; +using KeyStringSet = boost::container::flat_set<KeyString::Value>; } // namespace mongo diff --git a/src/mongo/db/storage/kv/durable_catalog_test.cpp b/src/mongo/db/storage/kv/durable_catalog_test.cpp index 38bdc1c9fa9..187952be655 100644 --- a/src/mongo/db/storage/kv/durable_catalog_test.cpp +++ b/src/mongo/db/storage/kv/durable_catalog_test.cpp @@ -170,7 +170,7 @@ TEST_F(DurableCatalogTest, MultikeyPathsForBtreeIndexInitializedToVectorOfEmptyS { MultikeyPaths multikeyPaths; ASSERT(!catalog->isIndexMultikey(opCtx.get(), getCatalogId(), indexName, &multikeyPaths)); - assertMultikeyPathsAreEqual(multikeyPaths, {std::set<size_t>{}, std::set<size_t>{}}); + assertMultikeyPathsAreEqual(multikeyPaths, {MultikeyComponents{}, MultikeyComponents{}}); } } @@ -179,12 +179,12 @@ TEST_F(DurableCatalogTest, CanSetIndividualPathComponentOfBtreeIndexAsMultikey) auto opCtx = newOperationContext(); DurableCatalog* catalog = getCatalog(); ASSERT(catalog->setIndexIsMultikey( - opCtx.get(), getCatalogId(), indexName, {std::set<size_t>{}, {0U}})); + opCtx.get(), getCatalogId(), indexName, {MultikeyComponents{}, {0U}})); { MultikeyPaths multikeyPaths; ASSERT(catalog->isIndexMultikey(opCtx.get(), getCatalogId(), indexName, &multikeyPaths)); - assertMultikeyPathsAreEqual(multikeyPaths, {std::set<size_t>{}, {0U}}); + assertMultikeyPathsAreEqual(multikeyPaths, {MultikeyComponents{}, {0U}}); } } @@ -193,16 +193,16 @@ TEST_F(DurableCatalogTest, MultikeyPathsAccumulateOnDifferentFields) { auto opCtx = newOperationContext(); DurableCatalog* catalog = getCatalog(); ASSERT(catalog->setIndexIsMultikey( - opCtx.get(), getCatalogId(), indexName, {std::set<size_t>{}, {0U}})); + opCtx.get(), getCatalogId(), indexName, {MultikeyComponents{}, {0U}})); { MultikeyPaths multikeyPaths; ASSERT(catalog->isIndexMultikey(opCtx.get(), getCatalogId(), indexName, &multikeyPaths)); - assertMultikeyPathsAreEqual(multikeyPaths, {std::set<size_t>{}, {0U}}); + assertMultikeyPathsAreEqual(multikeyPaths, {MultikeyComponents{}, {0U}}); } ASSERT(catalog->setIndexIsMultikey( - opCtx.get(), getCatalogId(), indexName, {{0U}, std::set<size_t>{}})); + opCtx.get(), getCatalogId(), indexName, {{0U}, MultikeyComponents{}})); { MultikeyPaths multikeyPaths; @@ -283,7 +283,7 @@ DEATH_TEST_REGEX_F(DurableCatalogTest, auto opCtx = newOperationContext(); DurableCatalog* catalog = getCatalog(); catalog->setIndexIsMultikey( - opCtx.get(), getCatalogId(), indexName, {std::set<size_t>{}, std::set<size_t>{}}); + opCtx.get(), getCatalogId(), indexName, {MultikeyComponents{}, MultikeyComponents{}}); } TEST_F(DurableCatalogTest, PathLevelMultikeyTrackingIsSupportedBy2dsphereIndexes) { @@ -294,7 +294,7 @@ TEST_F(DurableCatalogTest, PathLevelMultikeyTrackingIsSupportedBy2dsphereIndexes { MultikeyPaths multikeyPaths; ASSERT(!catalog->isIndexMultikey(opCtx.get(), getCatalogId(), indexName, &multikeyPaths)); - assertMultikeyPathsAreEqual(multikeyPaths, {std::set<size_t>{}, std::set<size_t>{}}); + assertMultikeyPathsAreEqual(multikeyPaths, {MultikeyComponents{}, MultikeyComponents{}}); } } diff --git a/src/mongo/dbtests/multikey_paths_test.cpp b/src/mongo/dbtests/multikey_paths_test.cpp index 6c72c3e8936..5fcffe14b1d 100644 --- a/src/mongo/dbtests/multikey_paths_test.cpp +++ b/src/mongo/dbtests/multikey_paths_test.cpp @@ -145,7 +145,7 @@ TEST_F(MultikeyPathsTest, PathsUpdatedOnIndexCreation) { << "key" << keyPattern << "v" << static_cast<int>(kIndexVersion))) .transitional_ignore(); - assertMultikeyPaths(collection, keyPattern, {std::set<size_t>{}, {0U}}); + assertMultikeyPaths(collection, keyPattern, {MultikeyComponents{}, {0U}}); } TEST_F(MultikeyPathsTest, PathsUpdatedOnIndexCreationWithMultipleDocuments) { @@ -199,7 +199,7 @@ TEST_F(MultikeyPathsTest, PathsUpdatedOnDocumentInsert) { wuow.commit(); } - assertMultikeyPaths(collection, keyPattern, {std::set<size_t>{}, {0U}}); + assertMultikeyPaths(collection, keyPattern, {MultikeyComponents{}, {0U}}); { WriteUnitOfWork wuow(_opCtx.get()); @@ -234,7 +234,7 @@ TEST_F(MultikeyPathsTest, PathsUpdatedOnDocumentUpdate) { wuow.commit(); } - assertMultikeyPaths(collection, keyPattern, {std::set<size_t>{}, std::set<size_t>{}}); + assertMultikeyPaths(collection, keyPattern, {MultikeyComponents{}, MultikeyComponents{}}); { auto cursor = collection->getCursor(_opCtx.get()); @@ -259,7 +259,7 @@ TEST_F(MultikeyPathsTest, PathsUpdatedOnDocumentUpdate) { } } - assertMultikeyPaths(collection, keyPattern, {std::set<size_t>{}, {0U}}); + assertMultikeyPaths(collection, keyPattern, {MultikeyComponents{}, {0U}}); } TEST_F(MultikeyPathsTest, PathsNotUpdatedOnDocumentDelete) { @@ -284,7 +284,7 @@ TEST_F(MultikeyPathsTest, PathsNotUpdatedOnDocumentDelete) { wuow.commit(); } - assertMultikeyPaths(collection, keyPattern, {std::set<size_t>{}, {0U}}); + assertMultikeyPaths(collection, keyPattern, {MultikeyComponents{}, {0U}}); { auto cursor = collection->getCursor(_opCtx.get()); @@ -299,7 +299,7 @@ TEST_F(MultikeyPathsTest, PathsNotUpdatedOnDocumentDelete) { } } - assertMultikeyPaths(collection, keyPattern, {std::set<size_t>{}, {0U}}); + assertMultikeyPaths(collection, keyPattern, {MultikeyComponents{}, {0U}}); } TEST_F(MultikeyPathsTest, PathsUpdatedForMultipleIndexesOnDocumentInsert) { @@ -331,8 +331,8 @@ TEST_F(MultikeyPathsTest, PathsUpdatedForMultipleIndexesOnDocumentInsert) { wuow.commit(); } - assertMultikeyPaths(collection, keyPatternAB, {{0U}, std::set<size_t>{}}); - assertMultikeyPaths(collection, keyPatternAC, {{0U}, std::set<size_t>{}}); + assertMultikeyPaths(collection, keyPatternAB, {{0U}, MultikeyComponents{}}); + assertMultikeyPaths(collection, keyPatternAC, {{0U}, MultikeyComponents{}}); } } // namespace diff --git a/src/mongo/dbtests/storage_timestamp_tests.cpp b/src/mongo/dbtests/storage_timestamp_tests.cpp index cd064e00b9c..1b050e9e492 100644 --- a/src/mongo/dbtests/storage_timestamp_tests.cpp +++ b/src/mongo/dbtests/storage_timestamp_tests.cpp @@ -1957,7 +1957,7 @@ public: ASSERT(indexMetaData.multikey); ASSERT_EQ(std::size_t(1), indexMetaData.multikeyPaths.size()); - const bool match = indexMetaData.multikeyPaths[0] == std::set<std::size_t>({0}); + const bool match = indexMetaData.multikeyPaths[0] == MultikeyComponents({0}); if (!match) { FAIL(str::stream() << "Expected: [ [ 0 ] ] Actual: " << dumpMultikeyPaths(indexMetaData.multikeyPaths)); |