summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/commands/plan_cache_commands.cpp2
-rw-r--r--src/mongo/db/exec/cached_plan.cpp6
-rw-r--r--src/mongo/db/query/plan_cache.cpp19
-rw-r--r--src/mongo/db/query/plan_cache.h30
4 files changed, 13 insertions, 44 deletions
diff --git a/src/mongo/db/commands/plan_cache_commands.cpp b/src/mongo/db/commands/plan_cache_commands.cpp
index 1210588d066..3c1d6a00a6a 100644
--- a/src/mongo/db/commands/plan_cache_commands.cpp
+++ b/src/mongo/db/commands/plan_cache_commands.cpp
@@ -425,7 +425,7 @@ Status PlanCacheListPlans::list(OperationContext* opCtx,
BSONArrayBuilder scoresBob(feedbackBob.subarrayStart("scores"));
for (size_t i = 0; i < entry->feedback.size(); ++i) {
BSONObjBuilder scoreBob(scoresBob.subobjStart());
- scoreBob.append("score", entry->feedback[i]->score);
+ scoreBob.append("score", entry->feedback[i]);
}
scoresBob.doneFast();
}
diff --git a/src/mongo/db/exec/cached_plan.cpp b/src/mongo/db/exec/cached_plan.cpp
index 33a9759f9a8..ef3bc771b64 100644
--- a/src/mongo/db/exec/cached_plan.cpp
+++ b/src/mongo/db/exec/cached_plan.cpp
@@ -322,12 +322,10 @@ const SpecificStats* CachedPlanStage::getSpecificStats() const {
}
void CachedPlanStage::updatePlanCache() {
- std::unique_ptr<PlanCacheEntryFeedback> feedback = stdx::make_unique<PlanCacheEntryFeedback>();
- feedback->stats = getStats();
- feedback->score = PlanRanker::scoreTree(feedback->stats->children[0].get());
+ const double score = PlanRanker::scoreTree(getStats()->children[0].get());
PlanCache* cache = _collection->infoCache()->getPlanCache();
- Status fbs = cache->feedback(*_canonicalQuery, feedback.release());
+ Status fbs = cache->feedback(*_canonicalQuery, score);
if (!fbs.isOK()) {
LOG(5) << _canonicalQuery->ns() << ": Failed to update cache with feedback: " << redact(fbs)
<< " - "
diff --git a/src/mongo/db/query/plan_cache.cpp b/src/mongo/db/query/plan_cache.cpp
index f132dc077b9..ac5015b08d1 100644
--- a/src/mongo/db/query/plan_cache.cpp
+++ b/src/mongo/db/query/plan_cache.cpp
@@ -411,9 +411,6 @@ PlanCacheEntry::PlanCacheEntry(const std::vector<QuerySolution*>& solutions,
}
PlanCacheEntry::~PlanCacheEntry() {
- for (size_t i = 0; i < feedback.size(); ++i) {
- delete feedback[i];
- }
for (size_t i = 0; i < plannerData.size(); ++i) {
delete plannerData[i];
}
@@ -439,12 +436,8 @@ PlanCacheEntry* PlanCacheEntry::clone() const {
entry->works = works;
// Copy performance stats.
- for (size_t i = 0; i < feedback.size(); ++i) {
- PlanCacheEntryFeedback* fb = new PlanCacheEntryFeedback();
- fb->stats.reset(feedback[i]->stats->clone());
- fb->score = feedback[i]->score;
- entry->feedback.push_back(fb);
- }
+ entry->feedback = feedback;
+
return entry;
}
@@ -923,11 +916,7 @@ PlanCache::GetResult PlanCache::get(const PlanCacheKey& key) const {
return {state, stdx::make_unique<CachedSolution>(key, *entry)};
}
-Status PlanCache::feedback(const CanonicalQuery& cq, PlanCacheEntryFeedback* feedback) {
- if (NULL == feedback) {
- return Status(ErrorCodes::BadValue, "feedback is NULL");
- }
- std::unique_ptr<PlanCacheEntryFeedback> autoFeedback(feedback);
+Status PlanCache::feedback(const CanonicalQuery& cq, double score) {
PlanCacheKey ck = computeKey(cq);
stdx::lock_guard<stdx::mutex> cacheLock(_cacheMutex);
@@ -940,7 +929,7 @@ Status PlanCache::feedback(const CanonicalQuery& cq, PlanCacheEntryFeedback* fee
// We store up to a constant number of feedback entries.
if (entry->feedback.size() < static_cast<size_t>(internalQueryCacheFeedbacksStored.load())) {
- entry->feedback.push_back(autoFeedback.release());
+ entry->feedback.push_back(score);
}
return Status::OK();
diff --git a/src/mongo/db/query/plan_cache.h b/src/mongo/db/query/plan_cache.h
index b0b767c13ea..159b724df04 100644
--- a/src/mongo/db/query/plan_cache.h
+++ b/src/mongo/db/query/plan_cache.h
@@ -50,22 +50,6 @@ struct QuerySolution;
struct QuerySolutionNode;
/**
- * When the CachedPlanStage runs a cached query, it can provide feedback to the cache. This
- * feedback is available to anyone who retrieves that query in the future.
- */
-struct PlanCacheEntryFeedback {
- // How well did the cached plan perform?
- std::unique_ptr<PlanStageStats> stats;
-
- // The "goodness" score produced by the plan ranker
- // corresponding to 'stats'.
- double score;
-};
-
-// TODO: Replace with opaque type.
-typedef std::string PlanID;
-
-/**
* A PlanCacheIndexTree is the meaty component of the data
* stored in SolutionCacheData. It is a tree structure with
* index tags that indicates to the access planner which indices
@@ -283,9 +267,8 @@ public:
// the other plans lost.
std::unique_ptr<PlanRankingDecision> decision;
- // Annotations from cached runs. The CachedPlanStage provides these stats about its
- // runs when they complete.
- std::vector<PlanCacheEntryFeedback*> feedback;
+ // Scores from uses of this cache entry.
+ std::vector<double> feedback;
// Whether or not the cache entry is active. Inactive cache entries should not be used for
// planning.
@@ -407,10 +390,9 @@ public:
/**
* When the CachedPlanStage runs a plan out of the cache, we want to record data about the
- * plan's performance. The CachedPlanStage calls feedback(...) after executing the cached
- * plan for a trial period in order to do this.
- *
- * Cache takes ownership of 'feedback'.
+ * plan's performance. The CachedPlanStage calls feedback(...) after executing the cached
+ * plan for a trial period in order to do this. Currently, the only feedback metric recorded is
+ * the score associated with the cached plan trial period.
*
* If the entry corresponding to 'cq' isn't in the cache anymore, the feedback is ignored
* and an error Status is returned.
@@ -418,7 +400,7 @@ public:
* If the entry corresponding to 'cq' still exists, 'feedback' is added to the run
* statistics about the plan. Status::OK() is returned.
*/
- Status feedback(const CanonicalQuery& cq, PlanCacheEntryFeedback* feedback);
+ Status feedback(const CanonicalQuery& cq, double score);
/**
* Remove the entry corresponding to 'ck' from the cache. Returns Status::OK() if the plan