Beispiel #1
0
 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();
 }
Beispiel #2
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;
 }
Beispiel #3
0
    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 ];
    }
Beispiel #4
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 ];
    }