|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 2000.
//
// File: PIDXTBL.CXX
//
// Contents: Partition Index Table
//
// Classes: PIndexTable
//
// History: 16-Feb-94 SrikantS Created.
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <pidxtbl.hxx>
#include <pstore.hxx>
#include <rcstxact.hxx>
#include <rcstrmit.hxx>
#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<PRcovStorageObj> 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<PRcovStorageObj> xObj(pObj); xObj->InitHeader(GetStorage().GetStorageVersion()); } }
return pList.Acquire(); }
|