void buildBottomUpPhases2And3(bool dupsAllowed, IndexDetails& idx, BSONObjExternalSorter& sorter, bool dropDups, set<DiskLoc> &dupsToDrop, CurOp * op, SortPhaseOne *phase1, ProgressMeterHolder &pm, Timer& t ) { BtreeBuilder<V> btBuilder(dupsAllowed, idx); BSONObj keyLast; auto_ptr<BSONObjExternalSorter::Iterator> i = sorter.iterator(); verify( pm == op->setMessage( "index: (2/3) btree bottom up" , phase1->nkeys , 10 ) ); while( i->more() ) { RARELY killCurrentOp.checkForInterrupt(); BSONObjExternalSorter::Data d = i->next(); try { if ( !dupsAllowed && dropDups ) { LastError::Disabled led( lastError.get() ); btBuilder.addKey(d.first, d.second); } else { btBuilder.addKey(d.first, d.second); } } catch( AssertionException& e ) { if ( dupsAllowed ) { // unknown exception?? throw; } if( e.interrupted() ) { killCurrentOp.checkForInterrupt(); } if ( ! dropDups ) throw; /* we could queue these on disk, but normally there are very few dups, so instead we keep in ram and have a limit. */ dupsToDrop.insert(d.second); uassert( 10092 , "too may dups on index build with dropDups=true", dupsToDrop.size() < 1000000 ); } pm.hit(); } pm.finished(); op->setMessage( "index: (3/3) btree-middle" ); log(t.seconds() > 10 ? 0 : 1 ) << "\t done building bottom layer, going to commit" << endl; btBuilder.commit(); if ( btBuilder.getn() != phase1->nkeys && ! dropDups ) { warning() << "not all entries were added to the index, probably some keys were too large" << endl; } }
void commit( set<DiskLoc>* dupsToDrop, CurOp* op, bool mayInterrupt ) { Timer timer; IndexCatalogEntry* entry = _real->_btreeState; bool dupsAllowed = !entry->descriptor()->unique() || ignoreUniqueIndex(entry->descriptor()); bool dropDups = entry->descriptor()->dropDups() || inDBRepair; BtreeBuilder<V> btBuilder(dupsAllowed, entry); BSONObj keyLast; scoped_ptr<BSONObjExternalSorter::Iterator> i( _phase1.sorter->iterator() ); // verifies that pm and op refer to the same ProgressMeter ProgressMeter& pm = op->setMessage("Index Bulk Build: (2/3) btree bottom up", "Index: (2/3) BTree Bottom Up Progress", _phase1.nkeys, 10); while( i->more() ) { RARELY if ( mayInterrupt ) killCurrentOp.checkForInterrupt(); ExternalSortDatum d = i->next(); try { if ( !dupsAllowed && dropDups ) { LastError::Disabled led( lastError.get() ); btBuilder.addKey(d.first, d.second); } else { btBuilder.addKey(d.first, d.second); } } catch( AssertionException& e ) { if ( dupsAllowed ) { // unknown exception?? throw; } if (ErrorCodes::isInterruption( DBException::convertExceptionCode(e.getCode()))) { killCurrentOp.checkForInterrupt(); } if ( ! dropDups ) throw; /* we could queue these on disk, but normally there are very few dups, * so instead we keep in ram and have a limit. */ if ( dupsToDrop ) { dupsToDrop->insert(d.second); uassert( 10092, "too may dups on index build with dropDups=true", dupsToDrop->size() < 1000000 ); } } pm.hit(); } pm.finished(); op->setMessage("Index Bulk Build: (3/3) btree-middle", "Index: (3/3) BTree Middle Progress"); LOG(timer.seconds() > 10 ? 0 : 1 ) << "\t done building bottom layer, going to commit"; btBuilder.commit( mayInterrupt ); if ( btBuilder.getn() != _phase1.nkeys && ! dropDups ) { warning() << "not all entries were added to the index, probably some " << "keys were too large" << endl; } }