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; }
// 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 ); } }
IndexDetails& NamespaceDetails::idx(int idxNo, bool missingExpected) { if( idxNo < NIndexesBase ) { IndexDetails& id = _indexes[idxNo]; return id; } Extra *e = extra(); if ( ! e ) { if ( missingExpected ) throw MsgAssertionException( 13283 , "Missing Extra" ); massert(14045, "missing Extra", e); } int i = idxNo - NIndexesBase; if( i >= NIndexesExtra ) { e = e->next(this); if ( ! e ) { if ( missingExpected ) throw MsgAssertionException( 14823 , "missing extra" ); massert(14824, "missing Extra", e); } i -= NIndexesExtra; } return e->details[i]; }
// XXX - this method should go away NamespaceDetails *NamespaceDetails::writingWithExtra( OperationContext* txn ) { for( Extra *e = extra(); e; e = e->next( this ) ) { txn->recoveryUnit()->writing( e ); } return writingWithoutExtra( txn ); }