diff options
author | Aaron <aaron@10gen.com> | 2012-10-11 11:44:38 -0700 |
---|---|---|
committer | Aaron <aaron@10gen.com> | 2012-10-23 16:36:53 -0700 |
commit | c0355ccbf0a3e242fe2db1427989bcd22311ac4c (patch) | |
tree | 38406b16373a8fd09b989c6a121f7acf37ad374d /src/mongo/dbtests/queryutiltests.cpp | |
parent | 40020f6e56381b1fc6533aa3e85cf01f568ccaea (diff) | |
download | mongo-c0355ccbf0a3e242fe2db1427989bcd22311ac4c.tar.gz |
SERVER-1752 Improve performance of simple counts by avoiding use of a matcher when an optimal btree cursor can filter results internally.
Diffstat (limited to 'src/mongo/dbtests/queryutiltests.cpp')
-rw-r--r-- | src/mongo/dbtests/queryutiltests.cpp | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/mongo/dbtests/queryutiltests.cpp b/src/mongo/dbtests/queryutiltests.cpp index 236ffe38f1d..7ebe68e1763 100644 --- a/src/mongo/dbtests/queryutiltests.cpp +++ b/src/mongo/dbtests/queryutiltests.cpp @@ -129,6 +129,29 @@ namespace QueryUtilTests { virtual bool mustBeExactMatchRepresentation() { return true; } }; + class LtDate : public Base { + public: + LtDate() : + _o( BSON( "" << Date_t( 5000 ) ) ), + _o2( BSON( "" << true ) ) { + } + virtual BSONObj query() { return BSON( "a" << LT << _o.firstElement() ); } + virtual BSONElement lower() { + // $lt:date is bounded from below by 'true', the highest value of the next lowest + // canonical type. + return _o2.firstElement(); + } + virtual bool lowerInclusive() { + // 'true' should not match $lt:date, so the bound is exclusive. + return false; + } + virtual BSONElement upper() { return _o.firstElement(); } + virtual bool upperInclusive() { return false; } + virtual bool mustBeExactMatchRepresentation() { return true; } + private: + BSONObj _o, _o2; + }; + class Gt : public NumericBase { public: Gt() : o_( BSON( "-" << 1 ) ) {} @@ -145,6 +168,29 @@ namespace QueryUtilTests { virtual bool lowerInclusive() { return true; } }; + class GtString : public Base { + public: + GtString() : + _o( BSON( "" << "abc" ) ), + _o2( BSON( "" << BSONObj() ) ) { + } + virtual BSONObj query() { return BSON( "a" << GT << _o.firstElement() ); } + virtual BSONElement lower() { return _o.firstElement(); } + virtual bool lowerInclusive() { return false; } + virtual BSONElement upper() { + // $gt:string is bounded from above by '{}', the lowest value of the next highest + // canonical type. + return _o2.firstElement(); + } + virtual bool upperInclusive() { + // '{}' should not match $gt:string, so the bound is exclusive. + return false; + } + virtual bool mustBeExactMatchRepresentation() { return true; } + private: + BSONObj _o, _o2; + }; + class TwoLt : public Lt { virtual BSONObj query() { return BSON( "a" << LT << 1 << LT << 5 ); } }; @@ -1707,6 +1753,7 @@ namespace QueryUtilTests { } // namespace FieldRangeSetPairTests namespace FieldRangeVectorTests { + class ToString { public: void run() { @@ -1717,6 +1764,46 @@ namespace QueryUtilTests { fieldRangeVector.toString(); // Just test that we don't crash. } }; + + /** + * Check FieldRangeVector::hasAllIndexedRanges(), indicating when all indexed field ranges + * in a field range set are represented in a field range vector (and none are excluded due + * to multikey index field name conflicts). + */ + class HasAllIndexedRanges { + public: + void run() { + // Single key index. + ASSERT( rangesRepresented( BSON( "a" << 1 ), true, BSON( "a" << 1 ) ) ); + // Multikey index, but no unrepresented ranges. + ASSERT( rangesRepresented( BSON( "a" << 1 ), false, BSON( "a" << 1 ) ) ); + // Multikey index, but no unrepresented ranges in the index. + ASSERT( rangesRepresented( BSON( "a" << 1 ), false, + BSON( "a" << 1 << "b" << 2 ) ) ); + // Compound multikey index with no unrepresented ranges. + ASSERT( rangesRepresented( BSON( "a" << 1 << "b" << 1 ), false, + BSON( "a" << 2 << "b" << 3 ) ) ); + // Compound multikey index with range 'a.c' unrepresented because of a conflict + // with range 'a.b', hence 'false' expected. + ASSERT( !rangesRepresented( BSON( "a.b" << 1 << "a.c" << 1 ), false, + BSON( "a.b" << 2 << "a.c" << 3 ) ) ); + // Compound multikey index without conflicts due to use of the $elemMatch operator. + ASSERT( rangesRepresented( BSON( "a.b" << 1 << "a.c" << 1 ), false, + BSON( "a" << BSON( "$elemMatch" << + BSON( "b" << 2 << "c" << 3 ) ) ) ) ); + // Single key index. + ASSERT( rangesRepresented( BSON( "a.b" << 1 << "a.c" << 1 ), true, + BSON( "a.b" << 2 << "a.c" << 3 ) ) ); + } + private: + bool rangesRepresented( const BSONObj& index, bool singleKey, const BSONObj& query ) { + FieldRangeSet fieldRangeSet( "", query, singleKey, true ); + IndexSpec indexSpec( index ); + FieldRangeVector fieldRangeVector( fieldRangeSet, indexSpec, 1 ); + return fieldRangeVector.hasAllIndexedRanges(); + } + }; + } // namespace FieldRangeVectorTests // These are currently descriptive, not normative tests. SERVER-5450 @@ -2533,8 +2620,10 @@ namespace QueryUtilTests { add<FieldRangeTests::DupEq>(); add<FieldRangeTests::Lt>(); add<FieldRangeTests::Lte>(); + add<FieldRangeTests::LtDate>(); add<FieldRangeTests::Gt>(); add<FieldRangeTests::Gte>(); + add<FieldRangeTests::GtString>(); add<FieldRangeTests::TwoLt>(); add<FieldRangeTests::TwoGt>(); add<FieldRangeTests::EqGte>(); @@ -2685,6 +2774,7 @@ namespace QueryUtilTests { add<FieldRangeSetPairTests::ClearIndexesForPatterns>(); add<FieldRangeSetPairTests::BestIndexForPatterns>(); add<FieldRangeVectorTests::ToString>(); + add<FieldRangeVectorTests::HasAllIndexedRanges>(); add<FieldRangeVectorIteratorTests::AdvanceToNextIntervalEquality>(); add<FieldRangeVectorIteratorTests::AdvanceToNextIntervalExclusiveInequality>(); add<FieldRangeVectorIteratorTests::AdvanceToNextIntervalEqualityReverse>(); |