|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1998.
//
// File: mmerglog.hxx
//
// Contents: Master Log manipulation class.
//
// Classes: CMMergeLog, CNewMMergeLog, CMMergeIdxListIter
//
// Functions:
//
// History: 3-30-94 srikants Created
//
// Note : The Primary/Backup Streams in the master log have the
// following format.
//
// 4 Bytes - sigIdxList ("MMIL")
// 4 Bytes - Number of shadow indexes participating in the
// master merge.
// 4n Bytes- Where n is the number of shadow indexes in the
// master merge.
//
// This will be the index split key.
//
// 4 Bytes - sigSplitKey ("MMSK")
// 4 Bytes - Number of valid bytes in the SplitKey.
// MAXKEYSIZE Bytes - The index SplitKey.
// 4 Bytes - Property Id of the SplitKey.
// 4 Bytes - PageNumber
// 4 Bytes - Offset within Page Number
//
// This will be the keylist split key.
//
// 4 Bytes - sigSplitKey("MMSK")
// 4 Bytes - Number of valid bytes in the SplitKey.
// MAXKEYSIZE Bytes - The keylist SplitKey.
// 4 Bytes - Property id of the split key.
// 4 Bytes - PageNumber
// 4 Bytes - Offset within Page Number
//
//----------------------------------------------------------------------------
#pragma once
#include <prcstob.hxx>
#include <idxids.hxx>
#include <rcstxact.hxx>
#include <bitoff.hxx>
#ifndef OFFSET
#define OFFSET( CClass, mem ) ((int) (ULONG_PTR)&((CClass *)0)->mem)
#endif // OFFSET
#include <pshpack4.h>
//+---------------------------------------------------------------------------
//
// Class: CMMergeLogHdr
//
// Purpose: Header information stored in the user header portion of
// the MasterMergeLog.
//
// History: 3-31-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
class CMMergeLogHdr { enum { sigHdr = 0x44484d4d }; // "MMHD" in ascii.
public:
void Init() { _sigHdr1 = _sigHdr2 = sigHdr; _cShadowIndex = _oSplitKey = 0; _widMaxIndex = _widMaxKeyList = widInvalid; }
ULONG GetShadowIndexCount() const { return _cShadowIndex; } void SetShadowIndexCount( ULONG cShadowIndex ) { _cShadowIndex = cShadowIndex; }
ULONG GetSplitKeyOffset() const { return _oSplitKey; } void SetSplitKeyOffset( ULONG oSplitKey ) { _oSplitKey = oSplitKey; }
BOOL IsValid() { return _sigHdr1 == sigHdr && _sigHdr2 == sigHdr ; }
WORKID GetIndexWidMax() const { return _widMaxIndex; } void SetIndexWidMax( WORKID widMax ) { _widMaxIndex = widMax; }
WORKID GetKeyListWidMax() const { return _widMaxKeyList; } void SetKeyListWidMax( WORKID widMax ) { _widMaxKeyList = widMax; }
private:
ULONG _sigHdr1; // Signature - must be sigHdr
ULONG _cShadowIndex; // Number of shadow indexes in the merge.
ULONG _oSplitKey; // Offset of the split key in the stream.
ULONG _sigHdr2; // Signature - must be sigHdr
ULONG _widMaxIndex; // Maximum workid in the new index.
ULONG _widMaxKeyList; // Maximum workid in the key list.
};
DECL_DYNARRAY_INPLACE( CIndexIdArray, CIndexId );
class CMMergeLog;
//+---------------------------------------------------------------------------
//
// Class: CMMergeIndexList
//
// Purpose: Class for managing the list of indexes participating in a
// master merge.
//
// History: 3-31-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
class CMMergeIndexList { enum { sigIdxList = 0x4c494d4d }; // "MMIL" in ascii.
public:
CMMergeIndexList( ULONG cShadowIndex = 64 );
void Serialize( CRcovStrmWriteTrans & trans ); void DeSerialize( CRcovStrmReadTrans & trans, PRcovStorageObj & obj );
void AddIndex( CIndexId & iid );
ULONG GetShadowIndexCount() const { return _cShadowIndex; } BOOL GetIndex( CIndexId & iid, ULONG nIdx );
ULONG GetValidLength() const { return( OFFSET(CMMergeIndexList, _aShadowIndex) + _cShadowIndex * sizeof(CIndexId) ); }
private:
ULONG _sigIdxList; // Must be sigIdxList.
ULONG _cShadowIndex; // Count of the number of shadow indixes.
CIndexIdArray _aShadowIndex; // Array of shadow indexes.
};
//+---------------------------------------------------------------------------
//
// Class: CMMergeSplitKey
//
// Purpose: Class for managing the "SplitKey" in the Master Log.
//
// History: 3-31-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
class CMMergeSplitKey { enum { sigSplitKey = 0x4b534d4d }; // "MMSK" in ascii.
public:
CMMergeSplitKey() { _sigSplitKey = sigSplitKey; _cbKey = 0; _pid = 0; _bitOffBegin.Init(0,0); _bitOffEnd.Init(0,0); }
void GetKey( CKeyBuf & key );
void GetOffset( BitOffset & bitOffBegin, BitOffset & bitOffEnd ) { bitOffBegin = _bitOffBegin; bitOffEnd = _bitOffEnd; }
void SetKey( const CKeyBuf & key );
void SetOffset( const BitOffset & bitOffBegin, const BitOffset & bitOffEnd ) { _bitOffBegin = bitOffBegin; _bitOffEnd = bitOffEnd; }
ULONG GetCount() { return _cbKey; }
BOOL IsValid() { return sigSplitKey == _sigSplitKey; }
private:
ULONG _sigSplitKey; ULONG _cbKey; BYTE _buf[MAXKEYSIZE]; PROPID _pid; BitOffset _bitOffBegin; BitOffset _bitOffEnd; };
inline void CMMergeSplitKey::GetKey( CKeyBuf & key ) { key.SetCount( _cbKey ); key.SetPid( _pid ); ciAssert( _cbKey <= MAXKEYSIZE ); memcpy( key.GetWritableBuf(), _buf, _cbKey ); }
inline void CMMergeSplitKey::SetKey( const CKeyBuf & key ) { _pid = key.Pid(); _cbKey = key.Count(); ciAssert( _cbKey <= MAXKEYSIZE ); memcpy( _buf, key.GetBuf(), _cbKey ); }
#include <poppack.h>
//+---------------------------------------------------------------------------
//
// Class: CNewMMergeLog
//
// Purpose: Class used to create a new Master Log before starting a
// master merge.
//
// History: 3-31-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
class CNewMMergeLog { public:
CNewMMergeLog( PRcovStorageObj & obj ); ~CNewMMergeLog();
void AddPersistentIndex( CIndexId & iid ) { _shadowIdxList.AddIndex( iid ); }
void SetKeyListWidMax( WORKID widMax ) { _widMaxKeyList = widMax; } void SetIndexWidMax( WORKID widMax ) { _widMaxIndex = widMax; } void Commit() { _fCommit = TRUE; } void DoCommit();
private:
BOOL _fCommit; PRcovStorageObj & _objMMLog; CRcovStrmWriteTrans _trans; CMMergeIndexList _shadowIdxList; WORKID _widMaxKeyList; WORKID _widMaxIndex;
void SerializeIndexList(); void AppendEmptySplitKeys(); void WriteHeader();
};
//+---------------------------------------------------------------------------
//
// Class: CMMergeLog
//
// Purpose: The Master Merge Log class used during master merge to
// manage serializing/de-serializing the split key.
//
// History: 3-31-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
const LONGLONG eSigMMergeLog = 0x474f4c4752454d4di64; // "MMERGLOG"
class CMMergeLog {
public:
CMMergeLog( PRcovStorageObj & objMMLog );
void GetIdxSplitKeyInfo( CKeyBuf & splitKey, BitOffset & bitOffBegin, BitOffset & bitOffEnd ) { _idxSplitKey.GetKey( splitKey ); _idxSplitKey.GetOffset( bitOffBegin, bitOffEnd ); }
WORKID GetIndexWidMax() const { return _widMaxIndex; }
void SetIdxSplitKeyInfo( const CKeyBuf & splitKey, const BitOffset & bitOffBegin, const BitOffset & bitOffEnd ) { _idxSplitKey.SetKey( splitKey ); _idxSplitKey.SetOffset( bitOffBegin, bitOffEnd );
ciDebugOut(( DEB_ITRACE, "Current split key is '%ws'\n", splitKey.GetStr() )); }
void SetIndexWidMax( WORKID widMax ) { _widMaxIndex = widMax; }
void GetKeyListSplitKeyInfo( CKeyBuf & splitKey, BitOffset & bitOffBegin, BitOffset & bitOffEnd ) { _keylstSplitKey.GetKey(splitKey); _keylstSplitKey.GetOffset(bitOffBegin, bitOffEnd ); }
WORKID GetKeyListWidMax() const { return _widMaxKeyList; }
void SetKeyListSplitKeyInfo( const CKeyBuf & splitKey, const BitOffset & bitOffBegin, const BitOffset & bitOffEnd ) { _keylstSplitKey.SetKey( splitKey ); _keylstSplitKey.SetOffset( bitOffBegin, bitOffEnd ); }
void SetKeyListWidMax( WORKID widMax ) { _widMaxKeyList = widMax; }
void CheckPoint();
#ifdef CIEXTMODE
void CiExtDump(void *ciExtSelf); #endif
private:
const LONGLONG _sigMMergeLog;
PRcovStorageObj & _objMMLog; // MasterMerge Log Object.
CMMergeSplitKey _idxSplitKey; // The "SplitKey" between the current
// master and the old master.
CMMergeSplitKey _keylstSplitKey; // Split key for the key list.
WORKID _widMaxIndex; // Maximum workid in the new index.
WORKID _widMaxKeyList; // Maximum workid in the key list
};
//+---------------------------------------------------------------------------
//
// Class: CMMergeIdxListIter
//
// Purpose: Iterator to iterate through the list of participating
// shadow indexes in the master merge.
//
// History: 3-31-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
class CMMergeIdxListIter { public:
CMMergeIdxListIter( PRcovStorageObj & objMMLog );
BOOL Found( CIndexId & iid ); ULONG Count() { return _shadowIdxList.GetShadowIndexCount(); }
BOOL AtEnd() { return _curr >= _shadowIdxList.GetShadowIndexCount(); }
void GetIndex( CIndexId & iid ); void Advance() { _curr++; } void GetFirstIndex( CIndexId & iid ) { _curr = 0; GetIndex( iid ); }
private:
ULONG _curr; // The current index being returned.
PRcovStorageObj & _objMMLog; // Recoverable storage object.
CRcovStrmReadTrans _trans; // Read transaction.
CMMergeIndexList _shadowIdxList; // The list of shadow indexes.
};
inline void CMMergeIdxListIter::GetIndex( CIndexId & iid ) { Win4Assert( !AtEnd() ); _shadowIdxList.GetIndex( iid, _curr ); }
|