//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1991 - 1992. // // File: PINDEX.HXX // // Contents: Persistent Index // // Classes: CPersIndex // // History: 3-Apr-91 BartoszM Created stub. // //---------------------------------------------------------------------------- #pragma once #include "dindex.hxx" class PStorage; class CFreshTest; class PDirectory; class COccCurStack; class CRSemiInfinitePage; class CIndexSnapshot; class CIndexRecord; class CWKeyList; class CKeyList; //+--------------------------------------------------------------------------- // // Class: CPersIndex (pi) // // Purpose: Encapsulate directory and give access to pages // // Interface: // // History: 20-Apr-91 KyleP Added Merge method // 03-Apr-91 BartoszM Created stub. // //---------------------------------------------------------------------------- const LONGLONG eSigPersIndex = 0x58444e4953524550i64; // "PERSINDX" class CPersIndex : public CDiskIndex { friend class CMasterMergeIndex; friend class CMasterMergeIndex; public: // new index from scratch CPersIndex( PStorage & storage, WORKID objectId, INDEXID iid, unsigned c4KPages, CDiskIndex::EDiskIndexType idxType ); CPersIndex( PStorage & storage, WORKID objectId, INDEXID iid, WORKID widMax, CDiskIndex::EDiskIndexType idxType, PStorage::EOpenMode mode, BOOL fReadDir ); void Remove(); void Merge( CIndexSnapshot& indSnap, const CPartition & partn, CCiFrmPerfCounter & mergeProgress, BOOL fGetRW ); CKeyCursor * QueryCursor(); CKeyCursor * QueryKeyCursor(const CKey * pKey); // // From CQueriable // COccCursor * QueryCursor( const CKey * pkey, BOOL isRange, ULONG & cMaxNodes ); COccCursor * QueryRangeCursor( const CKey * pkey, const CKey * pkeyEnd, ULONG & cMaxNodes ); COccCursor * QuerySynCursor( CKeyArray & keyArr, BOOL isRange, ULONG & cMaxNodes ); unsigned Size () const; WORKID ObjectId() const { return _xPhysIndex->ObjectId(); } void FillRecord ( CIndexRecord& record ); inline void AbortMerge(); void ClearAbortMerge() { _fAbortMerge = FALSE; } #ifdef KEYLIST_ENABLED CRWStore * ComputeRelevantWords(ULONG cRows,ULONG cRW,WORKID *pwid, CKeyList *pkl); CRWStore * AcquireRelevantWords(); #endif // KEYLIST_ENABLED CPhysIndex & GetIndex() { return _xPhysIndex.GetReference(); } #ifdef CIEXTMODE void CiExtDump(void *ciExtSelf); #endif virtual void MakeBackupCopy( PStorage & storage, WORKID wid, PSaveProgressTracker & tracker ); protected: PDirectory & GetDirectory() { return _xDir.GetReference(); } SStorageObject & GetObj() { return _obj; } void CreateRange( COccCurStack & curStk, const CKey * pkey, const CKey * pkeyEnd, ULONG & cMaxNodes ); ULONG ShrinkFromFront( ULONG ulFirstPage, ULONG ulNumPages ) { if ( _storage.SupportsShrinkFromFront() ) return _xPhysIndex->ShrinkFromFront( ulFirstPage, ulNumPages); return 0; } const LONGLONG _sigPersIndex; XPtr _xDir; XPtr _xPhysIndex; PStorage & _storage; SStorageObject _obj; BOOL _fAbortMerge; }; //+------------------------------------------------------------------------- // // Member: CPersIndex::AbortMerge, public // // Synopsis: Sets flag to abort merge in 'reasonably short time' // // History: 13-Aug-93 KyleP Created // // Notes: Although the _fAbortMerge flag is accessed w/o lock // from multiple threads there's no contention problem. It's // a boolean flag and if we miss the set on one pass we'll // get it on the next. // //-------------------------------------------------------------------------- inline void CPersIndex::AbortMerge() { _fAbortMerge = TRUE; } //+--------------------------------------------------------------------------- // // Class: CMergeSourceCursor // // Purpose: Smart pointer to a merge cursor // // History: 29-Aug-92 BartoszM Created // //---------------------------------------------------------------------------- class CMergeSourceCursor { public: CMergeSourceCursor ( CIndexSnapshot & indSnap, const CKeyBuf * pKey = 0 ); CMergeSourceCursor ( CKeyCursor * pCurSrc ) : _pCurSrc(pCurSrc) {} ~CMergeSourceCursor (); BOOL IsEmpty() const { return 0 == _pCurSrc; } CKeyCursor* operator->() { return(_pCurSrc); } CKeyCursor* Acquire() { CKeyCursor * pTemp = _pCurSrc; _pCurSrc = 0; return pTemp; } private: CKeyCursor* _pCurSrc; }; //+-------------------------------------------------------------------------- // // Class: CPersIndexCursor // // Purpose: Smart pointer to a persistent index key cursor // // History: 17-Jun-94 dlee Created // //--------------------------------------------------------------------------- class CPersIndexCursor { public: CPersIndexCursor(CPersIndex *pIndex) : _pCursor(0) { _pCursor = pIndex->QueryCursor(); } ~CPersIndexCursor() { delete _pCursor; } CKeyCursor* operator->() { return(_pCursor); } private: CKeyCursor *_pCursor; }; //+-------------------------------------------------------------------------- // // Class: CSetReadAhead // // Purpose: Sets the hint in the storage object to favor read-ahead // when appropriate, then revert to the original state. // // History: 4-Nov-98 dlee Created // //--------------------------------------------------------------------------- class CSetReadAhead { public: CSetReadAhead( PStorage & storage ) : _storage( storage ), _fOldValue( storage.FavorReadAhead() ) { _storage.SetFavorReadAhead( TRUE ); } ~CSetReadAhead() { _storage.SetFavorReadAhead( _fOldValue ); } private: PStorage & _storage; BOOL _fOldValue; };