windows-nt/Source/XPSP1/NT/inetsrv/query/ntciutil/idxtab.hxx
2020-09-26 16:20:57 +08:00

371 lines
9.8 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: IDXTAB.HXX
//
// Contents: Index Manager
//
// Classes: CIndexTable
//
// History: 22-Mar-91 BartoszM Created.
//
//----------------------------------------------------------------------------
#pragma once
#include <pidxtbl.hxx>
#include <rcstxact.hxx>
#include <rcstrmit.hxx>
#include <cistore.hxx>
class CiStorage;
class CIndex;
class CPersIndex;
class CTransaction;
//+---------------------------------------------------------------------------
//
// Class: CIndexFile
//
// Purpose: A file of index records
//
// History: 01-jul-93 BartoszM Created.
// 03-mar-94 DwightKr Changed to user persistent streams
//
//----------------------------------------------------------------------------
class CIndexFile
{
public:
virtual ~CIndexFile(){}
virtual void Rewind() = 0;
virtual void BackUp() = 0;
virtual BOOL ReadRecord(CIndexRecord* pRecord) = 0;
};
//+---------------------------------------------------------------------------
//
// Class: CIndexTableUsrHdr
//
// Purpose: User specific header in the index table. This will track the
// master merge sequence number.
//
// History: 3-19-97 srikants Created
//
//----------------------------------------------------------------------------
class CIndexTableUsrHdr
{
public:
CIndexTableUsrHdr();
unsigned GetMMergeSeqNum() const { return _iMMergeSeqNum; }
void IncrMMergeSeqNum()
{
_iMMergeSeqNum++;
}
BOOL IsFullSave() const { return _fFullSave; }
void SetFullSave() { _fFullSave = TRUE; }
void ClearFullSave() { _fFullSave = FALSE; }
private:
unsigned _iReserved;
//
// Master Merge sequence number. This has the number of times
// a master merge has been performed in this catalog.
//
unsigned _iMMergeSeqNum;
//
// This field is used when the index table is transpored. At the
// destination, it will be used to ensure that for an incremental
// load, the master merge sequence numbers are same.
//
BOOL _fFullSave;
};
//+---------------------------------------------------------------------------
//
// Class: CWriteIndexFile
//
// Purpose: A file of index records
//
// History: 01-jul-93 BartoszM Created.
// 03-mar-94 DwightKr Changed to user persistent streams
//
//----------------------------------------------------------------------------
class CWriteIndexFile : INHERIT_VIRTUAL_UNWIND, public CIndexFile
{
DECLARE_UNWIND
public:
CWriteIndexFile ( PRcovStorageObj & rcovObj );
virtual ~CWriteIndexFile() {}
void Rewind() { _xact.Seek(0); _xactPtr = 0; }
void BackUp();
BOOL ReadRecord ( CIndexRecord* pRecord );
void WriteRecord ( CIndexRecord* pRecord );
void Commit() { _xact.Commit(); }
ULONG GetStorageVersion() { return _rcovObj.GetVersion(); }
void IncrMMergeSeqNum();
private:
PRcovStorageObj & _rcovObj;
CRcovStrmWriteTrans _xact;
CRcovStrmWriteIter _iter;
ULONG _xactPtr;
};
//+---------------------------------------------------------------------------
//
// Class: CReadIndexFile
//
// Purpose: A file of index records
//
// History: 01-jul-93 BartoszM Created.
// 03-mar-94 DwightKr Changed to user persistent streams
//
//----------------------------------------------------------------------------
class CReadIndexFile : INHERIT_VIRTUAL_UNWIND, public CIndexFile
{
DECLARE_UNWIND
public:
CReadIndexFile ( PRcovStorageObj & rcovObj );
virtual ~CReadIndexFile() {}
void Rewind() { _xact.Seek(0); _xactPtr = 0; }
void BackUp();
BOOL ReadRecord ( CIndexRecord* pRecord );
private:
PRcovStorageObj & _rcovObj;
CRcovStrmReadTrans _xact;
CRcovStrmReadIter _iter;
ULONG _xactPtr;
};
//+---------------------------------------------------------------------------
//
// Class: CNextIndexRecord
//
// Purpose: Reads in records from file. Only contains
// non-empty records (determined by INDEXID)-- doesn't contain
// anything useful if Found() returns false.
//
// History: 16-Mar-92 AmyA Created.
//
//----------------------------------------------------------------------------
class CNextIndexRecord: public CIndexRecord
{
public:
inline CNextIndexRecord( CIndexFile & indFile );
inline BOOL Found() { return _found; }
private:
BOOL _found;
};
//+---------------------------------------------------------------------------
//
// Member: CNextIndexRecord::CNextIndexRecord, public
//
// Synopsis: Reads IndexRecords in from the file indicated by indFile in a loop,
// stopping when either a non-empty record or EOF are reached.
//
// Notes: Whether or not a non-empty record was found can be determined
// by a call to Found().
//
// History: 16-Mar-92 AmyA Created.
//
//----------------------------------------------------------------------------
inline CNextIndexRecord::CNextIndexRecord( CIndexFile & indFile )
{
INDEXID iidNotValid = CIndexId( iidInvalid, partidInvalid );
do
{
_found = indFile.ReadRecord( this );
} while ( _found && ( Iid() == iidNotValid || Iid() == iidInvalid ) );
}
//+---------------------------------------------------------------------------
//
// Class: CAddReplaceIndexRecord
//
// Purpose: Reads and writes records from file. Only contains
// a useful record if Found() returns true.
//
// History: 16-Mar-92 AmyA Created.
// 29-Feb-95 DwightKr Created WriteRecord() method,
// and moved code from destructor there,
// since the destructor chould THROW().
// Also changed name to reflect what this
// class really does.
//
//----------------------------------------------------------------------------
class CAddReplaceIndexRecord : public CIndexRecord
{
public:
CAddReplaceIndexRecord( CWriteIndexFile & indFile, INDEXID iid );
void SetIid( INDEXID iid ) { _iid = iid; }
void SetType( ULONG type ) { _type = type | _indFile.GetStorageVersion(); }
void SetWid( WORKID maxWorkId ) { _maxWorkId = maxWorkId; }
void SetObjectId ( WORKID objectId )
{
_objectId = objectId;
}
inline BOOL Found() { return _found; }
void WriteRecord();
private:
BOOL _found;
CWriteIndexFile & _indFile;
};
//+---------------------------------------------------------------------------
//
// Class: CIndexTable
//
// Purpose: Manages Indexes.
// Contains the table of persistent indexes
// and partitions.
//
// History: 22-Mar-91 BartoszM Created.
// 07-Mar-92 AmyA -> FAT
//
//----------------------------------------------------------------------------
class CIndexTable : public PIndexTable
{
friend class CIndexTabIter;
public:
CIndexTable ( CiStorage& storage, CTransaction& xact );
~CIndexTable();
void AddObject( PARTITIONID partid, IndexType it, WORKID wid );
void AddMMergeObjects( PARTITIONID partid,
CIndexRecord & recNewMaster,
WORKID widMMLog,
WORKID widMMKeyList,
INDEXID iidDelOld,
INDEXID iidDelNew );
void DeleteObject( PARTITIONID partid, IndexType it, WORKID wid );
virtual void SwapIndexes ( CShadowMergeSwapInfo & info );
virtual void SwapIndexes ( CMasterMergeSwapInfo & info );
PIndexTabIter* QueryIterator();
PStorage& GetStorage();
void RemoveIndex ( INDEXID iid );
void AddIndex( INDEXID iid, IndexType it, WORKID maxWid, WORKID objId);
void LokEmpty();
virtual void LokMakeBackupCopy( PStorage & storage,
BOOL fFullSave,
PSaveProgressTracker & tracker );
void GetUserHdrInfo( unsigned & mMergeSeqNum, BOOL & fFullSave );
private:
void AddRecord( CWriteIndexFile & indFile,
INDEXID iid,
ULONG type,
WORKID maxWorkId,
WORKID objectId );
void DeleteRecord ( CWriteIndexFile & indFile, INDEXID iid );
void DeleteObject ( CWriteIndexFile & indFile, PARTITIONID partid,
IndexType it, WORKID wid );
PRcovStorageObj & GetIndexTableObj()
{
return *_pRcovObj;
}
CiStorage& _storage;
PRcovStorageObj * _pRcovObj;
};
//
// This has to be an unwindable object it has CReadIndexFile
// as an embedded object which is unwindable.
//
class CIndexTabIter: public PIndexTabIter
{
public:
CIndexTabIter ( CIndexTable& idxTable );
virtual ~CIndexTabIter();
BOOL Begin();
BOOL NextRecord ( CIndexRecord& record );
private:
PStorage & GetStorage() { return _idxTable._storage; }
CIndexTable& _idxTable;
CReadIndexFile _indFile;
};
//+---------------------------------------------------------------------------
//
// Member: CIndexTable::DeleteRecord, private
//
// Synopsis: Marks current record as deleted
//
// History: 12-Mar-92 AmyA Created.
//
//----------------------------------------------------------------------------
inline void CIndexTable::DeleteRecord ( CWriteIndexFile & indFile, INDEXID iid )
{
CAddReplaceIndexRecord rec( indFile, iid );
if ( rec.Found() )
{
rec.SetIid( CIndexId(iidInvalid, partidInvalid) );
rec.WriteRecord();
}
}