windows-nt/Source/XPSP1/NT/inetsrv/query/cindex/pidxtbl.cxx
2020-09-26 16:20:57 +08:00

289 lines
8.4 KiB
C++

//+---------------------------------------------------------------------------
//
// 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();
}