jstests/noPassthrough/explain_group_stage_exec_stats.js
/**
 * Checks that the execution stats in the explain output for a $group stage are as expected.
 * - 'stage' is an explain output of $group stage.
 * - 'expectedAccumMemUsages' is used to check the memory footprint stats for each accumulator.
 * - 'isExecExplain' indicates that the explain output is run with verbosity "executionStats" or
 * "allPlansExecution".
 * - 'expectedSpills' indicates how many times the data was spilled to disk when executing $group
 * stage.
 */
Checks that the execution stats in the explain output for a $group stage are as expected.
- 'stage' is an explain output of $group stage.
- 'expectedAccumMemUsages' is used to check the memory footprint stats for each accumulator.
- 'isExecExplain' indicates that the explain output is run with verbosity "executionStats" or
"allPlansExecution".
- 'expectedSpills' indicates how many times the data was spilled to disk when executing $group
stage.
Checks that the execution stats in the explain output for a $group stage are as expected . - ' stage ' is an explain output of $group stage . - ' expectedAccumMemUsages ' is used to check the memory footprint stats for each accumulator . - ' isExecExplain ' indicates that the explain output is run with verbosity " executionStats " or " allPlansExecution " . - ' expectedSpills ' indicates how many times the data was spilled to disk when executing $group stage .
function checkGroupStages(stage, expectedAccumMemUsages, isExecExplain, expectedSpills) {
    let totalAccumMemoryUsageBytes = 0;
    assert(stage.hasOwnProperty("$group"), stage);
    if (isExecExplain) {
        assert(stage.hasOwnProperty("maxAccumulatorMemoryUsageBytes"), stage);
        const maxAccmMemUsages = stage["maxAccumulatorMemoryUsageBytes"];
        for (const field of Object.keys(maxAccmMemUsages)) {
            totalAccumMemoryUsageBytes += maxAccmMemUsages[field];
            if (!debugBuild && expectedAccumMemUsages.hasOwnProperty(field)) {
                assert.gt(maxAccmMemUsages[field], expectedAccumMemUsages[field]);
                assert.lt(maxAccmMemUsages[field], 5 * expectedAccumMemUsages[field]);
            }
        }
        if (!debugBuild) {
            assert.eq(stage.usedDisk, expectedSpills > 0, stage);
            assert.gte(stage.spills, expectedSpills, stage);
            assert.lte(stage.spills, 2 * expectedSpills, stage);
        }
    } else {
        assert(!stage.hasOwnProperty("usedDisk"), stage);
        assert(!stage.hasOwnProperty("spills"), stage);
        assert(!stage.hasOwnProperty("maxAccumulatorMemoryUsageBytes"), stage);
    }
    if (expectedSpills > 0)
        assert.gt(maxMemoryLimitForGroupStage + 4 * 1024, totalAccumMemoryUsageBytes, stage);
}
function checkGroupStages ( stage , expectedAccumMemUsages , isExecExplain , expectedSpills ) { let totalAccumMemoryUsageBytes = 0 ; assert ( stage . hasOwnProperty ( "$group" ) , stage ) ; if ( isExecExplain ) { assert ( stage . hasOwnProperty ( "maxAccumulatorMemoryUsageBytes" ) , stage ) ; const maxAccmMemUsages = stage [ "maxAccumulatorMemoryUsageBytes" ] ; for ( const field of Object . keys ( maxAccmMemUsages ) ) { totalAccumMemoryUsageBytes += maxAccmMemUsages [ field ] ; if ( ! debugBuild && expectedAccumMemUsages . hasOwnProperty ( field ) ) { assert . gt ( maxAccmMemUsages [ field ] , expectedAccumMemUsages [ field ] ) ; assert . lt ( maxAccmMemUsages [ field ] , 5 * expectedAccumMemUsages [ field ] ) ; } } if ( ! debugBuild ) { assert . eq ( stage . usedDisk , expectedSpills > 0 , stage ) ; assert . gte ( stage . spills , expectedSpills , stage ) ; assert . lte ( stage . spills , 2 * expectedSpills , stage ) ; } } else { assert ( ! stage . hasOwnProperty ( "usedDisk" ) , stage ) ; assert ( ! stage . hasOwnProperty ( "spills" ) , stage ) ; assert ( ! stage . hasOwnProperty ( "maxAccumulatorMemoryUsageBytes" ) , stage ) ; } if ( expectedSpills > 0 ) assert . gt ( maxMemoryLimitForGroupStage + 4 * 1024 , totalAccumMemoryUsageBytes , stage ) ; }
Checks that the execution stats in the explain output for a $group stage are as expected.
Checks that the execution stats in the explain output for a $group stage are as expected .
// Tracks the memory usage per accumulator in total as 'stages' passed in could be the explain // output across a cluster. // Ensures that the expected accumulators are all included and the corresponding // memory usage is in a reasonable range. Note that in debug mode, data will be // spilled to disk every time we add a new value to a pre-existing group. // Don't verify spill count for debug builds, since for debug builds a spill occurs on every // duplicate id in a group. // Add some wiggle room to the total memory used compared to the limit parameter since the check // for spilling to disk happens after each document is processed.