Skip to content

Commit

Permalink
SERVER-371 checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
astaple committed Jul 7, 2010
1 parent aa3995d commit 4798e64
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 28 deletions.
110 changes: 110 additions & 0 deletions db/btree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,34 @@ namespace mongo {
break;
}
}

int BtreeBucket::customBSONCmp( const BSONObj &l, const BSONObj &rBegin, int rBeginLen, const BSONObj &rEnd, const Ordering &o ) {
BSONObjIterator ll( l );
BSONObjIterator rr( rBegin );
BSONObjIterator rr2( rEnd );
unsigned mask = 1;
for( int i = 0; i < rBeginLen; ++i, mask <<= 1 ) {
BSONElement lll = ll.next();
BSONElement rrr = rr.next();
rr2.next();

int x = lll.woCompare( rrr, false );
if ( o.descending( mask ) )
x = -x;
if ( x != 0 )
return x;
}
for( ; ll.more(); mask <<= 1 ) {
BSONElement lll = ll.next();
BSONElement rrr = rr2.next();
int x = lll.woCompare( rrr, false );
if ( o.descending( mask ) )
x = -x;
if ( x != 0 )
return x;
}
return 0;
}

bool BtreeBucket::exists(const IndexDetails& idx, DiskLoc thisLoc, const BSONObj& key, const Ordering& order) {
int pos;
Expand Down Expand Up @@ -848,6 +876,88 @@ namespace mongo {
return pos == n ? DiskLoc() /*theend*/ : thisLoc;
}

bool BtreeBucket::customFind( int l, int h, const BSONObj &keyBegin, int keyBeginLen, const BSONObj &keyEnd, const Ordering &order, int direction, DiskLoc &thisLoc, int &keyOfs, pair< DiskLoc, int > &bestParent ) {
while( 1 ) {
if ( l + 1 == h ) {
keyOfs = h;
DiskLoc next = thisLoc.btree()->k( keyOfs ).prevChildBucket;
if ( !next.isNull() ) {
bestParent = make_pair( thisLoc, keyOfs );
thisLoc = next;
return true;
} else {
return false;
}
}
int m = l + ( h - l ) / 2;
int cmp = customBSONCmp( thisLoc.btree()->keyNode( m ).key, keyBegin, keyBeginLen, keyEnd, order );
if ( cmp < 0 ) {
l = m;
} else {
h = m;
}
}
}

// find smallest/biggest value greater-equal/less-equal than specified
// starting thisLoc + keyOfs will be strictly less than/strictly greater than keyBegin/keyBeginLen/keyEnd
void BtreeBucket::advanceTo(const IndexDetails &id, DiskLoc &thisLoc, int &keyOfs, const BSONObj &keyBegin, int keyBeginLen, const BSONObj &keyEnd, const Ordering &order, int direction ) {
// TODO direction
if ( direction < 0 ) {
return;
}
int l = keyOfs;
int h = n - 1;
pair< DiskLoc, int > bestParent;
if ( customBSONCmp( keyNode( h ).key, keyBegin, keyBeginLen, keyEnd, order ) >= 0 ) {
// this comparison result assures h > l
if ( !customFind( l, h, keyBegin, keyBeginLen, keyEnd, order, direction, thisLoc, keyOfs, bestParent ) ) {
return;
}
} else {
// go up parents until rightmost node is >= target or at top
while( !thisLoc.btree()->parent.isNull() ) {
thisLoc = thisLoc.btree()->parent;
if ( customBSONCmp( thisLoc.btree()->keyNode( thisLoc.btree()->n - 1 ).key, keyBegin, keyBeginLen, keyEnd, order ) >= 0 ) {
break;
}
}
}
// go down until find smallest >= target
while( 1 ) {
l = 0;
// leftmost key may possibly be >= search key (if search target is in rChild of this node's leftmost child)
if ( customBSONCmp( thisLoc.btree()->keyNode( 0 ).key, keyBegin, keyBeginLen, keyEnd, order ) >= 0 ) {
DiskLoc next = thisLoc.btree()->k( 0 ).prevChildBucket;
if ( !next.isNull() ) {
bestParent = make_pair( thisLoc, 0 );
thisLoc = next;
continue;
} else {
keyOfs = 0;
return;
}
}
h = thisLoc.btree()->n - 1;
if ( customBSONCmp( thisLoc.btree()->keyNode( h ).key, keyBegin, keyBeginLen, keyEnd, order ) < 0 ) {
DiskLoc next = thisLoc.btree()->nextChild;
if ( next.isNull() ) {
// if bestParent is null, we've hit the end and thisLoc gets set to DiskLoc()
thisLoc = bestParent.first;
keyOfs = bestParent.second;
return;
} else {
thisLoc = next;
continue;
}
}
if ( !customFind( l, h, keyBegin, keyBeginLen, keyEnd, order, direction, thisLoc, keyOfs, bestParent ) ) {
return;
}
}
}


/* @thisLoc disk location of *this
*/
int BtreeBucket::_insert(DiskLoc thisLoc, DiskLoc recordLoc,
Expand Down
25 changes: 20 additions & 5 deletions db/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ namespace mongo {

/* advance one key position in the index: */
DiskLoc advance(const DiskLoc& thisLoc, int& keyOfs, int direction, const char *caller);

void advanceTo(const IndexDetails &id, DiskLoc &thisLoc, int &keyOfs, const BSONObj &keyBegin, int keyBeginLen, const BSONObj &keyEnd, const Ordering &order, int direction );

DiskLoc getHead(const DiskLoc& thisLoc);

/* get tree shape */
Expand All @@ -256,7 +259,9 @@ namespace mongo {
const BSONObj& key, const Ordering &order, bool dupsAllowed,
DiskLoc lChild, DiskLoc rChild, IndexDetails&);
bool find(const IndexDetails& idx, const BSONObj& key, DiskLoc recordLoc, const Ordering &order, int& pos, bool assertIfDup);
bool customFind( int l, int h, const BSONObj &keyBegin, int keyBeginLen, const BSONObj &keyEnd, const Ordering &order, int direction, DiskLoc &thisLoc, int &keyOfs, pair< DiskLoc, int > &bestParent );
static void findLargestKey(const DiskLoc& thisLoc, DiskLoc& largestLoc, int& largestKey);
static int customBSONCmp( const BSONObj &l, const BSONObj &rBegin, int rBeginLen, const BSONObj &rEnd, const Ordering &o );
public:
// simply builds and returns a dup key error message string
static string dupKeyError( const IndexDetails& idx , const BSONObj& key );
Expand All @@ -265,7 +270,7 @@ namespace mongo {

class BtreeCursor : public Cursor {
public:
BtreeCursor( NamespaceDetails *_d, int _idxNo, const IndexDetails&, const BSONObj &startKey, const BSONObj &endKey, bool endKeyInclusive, int direction );
BtreeCursor( NamespaceDetails *_d, int _idxNo, const IndexDetails&, const BSONObj &startKey, const BSONObj &endKey, bool endKeyInclusive, int direction, bool independentFieldRanges = true );

BtreeCursor( NamespaceDetails *_d, int _idxNo, const IndexDetails& _id, const BoundList &_bounds, int _direction );
~BtreeCursor(){
Expand Down Expand Up @@ -369,9 +374,9 @@ namespace mongo {
/* Our btrees may (rarely) have "unused" keys when items are deleted.
Skip past them.
*/
void skipUnusedKeys();

/* Check if the current key is beyond endKey. */
bool skipUnusedKeys();
bool skipOutOfRangeKeysAndCheckEnd();
void skipAndCheck();
void checkEnd();

// selective audits on construction
Expand All @@ -382,18 +387,27 @@ namespace mongo {

// init start / end keys with a new range
void initInterval();


void advanceTo( const BSONObj &keyBegin, int keyBeginLen, const BSONObj &keyEnd);

static BSONObj makeSuperlativeKey( const BSONObj &order, int direction );

friend class BtreeBucket;
set<DiskLoc> dups;
NamespaceDetails *d;
int idxNo;

BSONObj startKey;
BSONObj endKey;
bool endKeyInclusive_;
int _nEqKeyElts;

bool multikey; // note this must be updated every getmore batch in case someone added a multikey...

const IndexDetails& indexDetails;
BSONObj order;
Ordering _ordering;
BSONObj _superlativeKey;
DiskLoc bucket;
int keyOfs;
int direction; // 1=fwd,-1=reverse
Expand All @@ -403,6 +417,7 @@ namespace mongo {
unsigned boundIndex_;
const IndexSpec& _spec;
shared_ptr< CoveredIndexMatcher > _matcher;
bool _independentFieldRanges;
};


Expand Down
Loading

0 comments on commit 4798e64

Please sign in to comment.