DiskLoc MmapV1ExtentManager::extentLocForV1( const DiskLoc& loc ) const {
     MmapV1RecordHeader* record = recordForV1( loc );
     return DiskLoc( loc.a(), record->extentOfs() );
 }
void initializeV1RS(OperationContext* opCtx,
                    const LocAndSize* records,
                    const LocAndSize* drecs,
                    const LocAndSize* legacyGrabBag,
                    DummyExtentManager* em,
                    DummyRecordStoreV1MetaData* md) {
    invariant(records || drecs);  // if both are NULL nothing is being created...

    // Need to start with a blank slate
    invariant(em->numFiles() == 0);
    invariant(md->firstExtent(opCtx).isNull());

    // pre-allocate extents (even extents that aren't part of this RS)
    {
        typedef std::map<int, size_t> ExtentSizes;
        ExtentSizes extentSizes;
        accumulateExtentSizeRequirements(records, &extentSizes);
        accumulateExtentSizeRequirements(drecs, &extentSizes);
        accumulateExtentSizeRequirements(legacyGrabBag, &extentSizes);
        invariant(!extentSizes.empty());

        const int maxExtent = extentSizes.rbegin()->first;
        for (int i = 0; i <= maxExtent; i++) {
            const size_t size = extentSizes.count(i) ? extentSizes[i] : 0;
            const DiskLoc loc = em->allocateExtent(opCtx, md->isCapped(), size, 0);

            // This function and assertState depend on these details of DummyExtentManager
            invariant(loc.a() == i);
            invariant(loc.getOfs() == 0);
        }

        // link together extents that should be part of this RS
        md->setFirstExtent(opCtx, DiskLoc(extentSizes.begin()->first, 0));
        md->setLastExtent(opCtx, DiskLoc(extentSizes.rbegin()->first, 0));
        for (ExtentSizes::iterator it = extentSizes.begin(); boost::next(it) != extentSizes.end();
             /* ++it */) {
            const int a = it->first;
            ++it;
            const int b = it->first;
            em->getExtent(DiskLoc(a, 0))->xnext = DiskLoc(b, 0);
            em->getExtent(DiskLoc(b, 0))->xprev = DiskLoc(a, 0);
        }

        // This signals "done allocating new extents".
        if (md->isCapped())
            md->setDeletedListEntry(opCtx, 1, DiskLoc());
    }

    if (records && !records[0].loc.isNull()) {
        int recIdx = 0;
        DiskLoc extLoc = md->firstExtent(opCtx);
        while (!extLoc.isNull()) {
            Extent* ext = em->getExtent(extLoc);
            int prevOfs = DiskLoc::NullOfs;
            while (extLoc.a() == records[recIdx].loc.a()) {  // for all records in this extent
                const DiskLoc loc = records[recIdx].loc;
                const int size = records[recIdx].size;
                ;
                invariant(size >= MmapV1RecordHeader::HeaderSize);

                md->incrementStats(opCtx, size - MmapV1RecordHeader::HeaderSize, 1);

                if (ext->firstRecord.isNull())
                    ext->firstRecord = loc;

                MmapV1RecordHeader* rec = em->recordForV1(loc);
                rec->lengthWithHeaders() = size;
                rec->extentOfs() = 0;

                rec->prevOfs() = prevOfs;
                prevOfs = loc.getOfs();

                const DiskLoc nextLoc = records[recIdx + 1].loc;
                if (nextLoc.a() == loc.a()) {  // if next is in same extent
                    rec->nextOfs() = nextLoc.getOfs();
                } else {
                    rec->nextOfs() = DiskLoc::NullOfs;
                    ext->lastRecord = loc;
                }

                recIdx++;
            }
            extLoc = ext->xnext;
        }
        invariant(records[recIdx].loc.isNull());
    }

    if (drecs && !drecs[0].loc.isNull()) {
        int drecIdx = 0;
        DiskLoc* prevNextPtr = NULL;
        int lastBucket = -1;
        while (!drecs[drecIdx].loc.isNull()) {
            const DiskLoc loc = drecs[drecIdx].loc;
            const int size = drecs[drecIdx].size;
            invariant(size >= MmapV1RecordHeader::HeaderSize);
            const int bucket = RecordStoreV1Base::bucket(size);

            if (md->isCapped()) {
                // All drecs form a single list in bucket 0
                if (prevNextPtr == NULL) {
                    md->setDeletedListEntry(opCtx, 0, loc);
                } else {
                    *prevNextPtr = loc;
                }

                if (loc.a() < md->capExtent().a() &&
                    drecs[drecIdx + 1].loc.a() == md->capExtent().a()) {
                    // Bucket 1 is known as cappedLastDelRecLastExtent
                    md->setDeletedListEntry(opCtx, 1, loc);
                }
            } else if (bucket != lastBucket) {
                invariant(bucket > lastBucket);  // if this fails, drecs weren't sorted by bucket
                md->setDeletedListEntry(opCtx, bucket, loc);
                lastBucket = bucket;
            } else {
                *prevNextPtr = loc;
            }

            DeletedRecord* drec = &em->recordForV1(loc)->asDeleted();
            drec->lengthWithHeaders() = size;
            drec->extentOfs() = 0;
            drec->nextDeleted() = DiskLoc();
            prevNextPtr = &drec->nextDeleted();

            drecIdx++;
        }
    }

    if (legacyGrabBag && !legacyGrabBag[0].loc.isNull()) {
        invariant(!md->isCapped());  // capped should have an empty legacy grab bag.

        int grabBagIdx = 0;
        DiskLoc* prevNextPtr = NULL;
        while (!legacyGrabBag[grabBagIdx].loc.isNull()) {
            const DiskLoc loc = legacyGrabBag[grabBagIdx].loc;
            const int size = legacyGrabBag[grabBagIdx].size;
            invariant(size >= MmapV1RecordHeader::HeaderSize);

            if (grabBagIdx == 0) {
                md->setDeletedListLegacyGrabBag(opCtx, loc);
            } else {
                *prevNextPtr = loc;
            }

            DeletedRecord* drec = &em->recordForV1(loc)->asDeleted();
            drec->lengthWithHeaders() = size;
            drec->extentOfs() = 0;
            drec->nextDeleted() = DiskLoc();
            prevNextPtr = &drec->nextDeleted();

            grabBagIdx++;
        }
    }

    // Make sure we set everything up as requested.
    assertStateV1RS(opCtx, records, drecs, legacyGrabBag, em, md);
}