diff options
author | Kyle Suarez <kyle.suarez@mongodb.com> | 2018-03-13 15:15:14 -0400 |
---|---|---|
committer | Kyle Suarez <kyle.suarez@mongodb.com> | 2018-03-13 15:15:14 -0400 |
commit | f176b8eefccdb1708c01f7a7ba508ccaae4709bc (patch) | |
tree | 3d26fb6ae7919933bc63d3e9653b375afb4ba769 /src/mongo | |
parent | 64e649a622b5ac4c1bfad0933132dc7d994b9458 (diff) | |
download | mongo-f176b8eefccdb1708c01f7a7ba508ccaae4709bc.tar.gz |
SERVER-33847 create type aliases for BSONObj containers with binary comparison semantics
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/bson/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/bson/simple_bsonobj_comparator.h | 97 | ||||
-rw-r--r-- | src/mongo/bson/simple_bsonobj_comparator_test.cpp | 150 | ||||
-rw-r--r-- | src/mongo/db/repl/dbcheck.cpp | 2 |
4 files changed, 248 insertions, 2 deletions
diff --git a/src/mongo/bson/SConscript b/src/mongo/bson/SConscript index 941f7cdc2f0..783aad2f1ab 100644 --- a/src/mongo/bson/SConscript +++ b/src/mongo/bson/SConscript @@ -28,6 +28,7 @@ env.CppUnitTest( target='bson_obj_test', source=[ 'bson_obj_test.cpp', + 'simple_bsonobj_comparator_test.cpp', ], LIBDEPS=[ '$BUILD_DIR/mongo/base', diff --git a/src/mongo/bson/simple_bsonobj_comparator.h b/src/mongo/bson/simple_bsonobj_comparator.h index 2202e221696..59a61e27dd8 100644 --- a/src/mongo/bson/simple_bsonobj_comparator.h +++ b/src/mongo/bson/simple_bsonobj_comparator.h @@ -28,7 +28,12 @@ #pragma once +#include <map> +#include <set> + #include "mongo/bson/bsonobj_comparator_interface.h" +#include "mongo/stdx/unordered_map.h" +#include "mongo/stdx/unordered_set.h" namespace mongo { @@ -38,7 +43,7 @@ namespace mongo { class SimpleBSONObjComparator final : public BSONObj::ComparatorInterface { public: // Global simple comparator for stateless BSONObj comparisons. BSONObj comparisons that require - // database logic, such as collations, much instantiate their own comparator. + // database logic, such as collations, must instantiate their own comparator. static const SimpleBSONObjComparator kInstance; int compare(const BSONObj& lhs, const BSONObj& rhs) const final { @@ -48,6 +53,96 @@ public: void hash_combine(size_t& seed, const BSONObj& toHash) const final { hashCombineBSONObj(seed, toHash, ComparisonRules::kConsiderFieldName, nullptr); } + + /** + * A functor with simple binary comparison semantics that's suitable for use with ordered STL + * containers. + */ + class LessThan { + public: + explicit LessThan() = default; + + bool operator()(const BSONObj& lhs, const BSONObj& rhs) const { + return kInstance.compare(lhs, rhs) < 0; + } + }; + + /** + * A functor with simple binary comparison semantics that's suitable for use with unordered STL + * containers. + */ + class EqualTo { + public: + explicit EqualTo() = default; + + bool operator()(const BSONObj& lhs, const BSONObj& rhs) const { + return kInstance.compare(lhs, rhs) == 0; + } + }; + + /** + * Functor for computing the hash of a BSONObj, compatible for use with unordered STL + * containers. + */ + class Hasher { + public: + explicit Hasher() = default; + + size_t operator()(const BSONObj& obj) const { + return kInstance.hash(obj); + } + }; }; +/** + * A set of BSONObjs that performs comparisons with simple binary semantics. + */ +using SimpleBSONObjSet = std::set<BSONObj, SimpleBSONObjComparator::LessThan>; + +/** + * A multiset of BSONObjs that performs comparisons with simple binary semantics. + */ +using SimpleBSONObjMultiSet = std::multiset<BSONObj, SimpleBSONObjComparator::LessThan>; + +/** + * An unordered_set of BSONObjs that performs equality checks using simple binary semantics. + */ +using SimpleBSONObjUnorderedSet = + stdx::unordered_set<BSONObj, SimpleBSONObjComparator::Hasher, SimpleBSONObjComparator::EqualTo>; + +/** + * An unordered_multiset of BSONObjs that performs equality checks using simple binary semantics. + */ +using SimpleBSONObjUnorderedMultiset = stdx::unordered_multiset<BSONObj, + SimpleBSONObjComparator::Hasher, + SimpleBSONObjComparator::EqualTo>; + +/** + * A map keyed on BSONObj that performs comparisons with simple binary semantics. + */ +template <typename T> +using SimpleBSONObjMap = std::map<BSONObj, T, SimpleBSONObjComparator::LessThan>; + +/** + * A multimap keyed on BSONObj that performs comparisons with simple binary semantics. + */ +template <typename T> +using SimpleBSONObjMultiMap = std::multimap<BSONObj, T, SimpleBSONObjComparator::LessThan>; + +/** + * An unordered_map keyed on BSONObj that performs equality checks using simple binary semantics. + */ +template <typename T> +using SimpleBSONObjUnorderedMap = stdx:: + unordered_map<BSONObj, T, SimpleBSONObjComparator::Hasher, SimpleBSONObjComparator::EqualTo>; + +/** + * An unordered_multimap keyed on BSONObj that performs equality checks using simple binary + * semantics. + */ +template <typename T> +using SimpleBSONObjUnorderedMultiMap = stdx::unordered_multimap<BSONObj, + T, + SimpleBSONObjComparator::Hasher, + SimpleBSONObjComparator::EqualTo>; } // namespace mongo diff --git a/src/mongo/bson/simple_bsonobj_comparator_test.cpp b/src/mongo/bson/simple_bsonobj_comparator_test.cpp new file mode 100644 index 00000000000..40d536f0bdf --- /dev/null +++ b/src/mongo/bson/simple_bsonobj_comparator_test.cpp @@ -0,0 +1,150 @@ +/** + * Copyright (C) 2018 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. + */ + +#include "mongo/platform/basic.h" + +#include <map> +#include <set> +#include <utility> + +#include "mongo/bson/bsonmisc.h" +#include "mongo/bson/bsonobjbuilder.h" +#include "mongo/bson/simple_bsonobj_comparator.h" +#include "mongo/stdx/unordered_map.h" +#include "mongo/stdx/unordered_set.h" +#include "mongo/unittest/unittest.h" + +namespace mongo { +namespace { +/** + * Asserts that 'obj' can be successfully inserted into 'set'. + */ +template <typename Set> +void assertInsertSucceeds(Set& set, BSONObj obj) { + ASSERT(set.insert(obj).second) << "failed to insert object: " << obj.jsonString(); +} + +/** + * Asserts that 'obj' fails to be inserted into 'set'. + */ +template <typename Set> +void assertInsertFails(Set& set, BSONObj obj) { + ASSERT_FALSE(set.insert(obj).second) + << "object was inserted successfully, but should have failed: " << obj.jsonString(); +} + +TEST(SimpleBSONObjContainerTest, SetIsDefaultConstructible) { + SimpleBSONObjSet set; + assertInsertSucceeds(set, BSON("x" << 1)); + ASSERT_EQ(set.size(), 1UL); + assertInsertSucceeds(set, BSON("y" << 1)); + assertInsertFails(set, BSON("x" << 1)); + ASSERT_EQ(set.size(), 2UL); +} + +TEST(SimpleBSONObjContainerTest, MultiSetIsDefaultConstructible) { + SimpleBSONObjMultiSet multiset; + multiset.insert(BSON("x" << 1)); + multiset.insert(BSON("x" << 1)); + multiset.insert(BSON("y" << 1)); + ASSERT_EQ(multiset.size(), 3UL); +} + +TEST(SimpleBSONObjContainerTest, UnorderedSetIsDefaultConstructible) { + SimpleBSONObjUnorderedSet uset; + assertInsertSucceeds(uset, BSON("x" << 1)); + ASSERT_EQ(uset.size(), 1UL); + assertInsertSucceeds(uset, BSON("y" << 1)); + assertInsertFails(uset, BSON("x" << 1)); + ASSERT_EQ(uset.size(), 2UL); +} + +TEST(SimpleBSONObjContainerTest, UnorderedMultiSetIsDefaultConstructible) { + SimpleBSONObjUnorderedMultiset umultiset; + umultiset.insert(BSON("x" << 1)); + umultiset.insert(BSON("x" << 1)); + umultiset.insert(BSON("y" << 1)); + ASSERT_EQ(umultiset.size(), 3UL); +} + +/** + * Asserts that the key-value pair 'pair' can be successfully inserted into 'map'. + */ +template <typename Map, typename T> +void assertInsertSucceeds(Map& map, std::pair<BSONObj, T> pair) { + ASSERT(map.insert(pair).second) << "failed to insert {key: " << pair.first.jsonString() + << ", value: '" << pair.second << "'}"; +} + +/** + * Asserts that the key-value pair 'pair' fails to be inserted into 'map'. + */ +template <typename Map, typename T> +void assertInsertFails(Map& map, std::pair<BSONObj, T> pair) { + ASSERT_FALSE(map.insert(pair).second) + << "key-value pair was inserted successfully, but should have failed: {key: " + << pair.first.jsonString() << ", value: '" << pair.second << "'}"; +} + +TEST(SimpleBSONObjContainerTest, MapIsDefaultConstructible) { + SimpleBSONObjMap<std::string> map; + assertInsertSucceeds(map, std::make_pair(BSON("_id" << 0), "kyle")); + ASSERT_EQ(map.size(), 1UL); + assertInsertSucceeds(map, std::make_pair(BSON("_id" << 1), "jungsoo")); + ASSERT_EQ(map.size(), 2UL); + assertInsertFails(map, std::make_pair(BSON("_id" << 1), "erjon")); + ASSERT_EQ(map.size(), 2UL); +} + +TEST(SimpleBSONObjContainerTest, MultiMapIsDefaultConstructible) { + SimpleBSONObjMultiMap<std::string> multimap; + multimap.insert(std::make_pair(BSON("_id" << 0), "anica")); + multimap.insert(std::make_pair(BSON("_id" << 0), "raj")); + multimap.insert(std::make_pair(BSON("_id" << 1), "ian")); + ASSERT_EQ(multimap.size(), 3UL); +} + +TEST(SimpleBSONObjContainerTest, UnorderedMapIsDefaultConstructible) { + SimpleBSONObjUnorderedMap<std::string> umap; + assertInsertSucceeds(umap, std::make_pair(BSON("_id" << 0), "kyle")); + ASSERT_EQ(umap.size(), 1UL); + assertInsertSucceeds(umap, std::make_pair(BSON("_id" << 1), "jungsoo")); + ASSERT_EQ(umap.size(), 2UL); + assertInsertFails(umap, std::make_pair(BSON("_id" << 1), "erjon")); + ASSERT_EQ(umap.size(), 2UL); +} + +TEST(SimpleBSONObjContainerTest, UnorderedMultiMapIsDefaultConstructible) { + SimpleBSONObjUnorderedMultiMap<std::string> umultimap; + umultimap.insert(std::make_pair(BSON("_id" << 0), "anica")); + umultimap.insert(std::make_pair(BSON("_id" << 0), "raj")); + umultimap.insert(std::make_pair(BSON("_id" << 1), "ian")); + ASSERT_EQ(umultimap.size(), 3UL); +} +} // namespace +} // namespace mongo diff --git a/src/mongo/db/repl/dbcheck.cpp b/src/mongo/db/repl/dbcheck.cpp index 781d968f7f5..62e3f5da9f8 100644 --- a/src/mongo/db/repl/dbcheck.cpp +++ b/src/mongo/db/repl/dbcheck.cpp @@ -358,7 +358,7 @@ std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, Collection* co auto comp = stdx::make_unique<SimpleBSONObjComparator>(); - std::sort(result.begin(), result.end(), SimpleBSONObjComparator::LessThan(comp.get())); + std::sort(result.begin(), result.end(), SimpleBSONObjComparator::LessThan()); return result; } |