shared_ptr< QueryOp > QueryPlanSet::Runner::run() { massert( "no plans", plans_.plans_.size() > 0 ); vector< shared_ptr< QueryOp > > ops; for( PlanSet::iterator i = plans_.plans_.begin(); i != plans_.plans_.end(); ++i ) { shared_ptr< QueryOp > op( op_.clone() ); 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; } long long nScanned = 0; long long nScannedBackup = 0; while( 1 ) { ++nScanned; unsigned errCount = 0; bool first = true; for( vector< shared_ptr< QueryOp > >::iterator i = ops.begin(); i != ops.end(); ++i ) { QueryOp &op = **i; nextOp( op ); if ( op.complete() ) { if ( first ) nScanned += nScannedBackup; if ( plans_.mayRecordPlan_ && op.mayRecordPlan() ) op.qp().registerSelf( nScanned ); return *i; } if ( op.error() ) ++errCount; first = false; } if ( errCount == ops.size() ) break; if ( plans_.usingPrerecordedPlan_ && nScanned > plans_.oldNScanned_ * 10 ) { plans_.addOtherPlans( true ); PlanSet::iterator i = plans_.plans_.begin(); ++i; for( ; i != plans_.plans_.end(); ++i ) { shared_ptr< QueryOp > op( op_.clone() ); op->setQueryPlan( i->get() ); ops.push_back( op ); initOp( *op ); if ( op->complete() ) return op; } plans_.mayRecordPlan_ = true; plans_.usingPrerecordedPlan_ = false; nScannedBackup = nScanned; nScanned = 0; } } return ops[ 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; }
shared_ptr<QueryOp> QueryPlanSet::Runner::init() { massert( 10369 , "no plans", _plans._plans.size() > 0 ); 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 ); } } // Initialize ops. for( vector<shared_ptr<QueryOp> >::iterator i = _ops.begin(); i != _ops.end(); ++i ) { initOp( **i ); if ( (*i)->complete() ) return *i; } // Put runnable ops in the priority queue. for( vector<shared_ptr<QueryOp> >::iterator i = _ops.begin(); i != _ops.end(); ++i ) { if ( !(*i)->error() ) { _queue.push( *i ); } } return *_ops.begin(); }
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 ]; }