// static void Explain::getSummaryStats(PlanExecutor* exec, PlanSummaryStats* statsOut) { invariant(NULL != statsOut); PlanStage* root = exec->getRootStage(); // We can get some of the fields we need from the common stats stored in the // root stage of the plan tree. const CommonStats* common = root->getCommonStats(); statsOut->nReturned = common->advanced; statsOut->executionTimeMillis = common->executionTimeMillis; // Generate the plan summary string. statsOut->summaryStr = getPlanSummary(root); // The other fields are aggregations over the stages in the plan tree. We flatten // the tree into a list and then compute these aggregations. vector<PlanStage*> stages; flattenExecTree(root, &stages); for (size_t i = 0; i < stages.size(); i++) { statsOut->totalKeysExamined += getKeysExamined(stages[i]->stageType(), stages[i]->getSpecificStats()); statsOut->totalDocsExamined += getDocsExamined(stages[i]->stageType(), stages[i]->getSpecificStats()); if (STAGE_IDHACK == stages[i]->stageType()) { statsOut->isIdhack = true; } if (STAGE_SORT == stages[i]->stageType()) { statsOut->hasSortStage = true; } } }
void Explain::getSummaryStats(PlanExecutor* exec, PlanSummaryStats* statsOut) { invariant(NULL != statsOut); PlanStage* root = exec->getStages(); // We can get some of the fields we need from the common stats stored in the // root stage of the plan tree. const CommonStats* common = root->getCommonStats(); statsOut->nReturned = common->advanced; statsOut->executionTimeMillis = common->executionTimeMillis; // The other fields are aggregations over the stages in the plan tree. We flatten // the tree into a list and then compute these aggregations. vector<PlanStage*> stages; flattenExecTree(root, &stages); // Use this stream to build the plan summary string. mongoutils::str::stream ss; bool seenLeaf = false; for (size_t i = 0; i < stages.size(); i++) { statsOut->totalKeysExamined += getKeysExamined(stages[i]->stageType(), stages[i]->getSpecificStats()); statsOut->totalDocsExamined += getDocsExamined(stages[i]->stageType(), stages[i]->getSpecificStats()); if (STAGE_IDHACK == stages[i]->stageType()) { statsOut->isIdhack = true; } if (STAGE_SORT == stages[i]->stageType()) { statsOut->hasSortStage = true; } if (stages[i]->getChildren().empty()) { // This is a leaf node. Add to the plan summary string accordingly. Unless // this is the first leaf we've seen, add a delimiting string first. if (seenLeaf) { ss << ", "; } else { seenLeaf = true; } addStageSummaryStr(stages[i], ss); } } statsOut->summaryStr = ss; }