Runner improvements
This commit is contained in:
@@ -142,37 +142,56 @@ namespace mongo {
|
||||
}
|
||||
|
||||
QueryPlanSet::QueryPlanSet( const char *ns, const BSONObj &query, const BSONObj &order, const BSONElement *hint ) :
|
||||
fbs_( ns, query ) {
|
||||
fbs_( ns, query ),
|
||||
mayRecordPlan_( true ),
|
||||
usingPrerecordedPlan_( false ),
|
||||
hint_( emptyObj ),
|
||||
order_( order.copy() ) {
|
||||
if ( hint && !hint->eoo() ) {
|
||||
BSONObjBuilder b;
|
||||
b.append( *hint );
|
||||
hint_ = b.obj();
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
void QueryPlanSet::init() {
|
||||
mayRecordPlan_ = true;
|
||||
usingPrerecordedPlan_ = false;
|
||||
|
||||
const char *ns = fbs_.ns();
|
||||
NamespaceDetails *d = nsdetails( ns );
|
||||
if ( !d || !fbs_.matchPossible() ) {
|
||||
// Table scan plan, when no matches are possible
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order ) ) );
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order_ ) ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( hint && !hint->eoo() ) {
|
||||
if( hint->type() == String ) {
|
||||
string hintstr = hint->valuestr();
|
||||
BSONElement hint = hint_.firstElement();
|
||||
if ( !hint.eoo() ) {
|
||||
mayRecordPlan_ = false;
|
||||
if( hint.type() == String ) {
|
||||
string hintstr = hint.valuestr();
|
||||
for (int i = 0; i < d->nIndexes; i++ ) {
|
||||
IndexDetails& ii = d->indexes[i];
|
||||
if ( ii.indexName() == hintstr ) {
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order, &ii ) ) );
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order_, &ii ) ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( hint->type() == Object ) {
|
||||
BSONObj hintobj = hint->embeddedObject();
|
||||
else if( hint.type() == Object ) {
|
||||
BSONObj hintobj = hint.embeddedObject();
|
||||
uassert( "bad hint", !hintobj.isEmpty() );
|
||||
if ( !strcmp( hintobj.firstElement().fieldName(), "$natural" ) ) {
|
||||
// Table scan plan
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order ) ) );
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order_ ) ) );
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < d->nIndexes; i++ ) {
|
||||
IndexDetails& ii = d->indexes[i];
|
||||
if( ii.keyPattern().woCompare(hintobj) == 0 ) {
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order, &ii ) ) );
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order_, &ii ) ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -182,34 +201,36 @@ namespace mongo {
|
||||
|
||||
BSONObj bestIndex = indexForPattern( ns, fbs_.pattern() );
|
||||
if ( !bestIndex.isEmpty() ) {
|
||||
usingPrerecordedPlan_ = true;
|
||||
if ( !strcmp( bestIndex.firstElement().fieldName(), "$natural" ) ) {
|
||||
// Table scan plan
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order ) ) );
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order_ ) ) );
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < d->nIndexes; i++ ) {
|
||||
IndexDetails& ii = d->indexes[i];
|
||||
if( ii.keyPattern().woCompare(bestIndex) == 0 ) {
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order, &ii ) ) );
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order_, &ii ) ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert( false );
|
||||
}
|
||||
|
||||
// Table scan plan
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order ) ) );
|
||||
plans_.push_back( PlanPtr( new QueryPlan( fbs_, order_ ) ) );
|
||||
|
||||
// If table scan is optimal
|
||||
if ( fbs_.nNontrivialBounds() == 0 && order.isEmpty() )
|
||||
if ( fbs_.nNontrivialBounds() == 0 && order_.isEmpty() )
|
||||
return;
|
||||
|
||||
// Only table scan can give natural order.
|
||||
if ( !order.isEmpty() && !strcmp( order.firstElement().fieldName(), "$natural" ) )
|
||||
if ( !order_.isEmpty() && !strcmp( order_.firstElement().fieldName(), "$natural" ) )
|
||||
return;
|
||||
|
||||
PlanSet plans;
|
||||
for( int i = 0; i < d->nIndexes; ++i ) {
|
||||
PlanPtr p( new QueryPlan( fbs_, order, &d->indexes[ i ] ) );
|
||||
PlanPtr p( new QueryPlan( fbs_, order_, &d->indexes[ i ] ) );
|
||||
if ( p->optimal() ) {
|
||||
plans_.push_back( p );
|
||||
return;
|
||||
@@ -222,6 +243,14 @@ namespace mongo {
|
||||
}
|
||||
|
||||
shared_ptr< QueryOp > QueryPlanSet::runOp( QueryOp &op ) {
|
||||
if ( usingPrerecordedPlan_ ) {
|
||||
Runner r( *this, op );
|
||||
shared_ptr< QueryOp > res = r.run();
|
||||
if ( res->complete() )
|
||||
return res;
|
||||
registerIndexForPattern( fbs_.ns(), fbs_.pattern(), BSONObj() );
|
||||
init();
|
||||
}
|
||||
Runner r( *this, op );
|
||||
return r.run();
|
||||
}
|
||||
@@ -257,7 +286,7 @@ namespace mongo {
|
||||
op.setExceptionMessage( "Caught unknown exception" );
|
||||
}
|
||||
if ( op.complete() ) {
|
||||
if ( op.mayRecordPlan() )
|
||||
if ( plans_.mayRecordPlan_ && op.mayRecordPlan() )
|
||||
op.qp().registerSelf();
|
||||
return *i;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user