diff options
Diffstat (limited to 'src/mongo/db/query/plan_cache.h')
-rw-r--r-- | src/mongo/db/query/plan_cache.h | 84 |
1 files changed, 70 insertions, 14 deletions
diff --git a/src/mongo/db/query/plan_cache.h b/src/mongo/db/query/plan_cache.h index d88e269bebd..99f88ed23a9 100644 --- a/src/mongo/db/query/plan_cache.h +++ b/src/mongo/db/query/plan_cache.h @@ -44,8 +44,69 @@ namespace mongo { -// A PlanCacheKey is a string-ified version of a query's predicate/projection/sort. -typedef std::string PlanCacheKey; +/** + * Represents the "key" used in the PlanCache mapping from query shape -> query plan. + */ +class PlanCacheKey { +public: + PlanCacheKey(CanonicalQuery::QueryShapeString shapeString, std::string indexabilityString) { + _lengthOfStablePart = shapeString.size(); + _key = std::move(shapeString); + _key += indexabilityString; + } + + CanonicalQuery::QueryShapeString getStableKey() const { + return std::string(_key, 0, _lengthOfStablePart); + } + + StringData getStableKeyStringData() const { + return StringData(_key.c_str(), _lengthOfStablePart); + } + + /** + * Return the "unstable" portion of the key, which may vary across catalog changes. + */ + StringData getUnstablePart() const { + return StringData(_key.c_str() + _lengthOfStablePart, _key.size() - _lengthOfStablePart); + } + + StringData stringData() const { + return _key; + } + + const std::string& toString() const { + return _key; + } + + bool operator==(const PlanCacheKey& other) const { + return other._key == _key && other._lengthOfStablePart == _lengthOfStablePart; + } + + bool operator!=(const PlanCacheKey& other) const { + return !(*this == other); + } + +private: + // Key is broken into two parts: + // <stable key> | <indexability discriminators> + // Combined, the two parts make up the plan cache key. We store them in one std::string so that + // we can easily/cheaply extract the stable key. + std::string _key; + + // How long the "stable key" is. + size_t _lengthOfStablePart; +}; + +std::ostream& operator<<(std::ostream& stream, const PlanCacheKey& key); +StringBuilder& operator<<(StringBuilder& builder, const PlanCacheKey& key); + +class PlanCacheKeyHasher { +public: + std::size_t operator()(const PlanCacheKey& k) const { + return std::hash<std::string>{}(k.toString()); + } +}; + struct PlanRankingDecision; struct QuerySolution; @@ -225,7 +286,8 @@ public: */ PlanCacheEntry(const std::vector<QuerySolution*>& solutions, PlanRankingDecision* why, - uint32_t queryHash); + uint32_t queryHash, + uint32_t planCacheKey); ~PlanCacheEntry(); @@ -261,6 +323,9 @@ public: // diagnostic output. uint32_t queryHash; + // Hash of the "stable" PlanCacheKey, which is the same regardless of what indexes are around. + uint32_t planCacheKey; + // // Performance stats // @@ -427,12 +492,6 @@ public: PlanCacheKey computeKey(const CanonicalQuery&) const; /** - * Returns a hash of the plan cache key. This hash may not be stable between different versions - * of the server. - */ - static uint32_t computeQueryHash(const PlanCacheKey& key); - - /** * Returns a copy of a cache entry. * Used by planCacheListPlans to display plan details. * @@ -480,15 +539,12 @@ private: NewEntryState getNewEntryState(const CanonicalQuery& query, uint32_t queryHash, + uint32_t planCacheKey, PlanCacheEntry* oldEntry, size_t newWorks, double growthCoefficient); - void encodeKeyForMatch(const MatchExpression* tree, StringBuilder* keyBuilder) const; - void encodeKeyForSort(const BSONObj& sortObj, StringBuilder* keyBuilder) const; - void encodeKeyForProj(const BSONObj& projObj, StringBuilder* keyBuilder) const; - - LRUKeyValue<PlanCacheKey, PlanCacheEntry> _cache; + LRUKeyValue<PlanCacheKey, PlanCacheEntry, PlanCacheKeyHasher> _cache; // Protects _cache. mutable stdx::mutex _cacheMutex; |