diff options
Diffstat (limited to 'src/mongo/db/exec/plan_stats.h')
-rw-r--r-- | src/mongo/db/exec/plan_stats.h | 948 |
1 files changed, 468 insertions, 480 deletions
diff --git a/src/mongo/db/exec/plan_stats.h b/src/mongo/db/exec/plan_stats.h index 3504355f071..c3b514260a3 100644 --- a/src/mongo/db/exec/plan_stats.h +++ b/src/mongo/db/exec/plan_stats.h @@ -37,626 +37,614 @@ #include "mongo/db/query/stage_types.h" #include "mongo/platform/cstdint.h" #include "mongo/util/time_support.h" -#include "mongo/util/net/listen.h" // for Listener::getElapsedTimeMillis() +#include "mongo/util/net/listen.h" // for Listener::getElapsedTimeMillis() namespace mongo { +/** + * The interface all specific-to-stage stats provide. + */ +struct SpecificStats { + virtual ~SpecificStats() {} + /** - * The interface all specific-to-stage stats provide. + * Make a deep copy. */ - struct SpecificStats { - virtual ~SpecificStats() { } - - /** - * Make a deep copy. - */ - virtual SpecificStats* clone() const = 0; - }; - - // Every stage has CommonStats. - struct CommonStats { - CommonStats(const char* type) - : stageTypeStr(type), - works(0), - yields(0), - unyields(0), - invalidates(0), - advanced(0), - needTime(0), - needYield(0), - executionTimeMillis(0), - isEOF(false) { } - // String giving the type of the stage. Not owned. - const char* stageTypeStr; - - // Count calls into the stage. - size_t works; - size_t yields; - size_t unyields; - size_t invalidates; - - // How many times was this state the return value of work(...)? - size_t advanced; - size_t needTime; - size_t needYield; - - // BSON representation of a MatchExpression affixed to this node. If there - // is no filter affixed, then 'filter' should be an empty BSONObj. - BSONObj filter; - - // Time elapsed while working inside this stage. - long long executionTimeMillis; - - // TODO: have some way of tracking WSM sizes (or really any series of #s). We can measure - // the size of our inputs and the size of our outputs. We can do a lot with the WS here. - - // TODO: once we've picked a plan, collect different (or additional) stats for display to - // the user, eg. time_t totalTimeSpent; - - // TODO: keep track of the total yield time / fetch time done for a plan. - - bool isEOF; - private: - // Default constructor is illegal. - CommonStats(); - }; - - // The universal container for a stage's stats. - struct PlanStageStats { - PlanStageStats(const CommonStats& c, StageType t) : stageType(t), common(c) { } - - ~PlanStageStats() { - for (size_t i = 0; i < children.size(); ++i) { - delete children[i]; - } + virtual SpecificStats* clone() const = 0; +}; + +// Every stage has CommonStats. +struct CommonStats { + CommonStats(const char* type) + : stageTypeStr(type), + works(0), + yields(0), + unyields(0), + invalidates(0), + advanced(0), + needTime(0), + needYield(0), + executionTimeMillis(0), + isEOF(false) {} + // String giving the type of the stage. Not owned. + const char* stageTypeStr; + + // Count calls into the stage. + size_t works; + size_t yields; + size_t unyields; + size_t invalidates; + + // How many times was this state the return value of work(...)? + size_t advanced; + size_t needTime; + size_t needYield; + + // BSON representation of a MatchExpression affixed to this node. If there + // is no filter affixed, then 'filter' should be an empty BSONObj. + BSONObj filter; + + // Time elapsed while working inside this stage. + long long executionTimeMillis; + + // TODO: have some way of tracking WSM sizes (or really any series of #s). We can measure + // the size of our inputs and the size of our outputs. We can do a lot with the WS here. + + // TODO: once we've picked a plan, collect different (or additional) stats for display to + // the user, eg. time_t totalTimeSpent; + + // TODO: keep track of the total yield time / fetch time done for a plan. + + bool isEOF; + +private: + // Default constructor is illegal. + CommonStats(); +}; + +// The universal container for a stage's stats. +struct PlanStageStats { + PlanStageStats(const CommonStats& c, StageType t) : stageType(t), common(c) {} + + ~PlanStageStats() { + for (size_t i = 0; i < children.size(); ++i) { + delete children[i]; } + } - /** - * Make a deep copy. - */ - PlanStageStats* clone() const { - PlanStageStats* stats = new PlanStageStats(common, stageType); - if (specific.get()) { - stats->specific.reset(specific->clone()); - } - for (size_t i = 0; i < children.size(); ++i) { - invariant(children[i]); - stats->children.push_back(children[i]->clone()); - } - return stats; + /** + * Make a deep copy. + */ + PlanStageStats* clone() const { + PlanStageStats* stats = new PlanStageStats(common, stageType); + if (specific.get()) { + stats->specific.reset(specific->clone()); } + for (size_t i = 0; i < children.size(); ++i) { + invariant(children[i]); + stats->children.push_back(children[i]->clone()); + } + return stats; + } - // See query/stage_type.h - StageType stageType; + // See query/stage_type.h + StageType stageType; - // Stats exported by implementing the PlanStage interface. - CommonStats common; + // Stats exported by implementing the PlanStage interface. + CommonStats common; - // Per-stage place to stash additional information - std::unique_ptr<SpecificStats> specific; + // Per-stage place to stash additional information + std::unique_ptr<SpecificStats> specific; - // The stats of the node's children. - std::vector<PlanStageStats*> children; + // The stats of the node's children. + std::vector<PlanStageStats*> children; - private: - MONGO_DISALLOW_COPYING(PlanStageStats); - }; +private: + MONGO_DISALLOW_COPYING(PlanStageStats); +}; - struct AndHashStats : public SpecificStats { - AndHashStats() : flaggedButPassed(0), - flaggedInProgress(0), - memUsage(0), - memLimit(0) { } +struct AndHashStats : public SpecificStats { + AndHashStats() : flaggedButPassed(0), flaggedInProgress(0), memUsage(0), memLimit(0) {} - virtual ~AndHashStats() { } + virtual ~AndHashStats() {} - virtual SpecificStats* clone() const { - AndHashStats* specific = new AndHashStats(*this); - return specific; - } + virtual SpecificStats* clone() const { + AndHashStats* specific = new AndHashStats(*this); + return specific; + } - // Invalidation counters. - // How many results had the AND fully evaluated but were invalidated? - size_t flaggedButPassed; + // Invalidation counters. + // How many results had the AND fully evaluated but were invalidated? + size_t flaggedButPassed; - // How many results were mid-AND but got flagged? - size_t flaggedInProgress; + // How many results were mid-AND but got flagged? + size_t flaggedInProgress; - // How many entries are in the map after each child? - // child 'i' produced children[i].common.advanced RecordIds, of which mapAfterChild[i] were - // intersections. - std::vector<size_t> mapAfterChild; + // How many entries are in the map after each child? + // child 'i' produced children[i].common.advanced RecordIds, of which mapAfterChild[i] were + // intersections. + std::vector<size_t> mapAfterChild; - // mapAfterChild[mapAfterChild.size() - 1] WSMswere match tested. - // commonstats.advanced is how many passed. + // mapAfterChild[mapAfterChild.size() - 1] WSMswere match tested. + // commonstats.advanced is how many passed. - // What's our current memory usage? - size_t memUsage; + // What's our current memory usage? + size_t memUsage; - // What's our memory limit? - size_t memLimit; - }; + // What's our memory limit? + size_t memLimit; +}; - struct AndSortedStats : public SpecificStats { - AndSortedStats() : flagged(0) { } +struct AndSortedStats : public SpecificStats { + AndSortedStats() : flagged(0) {} - virtual ~AndSortedStats() { } + virtual ~AndSortedStats() {} - virtual SpecificStats* clone() const { - AndSortedStats* specific = new AndSortedStats(*this); - return specific; - } + virtual SpecificStats* clone() const { + AndSortedStats* specific = new AndSortedStats(*this); + return specific; + } - // How many results from each child did not pass the AND? - std::vector<size_t> failedAnd; + // How many results from each child did not pass the AND? + std::vector<size_t> failedAnd; - // How many results were flagged via invalidation? - size_t flagged; - }; + // How many results were flagged via invalidation? + size_t flagged; +}; - struct CachedPlanStats : public SpecificStats { - CachedPlanStats() { } +struct CachedPlanStats : public SpecificStats { + CachedPlanStats() {} - virtual SpecificStats* clone() const { - return new CachedPlanStats(*this); - } - }; + virtual SpecificStats* clone() const { + return new CachedPlanStats(*this); + } +}; - struct CollectionScanStats : public SpecificStats { - CollectionScanStats() : docsTested(0), direction(1) { } +struct CollectionScanStats : public SpecificStats { + CollectionScanStats() : docsTested(0), direction(1) {} - virtual SpecificStats* clone() const { - CollectionScanStats* specific = new CollectionScanStats(*this); - return specific; - } + virtual SpecificStats* clone() const { + CollectionScanStats* specific = new CollectionScanStats(*this); + return specific; + } - // How many documents did we check against our filter? - size_t docsTested; + // How many documents did we check against our filter? + size_t docsTested; - // >0 if we're traversing the collection forwards. <0 if we're traversing it - // backwards. - int direction; - }; + // >0 if we're traversing the collection forwards. <0 if we're traversing it + // backwards. + int direction; +}; - struct CountStats : public SpecificStats { - CountStats() : nCounted(0), nSkipped(0), trivialCount(false) { } +struct CountStats : public SpecificStats { + CountStats() : nCounted(0), nSkipped(0), trivialCount(false) {} - virtual SpecificStats* clone() const { - CountStats* specific = new CountStats(*this); - return specific; - } + virtual SpecificStats* clone() const { + CountStats* specific = new CountStats(*this); + return specific; + } - // The result of the count. - long long nCounted; + // The result of the count. + long long nCounted; - // The number of results we skipped over. - long long nSkipped; + // The number of results we skipped over. + long long nSkipped; - // A "trivial count" is one that we can answer by calling numRecords() on the - // collection, without actually going through any query logic. - bool trivialCount; - }; + // A "trivial count" is one that we can answer by calling numRecords() on the + // collection, without actually going through any query logic. + bool trivialCount; +}; - struct CountScanStats : public SpecificStats { - CountScanStats() : indexVersion(0), - isMultiKey(false), - isPartial(false), - isSparse(false), - isUnique(false), - keysExamined(0) { } +struct CountScanStats : public SpecificStats { + CountScanStats() + : indexVersion(0), + isMultiKey(false), + isPartial(false), + isSparse(false), + isUnique(false), + keysExamined(0) {} - virtual ~CountScanStats() { } + virtual ~CountScanStats() {} - virtual SpecificStats* clone() const { - CountScanStats* specific = new CountScanStats(*this); - // BSON objects have to be explicitly copied. - specific->keyPattern = keyPattern.getOwned(); - return specific; - } + virtual SpecificStats* clone() const { + CountScanStats* specific = new CountScanStats(*this); + // BSON objects have to be explicitly copied. + specific->keyPattern = keyPattern.getOwned(); + return specific; + } - std::string indexName; + std::string indexName; - BSONObj keyPattern; + BSONObj keyPattern; - int indexVersion; + int indexVersion; - bool isMultiKey; - bool isPartial; - bool isSparse; - bool isUnique; + bool isMultiKey; + bool isPartial; + bool isSparse; + bool isUnique; - size_t keysExamined; + size_t keysExamined; +}; - }; +struct DeleteStats : public SpecificStats { + DeleteStats() : docsDeleted(0), nInvalidateSkips(0) {} - struct DeleteStats : public SpecificStats { - DeleteStats() : docsDeleted(0), nInvalidateSkips(0) { } + virtual SpecificStats* clone() const { + return new DeleteStats(*this); + } - virtual SpecificStats* clone() const { - return new DeleteStats(*this); - } + size_t docsDeleted; - size_t docsDeleted; + // Invalidated documents can be force-fetched, causing the now invalid RecordId to + // be thrown out. The delete stage skips over any results which do not have a RecordId. + size_t nInvalidateSkips; +}; - // Invalidated documents can be force-fetched, causing the now invalid RecordId to - // be thrown out. The delete stage skips over any results which do not have a RecordId. - size_t nInvalidateSkips; - }; +struct DistinctScanStats : public SpecificStats { + DistinctScanStats() : keysExamined(0), indexVersion(0) {} - struct DistinctScanStats : public SpecificStats { - DistinctScanStats() : keysExamined(0), indexVersion(0) { } + virtual SpecificStats* clone() const { + DistinctScanStats* specific = new DistinctScanStats(*this); + specific->keyPattern = keyPattern.getOwned(); + return specific; + } - virtual SpecificStats* clone() const { - DistinctScanStats* specific = new DistinctScanStats(*this); - specific->keyPattern = keyPattern.getOwned(); - return specific; - } + // How many keys did we look at while distinct-ing? + size_t keysExamined; - // How many keys did we look at while distinct-ing? - size_t keysExamined; + std::string indexName; - std::string indexName; + BSONObj keyPattern; - BSONObj keyPattern; + int indexVersion; +}; - int indexVersion; - }; +struct FetchStats : public SpecificStats { + FetchStats() : alreadyHasObj(0), forcedFetches(0), docsExamined(0) {} - struct FetchStats : public SpecificStats { - FetchStats() : alreadyHasObj(0), - forcedFetches(0), - docsExamined(0) { } + virtual ~FetchStats() {} - virtual ~FetchStats() { } + virtual SpecificStats* clone() const { + FetchStats* specific = new FetchStats(*this); + return specific; + } - virtual SpecificStats* clone() const { - FetchStats* specific = new FetchStats(*this); - return specific; - } + // Have we seen anything that already had an object? + size_t alreadyHasObj; - // Have we seen anything that already had an object? - size_t alreadyHasObj; + // How many records were we forced to fetch as the result of an invalidation? + size_t forcedFetches; - // How many records were we forced to fetch as the result of an invalidation? - size_t forcedFetches; + // The total number of full documents touched by the fetch stage. + size_t docsExamined; +}; - // The total number of full documents touched by the fetch stage. - size_t docsExamined; - }; +struct GroupStats : public SpecificStats { + GroupStats() : nGroups(0) {} - struct GroupStats : public SpecificStats { - GroupStats() : nGroups(0) { } + virtual ~GroupStats() {} - virtual ~GroupStats() { } + virtual SpecificStats* clone() const { + GroupStats* specific = new GroupStats(*this); + return specific; + } - virtual SpecificStats* clone() const { - GroupStats* specific = new GroupStats(*this); - return specific; - } + // The total number of groups. + size_t nGroups; +}; - // The total number of groups. - size_t nGroups; - }; +struct IDHackStats : public SpecificStats { + IDHackStats() : keysExamined(0), docsExamined(0) {} - struct IDHackStats : public SpecificStats { - IDHackStats() : keysExamined(0), - docsExamined(0) { } + virtual ~IDHackStats() {} - virtual ~IDHackStats() { } + virtual SpecificStats* clone() const { + IDHackStats* specific = new IDHackStats(*this); + return specific; + } - virtual SpecificStats* clone() const { - IDHackStats* specific = new IDHackStats(*this); - return specific; - } + // Number of entries retrieved from the index while executing the idhack. + size_t keysExamined; - // Number of entries retrieved from the index while executing the idhack. - size_t keysExamined; - - // Number of documents retrieved from the collection while executing the idhack. - size_t docsExamined; - - }; - - struct IndexScanStats : public SpecificStats { - IndexScanStats() : indexVersion(0), - direction(1), - isMultiKey(false), - isPartial(false), - isSparse(false), - isUnique(false), - dupsTested(0), - dupsDropped(0), - seenInvalidated(0), - keysExamined(0) { } - - virtual ~IndexScanStats() { } - - virtual SpecificStats* clone() const { - IndexScanStats* specific = new IndexScanStats(*this); - // BSON objects have to be explicitly copied. - specific->keyPattern = keyPattern.getOwned(); - specific->indexBounds = indexBounds.getOwned(); - return specific; - } + // Number of documents retrieved from the collection while executing the idhack. + size_t docsExamined; +}; - // Index type being used. - std::string indexType; +struct IndexScanStats : public SpecificStats { + IndexScanStats() + : indexVersion(0), + direction(1), + isMultiKey(false), + isPartial(false), + isSparse(false), + isUnique(false), + dupsTested(0), + dupsDropped(0), + seenInvalidated(0), + keysExamined(0) {} - // name of the index being used - std::string indexName; + virtual ~IndexScanStats() {} - BSONObj keyPattern; + virtual SpecificStats* clone() const { + IndexScanStats* specific = new IndexScanStats(*this); + // BSON objects have to be explicitly copied. + specific->keyPattern = keyPattern.getOwned(); + specific->indexBounds = indexBounds.getOwned(); + return specific; + } - int indexVersion; + // Index type being used. + std::string indexType; - // A BSON (opaque, ie. hands off other than toString() it) representation of the bounds - // used. - BSONObj indexBounds; + // name of the index being used + std::string indexName; - // >1 if we're traversing the index along with its order. <1 if we're traversing it - // against the order. - int direction; + BSONObj keyPattern; - // index properties - // Whether this index is over a field that contain array values. - bool isMultiKey; - bool isPartial; - bool isSparse; - bool isUnique; + int indexVersion; - size_t dupsTested; - size_t dupsDropped; + // A BSON (opaque, ie. hands off other than toString() it) representation of the bounds + // used. + BSONObj indexBounds; - size_t seenInvalidated; - // TODO: we could track key sizes here. + // >1 if we're traversing the index along with its order. <1 if we're traversing it + // against the order. + int direction; - // Number of entries retrieved from the index during the scan. - size_t keysExamined; + // index properties + // Whether this index is over a field that contain array values. + bool isMultiKey; + bool isPartial; + bool isSparse; + bool isUnique; - }; + size_t dupsTested; + size_t dupsDropped; - struct LimitStats : public SpecificStats { - LimitStats() : limit(0) { } + size_t seenInvalidated; + // TODO: we could track key sizes here. - virtual SpecificStats* clone() const { - LimitStats* specific = new LimitStats(*this); - return specific; - } + // Number of entries retrieved from the index during the scan. + size_t keysExamined; +}; - size_t limit; - }; +struct LimitStats : public SpecificStats { + LimitStats() : limit(0) {} - struct MockStats : public SpecificStats { - MockStats() { } + virtual SpecificStats* clone() const { + LimitStats* specific = new LimitStats(*this); + return specific; + } - virtual SpecificStats* clone() const { - return new MockStats(*this); - } - }; + size_t limit; +}; - struct MultiPlanStats : public SpecificStats { - MultiPlanStats() { } +struct MockStats : public SpecificStats { + MockStats() {} - virtual SpecificStats* clone() const { - return new MultiPlanStats(*this); - } - }; + virtual SpecificStats* clone() const { + return new MockStats(*this); + } +}; - struct OrStats : public SpecificStats { - OrStats() : dupsTested(0), - dupsDropped(0), - locsForgotten(0) { } +struct MultiPlanStats : public SpecificStats { + MultiPlanStats() {} - virtual ~OrStats() { } + virtual SpecificStats* clone() const { + return new MultiPlanStats(*this); + } +}; - virtual SpecificStats* clone() const { - OrStats* specific = new OrStats(*this); - return specific; - } +struct OrStats : public SpecificStats { + OrStats() : dupsTested(0), dupsDropped(0), locsForgotten(0) {} - size_t dupsTested; - size_t dupsDropped; + virtual ~OrStats() {} - // How many calls to invalidate(...) actually removed a RecordId from our deduping map? - size_t locsForgotten; - }; + virtual SpecificStats* clone() const { + OrStats* specific = new OrStats(*this); + return specific; + } - struct ProjectionStats : public SpecificStats { - ProjectionStats() { } + size_t dupsTested; + size_t dupsDropped; - virtual SpecificStats* clone() const { - ProjectionStats* specific = new ProjectionStats(*this); - return specific; - } + // How many calls to invalidate(...) actually removed a RecordId from our deduping map? + size_t locsForgotten; +}; - // Object specifying the projection transformation to apply. - BSONObj projObj; - }; +struct ProjectionStats : public SpecificStats { + ProjectionStats() {} - struct SortStats : public SpecificStats { - SortStats() : forcedFetches(0), memUsage(0), memLimit(0) { } + virtual SpecificStats* clone() const { + ProjectionStats* specific = new ProjectionStats(*this); + return specific; + } - virtual ~SortStats() { } + // Object specifying the projection transformation to apply. + BSONObj projObj; +}; - virtual SpecificStats* clone() const { - SortStats* specific = new SortStats(*this); - return specific; - } +struct SortStats : public SpecificStats { + SortStats() : forcedFetches(0), memUsage(0), memLimit(0) {} - // How many records were we forced to fetch as the result of an invalidation? - size_t forcedFetches; + virtual ~SortStats() {} - // What's our current memory usage? - size_t memUsage; + virtual SpecificStats* clone() const { + SortStats* specific = new SortStats(*this); + return specific; + } - // What's our memory limit? - size_t memLimit; + // How many records were we forced to fetch as the result of an invalidation? + size_t forcedFetches; - // The number of results to return from the sort. - size_t limit; + // What's our current memory usage? + size_t memUsage; - // The pattern according to which we are sorting. - BSONObj sortPattern; - }; + // What's our memory limit? + size_t memLimit; - struct MergeSortStats : public SpecificStats { - MergeSortStats() : dupsTested(0), - dupsDropped(0), - forcedFetches(0) { } + // The number of results to return from the sort. + size_t limit; - virtual ~MergeSortStats() { } + // The pattern according to which we are sorting. + BSONObj sortPattern; +}; - virtual SpecificStats* clone() const { - MergeSortStats* specific = new MergeSortStats(*this); - return specific; - } +struct MergeSortStats : public SpecificStats { + MergeSortStats() : dupsTested(0), dupsDropped(0), forcedFetches(0) {} - size_t dupsTested; - size_t dupsDropped; + virtual ~MergeSortStats() {} - // How many records were we forced to fetch as the result of an invalidation? - size_t forcedFetches; + virtual SpecificStats* clone() const { + MergeSortStats* specific = new MergeSortStats(*this); + return specific; + } - // The pattern according to which we are sorting. - BSONObj sortPattern; - }; + size_t dupsTested; + size_t dupsDropped; - struct ShardingFilterStats : public SpecificStats { - ShardingFilterStats() : chunkSkips(0) { } + // How many records were we forced to fetch as the result of an invalidation? + size_t forcedFetches; - virtual SpecificStats* clone() const { - ShardingFilterStats* specific = new ShardingFilterStats(*this); - return specific; - } + // The pattern according to which we are sorting. + BSONObj sortPattern; +}; - size_t chunkSkips; - }; +struct ShardingFilterStats : public SpecificStats { + ShardingFilterStats() : chunkSkips(0) {} - struct SkipStats : public SpecificStats { - SkipStats() : skip(0) { } + virtual SpecificStats* clone() const { + ShardingFilterStats* specific = new ShardingFilterStats(*this); + return specific; + } - virtual SpecificStats* clone() const { - SkipStats* specific = new SkipStats(*this); - return specific; - } + size_t chunkSkips; +}; - size_t skip; - }; - - struct IntervalStats { - - IntervalStats() : - numResultsFound(0), - numResultsBuffered(0), - minDistanceAllowed(-1), - maxDistanceAllowed(-1), - inclusiveMaxDistanceAllowed(false), - minDistanceFound(-1), - maxDistanceFound(-1), - minDistanceBuffered(-1), - maxDistanceBuffered(-1) { - } +struct SkipStats : public SpecificStats { + SkipStats() : skip(0) {} - long long numResultsFound; - long long numResultsBuffered; + virtual SpecificStats* clone() const { + SkipStats* specific = new SkipStats(*this); + return specific; + } - double minDistanceAllowed; - double maxDistanceAllowed; - bool inclusiveMaxDistanceAllowed; + size_t skip; +}; - double minDistanceFound; - double maxDistanceFound; - double minDistanceBuffered; - double maxDistanceBuffered; - }; +struct IntervalStats { + IntervalStats() + : numResultsFound(0), + numResultsBuffered(0), + minDistanceAllowed(-1), + maxDistanceAllowed(-1), + inclusiveMaxDistanceAllowed(false), + minDistanceFound(-1), + maxDistanceFound(-1), + minDistanceBuffered(-1), + maxDistanceBuffered(-1) {} - class NearStats : public SpecificStats { - public: + long long numResultsFound; + long long numResultsBuffered; - NearStats() {} + double minDistanceAllowed; + double maxDistanceAllowed; + bool inclusiveMaxDistanceAllowed; - virtual SpecificStats* clone() const { - return new NearStats(*this); - } + double minDistanceFound; + double maxDistanceFound; + double minDistanceBuffered; + double maxDistanceBuffered; +}; - long long totalResultsFound() { - long long totalResultsFound = 0; - for (std::vector<IntervalStats>::iterator it = intervalStats.begin(); - it != intervalStats.end(); ++it) { - totalResultsFound += it->numResultsFound; - } - return totalResultsFound; - } +class NearStats : public SpecificStats { +public: + NearStats() {} + + virtual SpecificStats* clone() const { + return new NearStats(*this); + } - std::vector<IntervalStats> intervalStats; - std::string indexName; - BSONObj keyPattern; - }; - - struct UpdateStats : public SpecificStats { - UpdateStats() - : nMatched(0), - nModified(0), - isDocReplacement(false), - fastmod(false), - fastmodinsert(false), - inserted(false), - nInvalidateSkips(0) { } - - virtual SpecificStats* clone() const { - return new UpdateStats(*this); + long long totalResultsFound() { + long long totalResultsFound = 0; + for (std::vector<IntervalStats>::iterator it = intervalStats.begin(); + it != intervalStats.end(); + ++it) { + totalResultsFound += it->numResultsFound; } + return totalResultsFound; + } - // The number of documents which match the query part of the update. - size_t nMatched; + std::vector<IntervalStats> intervalStats; + std::string indexName; + BSONObj keyPattern; +}; - // The number of documents modified by this update. - size_t nModified; +struct UpdateStats : public SpecificStats { + UpdateStats() + : nMatched(0), + nModified(0), + isDocReplacement(false), + fastmod(false), + fastmodinsert(false), + inserted(false), + nInvalidateSkips(0) {} - // True iff this is a doc-replacement style update, as opposed to a $mod update. - bool isDocReplacement; + virtual SpecificStats* clone() const { + return new UpdateStats(*this); + } - // A 'fastmod' update is an in-place update that does not have to modify - // any indices. It's "fast" because the only work needed is changing the bits - // inside the document. - bool fastmod; + // The number of documents which match the query part of the update. + size_t nMatched; - // A 'fastmodinsert' is an insert resulting from an {upsert: true} update - // which is a doc-replacement style update. It's "fast" because we don't need - // to compute the document to insert based on the modifiers. - bool fastmodinsert; + // The number of documents modified by this update. + size_t nModified; - // Is this an {upsert: true} update that did an insert? - bool inserted; + // True iff this is a doc-replacement style update, as opposed to a $mod update. + bool isDocReplacement; - // The object that was inserted. This is an empty document if no insert was performed. - BSONObj objInserted; + // A 'fastmod' update is an in-place update that does not have to modify + // any indices. It's "fast" because the only work needed is changing the bits + // inside the document. + bool fastmod; - // Invalidated documents can be force-fetched, causing the now invalid RecordId to - // be thrown out. The update stage skips over any results which do not have the - // RecordId to update. - size_t nInvalidateSkips; - }; + // A 'fastmodinsert' is an insert resulting from an {upsert: true} update + // which is a doc-replacement style update. It's "fast" because we don't need + // to compute the document to insert based on the modifiers. + bool fastmodinsert; - struct TextStats : public SpecificStats { - TextStats() : keysExamined(0), fetches(0), parsedTextQuery() { } + // Is this an {upsert: true} update that did an insert? + bool inserted; - virtual SpecificStats* clone() const { - TextStats* specific = new TextStats(*this); - return specific; - } + // The object that was inserted. This is an empty document if no insert was performed. + BSONObj objInserted; + + // Invalidated documents can be force-fetched, causing the now invalid RecordId to + // be thrown out. The update stage skips over any results which do not have the + // RecordId to update. + size_t nInvalidateSkips; +}; + +struct TextStats : public SpecificStats { + TextStats() : keysExamined(0), fetches(0), parsedTextQuery() {} + + virtual SpecificStats* clone() const { + TextStats* specific = new TextStats(*this); + return specific; + } - std::string indexName; + std::string indexName; - size_t keysExamined; + size_t keysExamined; - size_t fetches; + size_t fetches; - // Human-readable form of the FTSQuery associated with the text stage. - BSONObj parsedTextQuery; + // Human-readable form of the FTSQuery associated with the text stage. + BSONObj parsedTextQuery; - // Index keys that precede the "text" index key. - BSONObj indexPrefix; - }; + // Index keys that precede the "text" index key. + BSONObj indexPrefix; +}; } // namespace mongo |