void run() { IndexDetails& id = addIndexWithInfo(); // Create a btree builder. BtreeBuilder<V1> builder( false, id ); // Add some keys to the builder, in order. int32_t nKeys = 1000; for( int32_t i = 0; i < nKeys; ++i ) { BSONObj key = BSON( "a" << i ); builder.addKey( key, /* dummy location */ DiskLoc() ); } // The root of the index has not yet been set. ASSERT( id.head.isNull() ); // Call commit on the builder to finish building the btree. builder.commit( true ); // The root of the index is now set. ASSERT( !id.head.isNull() ); // Create a cursor over the index. scoped_ptr<BtreeCursor> cursor( BtreeCursor::make( nsdetails( _ns ), id, BSON( "" << -1 ), // startKey below minimum key value. BSON( "" << nKeys ), // endKey above maximum key value. true, // endKeyInclusive true. 1 // direction forward. ) ); // Check that the keys in the index are the expected ones. int32_t expectedKey = 0; for( ; cursor->ok(); cursor->advance(), ++expectedKey ) { ASSERT_EQUALS( expectedKey, cursor->currKey().firstElement().number() ); } ASSERT_EQUALS( nKeys, expectedKey ); }
void run() { IndexDetails& id = addIndexWithInfo(); // Create a btree builder. BtreeBuilder<V1> builder( false, id ); // Add some keys to the builder, in order. We need enough keys to build an internal // node in order to check for an interrupt. int32_t nKeys = 1000; for( int32_t i = 0; i < nKeys; ++i ) { BSONObj key = BSON( "a" << i ); builder.addKey( key, /* dummy location */ DiskLoc() ); } // The root of the index has not yet been set. ASSERT( id.head.isNull() ); // Register a request to kill the current operation. cc().curop()->kill(); if ( _mayInterrupt ) { // Call commit on the builder, which will be aborted due to the kill request. ASSERT_THROWS( builder.commit( _mayInterrupt ), UserException ); // The root of the index is not set because commit() did not complete. ASSERT( id.head.isNull() ); } else { // Call commit on the builder, which will not be aborted because mayInterrupt is // false. builder.commit( _mayInterrupt ); // The root of the index is set because commit() completed. ASSERT( !id.head.isNull() ); } }
void run() { IndexDetails& id = addIndexWithInfo(); // Create a SortPhaseOne. SortPhaseOne phaseOne; phaseOne.sorter.reset( new BSONObjExternalSorter( id.idxInterface(), BSON( "a" << 1 ) ) ); // Add index keys to the phaseOne. int32_t nKeys = 130; for( int32_t i = 0; i < nKeys; ++i ) { phaseOne.sorter->add( BSON( "a" << i ), /* dummy disk loc */ DiskLoc(), false ); } phaseOne.nkeys = phaseOne.n = nKeys; phaseOne.sorter->sort( false ); // Set up remaining arguments. set<DiskLoc> dups; CurOp* op = cc().curop(); ProgressMeterHolder pm (op->setMessage("BuildBottomUp", "BuildBottomUp Progress", nKeys, nKeys)); pm.finished(); Timer timer; // The index's root has not yet been set. ASSERT( id.head.isNull() ); // Finish building the index. buildBottomUpPhases2And3<V1>( true, id, *phaseOne.sorter, false, dups, op, &phaseOne, pm, timer, true ); // The index's root is set after the build is complete. ASSERT( !id.head.isNull() ); // Create a cursor over the index. scoped_ptr<BtreeCursor> cursor( BtreeCursor::make( nsdetails( _ns ), id, BSON( "" << -1 ), // startKey below minimum key. BSON( "" << nKeys ), // endKey above maximum key. true, // endKeyInclusive true. 1 // direction forward. ) ); // Check that the keys in the index are the expected ones. int32_t expectedKey = 0; for( ; cursor->ok(); cursor->advance(), ++expectedKey ) { ASSERT_EQUALS( expectedKey, cursor->currKey().firstElement().number() ); } ASSERT_EQUALS( nKeys, expectedKey ); }
void run() { // It's necessary to index sufficient keys that a RARELY condition will be triggered. int32_t nDocs = 130; // Add some data to the collection. for( int32_t i = 0; i < nDocs; ++i ) { _client.insert( _ns, BSON( "a" << i ) ); } IndexDetails& id = addIndexWithInfo(); // Create a SortPhaseOne. SortPhaseOne phaseOne; ProgressMeterHolder pm (cc().curop()->setMessage("InterruptAddKeysToPhaseOne", "InterruptAddKeysToPhaseOne Progress", nDocs, nDocs)); // Register a request to kill the current operation. cc().curop()->kill(); if ( _mayInterrupt ) { // Add keys to phaseOne. ASSERT_THROWS( BtreeBasedBuilder::addKeysToPhaseOne( nsdetails(_ns), _ns, id, BSON( "a" << 1 ), &phaseOne, nDocs, pm.get(), _mayInterrupt, nsdetails(_ns)->idxNo(id) ), UserException ); // Not all keys were added to phaseOne due to the interrupt. ASSERT( static_cast<uint64_t>( nDocs ) > phaseOne.n ); } else { // Add keys to phaseOne. BtreeBasedBuilder::addKeysToPhaseOne( nsdetails(_ns), _ns, id, BSON( "a" << 1 ), &phaseOne, nDocs, pm.get(), _mayInterrupt, nsdetails(_ns)->idxNo(id) ); // All keys were added to phaseOne despite to the kill request, because // mayInterrupt == false. ASSERT_EQUALS( static_cast<uint64_t>( nDocs ), phaseOne.n ); } }
void run() { // Add some data to the collection. int32_t nDocs = 130; for( int32_t i = 0; i < nDocs; ++i ) { _client.insert( _ns, BSON( "a" << i ) ); } IndexDetails& id = addIndexWithInfo(); // Create a SortPhaseOne. SortPhaseOne phaseOne; ProgressMeterHolder pm (cc().curop()->setMessage("AddKeysToPhaseOne", "AddKeysToPhaseOne Progress", nDocs, nDocs)); // Add keys to phaseOne. BtreeBasedBuilder::addKeysToPhaseOne( nsdetails(_ns), _ns, id, BSON( "a" << 1 ), &phaseOne, nDocs, pm.get(), true, nsdetails(_ns)->idxNo(id) ); // Keys for all documents were added to phaseOne. ASSERT_EQUALS( static_cast<uint64_t>( nDocs ), phaseOne.n ); }
void run() { IndexDescriptor* id = addIndexWithInfo(); // Create a SortPhaseOne. SortPhaseOne phaseOne; phaseOne.sorter.reset(new BSONObjExternalSorter(_aFirstSort)); // It's necessary to index sufficient keys that a RARELY condition will be triggered, // but few enough keys that the btree builder will not create an internal node and check // for an interrupt internally (which would cause this test to pass spuriously). int32_t nKeys = 130; // Add index keys to the phaseOne. for( int32_t i = 0; i < nKeys; ++i ) { phaseOne.sorter->add( BSON( "a" << i ), /* dummy disk loc */ DiskLoc(), false ); } phaseOne.nkeys = phaseOne.n = nKeys; phaseOne.sorter->sort( false ); // Set up remaining arguments. set<DiskLoc> dups; CurOp* op = cc().curop(); ProgressMeterHolder pm (op->setMessage("InterruptBuildBottomUp", "InterruptBuildBottomUp Progress", nKeys, nKeys)); pm.finished(); Timer timer; // The index's root has not yet been set. ASSERT( id->getHead().isNull() ); // Register a request to kill the current operation. cc().curop()->kill(); if ( _mayInterrupt ) { // The build is aborted due to the kill request. ASSERT_THROWS ( buildBottomUpPhases2And3<V1>( true, id, *phaseOne.sorter, false, dups, op, &phaseOne, pm, timer, _mayInterrupt ), UserException ); // The root of the index is not set because the build did not complete. ASSERT( id->getHead().isNull() ); } else { // The build is aborted despite the kill request because mayInterrupt == false. buildBottomUpPhases2And3<V1>( true, id, *phaseOne.sorter, false, dups, op, &phaseOne, pm, timer, _mayInterrupt ); // The index's root is set after the build is complete. ASSERT( !id->getHead().isNull() ); } }