Пример #1
0
    void RecordStoreV1Base::deleteRecord( TransactionExperiment* txn, const DiskLoc& dl ) {

        Record* todelete = recordFor( dl );

        /* remove ourself from the record next/prev chain */
        {
            if ( todelete->prevOfs() != DiskLoc::NullOfs ) {
                DiskLoc prev = getPrevRecordInExtent( dl );
                Record* prevRecord = recordFor( prev );
                txn->writingInt( prevRecord->nextOfs() ) = todelete->nextOfs();
            }

            if ( todelete->nextOfs() != DiskLoc::NullOfs ) {
                DiskLoc next = getNextRecord( dl );
                Record* nextRecord = recordFor( next );
                txn->writingInt( nextRecord->prevOfs() ) = todelete->prevOfs();
            }
        }

        /* remove ourself from extent pointers */
        {
            Extent *e = txn->writing( _getExtent( _getExtentLocForRecord( dl ) ) );
            if ( e->firstRecord == dl ) {
                if ( todelete->nextOfs() == DiskLoc::NullOfs )
                    e->firstRecord.Null();
                else
                    e->firstRecord.set(dl.a(), todelete->nextOfs() );
            }
            if ( e->lastRecord == dl ) {
                if ( todelete->prevOfs() == DiskLoc::NullOfs )
                    e->lastRecord.Null();
                else
                    e->lastRecord.set(dl.a(), todelete->prevOfs() );
            }
        }

        /* add to the free list */
        {
            _details->incrementStats( txn, -1 * todelete->netLength(), -1 );

            if ( _isSystemIndexes ) {
                /* temp: if in system.indexes, don't reuse, and zero out: we want to be
                   careful until validated more, as IndexDetails has pointers
                   to this disk location.  so an incorrectly done remove would cause
                   a lot of problems.
                */
                memset( txn->writingPtr(todelete, todelete->lengthWithHeaders() ),
                        0, todelete->lengthWithHeaders() );
            }
            else {
                DEV {
                    unsigned long long *p = reinterpret_cast<unsigned long long *>( todelete->data() );
                    *txn->writing(p) = 0;
                }
                addDeletedRec(txn, dl);
            }
        }

    }
Пример #2
0
 void RecordStoreV1Base::_addRecordToRecListInExtent(OperationContext* txn,
                                                     Record *r,
                                                     DiskLoc loc) {
     dassert( recordFor(loc) == r );
     Extent *e = _getExtent( _getExtentLocForRecord( loc ) );
     if ( e->lastRecord.isNull() ) {
         *txn->recoveryUnit()->writing(&e->firstRecord) = loc;
         *txn->recoveryUnit()->writing(&e->lastRecord) = loc;
         r->prevOfs() = r->nextOfs() = DiskLoc::NullOfs;
     }
     else {
         Record *oldlast = recordFor(e->lastRecord);
         r->prevOfs() = e->lastRecord.getOfs();
         r->nextOfs() = DiskLoc::NullOfs;
         txn->recoveryUnit()->writingInt(oldlast->nextOfs()) = loc.getOfs();
         *txn->recoveryUnit()->writing(&e->lastRecord) = loc;
     }
 }
Пример #3
0
    DiskLoc RecordStoreV1Base::getNextRecord( const DiskLoc& loc ) const {
        DiskLoc next = getNextRecordInExtent( loc );
        if ( !next.isNull() )
            return next;

        // now traverse extents

        Extent* e = _getExtent( _getExtentLocForRecord(loc) );
        while ( 1 ) {
            if ( e->xnext.isNull() )
                return DiskLoc(); // end of collection
            e = _getExtent( e->xnext );
            if ( !e->firstRecord.isNull() )
                break;
            // entire extent could be empty, keep looking
        }
        return e->firstRecord;
    }
Пример #4
0
DiskLoc RecordStoreV1Base::getPrevRecord(OperationContext* txn, const DiskLoc& loc) const {
    DiskLoc prev = getPrevRecordInExtent(txn, loc);
    if (!prev.isNull()) {
        return prev;
    }

    // now traverse extents

    Extent* e = _getExtent(txn, _getExtentLocForRecord(txn, loc));
    while (1) {
        if (e->xprev.isNull())
            return DiskLoc();  // end of collection
        e = _getExtent(txn, e->xprev);
        if (!e->firstRecord.isNull())
            break;
        // entire extent could be empty, keep looking
    }
    return e->lastRecord;
}