//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 2000. // // File: tableseg.hxx // // Contents: CTableSegment class declaration // // Classes: // // Functions: // // History: 1-16-95 srikants Moved from bigtable.hxx // //---------------------------------------------------------------------------- #pragma once #include #include #include #include #include //+------------------------------------------------------------------------- // // Class: CNotificationSync // // Purpose: Synchronization information for notifications. // //-------------------------------------------------------------------------- class CRequestServer; class CNotificationSync { public: CNotificationSync( HANDLE hEvent ) : _hCancelEvent( hEvent ), _pServer( 0 ) {} CNotificationSync( CRequestServer *pServer ) : _hCancelEvent( 0 ), _pServer( pServer ) {} HANDLE GetCancelEvent() { Win4Assert( 0 == _pServer ); return _hCancelEvent; } BOOL IsSvcMode() { return 0 != _pServer; } CRequestServer * GetRequestServer() { Win4Assert( 0 == _hCancelEvent ); return _pServer; } private: HANDLE _hCancelEvent; CRequestServer * _pServer; }; //+------------------------------------------------------------------------- // // Class: CNotificationParams // // Purpose: Bundles the notification parameters so they are easy to // pass from place to place. // //-------------------------------------------------------------------------- enum ENotifyType { notifyAdd, notifyDelete, notifyModify }; class CNotificationParams { public: CNotificationParams() { memset(_acRows,0,sizeof _acRows); memset(_apRows,0,sizeof _apRows); } ~CNotificationParams() { delete _apRows[notifyAdd]; delete _apRows[notifyDelete]; delete _apRows[notifyModify]; } CI_TBL_BMK * GetRows(ENotifyType type) { return _apRows[type]; } void SetRows(ENotifyType type,CI_TBL_BMK * p) { _apRows[type] = p; } ULONG GetCount(ENotifyType type) { return _acRows[type]; } void SetCount(ENotifyType type, ULONG c) { _acRows[type] = c; } ULONG IncrementCount(ENotifyType type) { return _acRows[type]++; } BOOL AnyNotifications() { return 0 != _acRows[notifyAdd] || 0 != _acRows[notifyDelete] || 0 != _acRows[notifyModify]; } void Marshall(CNotificationParams &rFrom) { memcpy(_acRows,rFrom._acRows,sizeof _acRows); } void UnMarshall(CNotificationParams &rFrom) { Marshall(rFrom); } ULONG MarshalledSize() { return sizeof CNotificationParams; } void Resize(ENotifyType type,ULONG cNew) { _apRows[type] = renewx(_apRows[type], _acRows[type], _acRows[type] + cNew); } void SetHROW(ENotifyType type,ULONG index,CI_TBL_BMK hrow) { _apRows[type][index] = hrow; } private: ULONG _acRows[3]; CI_TBL_BMK * _apRows[3]; }; // // Forward declaration of classes // class CQueryIterator; class CRetriever; class CTableCursor; class CTableSegIter; class CTableWindow; class CGetRowsParams; //+--------------------------------------------------------------------------- // // Class: CTableSource // // Purpose: Abstract base class for a source of rows from the bigtable // categorization tables // // History: 3-20-95 srikants Created (Split from CTableSegment) // // Notes: // //---------------------------------------------------------------------------- class CTableSource { public: CTableSource() : _fFwdFetchPrev( TRUE ), _fFirstGetNextRows( TRUE ) { } virtual SCODE GetRows( HWATCHREGION hRegion, WORKID widStart, CI_TBL_CHAPT chapt, CTableColumnSet const & rOutColumns, CGetRowsParams & rGetParams, WORKID& rwidNextRowToTransfer ) = 0; virtual SCODE GetRowsAt( HWATCHREGION hRegion, WORKID widStart, CI_TBL_CHAPT chapt, DBROWOFFSET cRowsToMove, CTableColumnSet const & rOutColumns, CGetRowsParams & rGetParams, WORKID & rwidLastRowTransferred ) = 0; virtual SCODE GetRowsAtRatio( HWATCHREGION hRegion, ULONG num, ULONG denom, CI_TBL_CHAPT chapt, CTableColumnSet const & rOutColumns, CGetRowsParams & rGetParams, WORKID & rwidLastRowTransferred ) = 0; virtual SCODE GetApproximatePosition( CI_TBL_CHAPT chapt, CI_TBL_BMK bmk, DBCOUNTITEM * pulNumerator, DBCOUNTITEM * pulDenominator) = 0; virtual void RestartPosition ( CI_TBL_CHAPT chapt ) { _fFwdFetchPrev = TRUE; _fFirstGetNextRows = TRUE; } virtual void LokGetOneColumn( WORKID wid, CTableColumn const & rOutColumn, BYTE * pbOut, PVarAllocator & rVarAllocator ) { Win4Assert(!"Never called!"); } virtual WORKID GetCurrentPosition( CI_TBL_CHAPT chapt ) = 0; virtual WORKID SetCurrentPosition( CI_TBL_CHAPT chapt, WORKID wid ) = 0; BOOL GetFwdFetchPrev() { return _fFwdFetchPrev; } void SetFwdFetchPrev( BOOL fFwdFetch) { _fFwdFetchPrev = fFwdFetch; } BOOL IsFirstGetNextRows() { return _fFirstGetNextRows; } void ResetFirstGetNextRows() { _fFirstGetNextRows = FALSE; } private: BOOL _fFwdFetchPrev; // Fetch direction of previous GetNextRows call BOOL _fFirstGetNextRows; // Is this the first GetNextRows call ? }; //+--------------------------------------------------------------------------- // // Class: CCompareResult () // // Purpose: To hold the result of a comparison of a row with a segment. // (For CompareRange). // // History: 3-20-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- class CCompareResult { public: enum ECompareResult { eInRange, eLesser, eGreater, eUnknown }; CCompareResult( ECompareResult rslt = eUnknown ) : _rslt(rslt) {} ECompareResult Get() const { return _rslt; } int GetComp() const { return _iComp; } void Set( ECompareResult rslt ) { _rslt = rslt; } void Set( int iComp ) { _iComp = iComp; if ( 0 == iComp ) { _rslt = eInRange; } else if ( iComp > 0 ) { _rslt = eGreater; } else { _rslt = eLesser; } } BOOL IsUnknown() const { return eUnknown == _rslt; } BOOL IsEQ() const { return eInRange == _rslt ; } BOOL IsGT() const { return eGreater == _rslt; } BOOL IsLT() const { return eLesser == _rslt; } BOOL IsLE() const { return eLesser == _rslt || eInRange == _rslt; } BOOL IsGE() const { return eGreater == _rslt || eInRange == _rslt; } BOOL IsNE() const { return eInRange != _rslt; } private: ECompareResult _rslt; int _iComp; }; //+--------------------------------------------------------------------------- // // Class: CTableSegment // // Purpose: Base class for a segment in the bigtable. // // History: 3-20-95 srikants Created ( Split into CTableSource and // CTableSegment ) // // Notes: // //---------------------------------------------------------------------------- class CTableSegment: public CDoubleLink, public CTableSink { public: enum ETableSegType { eWindow, eBucket, eLargeTable }; CTableSegment( ETableSegType eType, ULONG segId, const CSortSet & sortSet, CTableKeyCompare & comparator) : _type(eType), _segId(segId), _refCount(0), _fZombie(0), _lowKey(sortSet), _highKey(sortSet), _comparator(comparator) { _next = _prev = 0; } CTableSegment( CTableSegment & src, ULONG segId ) :_type(src._type), _segId(segId), _refCount(0), _fZombie(0), _lowKey( src._lowKey.GetSortSet() ), _highKey( src._highKey.GetSortSet() ), _comparator(src._comparator) { _next = _prev = 0; } virtual ~CTableSegment() { Win4Assert( ! InUse() ); } virtual BOOL PutRow( CRetriever & obj, CTableRowKey & currKey ) = 0; virtual DBCOUNTITEM RowCount() = 0; // // Column manipulation // virtual BOOL RowOffset(WORKID wid, ULONG& riRow) { Win4Assert( !"Should not be called\n" ); return FALSE; } // // Row Deletions. // virtual void RemoveRow( PROPVARIANT const & varUnique ) { Win4Assert( !"Must Not Be Called" ); } virtual BOOL RemoveRow( PROPVARIANT const & varUnique, WORKID & widNext, CI_TBL_CHAPT & chapt ) = 0; // // Sort related methods. // virtual BOOL IsRowInSegment( WORKID wid ) = 0; ETableSegType GetSegmentType() const { return _type; } BOOL IsWindow() const { return eWindow == _type; } BOOL IsBucket() const { return eBucket == _type; } ULONG GetSegId() const { return _segId; } virtual BOOL IsEmptyForQuery() = 0; virtual BOOL IsGettingFull() = 0; virtual BOOL IsSortedSplit( ULONG & riSplit ) = 0; BOOL InUse() const { return 0 != _refCount; } void Reference() { _refCount++; } void Release() { Win4Assert( _refCount > 0 ); _refCount--; } BOOL IsZombie() const { return _fZombie; } void Zombify() { _fZombie = TRUE; } CTableRowKey & GetLowestKey() { return _lowKey; } CTableRowKey & GetHighestKey() { return _highKey; } #ifdef CIEXTMODE void CiExtDump(void *ciExtSelf); #endif protected: ETableSegType _type; const ULONG _segId; unsigned _refCount; BOOL _fZombie; CTableRowKey _lowKey; // Lowest row in this segment CTableRowKey _highKey; // Highest row in this segment CTableKeyCompare & _comparator; // Comparator }; //+--------------------------------------------------------------------------- // // Class: CTableSegRef // // Purpose: A class to automatically de-reference the table segment // if there is a failure. // // History: 3-09-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- class CTableSegRef { public: CTableSegRef( CTableSegment * pTableSeg = 0 ) : _pTableSeg(pTableSeg) { } ~CTableSegRef() { if ( _pTableSeg ) { _pTableSeg->Release(); } } void Set( CTableSegment * pTableSeg ) { Win4Assert( 0 == _pTableSeg ); _pTableSeg = pTableSeg; } CTableSegment * Get() { return _pTableSeg; } CTableSegment * Transfer() { CTableSegment * pTemp = _pTableSeg; _pTableSeg = 0; return pTemp; } private: CTableSegment * _pTableSeg; }; class CTableBucket; typedef XPtr XTableSegment;