Exemple #1
0
 shared_ptr<QueryOp> QueryPlanSet::Runner::next() {
     mayYield();
     OpHolder holder = _queue.top();
     _queue.pop();
     QueryOp &op = *holder._op;
     nextOp( op );
     if ( op.complete() ) {
         if ( _plans._mayRecordPlan && op.mayRecordPlan() ) {
             op.qp().registerSelf( op.nscanned() );
         }
         return holder._op;
     }
     if ( op.error() ) {
         return holder._op;
     }
     _queue.push( holder );
     if ( !_plans._bestGuessOnly && _plans._usingPrerecordedPlan && op.nscanned() > _plans._oldNScanned * 10 && _plans._special.empty() ) {
         holder._offset = -op.nscanned();
         _plans.addOtherPlans( /* avoid duplicating the initial plan */ true );
         PlanSet::iterator i = _plans._plans.begin();
         ++i;
         for( ; i != _plans._plans.end(); ++i ) {
             shared_ptr<QueryOp> op( _op.createChild() );
             op->setQueryPlan( i->get() );
             _ops.push_back( op );
             initOp( *op );
             if ( op->complete() )
                 return op;
             _queue.push( op );
         }
         _plans._mayRecordPlan = true;
         _plans._usingPrerecordedPlan = false;
     }
     return holder._op;
 }
Exemple #2
0
    shared_ptr<QueryOp> QueryPlanSet::Runner::run() {
        massert( 10369 ,  "no plans", _plans._plans.size() > 0 );

        vector<shared_ptr<QueryOp> > ops;
        if ( _plans._bestGuessOnly ) {
            shared_ptr<QueryOp> op( _op.createChild() );
            op->setQueryPlan( _plans.getBestGuess().get() );
            ops.push_back( op );
        }
        else {
            if ( _plans._plans.size() > 1 )
                log(1) << "  running multiple plans" << endl;
            for( PlanSet::iterator i = _plans._plans.begin(); i != _plans._plans.end(); ++i ) {
                shared_ptr<QueryOp> op( _op.createChild() );
                op->setQueryPlan( i->get() );
                ops.push_back( op );
            }
        }

        for( vector<shared_ptr<QueryOp> >::iterator i = ops.begin(); i != ops.end(); ++i ) {
            initOp( **i );
            if ( (*i)->complete() )
                return *i;
        }

        std::priority_queue<OpHolder> queue;
        for( vector<shared_ptr<QueryOp> >::iterator i = ops.begin(); i != ops.end(); ++i ) {
            if ( !(*i)->error() ) {
                queue.push( *i );
            }
        }

        while( !queue.empty() ) {
            mayYield( ops );
            OpHolder holder = queue.top();
            queue.pop();
            QueryOp &op = *holder._op;
            nextOp( op );
            if ( op.complete() ) {
                if ( _plans._mayRecordPlan && op.mayRecordPlan() ) {
                    op.qp().registerSelf( op.nscanned() );
                }
                return holder._op;
            }
            if ( op.error() ) {
                continue;
            }
            queue.push( holder );
            if ( !_plans._bestGuessOnly && _plans._usingPrerecordedPlan && op.nscanned() > _plans._oldNScanned * 10 && _plans._special.empty() ) {
                holder._offset = -op.nscanned();
                _plans.addOtherPlans( /* avoid duplicating the initial plan */ true );
                PlanSet::iterator i = _plans._plans.begin();
                ++i;
                for( ; i != _plans._plans.end(); ++i ) {
                    shared_ptr<QueryOp> op( _op.createChild() );
                    op->setQueryPlan( i->get() );
                    ops.push_back( op );
                    initOp( *op );
                    if ( op->complete() )
                        return op;
                    queue.push( op );
                }
                _plans._mayRecordPlan = true;
                _plans._usingPrerecordedPlan = false;
            }
        }
        return ops[ 0 ];
    }