diff --git a/jstests/minmax.js b/jstests/minmax.js index e52799b0cfbba..d84a6e42855cf 100644 --- a/jstests/minmax.js +++ b/jstests/minmax.js @@ -42,3 +42,13 @@ assert.throws( function() { t.find().min( { b: 1 } ).max( { a: 1, b: 2 } ).hint( assert.throws( function() { t.find().min( { a: 1 } ).hint( { $natural: 1 } ).toArray() } ); assert.throws( function() { t.find().max( { a: 1 } ).hint( { $natural: 1 } ).toArray() } ); +// Reverse direction scan of the a:1 index between a:6 (inclusive) and a:3 (exclusive). +t.drop(); +t.ensureIndex( { a:1 } ); +for( i = 0; i < 10; ++i ) { + t.save( { _id:i, a:i } ); +} +if ( 0 ) { // SERVER-3766 +reverseResult = t.find().min( { a:6 } ).max( { a:3 } ).sort( { a:-1 } ).hint( { a:1 } ).toArray(); +assert.eq( [ { _id:6, a:6 }, { _id:5, a:5 }, { _id:4, a:4 } ], reverseResult ); +} diff --git a/src/mongo/db/diskloc.h b/src/mongo/db/diskloc.h index e84fcf855838d..8682d8d97d46f 100644 --- a/src/mongo/db/diskloc.h +++ b/src/mongo/db/diskloc.h @@ -48,7 +48,11 @@ namespace mongo { enum SentinelValues { /* note NullOfs is different. todo clean up. see refs to NullOfs in code - use is valid but outside DiskLoc context so confusing as-is. */ NullOfs = -1, - MaxFiles=16000 // thus a limit of about 32TB of data per db + + // Caps the number of files that may be allocated in a database, allowing about 32TB of + // data per db. Note that the DiskLoc and DiskLoc56Bit types supports more files than + // this value, as does the storage format. + MaxFiles=16000 }; DiskLoc(int a, int Ofs) : _a(a), ofs(Ofs) { } @@ -154,7 +158,14 @@ namespace mongo { }; #pragma pack() - const DiskLoc minDiskLoc(0, 1); - const DiskLoc maxDiskLoc(0x7fffffff, 0x7fffffff); + // Minimum allowed DiskLoc. No Record may begin at this location because file and extent + // headers must precede Records in a file. + const DiskLoc minDiskLoc(0, 0); + + // Maximum allowed DiskLoc. Note that only three bytes are used to represent the file number + // for consistency with the v1 index DiskLoc storage format, which uses only 7 bytes total. + // No Record may begin at this location because the minimum size of a Record is larger than one + // byte. + const DiskLoc maxDiskLoc(0x00ffffff, 0x7fffffff); } // namespace mongo diff --git a/src/mongo/dbtests/cursortests.cpp b/src/mongo/dbtests/cursortests.cpp index 747b906049b6b..14297e6f51e46 100644 --- a/src/mongo/dbtests/cursortests.cpp +++ b/src/mongo/dbtests/cursortests.cpp @@ -532,6 +532,31 @@ namespace CursorTests { } } }; + + /** Test iteration of a reverse direction btree cursor between start and end keys. */ + class ReverseDirectionStartEndKeys : public Base { + public: + void run() { + _c.dropCollection( ns() ); + _c.ensureIndex( ns(), BSON( "a" << 1 ) ); + // Add documents a:4 and a:5 + _c.insert( ns(), BSON( "a" << 4 ) ); + _c.insert( ns(), BSON( "a" << 5 ) ); + Client::ReadContext ctx( ns() ); + scoped_ptr cursor( BtreeCursor::make( nsdetails( ns() ), + nsdetails( ns() )->idx( 1 ), + /* startKey */ BSON( "" << 5 ), + /* endKey */ BSON( "" << 4 ), + /* endKeyInclusive */ true, + /* direction */ -1 ) ); + // Check that the iterator produces the expected results, in the expected order. + ASSERT( cursor->ok() ); + ASSERT_EQUALS( 5, cursor->current()[ "a" ].Int() ); + ASSERT( cursor->advance() ); + ASSERT_EQUALS( 4, cursor->current()[ "a" ].Int() ); + ASSERT( !cursor->advance() ); + } + }; } // namespace BtreeCursor @@ -769,6 +794,7 @@ namespace CursorTests { add(); add(); add(); + add(); add(); add(); add();