Description
Reverse natural iteration of a non capped or capped collection will abort when the first empty extent is encountered, because Record::getPrev() does not skip over empty extents.
inline DiskLoc Record::getPrev(const DiskLoc& myLoc) {
|
_accessing();
|
if ( _prevOfs != DiskLoc::NullOfs )
|
return DiskLoc(myLoc.a(), _prevOfs);
|
Extent *e = myExtent(myLoc);
|
if ( e->xprev.isNull() )
|
return DiskLoc();
|
return e->xprev.ext()->lastRecord;
|
}
|
Test
c = db.c;
|
c.drop();
|
|
|
a = 0;
|
c.save( { a:a++ } );
|
|
|
big = new Array( 1024*1024 ).toString();
|
// Save 3 extents of data.
|
while( c.stats().numExtents < 3 ) {
|
c.save( { a:a++, b:big } );
|
}
|
|
|
savedCount = c.count();
|
assert.gt( savedCount, 2 );
|
|
|
// Remove all but the first and last documents, with the expectation that the first doc is in the
|
// first extent and the last in the last extent. This leaves the middle extent empty.
|
c.remove( { a:{ $gt:0, $lt:a-1 } } );
|
assert.eq( 2, c.count() );
|
assert.eq( 2, c.find().sort( { $natural:1 } ).itcount() );
|
// Check that reverse iteration properly iterates past the empty middle extent.
|
// Currently it stops at the empty extent (and only sees one document).
|
assert.eq( 2, c.find().sort( { $natural:-1 } ).itcount() );
|