示例#1
0
    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();
    }
示例#2
0
    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();
    }
示例#3
0
    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;
    }
示例#4
0
    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;
        }
    }