summaryrefslogtreecommitdiff
path: root/src/mongo/db/collection_index_usage_tracker.cpp
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@mongodb.com>2020-07-24 17:03:21 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-08-19 00:56:17 +0000
commit6ffbf7c475ee34575a632040b70a6a20aa13cb4a (patch)
tree8575e17e2509dcd5dd99ad23dd2fca2108c07bd3 /src/mongo/db/collection_index_usage_tracker.cpp
parentc4e552d731362a49f9d4a7ed4e646cfc852958da (diff)
downloadmongo-6ffbf7c475ee34575a632040b70a6a20aa13cb4a.tar.gz
SERVER-48539 Add internal concurrency control to CollectionIndexUsageTracker
Diffstat (limited to 'src/mongo/db/collection_index_usage_tracker.cpp')
-rw-r--r--src/mongo/db/collection_index_usage_tracker.cpp48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/mongo/db/collection_index_usage_tracker.cpp b/src/mongo/db/collection_index_usage_tracker.cpp
index 4a30940d3cb..8cab4bb51b7 100644
--- a/src/mongo/db/collection_index_usage_tracker.cpp
+++ b/src/mongo/db/collection_index_usage_tracker.cpp
@@ -31,8 +31,11 @@
#include "mongo/platform/basic.h"
-#include "mongo/base/counter.h"
#include "mongo/db/collection_index_usage_tracker.h"
+
+#include <atomic>
+
+#include "mongo/base/counter.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/clock_source.h"
@@ -49,15 +52,21 @@ ServerStatusMetricField<Counter64> displayCollectionScansNonTailable(
} // namespace
CollectionIndexUsageTracker::CollectionIndexUsageTracker(ClockSource* clockSource)
- : _clockSource(clockSource) {
+ : _indexUsageStatsMap(std::make_shared<CollectionIndexUsageMap>()), _clockSource(clockSource) {
invariant(_clockSource);
}
void CollectionIndexUsageTracker::recordIndexAccess(StringData indexName) {
invariant(!indexName.empty());
- dassert(_indexUsageMap.find(indexName) != _indexUsageMap.end());
- _indexUsageMap[indexName].accesses.fetchAndAdd(1);
+ // The following update after fetching the map can race with the removal of this index entry
+ // from the map. However, that race is inconsequential and remains memory safe.
+ auto mapSharedPtr = atomic_load(&_indexUsageStatsMap);
+
+ dassert(mapSharedPtr->find(indexName) != mapSharedPtr->end());
+
+ // Increment the index usage atomic counter.
+ mapSharedPtr->at(indexName)->accesses.fetchAndAdd(1);
}
void CollectionIndexUsageTracker::recordCollectionScans(unsigned long long collectionScans) {
@@ -73,20 +82,39 @@ void CollectionIndexUsageTracker::recordCollectionScansNonTailable(
void CollectionIndexUsageTracker::registerIndex(StringData indexName, const BSONObj& indexKey) {
invariant(!indexName.empty());
- dassert(_indexUsageMap.find(indexName) == _indexUsageMap.end());
- // Create map entry.
- _indexUsageMap[indexName] = IndexUsageStats(_clockSource->now(), indexKey);
+ // Create a copy of the map to modify.
+ auto mapSharedPtr = atomic_load(&_indexUsageStatsMap);
+ auto mapCopy = std::make_shared<CollectionIndexUsageMap>(*mapSharedPtr);
+
+ dassert(mapCopy->find(indexName) == mapCopy->end());
+
+ // Create the map entry.
+ auto inserted = mapCopy->try_emplace(
+ indexName, make_intrusive<IndexUsageStats>(_clockSource->now(), indexKey));
+ invariant(inserted.second);
+
+ // Swap the modified map into place atomically.
+ atomic_store(&_indexUsageStatsMap, std::move(mapCopy));
}
void CollectionIndexUsageTracker::unregisterIndex(StringData indexName) {
invariant(!indexName.empty());
- _indexUsageMap.erase(indexName);
+ // Create a copy of the map to modify.
+ auto mapSharedPtr = atomic_load(&_indexUsageStatsMap);
+ auto mapCopy = std::make_shared<CollectionIndexUsageMap>(*mapSharedPtr);
+
+ // Remove the map entry.
+ mapCopy->erase(indexName);
+
+ // Swap the modified map into place atomically.
+ atomic_store(&_indexUsageStatsMap, std::move(mapCopy));
}
-CollectionIndexUsageMap CollectionIndexUsageTracker::getUsageStats() const {
- return _indexUsageMap;
+std::shared_ptr<CollectionIndexUsageTracker::CollectionIndexUsageMap>
+CollectionIndexUsageTracker::getUsageStats() const {
+ return atomic_load(&_indexUsageStatsMap);
}
CollectionIndexUsageTracker::CollectionScanStats