Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

SERVER-958 Prefer fully contained multikey ranges since they are smal…

…ler.
  • Loading branch information...
commit 4786360d414f6b4421a71456222866c9a4f033fa 1 parent 216f9ca
@astaple astaple authored
View
5 db/queryutil.cpp
@@ -448,6 +448,9 @@ namespace mongo {
const FieldRange &FieldRange::operator&=( const FieldRange &other ) {
if ( !_singleKey && nontrivial() ) {
+ if ( other <= *this ) {
+ *this = other;
+ }
return *this;
}
vector<FieldInterval> newIntervals;
@@ -586,7 +589,7 @@ namespace mongo {
}
// TODO write a proper implementation that doesn't do a full copy
- bool FieldRange::operator<=( const FieldRange &other ) {
+ bool FieldRange::operator<=( const FieldRange &other ) const {
FieldRange temp = *this;
temp -= other;
return temp.empty();
View
4 db/queryutil.h
@@ -70,7 +70,7 @@ namespace mongo {
/** @return Range of elements elements included in 'this' but not 'other'. */
const FieldRange &operator-=( const FieldRange &other );
/** @return true iff this range is a subset of 'other'. */
- bool operator<=( const FieldRange &other );
+ bool operator<=( const FieldRange &other ) const;
/**
* If there are any valid values for this range, the extreme values can
@@ -100,7 +100,7 @@ namespace mongo {
/**
* Constructs a range where all FieldIntervals and FieldBounds are in
* the opposite order of the current range.
- * NOTE the resulting intervals may not be strictValid().
+ * NOTE the resulting intervals might not be strictValid().
*/
void reverse( FieldRange &ret ) const;
private:
View
18 dbtests/queryutiltests.cpp
@@ -706,7 +706,11 @@ namespace QueryUtilTests {
virtual BSONObj obj() const { return BSONObj(); }
};
- class SetIntersect {
+ } // namespace FieldRangeTests
+
+ namespace FieldRangeSetTests {
+
+ class Intersect {
public:
void run() {
FieldRangeSet frs1( "", fromjson( "{b:{$in:[5,6]},c:7,d:{$in:[8,9]}}" ), true );
@@ -715,11 +719,7 @@ namespace QueryUtilTests {
ASSERT_EQUALS( fromjson( "{a:1,b:5,c:7,d:{$gte:8,$lte:9},e:10}" ), frs1.simplifiedQuery( BSONObj() ) );
}
};
-
- } // namespace FieldRangeTests
-
- namespace FieldRangeSetTests {
-
+
class MultiKeyIntersect {
public:
void run() {
@@ -733,6 +733,10 @@ namespace QueryUtilTests {
// multikey match.
frs1 &= frs3;
ASSERT_EQUALS( frs2.simplifiedQuery( BSONObj() ), frs1.simplifiedQuery( BSONObj() ) );
+ // Now intersect with a fully contained range.
+ FieldRangeSet frs4( "", BSON( "a" << GT << 6 ), false );
+ frs1 &= frs4;
+ ASSERT_EQUALS( frs4.simplifiedQuery( BSONObj() ), frs1.simplifiedQuery( BSONObj() ) );
}
};
@@ -969,7 +973,7 @@ namespace QueryUtilTests {
add< FieldRangeTests::Diff64 >();
add< FieldRangeTests::DiffMulti1 >();
add< FieldRangeTests::DiffMulti2 >();
- add< FieldRangeTests::SetIntersect >();
+ add< FieldRangeSetTests::Intersect >();
add< FieldRangeSetTests::MultiKeyIntersect >();
add< FieldRangeSetTests::MultiKeyDiff >();
add< FieldRangeSetTests::MatchPossible >();
View
14 jstests/indexq.js
@@ -0,0 +1,14 @@
+// Test multikey range preference for a fully included range SERVER-958.
+
+t = db.jstests_indexq;
+t.drop();
+
+t.ensureIndex( {a:1} );
+// Single key index
+assert.eq( 5, t.find( {a:{$gt:4,$gte:5}} ).explain().indexBounds.a[ 0 ][ 0 ] );
+assert.eq( [[1,1],[2,2]], t.find( {a:{$in:[1,2,3]},$or:[{a:{$in:[1,2]}}]} ).explain().indexBounds.a );
+
+t.save( {a:[1,3]} );
+// Now with multi key index.
+assert.eq( 5, t.find( {a:{$gt:4,$gte:5}} ).explain().indexBounds.a[ 0 ][ 0 ] );
+assert.eq( [[1,1],[2,2]], t.find( {a:{$in:[1,2,3]},$or:[{a:{$in:[1,2]}}]} ).explain().indexBounds.a );
Please sign in to comment.
Something went wrong with that request. Please try again.