void BtreeBuilder<V>::addKey(BSONObj& _key, DiskLoc loc) { auto_ptr< KeyOwned > key( new KeyOwned(_key) ); if ( key->dataSize() > BtreeBucket<V>::KeyMax ) { string msg = str::stream() << "Btree::insert: key too large to index, failing " << _btreeState->descriptor()->indexNamespace() << ' ' << key->dataSize() << ' ' << key->toString(); problem() << msg << endl; keyTooLongAssert( 17282, msg ); return; } if( !_dupsAllowed ) { if( _numAdded > 0 ) { int cmp = keyLast->woCompare(*key, _btreeState->ordering()); massert( 10288 , "bad key order in BtreeBuilder - server internal error", cmp <= 0 ); if( cmp == 0 ) { //if( !dupsAllowed ) uasserted( ASSERT_ID_DUPKEY, BtreeBucket<V>::dupKeyError( _btreeState->descriptor(), *keyLast ) ); } } } if ( ! b->_pushBack(loc, *key, _btreeState->ordering(), DiskLoc()) ) { // bucket was full newBucket(); b->pushBack(loc, *key, _btreeState->ordering(), DiskLoc()); } keyLast = key; _numAdded++; mayCommitProgressDurably(); }
void BtreeBuilder<V>::addKey(BSONObj& _key, DiskLoc loc) { auto_ptr< KeyOwned > key( new KeyOwned(_key) ); if ( key->dataSize() > BtreeBucket<V>::KeyMax ) { problem() << "Btree::insert: key too large to index, skipping " << idx.indexNamespace() << ' ' << key->dataSize() << ' ' << key->toString() << endl; return; } if( !dupsAllowed ) { if( n > 0 ) { int cmp = keyLast->woCompare(*key, ordering); massert( 10288 , "bad key order in BtreeBuilder - server internal error", cmp <= 0 ); if( cmp == 0 ) { //if( !dupsAllowed ) uasserted( ASSERT_ID_DUPKEY , BtreeBucket<V>::dupKeyError( idx , *keyLast ) ); } } } if ( ! b->_pushBack(loc, *key, ordering, DiskLoc()) ) { // bucket was full newBucket(); b->pushBack(loc, *key, ordering, DiskLoc()); } keyLast = key; n++; mayCommitProgressDurably(); }
void BtreeBuilder<V>::buildNextLevel(DiskLoc loc) { int levels = 1; while( 1 ) { if( loc.btree<V>()->tempNext().isNull() ) { // only 1 bucket at this level. we are done. getDur().writingDiskLoc(idx.head) = loc; break; } levels++; DiskLoc upLoc = BtreeBucket<V>::addBucket(idx); DiskLoc upStart = upLoc; BtreeBucket<V> *up = upLoc.btreemod<V>(); DiskLoc xloc = loc; while( !xloc.isNull() ) { if ( getDur().commitIfNeeded() ) { b = cur.btreemod<V>(); up = upLoc.btreemod<V>(); } BtreeBucket<V> *x = xloc.btreemod<V>(); Key k; DiskLoc r; x->popBack(r,k); bool keepX = ( x->n != 0 ); DiskLoc keepLoc = keepX ? xloc : x->nextChild; if ( ! up->_pushBack(r, k, ordering, keepLoc) ) { // current bucket full DiskLoc n = BtreeBucket<V>::addBucket(idx); up->setTempNext(n); upLoc = n; up = upLoc.btreemod<V>(); up->pushBack(r, k, ordering, keepLoc); } DiskLoc nextLoc = x->tempNext(); // get next in chain at current level if ( keepX ) { x->parent = upLoc; } else { if ( !x->nextChild.isNull() ) { DiskLoc ll = x->nextChild; ll.btreemod<V>()->parent = upLoc; //(x->nextChild.btreemod<V>())->parent = upLoc; } x->deallocBucket( xloc, idx ); } xloc = nextLoc; } loc = upStart; mayCommitProgressDurably(); } if( levels > 1 ) log(2) << "btree levels: " << levels << endl; }
void BtreeBuilder<V>::buildNextLevel(DiskLoc loc, bool mayInterrupt) { int levels = 1; while( 1 ) { if( _getBucket(loc)->tempNext().isNull() ) { // only 1 bucket at this level. we are done. _btreeState->setHead( loc ); break; } levels++; DiskLoc upLoc = BtreeBucket<V>::addBucket(_btreeState); DiskLoc upStart = upLoc; BtreeBucket<V> *up = _getModifiableBucket( upLoc ); DiskLoc xloc = loc; while( !xloc.isNull() ) { killCurrentOp.checkForInterrupt( !mayInterrupt ); if ( getDur().commitIfNeeded() ) { b = _getModifiableBucket( cur ); up = _getModifiableBucket( upLoc ); } BtreeBucket<V> *x = _getModifiableBucket( xloc ); Key k; DiskLoc r; x->popBack(r,k); bool keepX = ( x->n != 0 ); DiskLoc keepLoc = keepX ? xloc : x->nextChild; if ( ! up->_pushBack(r, k, _btreeState->ordering(), keepLoc) ) { // current bucket full DiskLoc n = BtreeBucket<V>::addBucket(_btreeState); up->setTempNext(n); upLoc = n; up = _getModifiableBucket( upLoc ); up->pushBack(r, k, _btreeState->ordering(), keepLoc); } DiskLoc nextLoc = x->tempNext(); // get next in chain at current level if ( keepX ) { x->parent = upLoc; } else { if ( !x->nextChild.isNull() ) { DiskLoc ll = x->nextChild; _getModifiableBucket(ll)->parent = upLoc; //(x->nextChild.btreemod<V>())->parent = upLoc; } x->deallocBucket( _btreeState, xloc ); } xloc = nextLoc; } loc = upStart; mayCommitProgressDurably(); } if( levels > 1 ) { LOG(2) << "btree levels: " << levels << endl; } }