Skip to content

Commit

Permalink
simple refactor of capped delete code
Browse files Browse the repository at this point in the history
  • Loading branch information
astaple committed Dec 28, 2010
1 parent 28b9f03 commit bf28508
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 51 deletions.
92 changes: 41 additions & 51 deletions db/cap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,32 @@ namespace mongo {
cout << "dl[1]: " << deletedList[1].toString() << endl;
}

void NamespaceDetails::cappedTruncateLastDelUpdate() {
if ( capExtent == firstExtent ) {
// Only one extent of the collection is in use, so there
// is no deleted record in a previous extent, so nullify
// cappedLastDelRecLastExtent().
cappedLastDelRecLastExtent().writing() = DiskLoc();
} else {
// Scan through all deleted records in the collection
// until the last deleted record for the extent prior
// to the new capExtent is found. Then set
// cappedLastDelRecLastExtent() to that deleted record.
DiskLoc i = cappedListOfAllDeletedRecords();
for( ;
!i.drec()->nextDeleted.isNull() &&
!inCapExtent( i.drec()->nextDeleted );
i = i.drec()->nextDeleted );
// In our capped storage model, every extent with real
// records must have at least one deleted record. Here
// we check that 'i' is not the last deleted record.
// (We expect that there will be deleted records in
// the new capExtent as well.)
assert( !i.drec()->nextDeleted.isNull() );
cappedLastDelRecLastExtent().writing() = i;
}
}

void NamespaceDetails::cappedTruncateAfter(const char *ns, DiskLoc end, bool inclusive) {
DEV assert( this == nsdetails(ns) );
assert( cappedLastDelRecLastExtent().isValid() );
Expand Down Expand Up @@ -311,17 +337,17 @@ namespace mongo {
// this case instead of asserting.
uassert( 13415, "emptying the collection is not allowed", stats.nrecords > 1 );

// Delete the newest record, and coalesce the new deleted
// record with existing deleted records.
theDataFileMgr.deleteRecord(ns, curr.rec(), curr, true);
compact();

// This is the case where we have not yet had to remove any
// documents to make room for other documents, and we are allocating
// documents from free space in fresh extents instead of reusing
// space from familiar extents.
if ( !capLooped() ) {

// Delete the newest record, and coalesce the new deleted
// record with existing deleted records.
theDataFileMgr.deleteRecord(ns, curr.rec(), curr, true);
compact();

// We just removed the last record from the 'capExtent', and
// the 'capExtent' can't be empty, so we set 'capExtent' to
// capExtent's prev extent.
Expand All @@ -331,47 +357,20 @@ namespace mongo {
// capLooped() is false, capExtent is not the first extent
// so xprev will be nonnull.
capExtent.writing() = theCapExtent()->xprev;
theCapExtent()->assertOk();

if ( capExtent == firstExtent ) {
// Only one extent of the collection is in use, so there
// is no deleted record in a previous extent, so nullify
// cappedLastDelRecLastExtent().
cappedLastDelRecLastExtent().writing() = DiskLoc();
} else {
// Scan through all deleted records in the collection
// until the last deleted record for the extent prior
// to the new capExtent is found. Then set
// cappedLastDelRecLastExtent() to that deleted record.
DiskLoc i = cappedListOfAllDeletedRecords();
for( ;
!i.drec()->nextDeleted.isNull() &&
!inCapExtent( i.drec()->nextDeleted );
i = i.drec()->nextDeleted );
// In our capped storage model, every extent with real
// records must have at least one deleted record. Here
// we check that 'i' is not the last deleted record.
// (We expect that there will be deleted records in
// the new capExtent as well.)
assert( !i.drec()->nextDeleted.isNull() );
cappedLastDelRecLastExtent().writing() = i;
}
theCapExtent()->assertOk();

// update cappedLastDelRecLastExtent()
cappedTruncateLastDelUpdate();
}
continue;
}

// Delete the newest record, and coalesce the new deleted
// record with existing deleted records.
// TODO refactor with equivalent statement above.
theDataFileMgr.deleteRecord(ns, curr.rec(), curr, true);
compact();

// This is the case where capLooped() is true, and we just deleted
// from capExtent, and we just deleted capFirstNewRecord, which was
// the last record on the fresh side of capExtent.
// NOTE In this comparison, curr and potentially capFirstNewRecord
// may point to invalid data, but we can still compare these
// references.
// may point to invalid data, but we can still compare the
// references themselves.
if ( curr == capFirstNewRecord ) {
// Set 'capExtent' to the cyclically previous extent
capExtent.writing() = ( capExtent == firstExtent ) ? lastExtent : theCapExtent()->xprev;
Expand All @@ -380,23 +379,14 @@ namespace mongo {
// TODO Validate that this will always be true, or else check
// the assert before setting capExtent.
assert( !theCapExtent()->firstRecord.isNull() );

// Place all documents in the new capExtent on the fresh side
// of the capExtent by setting capFirstNewRecord to the first
// document in the new capExtent
capFirstNewRecord.writing() = theCapExtent()->firstRecord;

// Update cappedLastDelRecLastExtent(), see comments above.
if ( capExtent == firstExtent ) {
cappedLastDelRecLastExtent().writing() = DiskLoc();
} else {
DiskLoc i = cappedListOfAllDeletedRecords();
for( ;
!i.drec()->nextDeleted.isNull() &&
!inCapExtent( i.drec()->nextDeleted );
i = i.drec()->nextDeleted );
assert( !i.drec()->nextDeleted.isNull() );
cappedLastDelRecLastExtent().writing() = i;
}

// update cappedLastDelRecLastExtent()
cappedTruncateLastDelUpdate();
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions db/namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ namespace mongo {
unsigned reserved2;
unsigned reserved3;
};
/** Update cappedLastDelRecLastExtent() after capExtent changed in cappedTruncateAfter() */
void cappedTruncateLastDelUpdate();
BOOST_STATIC_ASSERT( NIndexesMax <= NIndexesBase + NIndexesExtra*2 );
BOOST_STATIC_ASSERT( NIndexesMax <= 64 ); // multiKey bits
BOOST_STATIC_ASSERT( sizeof(NamespaceDetails::ExtraOld) == 496 );
Expand Down

0 comments on commit bf28508

Please sign in to comment.