| Server IP : 216.92.14.13 / Your IP : 216.73.216.171 Web Server : Apache System : Linux vps4089.pairvps.com 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64 User : rmlac2fmr ( 1040637) PHP Version : 8.2.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/include/mongo/db/ |
Upload File : |
// @file explain.h - Helper classes for generating query explain output.
/* Copyright 2012 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "cursor.h"
#include "../util/timer.h"
namespace mongo {
/**
* Note: by default we filter out allPlans and oldPlan in the shell's
* explain() function. If you add any recursive structures, make sure to
* edit the JS to make sure everything gets filtered.
*/
/** The timer starts on construction and provides the duration since then or until stopped. */
class DurationTimer {
public:
DurationTimer() : _running( true ), _duration() {}
void stop() { _running = false; _duration = _timer.millis(); }
int duration() const { return _running ? _timer.millis() : _duration; }
private:
Timer _timer;
bool _running;
int _duration;
};
class ExplainClauseInfo;
/** Data describing execution of a query plan. */
class ExplainPlanInfo {
public:
ExplainPlanInfo();
/** Note information about the plan. */
void notePlan( const Cursor &cursor, bool scanAndOrder, bool indexOnly );
/** Note an iteration of the plan. */
void noteIterate( bool match, bool loadedRecord, const Cursor &cursor );
/** Note that the plan finished execution. */
void noteDone( const Cursor &cursor );
/** Note that the plan was chosen over others by the query optimizer. */
void notePicked();
/** BSON summary of the plan. */
BSONObj bson() const;
/** Combined details of both the plan and its clause. */
BSONObj pickedPlanBson( const ExplainClauseInfo &clauseInfo ) const;
bool picked() const { return _picked; }
bool done() const { return _done; }
long long n() const { return _n; }
long long nscannedObjects() const { return _nscannedObjects; }
long long nscanned() const { return _nscanned; }
private:
void noteCursorUpdate( const Cursor &cursor );
string _cursorName;
bool _isMultiKey;
long long _n;
long long _nscannedObjects;
long long _nscanned;
bool _scanAndOrder;
bool _indexOnly;
BSONObj _indexBounds;
bool _picked;
bool _done;
BSONObj _details;
};
/** Data describing execution of a query clause. */
class ExplainClauseInfo {
public:
ExplainClauseInfo();
/** Note an iteration of the clause. */
void noteIterate( bool match, bool loadedRecord, bool chunkSkip );
/** Note a yield for the clause. */
void noteYield();
/** Revise the total number of documents returned to match an external count. */
void reviseN( long long n );
/** Stop the clauses's timer. */
void stopTimer();
/** Add information about a plan to this clause. */
void addPlanInfo( const shared_ptr<ExplainPlanInfo> &info );
BSONObj bson() const;
long long n() const { return _n; }
long long nscannedObjects() const;
long long nscanned() const;
long long nscannedObjectsAllPlans() const { return _nscannedObjects; }
long long nscannedAllPlans() const;
long long nChunkSkips() const { return _nChunkSkips; }
int nYields() const { return _nYields; }
int millis() const { return _timer.duration(); }
private:
/**
* @return Plan explain information to be displayed at the top of the explain output. A
* picked() plan will be returned if one is available, otherwise a successful non picked()
* plan will be returned.
*/
const ExplainPlanInfo &virtualPickedPlan() const;
list<shared_ptr<const ExplainPlanInfo> > _plans;
long long _n;
long long _nscannedObjects;
long long _nChunkSkips;
int _nYields;
DurationTimer _timer;
};
/** Data describing execution of a query. */
class ExplainQueryInfo {
public:
/** Note an iteration of the query's current clause. */
void noteIterate( bool match, bool loadedRecord, bool chunkSkip );
/** Note a yield of the query's current clause. */
void noteYield();
/** Revise the number of documents returned by the current clause. */
void reviseN( long long n );
/* Additional information describing the query. */
struct AncillaryInfo {
BSONObj _oldPlan;
};
void setAncillaryInfo( const AncillaryInfo &ancillaryInfo );
/* Add information about a clause to this query. */
void addClauseInfo( const shared_ptr<ExplainClauseInfo> &info );
BSONObj bson() const;
private:
static string server();
list<shared_ptr<ExplainClauseInfo> > _clauses;
AncillaryInfo _ancillaryInfo;
DurationTimer _timer;
};
/** Data describing execution of a query with a single clause and plan. */
class ExplainSinglePlanQueryInfo {
public:
ExplainSinglePlanQueryInfo();
/** Note information about the plan. */
void notePlan( const Cursor &cursor, bool scanAndOrder, bool indexOnly ) {
_planInfo->notePlan( cursor, scanAndOrder, indexOnly );
}
/** Note an iteration of the plan and the clause. */
void noteIterate( bool match, bool loadedRecord, bool chunkSkip, const Cursor &cursor ) {
_planInfo->noteIterate( match, loadedRecord, cursor );
_queryInfo->noteIterate( match, loadedRecord, chunkSkip );
}
/** Note a yield for the clause. */
void noteYield() {
_queryInfo->noteYield();
}
/** Note that the plan finished execution. */
void noteDone( const Cursor &cursor ) {
_planInfo->noteDone( cursor );
}
/** Return the corresponding ExplainQueryInfo for further use. */
shared_ptr<ExplainQueryInfo> queryInfo() const {
return _queryInfo;
}
private:
shared_ptr<ExplainPlanInfo> _planInfo;
shared_ptr<ExplainQueryInfo> _queryInfo;
};
} // namespace mongo