summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/aggregation/bugs/server12015.js12
-rw-r--r--jstests/aggregation/sources/facet/inner_graphlookup.js15
-rw-r--r--jstests/core/index_stats.js33
-rw-r--r--src/mongo/bson/simple_bsonobj_comparator.h16
-rw-r--r--src/mongo/bson/simple_bsonobj_comparator_test.cpp15
-rw-r--r--src/mongo/db/auth/authorization_manager.cpp1
-rw-r--r--src/mongo/db/auth/authorization_manager.h1
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.cpp2
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.h1
-rw-r--r--src/mongo/db/auth/resource_pattern.h20
-rw-r--r--src/mongo/db/auth/role_name.h16
-rw-r--r--src/mongo/db/auth/user_name.h5
-rw-r--r--src/mongo/db/concurrency/lock_manager_defs.h16
-rw-r--r--src/mongo/db/cursor_manager.cpp6
-rw-r--r--src/mongo/db/namespace_string.h22
-rw-r--r--src/mongo/db/pipeline/document_source_graph_lookup.cpp2
-rw-r--r--src/mongo/db/query/plan_enumerator.cpp8
-rw-r--r--src/mongo/db/transaction_coordinator_catalog.cpp10
-rw-r--r--src/mongo/dbtests/commandtests.cpp4
-rw-r--r--src/mongo/executor/task_executor.h20
-rw-r--r--src/mongo/platform/hash_namespace.h50
-rw-r--r--src/mongo/platform/process_id.h16
-rw-r--r--src/mongo/s/query/cluster_cursor_manager.cpp4
-rw-r--r--src/mongo/s/query/cluster_cursor_manager.h3
-rw-r--r--src/mongo/stdx/trusted_hasher.h (renamed from src/mongo/db/auth/user_name_hash.h)41
-rw-r--r--src/mongo/stdx/unordered_map.h17
-rw-r--r--src/mongo/stdx/unordered_set.h17
-rw-r--r--src/mongo/util/invalidating_lru_cache.h5
-rw-r--r--src/mongo/util/keyed_executor.h4
-rw-r--r--src/mongo/util/net/hostandport.cpp9
-rw-r--r--src/mongo/util/net/hostandport.h15
31 files changed, 137 insertions, 269 deletions
diff --git a/jstests/aggregation/bugs/server12015.js b/jstests/aggregation/bugs/server12015.js
index 150ff30e708..1b59a59545c 100644
--- a/jstests/aggregation/bugs/server12015.js
+++ b/jstests/aggregation/bugs/server12015.js
@@ -63,19 +63,23 @@ load("jstests/aggregation/extras/utils.js"); // For orderedArrayEq.
assertResultsMatch([{$sort: {a: -1, b: -1}}, {$project: {_id: 1, a: 1, b: 1}}]);
assertResultsMatch([{$sort: {a: 1, b: 1}}, {$project: {_id: 1, a: 1, b: 1}}]);
assertResultsMatch(
- [{$sort: {a: 1, b: 1}}, {$group: {_id: "$_id", arr: {$push: "$a"}, sum: {$sum: "$b"}}}]);
+ [{$sort: {a: 1, b: 1}}, {$group: {_id: "$_id", arr: {$push: "$a"}, sum: {$sum: "$b"}}}],
+ ignoreSortOrder);
// Non-blocking $sort, covered $project.
assertResultsMatch([{$sort: {a: -1, b: -1}}, {$project: {_id: 0, a: 1, b: 1}}]);
assertResultsMatch([{$sort: {a: 1, b: 1}}, {$project: {_id: 0, a: 1, b: 1}}]);
- assertResultsMatch([{$sort: {a: 1, b: 1}}, {$group: {_id: "$b", arr: {$push: "$a"}}}]);
+ assertResultsMatch([{$sort: {a: 1, b: 1}}, {$group: {_id: "$b", arr: {$push: "$a"}}}],
+ ignoreSortOrder);
// Blocking $sort, uncovered $project.
assertResultsMatch([{$sort: {b: 1, a: -1}}, {$project: {_id: 1, a: 1, b: 1}}]);
assertResultsMatch(
- [{$sort: {b: 1, a: -1}}, {$group: {_id: "$_id", arr: {$push: "$a"}, sum: {$sum: "$b"}}}]);
+ [{$sort: {b: 1, a: -1}}, {$group: {_id: "$_id", arr: {$push: "$a"}, sum: {$sum: "$b"}}}],
+ ignoreSortOrder);
// Blocking $sort, covered $project.
assertResultsMatch([{$sort: {b: 1, a: -1}}, {$project: {_id: 0, a: 1, b: 1}}]);
- assertResultsMatch([{$sort: {b: 1, a: -1}}, {$group: {_id: "$b", arr: {$push: "$a"}}}]);
+ assertResultsMatch([{$sort: {b: 1, a: -1}}, {$group: {_id: "$b", arr: {$push: "$a"}}}],
+ ignoreSortOrder);
}());
diff --git a/jstests/aggregation/sources/facet/inner_graphlookup.js b/jstests/aggregation/sources/facet/inner_graphlookup.js
index 870bb975a8a..340853f7721 100644
--- a/jstests/aggregation/sources/facet/inner_graphlookup.js
+++ b/jstests/aggregation/sources/facet/inner_graphlookup.js
@@ -30,14 +30,21 @@
as: "connected"
}
};
- const normalResults = graphColl.aggregate([graphLookupStage]).toArray();
- const facetedResults = graphColl.aggregate([{$facet: {nested: [graphLookupStage]}}]).toArray();
+
+ const projectStage = {$project: {_id: 1, edges: 1, connected_length: {$size: "$connected"}}};
+
+ const normalResults = graphColl.aggregate([graphLookupStage, projectStage]).toArray();
+ const facetedResults =
+ graphColl.aggregate([{$facet: {nested: [graphLookupStage, projectStage]}}]).toArray();
assert.eq(facetedResults, [{nested: normalResults}]);
+ const sortStage = {$sort: {_id: 1, "connected._id": 1}};
+
const normalResultsUnwound =
- graphColl.aggregate([graphLookupStage, {$unwind: "$connected"}]).toArray();
+ graphColl.aggregate([graphLookupStage, {$unwind: "$connected"}, sortStage]).toArray();
const facetedResultsUnwound =
- graphColl.aggregate([{$facet: {nested: [graphLookupStage, {$unwind: "$connected"}]}}])
+ graphColl
+ .aggregate([{$facet: {nested: [graphLookupStage, {$unwind: "$connected"}, sortStage]}}])
.toArray();
assert.eq(facetedResultsUnwound, [{nested: normalResultsUnwound}]);
}());
diff --git a/jstests/core/index_stats.js b/jstests/core/index_stats.js
index 6bed899e16e..1834e7bb05f 100644
--- a/jstests/core/index_stats.js
+++ b/jstests/core/index_stats.js
@@ -111,26 +111,21 @@
// Confirm $and operation ticks indexes for winning plan, but not rejected plans.
//
- // Run explain to determine which indexes would be used for this query. Note that index
- // access counters are not incremented for explain execution.
- var explain = col.find({a: 2, b: 2}).explain("queryPlanner");
- var indexNameList = getIndexNamesForWinningPlan(explain);
- assert.gte(indexNameList.length, 1);
-
- for (var i = 0; i < indexNameList.length; ++i) {
- // Increment the expected $indexStats count for each index used.
- var name = indexNameList[i];
- if (name === "a_1") {
- countA++;
- } else {
- assert(name === "b_1_c_1");
- countB++;
- }
+ // We cannot use explain() to determine which indexes would be used for this query, since
+ // 1) explain() will not bump the access counters
+ // 2) explain() always runs the multi planner, and the multi planner may choose a different
+ // index each run. We therefore run the query, and check that only one of the indexes has its
+ // counter bumped (assuming we never choose an index intersection plan).
+ const results = col.find({a: 2, b: 2}).itcount();
+ if (countA + 1 == getUsageCount("a_1")) {
+ // Plan using index A was chosen. Index B should not have been used (assuming no index
+ // intersection plans are used).
+ countA++;
+ } else {
+ // Plan using index B was chosen. Index A should not have been used (assuming no index
+ // intersection plans are used).
+ assert.eq(++countB, getUsageCount("b_1_c_1"));
}
-
- // Run the query again without explain to increment index access counters.
- col.findOne({a: 2, b: 2});
- // Check all indexes for proper count.
assert.eq(countA, getUsageCount("a_1"));
assert.eq(countB, getUsageCount("b_1_c_1"));
assert.eq(0, getUsageCount("_id_"));
diff --git a/src/mongo/bson/simple_bsonobj_comparator.h b/src/mongo/bson/simple_bsonobj_comparator.h
index 90183beadf5..24ef6ecfbdf 100644
--- a/src/mongo/bson/simple_bsonobj_comparator.h
+++ b/src/mongo/bson/simple_bsonobj_comparator.h
@@ -113,13 +113,6 @@ 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>
@@ -138,13 +131,4 @@ 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
index ca94968a483..a6d9ab85631 100644
--- a/src/mongo/bson/simple_bsonobj_comparator_test.cpp
+++ b/src/mongo/bson/simple_bsonobj_comparator_test.cpp
@@ -86,14 +86,6 @@ TEST(SimpleBSONObjContainerTest, UnorderedSetIsDefaultConstructible) {
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'.
*/
@@ -141,12 +133,5 @@ TEST(SimpleBSONObjContainerTest, UnorderedMapIsDefaultConstructible) {
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/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp
index af7d9d18f61..7795040d86e 100644
--- a/src/mongo/db/auth/authorization_manager.cpp
+++ b/src/mongo/db/auth/authorization_manager.cpp
@@ -55,7 +55,6 @@
#include "mongo/db/auth/user.h"
#include "mongo/db/auth/user_document_parser.h"
#include "mongo/db/auth/user_name.h"
-#include "mongo/db/auth/user_name_hash.h"
#include "mongo/db/global_settings.h"
#include "mongo/db/jsobj.h"
#include "mongo/platform/compiler.h"
diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h
index 1e1c29dc1b7..e186dbde970 100644
--- a/src/mongo/db/auth/authorization_manager.h
+++ b/src/mongo/db/auth/authorization_manager.h
@@ -47,7 +47,6 @@
#include "mongo/db/auth/role_graph.h"
#include "mongo/db/auth/user.h"
#include "mongo/db/auth/user_name.h"
-#include "mongo/db/auth/user_name_hash.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/server_options.h"
diff --git a/src/mongo/db/auth/authorization_manager_impl.cpp b/src/mongo/db/auth/authorization_manager_impl.cpp
index 88368a9fd17..43124722d28 100644
--- a/src/mongo/db/auth/authorization_manager_impl.cpp
+++ b/src/mongo/db/auth/authorization_manager_impl.cpp
@@ -58,7 +58,7 @@
#include "mongo/db/auth/user_document_parser.h"
#include "mongo/db/auth/user_management_commands_parser.h"
#include "mongo/db/auth/user_name.h"
-#include "mongo/db/auth/user_name_hash.h"
+
#include "mongo/db/global_settings.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/mongod_options.h"
diff --git a/src/mongo/db/auth/authorization_manager_impl.h b/src/mongo/db/auth/authorization_manager_impl.h
index 7d8794a5b35..a734a1301b8 100644
--- a/src/mongo/db/auth/authorization_manager_impl.h
+++ b/src/mongo/db/auth/authorization_manager_impl.h
@@ -46,7 +46,6 @@
#include "mongo/db/auth/role_graph.h"
#include "mongo/db/auth/user.h"
#include "mongo/db/auth/user_name.h"
-#include "mongo/db/auth/user_name_hash.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/server_options.h"
diff --git a/src/mongo/db/auth/resource_pattern.h b/src/mongo/db/auth/resource_pattern.h
index 584db465274..9fd1a8111dc 100644
--- a/src/mongo/db/auth/resource_pattern.h
+++ b/src/mongo/db/auth/resource_pattern.h
@@ -35,7 +35,6 @@
#include "mongo/base/string_data.h"
#include "mongo/db/namespace_string.h"
-#include "mongo/platform/hash_namespace.h"
namespace mongo {
@@ -174,11 +173,6 @@ public:
std::string toString() const;
- inline size_t hash() const {
- // TODO: Choose a better hash function.
- return MONGO_HASH_NAMESPACE::hash<std::string>()(_ns.ns()) ^ _matchType;
- }
-
bool operator==(const ResourcePattern& other) const {
if (_matchType != other._matchType)
return false;
@@ -187,6 +181,11 @@ public:
return true;
}
+ template <typename H>
+ friend H AbslHashValue(H h, const ResourcePattern& rp) {
+ return H::combine(std::move(h), rp._ns, rp._matchType);
+ }
+
private:
enum MatchType {
matchNever = 0, /// Matches no resource.
@@ -208,12 +207,3 @@ private:
std::ostream& operator<<(std::ostream& os, const ResourcePattern& pattern);
} // namespace mongo
-
-MONGO_HASH_NAMESPACE_START
-template <>
-struct hash<mongo::ResourcePattern> {
- size_t operator()(const mongo::ResourcePattern& resource) const {
- return resource.hash();
- }
-};
-MONGO_HASH_NAMESPACE_END
diff --git a/src/mongo/db/auth/role_name.h b/src/mongo/db/auth/role_name.h
index c9e77c03c58..24bdd4ffb18 100644
--- a/src/mongo/db/auth/role_name.h
+++ b/src/mongo/db/auth/role_name.h
@@ -40,7 +40,6 @@
#include "mongo/base/string_data.h"
#include "mongo/bson/bsonelement.h"
#include "mongo/bson/bsonobjbuilder.h"
-#include "mongo/platform/hash_namespace.h"
#include "mongo/util/assert_util.h"
namespace mongo {
@@ -94,6 +93,11 @@ public:
return getFullName();
}
+ template <typename H>
+ friend H AbslHashValue(H h, const RoleName& rname) {
+ return H::combine(std::move(h), rname.getFullName());
+ }
+
private:
std::string _fullName; // The full name, stored as a string. "role@db".
size_t _splitPoint; // The index of the "@" separating the role and db name parts.
@@ -175,16 +179,6 @@ private:
} // namespace mongo
-// Define hash function for RoleNames so they can be keys in stdx::unordered_map
-MONGO_HASH_NAMESPACE_START
-template <>
-struct hash<mongo::RoleName> {
- size_t operator()(const mongo::RoleName& rname) const {
- return hash<std::string>()(rname.getFullName());
- }
-};
-MONGO_HASH_NAMESPACE_END
-
namespace mongo {
template <typename ContainerIterator>
diff --git a/src/mongo/db/auth/user_name.h b/src/mongo/db/auth/user_name.h
index 54c653a98ee..6a3ebdfa885 100644
--- a/src/mongo/db/auth/user_name.h
+++ b/src/mongo/db/auth/user_name.h
@@ -113,6 +113,11 @@ public:
return getUser() < rhs.getUser() || (getUser() == rhs.getUser() && getDB() < rhs.getDB());
}
+ template <typename H>
+ friend H AbslHashValue(H h, const UserName& userName) {
+ return H::combine(std::move(h), userName.getFullName());
+ }
+
private:
void _serializeToSubObj(BSONObjBuilder* sub) const;
diff --git a/src/mongo/db/concurrency/lock_manager_defs.h b/src/mongo/db/concurrency/lock_manager_defs.h
index 3e161da066a..5722d3eff69 100644
--- a/src/mongo/db/concurrency/lock_manager_defs.h
+++ b/src/mongo/db/concurrency/lock_manager_defs.h
@@ -36,7 +36,6 @@
#include "mongo/base/static_assert.h"
#include "mongo/base/string_data.h"
#include "mongo/config.h"
-#include "mongo/platform/hash_namespace.h"
namespace mongo {
@@ -220,6 +219,11 @@ public:
std::string toString() const;
+ template <typename H>
+ friend H AbslHashValue(H h, const ResourceId& resource) {
+ return H::combine(std::move(h), resource._fullHash);
+ }
+
private:
/**
* The top 'resourceTypeBits' bits of '_fullHash' represent the resource type,
@@ -459,13 +463,3 @@ struct LockRequest {
const char* lockRequestStatusName(LockRequest::Status status);
} // namespace mongo
-
-
-MONGO_HASH_NAMESPACE_START
-template <>
-struct hash<mongo::ResourceId> {
- size_t operator()(const mongo::ResourceId& resource) const {
- return resource;
- }
-};
-MONGO_HASH_NAMESPACE_END
diff --git a/src/mongo/db/cursor_manager.cpp b/src/mongo/db/cursor_manager.cpp
index 05a5aa0b329..395555af2b7 100644
--- a/src/mongo/db/cursor_manager.cpp
+++ b/src/mongo/db/cursor_manager.cpp
@@ -444,7 +444,7 @@ void CursorManager::invalidateAll(OperationContext* opCtx,
// If there's an operation actively using the cursor, then that operation is now
// responsible for cleaning it up. Otherwise we can immediately dispose of it.
if (cursor->_operationUsingCursor) {
- it = partition.erase(it);
+ partition.erase(it++);
continue;
}
@@ -454,7 +454,7 @@ void CursorManager::invalidateAll(OperationContext* opCtx,
++it;
} else {
toDisposeWithoutMutex.emplace_back(cursor);
- it = partition.erase(it);
+ partition.erase(it++);
}
}
}
@@ -483,7 +483,7 @@ std::size_t CursorManager::timeoutCursors(OperationContext* opCtx, Date_t now) {
auto* cursor = it->second;
if (cursorShouldTimeout_inlock(cursor, now)) {
toDisposeWithoutMutex.emplace_back(cursor);
- it = lockedPartition->erase(it);
+ lockedPartition->erase(it++);
} else {
++it;
}
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index 651d769544b..3db2576fcc4 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -38,7 +38,6 @@
#include "mongo/base/status_with.h"
#include "mongo/base/string_data.h"
#include "mongo/db/repl/optime.h"
-#include "mongo/platform/hash_namespace.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/uuid.h"
@@ -211,12 +210,6 @@ public:
return _ns.empty();
}
- struct Hasher {
- size_t operator()(const NamespaceString& nss) const {
- return std::hash<std::string>()(nss._ns);
- }
- };
-
//
// The following methods assume isValid() is true for this NamespaceString.
//
@@ -452,6 +445,11 @@ public:
return a.ns() >= b.ns();
}
+ template <typename H>
+ friend H AbslHashValue(H h, const NamespaceString& nss) {
+ return H::combine(std::move(h), nss._ns);
+ }
+
private:
std::string _ns;
size_t _dotIndex;
@@ -615,13 +613,3 @@ inline bool NamespaceString::validCollectionName(StringData coll) {
}
} // namespace mongo
-
-MONGO_HASH_NAMESPACE_START
-template <>
-struct hash<mongo::NamespaceString> {
- size_t operator()(const mongo::NamespaceString& nss) const {
- mongo::NamespaceString::Hasher hasher;
- return hasher(nss);
- }
-};
-MONGO_HASH_NAMESPACE_END
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup.cpp b/src/mongo/db/pipeline/document_source_graph_lookup.cpp
index 1b6583bb655..926e056f9a2 100644
--- a/src/mongo/db/pipeline/document_source_graph_lookup.cpp
+++ b/src/mongo/db/pipeline/document_source_graph_lookup.cpp
@@ -289,7 +289,7 @@ boost::optional<BSONObj> DocumentSourceGraphLookUp::makeMatchStageFromFrontier(
if (auto entry = _cache[*it]) {
cached->insert(entry->begin(), entry->end());
size_t valueSize = it->getApproximateSize();
- it = _frontier.erase(it);
+ _frontier.erase(it++);
// If the cached value increased in size while in the cache, we don't want to underflow
// '_frontierUsageBytes'.
diff --git a/src/mongo/db/query/plan_enumerator.cpp b/src/mongo/db/query/plan_enumerator.cpp
index c8a12ee6335..c365b46ab44 100644
--- a/src/mongo/db/query/plan_enumerator.cpp
+++ b/src/mongo/db/query/plan_enumerator.cpp
@@ -411,7 +411,7 @@ bool PlanEnumerator::prepMemo(MatchExpression* node, PrepMemoContext context) {
// either of the predicates on 'c', since this would change the predicate's meaning
// from a==1 to "b.a"==1.
if (it->second.traversedThroughElemMatchObj) {
- it = childContextCopy.outsidePreds.erase(it);
+ childContextCopy.outsidePreds.erase(it++);
} else {
it->second.route.push_back(i);
++it;
@@ -1331,7 +1331,7 @@ void PlanEnumerator::getMultikeyCompoundablePreds(const vector<MatchExpression*>
RelevantTag* usedRt = static_cast<RelevantTag*>(assignedPred->getTag());
set<string> usedPrefixes;
usedPrefixes.insert(getPathPrefix(usedRt->path));
- used[NULL] = usedPrefixes;
+ used[nullptr] = usedPrefixes;
// If 'assigned' is a predicate inside an $elemMatch, we have to
// add the prefix not only to the top-level context, but also to the
@@ -1356,8 +1356,8 @@ void PlanEnumerator::getMultikeyCompoundablePreds(const vector<MatchExpression*>
if (used.end() == used.find(rt->elemMatchExpr)) {
// This is a new $elemMatch that we haven't seen before.
- invariant(used.end() != used.find(NULL));
- set<string>& topLevelUsed = used.find(NULL)->second;
+ invariant(used.end() != used.find(nullptr));
+ set<string>& topLevelUsed = used.find(nullptr)->second;
// If the top-level path prefix of the $elemMatch hasn't been
// used yet, couldCompound[i] is safe to compound.
diff --git a/src/mongo/db/transaction_coordinator_catalog.cpp b/src/mongo/db/transaction_coordinator_catalog.cpp
index 24a23035597..96520986a2e 100644
--- a/src/mongo/db/transaction_coordinator_catalog.cpp
+++ b/src/mongo/db/transaction_coordinator_catalog.cpp
@@ -94,10 +94,10 @@ std::shared_ptr<TransactionCoordinator> TransactionCoordinatorCatalog::get(Opera
std::shared_ptr<TransactionCoordinator> coordinatorToReturn;
- const auto& coordinatorsForSessionIter = _coordinatorsBySession.find(lsid);
+ auto coordinatorsForSessionIter = _coordinatorsBySession.find(lsid);
if (coordinatorsForSessionIter != _coordinatorsBySession.end()) {
const auto& coordinatorsForSession = coordinatorsForSessionIter->second;
- const auto& coordinatorForTxnIter = coordinatorsForSession.find(txnNumber);
+ auto coordinatorForTxnIter = coordinatorsForSession.find(txnNumber);
if (coordinatorForTxnIter != coordinatorsForSession.end()) {
coordinatorToReturn = coordinatorForTxnIter->second;
}
@@ -107,10 +107,10 @@ std::shared_ptr<TransactionCoordinator> TransactionCoordinatorCatalog::get(Opera
// If the failpoint is on and we couldn't find the coordinator in the main catalog, fall
// back to the "defunct" catalog, which stores coordinators that have completed and would
// normally be forgotten.
- const auto& coordinatorsForSessionIter = _coordinatorsBySessionDefunct.find(lsid);
- if (coordinatorsForSessionIter != _coordinatorsBySession.end()) {
+ auto coordinatorsForSessionIter = _coordinatorsBySessionDefunct.find(lsid);
+ if (coordinatorsForSessionIter != _coordinatorsBySessionDefunct.end()) {
const auto& coordinatorsForSession = coordinatorsForSessionIter->second;
- const auto& coordinatorForTxnIter = coordinatorsForSession.find(txnNumber);
+ auto coordinatorForTxnIter = coordinatorsForSession.find(txnNumber);
if (coordinatorForTxnIter != coordinatorsForSession.end()) {
coordinatorToReturn = coordinatorForTxnIter->second;
}
diff --git a/src/mongo/dbtests/commandtests.cpp b/src/mongo/dbtests/commandtests.cpp
index f7212764304..08c24bc60d2 100644
--- a/src/mongo/dbtests/commandtests.cpp
+++ b/src/mongo/dbtests/commandtests.cpp
@@ -349,9 +349,9 @@ public:
bool ok = db.runCommand(nsDb(), BSON("rolesInfo" << 1), result);
ASSERT(ok);
- stdx::unordered_set<std::string> observedFields;
+ StringSet observedFields;
for (const auto& field : result) {
- ASSERT(observedFields.find(field) == observedFields.end());
+ ASSERT(observedFields.find(field.fieldNameStringData()) == observedFields.end());
observedFields.insert(field);
}
}
diff --git a/src/mongo/executor/task_executor.h b/src/mongo/executor/task_executor.h
index e8cff8ee0f6..1e3051e17b4 100644
--- a/src/mongo/executor/task_executor.h
+++ b/src/mongo/executor/task_executor.h
@@ -40,7 +40,6 @@
#include "mongo/base/string_data.h"
#include "mongo/executor/remote_command_request.h"
#include "mongo/executor/remote_command_response.h"
-#include "mongo/platform/hash_namespace.h"
#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/functional.h"
#include "mongo/transport/baton.h"
@@ -335,14 +334,15 @@ public:
return isValid();
}
- std::size_t hash() const {
- return std::hash<decltype(_callback)>()(_callback);
- }
-
bool isCanceled() const {
return getCallback()->isCanceled();
}
+ template <typename H>
+ friend H AbslHashValue(H h, const CallbackHandle& handle) {
+ return H::combine(std::move(h), handle._callback);
+ }
+
private:
void setCallback(std::shared_ptr<CallbackState> callback) {
_callback = callback;
@@ -445,13 +445,3 @@ struct TaskExecutor::RemoteCommandCallbackArgs {
} // namespace executor
} // namespace mongo
-
-// Provide a specialization for hash<CallbackHandle> so it can easily be stored in unordered_set.
-MONGO_HASH_NAMESPACE_START
-template <>
-struct hash<::mongo::executor::TaskExecutor::CallbackHandle> {
- size_t operator()(const ::mongo::executor::TaskExecutor::CallbackHandle& x) const {
- return x.hash();
- }
-};
-MONGO_HASH_NAMESPACE_END
diff --git a/src/mongo/platform/hash_namespace.h b/src/mongo/platform/hash_namespace.h
deleted file mode 100644
index d38ceadc1df..00000000000
--- a/src/mongo/platform/hash_namespace.h
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * 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
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * 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 Server Side 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 <functional>
-#if defined(_WIN32)
-#include <boost/functional/hash.hpp>
-#endif
-
-#if defined(_WIN32)
-#define MONGO_HASH_NAMESPACE_START namespace boost {
-#else
-#define MONGO_HASH_NAMESPACE_START namespace std {
-#endif
-
-#define MONGO_HASH_NAMESPACE_END }
-
-#if defined(_WIN32)
-#define MONGO_HASH_NAMESPACE boost
-#else
-#define MONGO_HASH_NAMESPACE std
-#endif
diff --git a/src/mongo/platform/process_id.h b/src/mongo/platform/process_id.h
index 2e5d34f5146..f0cc3b62e73 100644
--- a/src/mongo/platform/process_id.h
+++ b/src/mongo/platform/process_id.h
@@ -38,8 +38,6 @@
#include <unistd.h>
#endif
-#include "mongo/platform/hash_namespace.h"
-
namespace mongo {
#ifdef _WIN32
@@ -126,6 +124,11 @@ public:
return _npid >= other._npid;
}
+ template <typename H>
+ friend H AbslHashValue(H h, const ProcessId pid) {
+ return H::combine(std::move(h), pid.asUInt32());
+ }
+
private:
explicit ProcessId(NativeProcessId npid) : _npid(npid) {}
@@ -135,12 +138,3 @@ private:
std::ostream& operator<<(std::ostream& os, ProcessId pid);
} // namespace mongo
-
-MONGO_HASH_NAMESPACE_START
-template <>
-struct hash<::mongo::ProcessId> {
- size_t operator()(const ::mongo::ProcessId pid) const {
- return hash<::std::uint32_t>()(pid.asUInt32());
- }
-};
-MONGO_HASH_NAMESPACE_END
diff --git a/src/mongo/s/query/cluster_cursor_manager.cpp b/src/mongo/s/query/cluster_cursor_manager.cpp
index 6d4ad57a806..7ba8c456276 100644
--- a/src/mongo/s/query/cluster_cursor_manager.cpp
+++ b/src/mongo/s/query/cluster_cursor_manager.cpp
@@ -538,7 +538,7 @@ std::size_t ClusterCursorManager::killCursorsSatisfying(
cursorsToDestroy.push_back(entry.releaseCursor(nullptr));
// Destroy the entry and set the iterator to the next element.
- cursorIdEntryIt = entryMap.erase(cursorIdEntryIt);
+ entryMap.erase(cursorIdEntryIt++);
}
if (entryMap.empty()) {
@@ -735,7 +735,7 @@ auto ClusterCursorManager::eraseContainer(NssToCursorContainerMap::iterator it)
// with this namespace.
size_t numDeleted = _cursorIdPrefixToNamespaceMap.erase(container.containerPrefix);
invariant(numDeleted == 1);
- it = _namespaceToContainerMap.erase(it);
+ _namespaceToContainerMap.erase(it++);
invariant(_namespaceToContainerMap.size() == _cursorIdPrefixToNamespaceMap.size());
return it;
}
diff --git a/src/mongo/s/query/cluster_cursor_manager.h b/src/mongo/s/query/cluster_cursor_manager.h
index 3b3d94c37c0..1a86765cd90 100644
--- a/src/mongo/s/query/cluster_cursor_manager.h
+++ b/src/mongo/s/query/cluster_cursor_manager.h
@@ -474,8 +474,7 @@ private:
class CursorEntry;
struct CursorEntryContainer;
using CursorEntryMap = stdx::unordered_map<CursorId, CursorEntry>;
- using NssToCursorContainerMap =
- stdx::unordered_map<NamespaceString, CursorEntryContainer, NamespaceString::Hasher>;
+ using NssToCursorContainerMap = stdx::unordered_map<NamespaceString, CursorEntryContainer>;
/**
* Transfers ownership of the given pinned cursor back to the manager, and moves the cursor to
diff --git a/src/mongo/db/auth/user_name_hash.h b/src/mongo/stdx/trusted_hasher.h
index 480479214b6..8e3df6f07e0 100644
--- a/src/mongo/db/auth/user_name_hash.h
+++ b/src/mongo/stdx/trusted_hasher.h
@@ -1,4 +1,3 @@
-
/**
* Copyright (C) 2018-present MongoDB, Inc.
*
@@ -30,18 +29,38 @@
#pragma once
-#include <string>
+// This file depends on internal implementation details in abseil. In a library upgrade you may have
+// to re-write this file significantly.
+#include <absl/container/internal/hash_function_defaults.h>
-#include "mongo/db/auth/user_name.h"
-#include "mongo/platform/hash_namespace.h"
+/**
+ * To be safe we let abseil hash the produced hash one more time to protect ourselves against bad
+ * hash functions. If you know your hash function is good and can be trusted you get mark it as
+ * trusted by specializing a template like this:
+ *
+ * namespace mongo {
+ * template <>
+ * struct IsTrustedHasher<YourHash, YourKey> : std::true_type {};
+ * }
+ */
+namespace mongo {
+template <typename Key>
+using DefaultHasher = absl::container_internal::hash_default_hash<Key>;
-// Define hash function for UserNames so they can be keys in stdx::unordered_map
-MONGO_HASH_NAMESPACE_START
-template <>
-struct hash<mongo::UserName> {
- size_t operator()(const mongo::UserName& pname) const {
- return hash<std::string>()(pname.getFullName());
+template <typename Hasher, typename Key>
+struct IsTrustedHasher : std::is_same<Hasher, DefaultHasher<Key>> {};
+
+template <typename Hasher, typename Key>
+struct HashImprover : private Hasher {
+ HashImprover(const Hasher& hasher = Hasher()) : Hasher(hasher) {}
+ std::size_t operator()(const Key& k) const {
+ return absl::Hash<std::size_t>{}(Hasher::operator()(k));
}
};
-MONGO_HASH_NAMESPACE_END
+
+template <typename Hasher, typename Key>
+using EnsureTrustedHasher =
+ std::conditional_t<IsTrustedHasher<Hasher, Key>::value, Hasher, HashImprover<Hasher, Key>>;
+
+} // namespace mongo
diff --git a/src/mongo/stdx/unordered_map.h b/src/mongo/stdx/unordered_map.h
index 0a207741b18..6f4e7a8728a 100644
--- a/src/mongo/stdx/unordered_map.h
+++ b/src/mongo/stdx/unordered_map.h
@@ -30,22 +30,15 @@
#pragma once
-#if defined(_WIN32)
-#include <boost/unordered_map.hpp>
-#else
-#include <unordered_map>
-#endif
+#include "mongo/stdx/trusted_hasher.h"
+
+#include <absl/container/node_hash_map.h>
namespace mongo {
namespace stdx {
-#if defined(_WIN32)
-using ::boost::unordered_map; // NOLINT
-using ::boost::unordered_multimap; // NOLINT
-#else
-using ::std::unordered_map; // NOLINT
-using ::std::unordered_multimap; // NOLINT
-#endif
+template <class Key, class Value, class Hasher = DefaultHasher<Key>, typename... Args>
+using unordered_map = absl::node_hash_map<Key, Value, EnsureTrustedHasher<Hasher, Key>, Args...>;
} // namespace stdx
} // namespace mongo
diff --git a/src/mongo/stdx/unordered_set.h b/src/mongo/stdx/unordered_set.h
index dc24c3e7235..d88450cce75 100644
--- a/src/mongo/stdx/unordered_set.h
+++ b/src/mongo/stdx/unordered_set.h
@@ -30,22 +30,15 @@
#pragma once
-#if defined(_WIN32)
-#include <boost/unordered_set.hpp>
-#else
-#include <unordered_set>
-#endif
+#include "mongo/stdx/trusted_hasher.h"
+
+#include <absl/container/node_hash_set.h>
namespace mongo {
namespace stdx {
-#if defined(_WIN32)
-using ::boost::unordered_set; // NOLINT
-using ::boost::unordered_multiset; // NOLINT
-#else
-using ::std::unordered_set; // NOLINT
-using ::std::unordered_multiset; // NOLINT
-#endif
+template <class Key, class Hasher = DefaultHasher<Key>, typename... Args>
+using unordered_set = absl::node_hash_set<Key, EnsureTrustedHasher<Hasher, Key>, Args...>;
} // namespace stdx
} // namespace mongo
diff --git a/src/mongo/util/invalidating_lru_cache.h b/src/mongo/util/invalidating_lru_cache.h
index 48550b22ba5..37a7bcdfef0 100644
--- a/src/mongo/util/invalidating_lru_cache.h
+++ b/src/mongo/util/invalidating_lru_cache.h
@@ -285,7 +285,7 @@ private:
* otherwise pass nullptr and this function will lock/check the weak_ptr itself.
*/
ActiveIterator _invalidateActiveIterator(UniqueLockWithPtrGuard& guard,
- const ActiveIterator& it,
+ ActiveIterator it,
std::shared_ptr<Value>&& value) {
// If the iterator is past-the-end, then just return the iterator
if (it == _active.end()) {
@@ -311,7 +311,8 @@ private:
// Erase the iterator from the _active map and return the next iterator (so this
// can be called in a loop).
- return _active.erase(it);
+ _active.erase(it++);
+ return it;
}
/*
diff --git a/src/mongo/util/keyed_executor.h b/src/mongo/util/keyed_executor.h
index 2f0938c907c..80862d81e8e 100644
--- a/src/mongo/util/keyed_executor.h
+++ b/src/mongo/util/keyed_executor.h
@@ -73,13 +73,13 @@ namespace mongo {
* be effected by ceasing to queue new work, running tasks which can fail early and waiting on
* onAllCurrentTasksDrained.
*/
-template <typename Key, typename... MapArgs>
+template <typename Key, typename Hasher = DefaultHasher<Key>, typename... MapArgs>
class KeyedExecutor {
// We hold a deque per key. Each entry in the deque represents a task we'll eventually execute
// and a list of callers who need to be notified after it completes.
using Deque = std::deque<std::vector<Promise<void>>>;
- using Map = stdx::unordered_map<Key, Deque, MapArgs...>;
+ using Map = stdx::unordered_map<Key, Deque, Hasher, MapArgs...>;
public:
explicit KeyedExecutor(OutOfLineExecutor* executor) : _executor(executor) {}
diff --git a/src/mongo/util/net/hostandport.cpp b/src/mongo/util/net/hostandport.cpp
index e9103fc8062..eb6b402a05c 100644
--- a/src/mongo/util/net/hostandport.cpp
+++ b/src/mongo/util/net/hostandport.cpp
@@ -217,12 +217,3 @@ template StringBuilderImpl<SharedBufferAllocator>& operator<<(
StringBuilderImpl<SharedBufferAllocator>&, const HostAndPort&);
} // namespace mongo
-
-MONGO_HASH_NAMESPACE_START
-size_t hash<mongo::HostAndPort>::operator()(const mongo::HostAndPort& host) const {
- hash<int> intHasher;
- size_t hash = intHasher(host.port());
- boost::hash_combine(hash, host.host());
- return hash;
-}
-MONGO_HASH_NAMESPACE_END
diff --git a/src/mongo/util/net/hostandport.h b/src/mongo/util/net/hostandport.h
index e01c75ebe06..d7b069ef08e 100644
--- a/src/mongo/util/net/hostandport.h
+++ b/src/mongo/util/net/hostandport.h
@@ -36,7 +36,6 @@
#include <boost/optional.hpp>
#include "mongo/bson/util/builder.h"
-#include "mongo/platform/hash_namespace.h"
#include "mongo/util/net/sockaddr.h"
namespace mongo {
@@ -154,6 +153,11 @@ struct HostAndPort {
return _port >= 0;
}
+ template <typename H>
+ friend H AbslHashValue(H h, const HostAndPort& hostAndPort) {
+ return H::combine(std::move(h), hostAndPort.host(), hostAndPort.port());
+ }
+
private:
boost::optional<SockAddr> _addr;
std::string _host;
@@ -166,12 +170,3 @@ template <typename Allocator>
StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, const HostAndPort& hp);
} // namespace mongo
-
-MONGO_HASH_NAMESPACE_START
-
-template <>
-struct hash<mongo::HostAndPort> {
- size_t operator()(const mongo::HostAndPort& host) const;
-};
-
-MONGO_HASH_NAMESPACE_END