Ejemplo n.º 1
0
            void run() {
                create();
                nsd()->deletedListEntry( 2 ) = nsd()->cappedListOfAllDeletedRecords().drec()->nextDeleted().drec()->nextDeleted();
                nsd()->cappedListOfAllDeletedRecords().drec()->nextDeleted().drec()->nextDeleted().writing() = DiskLoc();
                nsd()->cappedLastDelRecLastExtent().Null();
                NamespaceDetails *d = nsd();

                zero( &d->capExtent() );
                zero( &d->capFirstNewRecord() );

                // this has a side effect of called NamespaceDetails::cappedCheckMigrate
                db()->namespaceIndex().details( ns() );

                ASSERT( nsd()->firstExtent() == nsd()->capExtent() );
                ASSERT( nsd()->capExtent().getOfs() != 0 );
                ASSERT( !nsd()->capFirstNewRecord().isValid() );
                int nDeleted = 0;
                for ( DiskLoc i = nsd()->cappedListOfAllDeletedRecords(); !i.isNull(); i = i.drec()->nextDeleted(), ++nDeleted );
                ASSERT_EQUALS( 10, nDeleted );
                ASSERT( nsd()->cappedLastDelRecLastExtent().isNull() );
            }
    DiskLoc CappedRecordStoreV1Iterator::getNextCapped(const DiskLoc& dl) {
        invariant(!dl.isNull());
        NamespaceDetails* details = _recordStore->_details;

        if (CollectionScanParams::FORWARD == _direction) {
            // If it's not looped, it's easy.
            if (!_recordStore->details()->capLooped()) {
                return _getNextRecord( dl );
            }

            // TODO ELABORATE
            // EOF.
            if (dl == _getExtent( details->capExtent() )->lastRecord) {
                return DiskLoc();
            }

            DiskLoc ret = nextLoop(dl);

            // If we become capFirstNewRecord from same extent, advance to next extent.
            if (ret == details->capFirstNewRecord() && ret != _getExtent( details->capExtent() )->firstRecord) {
                ret = nextLoop(_getExtent( details->capExtent() )->lastRecord);
            }

            // If we have just gotten to beginning of capExtent, skip to capFirstNewRecord
            if (ret == _getExtent( details->capExtent() )->firstRecord) { ret = details->capFirstNewRecord(); }

            return ret;
        }
        else {
            if (!details->capLooped()) { return _getPrevRecord( dl ); }

            // TODO ELABORATE
            // Last record
            if (details->capFirstNewRecord() == _getExtent( details->capExtent() )->firstRecord) {
                if (dl == nextLoop(_getExtent( details->capExtent() )->lastRecord)) {
                    return DiskLoc();
                }
            }
            else {
                if (dl == _getExtent( details->capExtent() )->firstRecord) { return DiskLoc(); }
            }

            DiskLoc ret;
            // If we are capFirstNewRecord, advance to prev extent, otherwise just get prev.
            if (dl == details->capFirstNewRecord()) {
                ret = prevLoop(_getExtent( details->capExtent() )->firstRecord);
            }
            else {
                ret = prevLoop(dl);
            }

            // If we just became last in cap extent, advance past capFirstNewRecord
            // (We know ext(capExtent)->firstRecord != capFirstNewRecord, since would
            // have returned DiskLoc() earlier otherwise.)
            if (ret == _getExtent( details->capExtent() )->lastRecord) {
                ret = _getPrevRecord( details->capFirstNewRecord() );
            }

            return ret;
        }
    }