//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1991 - 2000. // // File: PIDXTBL.CXX // // Contents: Partition Index Table // // Classes: PIndexTable // // History: 16-Feb-94 SrikantS Created. // //---------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include #include #include "prtiflst.hxx" #define WORKID_CONTENTINDXROOT 0 //+--------------------------------------------------------------------------- // // Function: CreateAndAddIt // // Synopsis: This methods creates a WID for the specified "it" and // adds an entry to the index table. The "iid" is formed // by using the partition id and the index type. // // Arguments: [it] -- Index Type to be created. // [partid] -- Partition Id for the it. // // History: 2-16-94 srikants Created // // Notes: // //---------------------------------------------------------------------------- WORKID PIndexTable::CreateAndAddIt( IndexType it, PARTITIONID partid ) { WORKID wid; if ( itFreshLog == it ) { wid = GetStorage().GetNewObjectIdForFreshLog(); } else { // // In Kernel, OFS does not use the iid but in FAT that is used // as the wid of the object. So, generating a unique wid for // each "it" is by using the parition id and the it. // CIndexId iid(it, partid); wid = GetStorage().CreateObjectId( iid, PStorage::eRcovHdr ); } AddObject( partid, it, wid ); return wid; } //+--------------------------------------------------------------------------- //---------------------------------------------------------------------------- CPartInfo * PIndexTable::CreateOrGet( SPartInfoList & pList, PARTITIONID partId ) { CPartInfo * pPartInfo = pList->GetPartInfo( partId ); if ( !pPartInfo ) { pPartInfo = new CPartInfo( partId ); pList->Append( pPartInfo ); } return(pPartInfo); } //+--------------------------------------------------------------------------- // // Function: QueryBootStrapInfo // // Synopsis: This method acts as the bootstrap procedure by reading the // index table from disk and creating/initializing the // "special" index types like the changelog, freshlog, etc. // // It also handles creating the "first" partition entry if // none exists. // // History: 2-16-94 srikants Created // // Notes: It is upto the caller of the function to destroy the // CPartInfoList that is created here. // //---------------------------------------------------------------------------- CPartInfoList * PIndexTable::QueryBootStrapInfo() { WORKID widFreshLog = widInvalid; WORKID widPhraseLat = widInvalid; CPartInfoList * pPartInfoList = new CPartInfoList; SPartInfoList pList( pPartInfoList ); BOOL fCreatePart = TRUE; { // // Iterate over the index table and form the PartInfoList. // SIndexTabIter pIdxIter(QueryIterator()); if ( pIdxIter->Begin() ) { CIndexRecord record; while ( pIdxIter->NextRecord ( record ) ) { PARTITIONID partId = CIndexId( record.Iid()).PartId(); if ( partidInvalid == partId ) { // // The deleted index ids (iidDeleted1 and iidDeleted2) // both have 0xffff as their partid which is also the // partid invalid. We must treat it as a special case. // if ( itDeleted == record.Type() ) { Win4Assert( iidInvalid == _iidDeleted && "You have to reformat" ); _iidDeleted = record.Iid(); } continue; } // // Check if the partition is valid or not. // CPartInfo * pPartInfo = NULL; if ( partId != partidKeyList && partId != partidFresh1 && partId != partidFresh2 ) { pPartInfo = CreateOrGet( pList, partId ); Win4Assert( pPartInfo ); fCreatePart = FALSE; } else if ( partidKeyList == partId ) { continue; } switch( record.Type() ) { case itPartition: break; case itChangeLog: pPartInfo->SetChangeLogObjectId(record.ObjectId()); break; case itMaster: pPartInfo->SetCurrMasterIndex(record.ObjectId()); break; case itNewMaster: pPartInfo->SetNewMasterIndex(record.ObjectId()); break; case itMMLog: pPartInfo->SetMMergeLog(record.ObjectId()); break; case itFreshLog: widFreshLog = record.ObjectId(); Win4Assert( widInvalid != widFreshLog ); break; case itPhraseLat: widPhraseLat = record.ObjectId(); Win4Assert( widInvalid != widPhraseLat ); break; } // of switch } // of while } // of if } // This block necessary to destroy the pIdxIter if ( fCreatePart ) { AddPartition( partidDefault ); CPartInfo * pPartInfo = new CPartInfo( partidDefault ); pList->Append( pPartInfo ); } // // We now have to create any objects that are not created yet. // BOOL fNewFreshLog = FALSE; if ( widInvalid == widFreshLog ) { fNewFreshLog = TRUE; widFreshLog = CreateAndAddIt( itFreshLog, partidDefault ); } BOOL fNewPhraseLat = FALSE; if ( widInvalid == widPhraseLat ) { fNewPhraseLat = TRUE; widPhraseLat = CreateAndAddIt( itPhraseLat, partidDefault ); } if ( _iidDeleted == iidInvalid ) { SetDeletedIndex( iidDeleted1 ); } Win4Assert( widInvalid != widFreshLog ); Win4Assert( widInvalid != widPhraseLat ); GetStorage().InitRcovObj( widFreshLog, FALSE ); // other two strms also. GetStorage().InitRcovObj( widPhraseLat, TRUE ); // atomic strm only GetStorage().SetSpecialItObjectId( itFreshLog, widFreshLog ); GetStorage().SetSpecialItObjectId( itPhraseLat, widPhraseLat ); if ( fNewFreshLog ) { // // Inside kernel, we are guaranteed that a new object has no data in // it. In user space, we may be using an object that was not deleted // before due to a failure. // PRcovStorageObj * pObj = GetStorage().QueryFreshLog(widFreshLog); XPtr xObj(pObj); xObj->InitHeader(GetStorage().GetStorageVersion()); } // phrase lattice is not used now // // For each partition, create/initialize the persistent objects // that exist on a per-partition basis. eg. ChangeLog. // for ( CForPartInfoIter it(*pList); !pList->AtEnd(it); pList->Advance(it) ) { CPartInfo * pPartInfo = it.GetPartInfo(); Win4Assert( pPartInfo ); BOOL fNewChangeLog = FALSE; if ( widInvalid == pPartInfo->GetChangeLogObjectId() ) { pPartInfo->SetChangeLogObjectId( CreateAndAddIt( itChangeLog, pPartInfo->GetPartId() )); fNewChangeLog = TRUE; } Win4Assert( widInvalid != pPartInfo->GetChangeLogObjectId() ); GetStorage().InitRcovObj( pPartInfo->GetChangeLogObjectId(), FALSE ); if ( fNewChangeLog ) { PRcovStorageObj * pObj = GetStorage().QueryChangeLog( pPartInfo->GetChangeLogObjectId(), PStorage::ePrimChangeLog ); XPtr xObj(pObj); xObj->InitHeader(GetStorage().GetStorageVersion()); } } return pList.Acquire(); }