summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp')
-rw-r--r--src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp234
1 files changed, 115 insertions, 119 deletions
diff --git a/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp b/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp
index a4cb9977fe3..728f07d6013 100644
--- a/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp
+++ b/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp
@@ -38,49 +38,47 @@
namespace mongo {
- using std::endl;
-
- RecordStoreV1RepairCursor::RecordStoreV1RepairCursor(OperationContext* txn,
- const RecordStoreV1Base* recordStore)
- : _txn(txn), _recordStore(recordStore), _stage(FORWARD_SCAN) {
-
- // Position the iterator at the first record
- //
- advance();
- }
-
- boost::optional<Record> RecordStoreV1RepairCursor::next() {
- if (_currRecord.isNull()) return {};
- auto out = _currRecord.toRecordId();
- advance();
- return {{out, _recordStore->dataFor(_txn, out)}};
- }
-
- boost::optional<Record> RecordStoreV1RepairCursor::seekExact(const RecordId& id) {
- invariant(!"seekExact not supported");
- }
-
- void RecordStoreV1RepairCursor::advance() {
- const ExtentManager* em = _recordStore->_extentManager;
-
- while (true) {
- if (_currRecord.isNull()) {
-
- if (!_advanceToNextValidExtent()) {
- return;
- }
+using std::endl;
+
+RecordStoreV1RepairCursor::RecordStoreV1RepairCursor(OperationContext* txn,
+ const RecordStoreV1Base* recordStore)
+ : _txn(txn), _recordStore(recordStore), _stage(FORWARD_SCAN) {
+ // Position the iterator at the first record
+ //
+ advance();
+}
+
+boost::optional<Record> RecordStoreV1RepairCursor::next() {
+ if (_currRecord.isNull())
+ return {};
+ auto out = _currRecord.toRecordId();
+ advance();
+ return {{out, _recordStore->dataFor(_txn, out)}};
+}
+
+boost::optional<Record> RecordStoreV1RepairCursor::seekExact(const RecordId& id) {
+ invariant(!"seekExact not supported");
+}
+
+void RecordStoreV1RepairCursor::advance() {
+ const ExtentManager* em = _recordStore->_extentManager;
+
+ while (true) {
+ if (_currRecord.isNull()) {
+ if (!_advanceToNextValidExtent()) {
+ return;
+ }
- _seenInCurrentExtent.clear();
+ _seenInCurrentExtent.clear();
- // Otherwise _advanceToNextValidExtent would have returned false
- //
- invariant(!_currExtent.isNull());
+ // Otherwise _advanceToNextValidExtent would have returned false
+ //
+ invariant(!_currExtent.isNull());
- const Extent* e = em->getExtent(_currExtent, false);
- _currRecord = (FORWARD_SCAN == _stage ? e->firstRecord : e->lastRecord);
- }
- else {
- switch (_stage) {
+ const Extent* e = em->getExtent(_currExtent, false);
+ _currRecord = (FORWARD_SCAN == _stage ? e->firstRecord : e->lastRecord);
+ } else {
+ switch (_stage) {
case FORWARD_SCAN:
_currRecord = _recordStore->getNextRecordInExtent(_txn, _currRecord);
break;
@@ -90,37 +88,37 @@ namespace mongo {
default:
invariant(!"This should never be reached.");
break;
- }
- }
-
- if (_currRecord.isNull()) {
- continue;
}
+ }
- // Validate the contents of the record's disk location and deduplicate
- //
- if (!_seenInCurrentExtent.insert(_currRecord).second) {
- error() << "infinite loop in extent, seen: " << _currRecord << " before" << endl;
- _currRecord = DiskLoc();
- continue;
- }
+ if (_currRecord.isNull()) {
+ continue;
+ }
- if (_currRecord.getOfs() <= 0){
- error() << "offset is 0 for record which should be impossible" << endl;
- _currRecord = DiskLoc();
- continue;
- }
+ // Validate the contents of the record's disk location and deduplicate
+ //
+ if (!_seenInCurrentExtent.insert(_currRecord).second) {
+ error() << "infinite loop in extent, seen: " << _currRecord << " before" << endl;
+ _currRecord = DiskLoc();
+ continue;
+ }
- return;
+ if (_currRecord.getOfs() <= 0) {
+ error() << "offset is 0 for record which should be impossible" << endl;
+ _currRecord = DiskLoc();
+ continue;
}
+
+ return;
}
+}
- bool RecordStoreV1RepairCursor::_advanceToNextValidExtent() {
- const ExtentManager* em = _recordStore->_extentManager;
+bool RecordStoreV1RepairCursor::_advanceToNextValidExtent() {
+ const ExtentManager* em = _recordStore->_extentManager;
- while (true) {
- if (_currExtent.isNull()) {
- switch (_stage) {
+ while (true) {
+ if (_currExtent.isNull()) {
+ switch (_stage) {
case FORWARD_SCAN:
_currExtent = _recordStore->details()->firstExtent(_txn);
break;
@@ -130,35 +128,34 @@ namespace mongo {
default:
invariant(DONE == _stage);
return false;
- }
- }
- else {
- // If _currExtent is not NULL, then it must point to a valid extent, so no extra
- // checks here.
- //
- const Extent* e = em->getExtent(_currExtent, false);
- _currExtent = (FORWARD_SCAN == _stage ? e->xnext : e->xprev);
}
-
- bool hasNextExtent = !_currExtent.isNull();
-
- // Sanity checks for the extent's disk location
+ } else {
+ // If _currExtent is not NULL, then it must point to a valid extent, so no extra
+ // checks here.
//
- if (hasNextExtent && (!_currExtent.isValid() || (_currExtent.getOfs() < 0))) {
- error() << "Invalid extent location: " << _currExtent << endl;
+ const Extent* e = em->getExtent(_currExtent, false);
+ _currExtent = (FORWARD_SCAN == _stage ? e->xnext : e->xprev);
+ }
- // Switch the direction of scan
- //
- hasNextExtent = false;
- }
+ bool hasNextExtent = !_currExtent.isNull();
- if (hasNextExtent) {
- break;
- }
+ // Sanity checks for the extent's disk location
+ //
+ if (hasNextExtent && (!_currExtent.isValid() || (_currExtent.getOfs() < 0))) {
+ error() << "Invalid extent location: " << _currExtent << endl;
- // Swap the direction of scan and loop again
+ // Switch the direction of scan
//
- switch (_stage) {
+ hasNextExtent = false;
+ }
+
+ if (hasNextExtent) {
+ break;
+ }
+
+ // Swap the direction of scan and loop again
+ //
+ switch (_stage) {
case FORWARD_SCAN:
_stage = BACKWARD_SCAN;
break;
@@ -168,49 +165,48 @@ namespace mongo {
default:
invariant(!"This should never be reached.");
break;
- }
-
- _currExtent = DiskLoc();
}
+ _currExtent = DiskLoc();
+ }
- // Check _currExtent's contents for validity, but do not count is as failure if they
- // don't check out.
- //
- const Extent* e = em->getExtent(_currExtent, false);
- if (!e->isOk()){
- warning() << "Extent not ok magic: " << e->magic << " going to try to continue"
- << endl;
- }
-
- log() << (FORWARD_SCAN == _stage ? "FORWARD" : "BACKWARD") << " Extent loc: "
- << _currExtent << ", length: " << e->length << endl;
- return true;
+ // Check _currExtent's contents for validity, but do not count is as failure if they
+ // don't check out.
+ //
+ const Extent* e = em->getExtent(_currExtent, false);
+ if (!e->isOk()) {
+ warning() << "Extent not ok magic: " << e->magic << " going to try to continue" << endl;
}
- void RecordStoreV1RepairCursor::invalidate(const RecordId& id) {
- // If we see this record again it probably means it was reinserted rather than an infinite
- // loop. If we do loop, we should quickly hit another seen record that hasn't been
- // invalidated.
- DiskLoc dl = DiskLoc::fromRecordId(id);
- _seenInCurrentExtent.erase(dl);
+ log() << (FORWARD_SCAN == _stage ? "FORWARD" : "BACKWARD") << " Extent loc: " << _currExtent
+ << ", length: " << e->length << endl;
- if (_currRecord == dl) {
- // The DiskLoc being invalidated is also the one pointed at by this iterator. We
- // advance the iterator so it's not pointing at invalid data.
- advance();
+ return true;
+}
- if (_currRecord == dl) {
- // Even after advancing the iterator, we're still pointing at the DiskLoc being
- // invalidated. This is expected when 'dl' is the last DiskLoc in the FORWARD scan,
- // and the initial call to getNext() moves the iterator to the first loc in the
- // BACKWARDS scan.
- advance();
- }
+void RecordStoreV1RepairCursor::invalidate(const RecordId& id) {
+ // If we see this record again it probably means it was reinserted rather than an infinite
+ // loop. If we do loop, we should quickly hit another seen record that hasn't been
+ // invalidated.
+ DiskLoc dl = DiskLoc::fromRecordId(id);
+ _seenInCurrentExtent.erase(dl);
+
+ if (_currRecord == dl) {
+ // The DiskLoc being invalidated is also the one pointed at by this iterator. We
+ // advance the iterator so it's not pointing at invalid data.
+ advance();
- invariant(_currRecord != dl);
+ if (_currRecord == dl) {
+ // Even after advancing the iterator, we're still pointing at the DiskLoc being
+ // invalidated. This is expected when 'dl' is the last DiskLoc in the FORWARD scan,
+ // and the initial call to getNext() moves the iterator to the first loc in the
+ // BACKWARDS scan.
+ advance();
}
+
+ invariant(_currRecord != dl);
}
+}
} // namespace mongo