示例#1
0
NamespaceDetails::Extra* NamespaceDetails::allocExtra(OperationContext* txn,
        StringData ns,
        NamespaceIndex& ni,
        int nindexessofar) {
    // Namespace details must always be changed under an exclusive DB lock
    const NamespaceString nss(ns);
    invariant(txn->lockState()->isDbLockedForMode(nss.db(), MODE_X));

    int i = (nindexessofar - NIndexesBase) / NIndexesExtra;
    verify(i >= 0 && i <= 1);

    Namespace fullns(ns);
    Namespace extrans(fullns.extraName(i));  // throws UserException if ns name too long

    massert(10350, "allocExtra: base ns missing?", this);
    massert(10351, "allocExtra: extra already exists", ni.details(extrans) == 0);

    Extra temp;
    temp.init();

    ni.add_ns(txn, extrans, reinterpret_cast<NamespaceDetails*>(&temp));
    Extra* e = reinterpret_cast<NamespaceDetails::Extra*>(ni.details(extrans));

    long ofs = e->ofsFrom(this);
    if (i == 0) {
        verify(_extraOffset == 0);
        *txn->recoveryUnit()->writing(&_extraOffset) = ofs;
        verify(extra() == e);
    } else {
        Extra* hd = extra();
        verify(hd->next(this) == 0);
        hd->setNext(txn, ofs);
    }
    return e;
}
示例#2
0
 // must be called when renaming a NS to fix up extra
 void NamespaceDetails::copyingFrom( OperationContext* txn,
                                     const StringData& thisns,
                                     NamespaceIndex& ni,
                                     NamespaceDetails* src) {
     _extraOffset = 0; // we are a copy -- the old value is wrong.  fixing it up below.
     Extra *se = src->extra();
     int n = NIndexesBase;
     if( se ) {
         Extra *e = allocExtra(txn, thisns, ni, n);
         while( 1 ) {
             n += NIndexesExtra;
             e->copy(this, *se);
             se = se->next(src);
             if( se == 0 ) break;
             Extra *nxt = allocExtra(txn, thisns, ni, n);
             e->setNext( txn, nxt->ofsFrom(this) );
             e = nxt;
         }
         verify( _extraOffset );
     }
 }