diff options
Diffstat (limited to 'src/mongo/db/catalog/collection_compact.cpp')
-rw-r--r-- | src/mongo/db/catalog/collection_compact.cpp | 240 |
1 files changed, 118 insertions, 122 deletions
diff --git a/src/mongo/db/catalog/collection_compact.cpp b/src/mongo/db/catalog/collection_compact.cpp index a6f4f98041b..e3f0623006f 100644 --- a/src/mongo/db/catalog/collection_compact.cpp +++ b/src/mongo/db/catalog/collection_compact.cpp @@ -48,154 +48,150 @@ namespace mongo { - using std::endl; - using std::vector; - - namespace { - BSONObj _compactAdjustIndexSpec( const BSONObj& oldSpec ) { - BSONObjBuilder b; - BSONObj::iterator i( oldSpec ); - while( i.more() ) { - BSONElement e = i.next(); - if ( str::equals( e.fieldName(), "v" ) ) { - // Drop any preexisting index version spec. The default index version will - // be used instead for the new index. - continue; - } - if ( str::equals( e.fieldName(), "background" ) ) { - // Create the new index in the foreground. - continue; - } - // Pass the element through to the new index spec. - b.append(e); - } - return b.obj(); +using std::endl; +using std::vector; + +namespace { +BSONObj _compactAdjustIndexSpec(const BSONObj& oldSpec) { + BSONObjBuilder b; + BSONObj::iterator i(oldSpec); + while (i.more()) { + BSONElement e = i.next(); + if (str::equals(e.fieldName(), "v")) { + // Drop any preexisting index version spec. The default index version will + // be used instead for the new index. + continue; + } + if (str::equals(e.fieldName(), "background")) { + // Create the new index in the foreground. + continue; } + // Pass the element through to the new index spec. + b.append(e); + } + return b.obj(); +} - class MyCompactAdaptor : public RecordStoreCompactAdaptor { - public: - MyCompactAdaptor(Collection* collection, - MultiIndexBlock* indexBlock) +class MyCompactAdaptor : public RecordStoreCompactAdaptor { +public: + MyCompactAdaptor(Collection* collection, MultiIndexBlock* indexBlock) - : _collection( collection ), - _multiIndexBlock(indexBlock) { - } + : _collection(collection), _multiIndexBlock(indexBlock) {} - virtual bool isDataValid( const RecordData& recData ) { - return recData.toBson().valid(); - } - - virtual size_t dataSize( const RecordData& recData ) { - return recData.toBson().objsize(); - } + virtual bool isDataValid(const RecordData& recData) { + return recData.toBson().valid(); + } - virtual void inserted( const RecordData& recData, const RecordId& newLocation ) { - _multiIndexBlock->insert( recData.toBson(), newLocation ); - } + virtual size_t dataSize(const RecordData& recData) { + return recData.toBson().objsize(); + } - private: - Collection* _collection; + virtual void inserted(const RecordData& recData, const RecordId& newLocation) { + _multiIndexBlock->insert(recData.toBson(), newLocation); + } - MultiIndexBlock* _multiIndexBlock; - }; +private: + Collection* _collection; - } + MultiIndexBlock* _multiIndexBlock; +}; +} - StatusWith<CompactStats> Collection::compact( OperationContext* txn, - const CompactOptions* compactOptions ) { - dassert(txn->lockState()->isCollectionLockedForMode(ns().toString(), MODE_X)); +StatusWith<CompactStats> Collection::compact(OperationContext* txn, + const CompactOptions* compactOptions) { + dassert(txn->lockState()->isCollectionLockedForMode(ns().toString(), MODE_X)); - DisableDocumentValidation validationDisabler(txn); + DisableDocumentValidation validationDisabler(txn); - if ( !_recordStore->compactSupported() ) - return StatusWith<CompactStats>( ErrorCodes::CommandNotSupported, - str::stream() << - "cannot compact collection with record store: " << - _recordStore->name() ); + if (!_recordStore->compactSupported()) + return StatusWith<CompactStats>(ErrorCodes::CommandNotSupported, + str::stream() + << "cannot compact collection with record store: " + << _recordStore->name()); - if (_recordStore->compactsInPlace()) { - // Since we are compacting in-place, we don't need to touch the indexes. - // TODO SERVER-16856 compact indexes - CompactStats stats; - Status status = _recordStore->compact(txn, NULL, compactOptions, &stats); - if (!status.isOK()) - return StatusWith<CompactStats>(status); + if (_recordStore->compactsInPlace()) { + // Since we are compacting in-place, we don't need to touch the indexes. + // TODO SERVER-16856 compact indexes + CompactStats stats; + Status status = _recordStore->compact(txn, NULL, compactOptions, &stats); + if (!status.isOK()) + return StatusWith<CompactStats>(status); - return StatusWith<CompactStats>(stats); - } + return StatusWith<CompactStats>(stats); + } - if ( _indexCatalog.numIndexesInProgress( txn ) ) - return StatusWith<CompactStats>( ErrorCodes::BadValue, - "cannot compact when indexes in progress" ); - - - // same data, but might perform a little different after compact? - _infoCache.reset( txn ); - - vector<BSONObj> indexSpecs; - { - IndexCatalog::IndexIterator ii( _indexCatalog.getIndexIterator( txn, false ) ); - while ( ii.more() ) { - IndexDescriptor* descriptor = ii.next(); - - const BSONObj spec = _compactAdjustIndexSpec(descriptor->infoObj()); - const BSONObj key = spec.getObjectField("key"); - const Status keyStatus = validateKeyPattern(key); - if (!keyStatus.isOK()) { - return StatusWith<CompactStats>( - ErrorCodes::CannotCreateIndex, - str::stream() << "Cannot compact collection due to invalid index " - << spec << ": " << keyStatus.reason() << " For more info see" - << " http://dochub.mongodb.org/core/index-validation"); - } - indexSpecs.push_back(spec); + if (_indexCatalog.numIndexesInProgress(txn)) + return StatusWith<CompactStats>(ErrorCodes::BadValue, + "cannot compact when indexes in progress"); + + + // same data, but might perform a little different after compact? + _infoCache.reset(txn); + + vector<BSONObj> indexSpecs; + { + IndexCatalog::IndexIterator ii(_indexCatalog.getIndexIterator(txn, false)); + while (ii.more()) { + IndexDescriptor* descriptor = ii.next(); + + const BSONObj spec = _compactAdjustIndexSpec(descriptor->infoObj()); + const BSONObj key = spec.getObjectField("key"); + const Status keyStatus = validateKeyPattern(key); + if (!keyStatus.isOK()) { + return StatusWith<CompactStats>( + ErrorCodes::CannotCreateIndex, + str::stream() << "Cannot compact collection due to invalid index " << spec + << ": " << keyStatus.reason() << " For more info see" + << " http://dochub.mongodb.org/core/index-validation"); } + indexSpecs.push_back(spec); } + } - // Give a chance to be interrupted *before* we drop all indexes. - txn->checkForInterrupt(); - - { - // note that the drop indexes call also invalidates all clientcursors for the namespace, - // which is important and wanted here - WriteUnitOfWork wunit(txn); - log() << "compact dropping indexes" << endl; - Status status = _indexCatalog.dropAllIndexes(txn, true); - if ( !status.isOK() ) { - return StatusWith<CompactStats>( status ); - } - wunit.commit(); - } + // Give a chance to be interrupted *before* we drop all indexes. + txn->checkForInterrupt(); - CompactStats stats; + { + // note that the drop indexes call also invalidates all clientcursors for the namespace, + // which is important and wanted here + WriteUnitOfWork wunit(txn); + log() << "compact dropping indexes" << endl; + Status status = _indexCatalog.dropAllIndexes(txn, true); + if (!status.isOK()) { + return StatusWith<CompactStats>(status); + } + wunit.commit(); + } - MultiIndexBlock indexer(txn, this); - indexer.allowInterruption(); - indexer.ignoreUniqueConstraint(); // in compact we should be doing no checking + CompactStats stats; - Status status = indexer.init( indexSpecs ); - if ( !status.isOK() ) - return StatusWith<CompactStats>( status ); + MultiIndexBlock indexer(txn, this); + indexer.allowInterruption(); + indexer.ignoreUniqueConstraint(); // in compact we should be doing no checking - MyCompactAdaptor adaptor(this, &indexer); + Status status = indexer.init(indexSpecs); + if (!status.isOK()) + return StatusWith<CompactStats>(status); - status = _recordStore->compact( txn, &adaptor, compactOptions, &stats); - if (!status.isOK()) - return StatusWith<CompactStats>(status); + MyCompactAdaptor adaptor(this, &indexer); - log() << "starting index commits"; - status = indexer.doneInserting(); - if ( !status.isOK() ) - return StatusWith<CompactStats>( status ); + status = _recordStore->compact(txn, &adaptor, compactOptions, &stats); + if (!status.isOK()) + return StatusWith<CompactStats>(status); - { - WriteUnitOfWork wunit(txn); - indexer.commit(); - wunit.commit(); - } + log() << "starting index commits"; + status = indexer.doneInserting(); + if (!status.isOK()) + return StatusWith<CompactStats>(status); - return StatusWith<CompactStats>( stats ); + { + WriteUnitOfWork wunit(txn); + indexer.commit(); + wunit.commit(); } + return StatusWith<CompactStats>(stats); +} + } // namespace mongo |