Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

SERVER-4149 avoid double counting matches for the index selection quo…

…ta in certain yielding cases
  • Loading branch information...
commit dd62235d71bd2afcf2c9713a33f07892186ae458 1 parent 6bbe838
@astaple astaple authored
Showing with 23 additions and 4 deletions.
  1. +8 −3 db/queryoptimizercursor.h
  2. +15 −1 dbtests/queryoptimizercursortests.cpp
View
11 db/queryoptimizercursor.h
@@ -21,15 +21,19 @@ namespace mongo {
/** Helper class for caching and counting matches during execution of a QueryPlan. */
class CachedMatchCounter {
public:
- CachedMatchCounter( long long &aggregateNscanned, int cumulativeCount ) : _aggregateNscanned( aggregateNscanned ), _nscanned(), _cumulativeCount( cumulativeCount ), _count(), _checkDups(), _match( Unknown ) {}
+ CachedMatchCounter( long long &aggregateNscanned, int cumulativeCount ) : _aggregateNscanned( aggregateNscanned ), _nscanned(), _cumulativeCount( cumulativeCount ), _count(), _checkDups(), _match( Unknown ), _counted() {}
void setCheckDups( bool checkDups ) { _checkDups = checkDups; }
- void resetMatch() { _match = Unknown; }
+ void resetMatch() {
+ _match = Unknown;
+ _counted = false;
+ }
void setMatch( bool match ) { _match = match ? True : False; }
bool knowMatch() const { return _match != Unknown; }
void countMatch( const DiskLoc &loc ) {
- if ( _match == True && !getsetdup( loc ) ) {
+ if ( !_counted && _match == True && !getsetdup( loc ) ) {
++_cumulativeCount;
++_count;
+ _counted = true;
}
}
bool enoughCumulativeMatchesToChooseAPlan() const {
@@ -65,6 +69,7 @@ namespace mongo {
bool _checkDups;
enum MatchState { Unknown, False, True };
MatchState _match;
+ bool _counted;
set<DiskLoc> _dups;
};
View
16 dbtests/queryoptimizercursortests.cpp
@@ -66,6 +66,18 @@ namespace QueryOptimizerCursorTests {
c.countMatch( DiskLoc() );
ASSERT_EQUALS( 1, c.count() );
ASSERT_EQUALS( 1, c.cumulativeCount() );
+
+ // Don't count the same match twice, without checking the document location.
+ c.countMatch( DiskLoc( 1, 1 ) );
+ ASSERT_EQUALS( 1, c.count() );
+ ASSERT_EQUALS( 1, c.cumulativeCount() );
+
+ // Reset and count another match.
+ c.resetMatch();
+ c.setMatch( true );
+ c.countMatch( DiskLoc( 1, 1 ) );
+ ASSERT_EQUALS( 2, c.count() );
+ ASSERT_EQUALS( 2, c.cumulativeCount() );
}
};
@@ -858,11 +870,13 @@ namespace QueryOptimizerCursorTests {
Client::Context ctx( ns() );
shared_ptr<Cursor> c = newQueryOptimizerCursor( ns(), BSON( "a" << GTE << -1 << LTE << 0 << "b" << GTE << -1 << LTE << 0 ) );
while( c->advance() );
+ // {a:1} plan should be recorded now.
c = newQueryOptimizerCursor( ns(), BSON( "a" << GTE << 100 << LTE << 400 << "b" << GTE << 100 << LTE << 400 ) );
int count = 0;
while( c->ok() ) {
- if ( c->currentMatches() && !c->getsetdup( c->currLoc() ) ) {
+ if ( c->currentMatches() ) {
+ ASSERT( !c->getsetdup( c->currLoc() ) );
++count;
int id = c->current().getIntField( "_id" );
c->advance();
Please sign in to comment.
Something went wrong with that request. Please try again.