summaryrefslogtreecommitdiff
path: root/db/btreecursor.cpp
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2011-03-17 00:05:43 +0100
committerAntonin Kral <a.kral@bobek.cz>2011-03-17 00:05:43 +0100
commit582fc32574a3b158c81e49cb00e6ae59205e66ba (patch)
treeac64a3243e0d2121709f685695247052858115c8 /db/btreecursor.cpp
parent2761bffa96595ac1698d86bbc2e95ebb0d4d6e93 (diff)
downloadmongodb-582fc32574a3b158c81e49cb00e6ae59205e66ba.tar.gz
Imported Upstream version 1.8.0
Diffstat (limited to 'db/btreecursor.cpp')
-rw-r--r--db/btreecursor.cpp145
1 files changed, 79 insertions, 66 deletions
diff --git a/db/btreecursor.cpp b/db/btreecursor.cpp
index d6d0c09..9cab95f 100644
--- a/db/btreecursor.cpp
+++ b/db/btreecursor.cpp
@@ -20,54 +20,56 @@
#include "btree.h"
#include "pdfile.h"
#include "jsobj.h"
-#include "curop.h"
+#include "curop-inl.h"
namespace mongo {
extern int otherTraceLevel;
- BtreeCursor::BtreeCursor( NamespaceDetails *_d, int _idxNo, const IndexDetails &_id,
+ BtreeCursor::BtreeCursor( NamespaceDetails *_d, int _idxNo, const IndexDetails &_id,
const BSONObj &_startKey, const BSONObj &_endKey, bool endKeyInclusive, int _direction ) :
- d(_d), idxNo(_idxNo),
- startKey( _startKey ),
- endKey( _endKey ),
- endKeyInclusive_( endKeyInclusive ),
- multikey( d->isMultikey( idxNo ) ),
- indexDetails( _id ),
- order( _id.keyPattern() ),
- _ordering( Ordering::make( order ) ),
- direction( _direction ),
- _spec( _id.getSpec() ),
- _independentFieldRanges( false )
- {
+ d(_d), idxNo(_idxNo),
+ startKey( _startKey ),
+ endKey( _endKey ),
+ _endKeyInclusive( endKeyInclusive ),
+ _multikey( d->isMultikey( idxNo ) ),
+ indexDetails( _id ),
+ _order( _id.keyPattern() ),
+ _ordering( Ordering::make( _order ) ),
+ _direction( _direction ),
+ _spec( _id.getSpec() ),
+ _independentFieldRanges( false ),
+ _nscanned( 0 ) {
audit();
init();
- DEV assert( dups.size() == 0 );
+ dassert( _dups.size() == 0 );
}
BtreeCursor::BtreeCursor( NamespaceDetails *_d, int _idxNo, const IndexDetails& _id, const shared_ptr< FieldRangeVector > &_bounds, int _direction )
:
- d(_d), idxNo(_idxNo),
- endKeyInclusive_( true ),
- multikey( d->isMultikey( idxNo ) ),
- indexDetails( _id ),
- order( _id.keyPattern() ),
- _ordering( Ordering::make( order ) ),
- direction( _direction ),
- bounds_( ( assert( _bounds.get() ), _bounds ) ),
- _boundsIterator( new FieldRangeVector::Iterator( *bounds_ ) ),
- _spec( _id.getSpec() ),
- _independentFieldRanges( true )
- {
+ d(_d), idxNo(_idxNo),
+ _endKeyInclusive( true ),
+ _multikey( d->isMultikey( idxNo ) ),
+ indexDetails( _id ),
+ _order( _id.keyPattern() ),
+ _ordering( Ordering::make( _order ) ),
+ _direction( _direction ),
+ _bounds( ( assert( _bounds.get() ), _bounds ) ),
+ _boundsIterator( new FieldRangeVector::Iterator( *_bounds ) ),
+ _spec( _id.getSpec() ),
+ _independentFieldRanges( true ),
+ _nscanned( 0 ) {
massert( 13384, "BtreeCursor FieldRangeVector constructor doesn't accept special indexes", !_spec.getType() );
audit();
- startKey = bounds_->startKey();
- bool found;
+ startKey = _bounds->startKey();
_boundsIterator->advance( startKey ); // handles initialization
- bucket = indexDetails.head.btree()->
- locate(indexDetails, indexDetails.head, startKey, _ordering, keyOfs, found, direction > 0 ? minDiskLoc : maxDiskLoc, direction);
+ _boundsIterator->prepDive();
+ pair< DiskLoc, int > noBestParent;
+ bucket = indexDetails.head;
+ keyOfs = 0;
+ indexDetails.head.btree()->customLocate( bucket, keyOfs, startKey, 0, false, _boundsIterator->cmp(), _boundsIterator->inc(), _ordering, _direction, noBestParent );
skipAndCheck();
- DEV assert( dups.size() == 0 );
+ dassert( _dups.size() == 0 );
}
void BtreeCursor::audit() {
@@ -76,7 +78,7 @@ namespace mongo {
if ( otherTraceLevel >= 12 ) {
if ( otherTraceLevel >= 200 ) {
out() << "::BtreeCursor() qtl>200. validating entire index." << endl;
- indexDetails.head.btree()->fullValidate(indexDetails.head, order);
+ indexDetails.head.btree()->fullValidate(indexDetails.head, _order);
}
else {
out() << "BTreeCursor(). dumping head bucket" << endl;
@@ -86,17 +88,20 @@ namespace mongo {
}
void BtreeCursor::init() {
- if ( _spec.getType() ){
+ if ( _spec.getType() ) {
startKey = _spec.getType()->fixKey( startKey );
endKey = _spec.getType()->fixKey( endKey );
}
bool found;
bucket = indexDetails.head.btree()->
- locate(indexDetails, indexDetails.head, startKey, _ordering, keyOfs, found, direction > 0 ? minDiskLoc : maxDiskLoc, direction);
+ locate(indexDetails, indexDetails.head, startKey, _ordering, keyOfs, found, _direction > 0 ? minDiskLoc : maxDiskLoc, _direction);
+ if ( ok() ) {
+ _nscanned = 1;
+ }
skipUnusedKeys( false );
checkEnd();
}
-
+
void BtreeCursor::skipAndCheck() {
skipUnusedKeys( true );
while( 1 ) {
@@ -109,7 +114,7 @@ namespace mongo {
}
}
}
-
+
bool BtreeCursor::skipOutOfRangeKeysAndCheckEnd() {
if ( !ok() ) {
return false;
@@ -118,25 +123,30 @@ namespace mongo {
if ( ret == -2 ) {
bucket = DiskLoc();
return false;
- } else if ( ret == -1 ) {
+ }
+ else if ( ret == -1 ) {
+ ++_nscanned;
return false;
}
- advanceTo( currKeyNode().key, ret, _boundsIterator->cmp() );
+ ++_nscanned;
+ advanceTo( currKeyNode().key, ret, _boundsIterator->after(), _boundsIterator->cmp(), _boundsIterator->inc() );
return true;
}
-
+
/* skip unused keys. */
bool BtreeCursor::skipUnusedKeys( bool mayJump ) {
int u = 0;
while ( 1 ) {
if ( !ok() )
break;
- BtreeBucket *b = bucket.btree();
- _KeyNode& kn = b->k(keyOfs);
+ const BtreeBucket *b = bucket.btree();
+ const _KeyNode& kn = b->k(keyOfs);
if ( kn.isUsed() )
break;
- bucket = b->advance(bucket, keyOfs, direction, "skipUnusedKeys");
+ bucket = b->advance(bucket, keyOfs, _direction, "skipUnusedKeys");
u++;
+ //don't include unused keys in nscanned
+ //++_nscanned;
if ( mayJump && ( u % 10 == 0 ) ) {
skipOutOfRangeKeysAndCheckEnd();
}
@@ -158,31 +168,34 @@ namespace mongo {
if ( bucket.isNull() )
return;
if ( !endKey.isEmpty() ) {
- int cmp = sgn( endKey.woCompare( currKey(), order ) );
- if ( ( cmp != 0 && cmp != direction ) ||
- ( cmp == 0 && !endKeyInclusive_ ) )
+ int cmp = sgn( endKey.woCompare( currKey(), _order ) );
+ if ( ( cmp != 0 && cmp != _direction ) ||
+ ( cmp == 0 && !_endKeyInclusive ) )
bucket = DiskLoc();
}
}
-
- void BtreeCursor::advanceTo( const BSONObj &keyBegin, int keyBeginLen, const vector< const BSONElement * > &keyEnd) {
- bucket.btree()->advanceTo( indexDetails, bucket, keyOfs, keyBegin, keyBeginLen, keyEnd, _ordering, direction );
+
+ void BtreeCursor::advanceTo( const BSONObj &keyBegin, int keyBeginLen, bool afterKey, const vector< const BSONElement * > &keyEnd, const vector< bool > &keyEndInclusive) {
+ bucket.btree()->advanceTo( bucket, keyOfs, keyBegin, keyBeginLen, afterKey, keyEnd, keyEndInclusive, _ordering, _direction );
}
-
+
bool BtreeCursor::advance() {
killCurrentOp.checkForInterrupt();
if ( bucket.isNull() )
return false;
- bucket = bucket.btree()->advance(bucket, keyOfs, direction, "BtreeCursor::advance");
+ bucket = bucket.btree()->advance(bucket, keyOfs, _direction, "BtreeCursor::advance");
if ( !_independentFieldRanges ) {
skipUnusedKeys( false );
checkEnd();
- return ok();
+ if ( ok() ) {
+ ++_nscanned;
+ }
+ }
+ else {
+ skipAndCheck();
}
-
- skipAndCheck();
return ok();
}
@@ -207,10 +220,10 @@ namespace mongo {
if ( eof() )
return;
- multikey = d->isMultikey(idxNo);
+ _multikey = d->isMultikey(idxNo);
if ( keyOfs >= 0 ) {
- BtreeBucket *b = bucket.btree();
+ const BtreeBucket *b = bucket.btree();
assert( !keyAtKeyOfs.isEmpty() );
@@ -219,17 +232,17 @@ namespace mongo {
int x = 0;
while( 1 ) {
if ( b->keyAt(keyOfs).woEqual(keyAtKeyOfs) &&
- b->k(keyOfs).recordLoc == locAtKeyOfs ) {
- if ( !b->k(keyOfs).isUsed() ) {
- /* we were deleted but still exist as an unused
- marker key. advance.
- */
- skipUnusedKeys( false );
- }
- return;
+ b->k(keyOfs).recordLoc == locAtKeyOfs ) {
+ if ( !b->k(keyOfs).isUsed() ) {
+ /* we were deleted but still exist as an unused
+ marker key. advance.
+ */
+ skipUnusedKeys( false );
+ }
+ return;
}
- /* we check one key earlier too, in case a key was just deleted. this is
+ /* we check one key earlier too, in case a key was just deleted. this is
important so that multi updates are reasonably fast.
*/
if( keyOfs == 0 || x++ )
@@ -245,7 +258,7 @@ namespace mongo {
bool found;
/* TODO: Switch to keep indexdetails and do idx.head! */
- bucket = indexDetails.head.btree()->locate(indexDetails, indexDetails.head, keyAtKeyOfs, _ordering, keyOfs, found, locAtKeyOfs, direction);
+ bucket = indexDetails.head.btree()->locate(indexDetails, indexDetails.head, keyAtKeyOfs, _ordering, keyOfs, found, locAtKeyOfs, _direction);
RARELY log() << " key seems to have moved in the index, refinding. found:" << found << endl;
if ( ! bucket.isNull() )
skipUnusedKeys( false );