//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1995 - 2000. // // File: tblbuket.cxx // // Contents: Implementation of the bucket in large table. // // Classes: CTableBucket // CBucketRowIter // // History: 2-14-95 srikants Created // //-------------------------------------------------------------------------- #pragma once #include #include #include #include // for CTableRowAlloc #include "bmkmap.hxx" // for Book Mark Mapping class CQuickBktCompare; class CTableWindow; class CLargeTable; //+--------------------------------------------------------------------------- // // Class: CRowLocateInfo // // Purpose: A class that gets the location of a row in a segment. This // is used while locating a row in a bucket. // // History: 4-20-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- class CRowLocateInfo { friend class CTableBucket; public: CRowLocateInfo( WORKID widStart, LONG cRowsToMove ) : _widStart(widStart), _cRowsToMove(cRowsToMove), _cRowsResidual(LONG_MAX), _widOut(widInvalid), _rowOffset(ULONG_MAX) { } WORKID WidStart() const { return _widStart; } LONG RowsToMove() const { return _cRowsToMove; } BOOL IsFound() const { return 0 == _cRowsResidual && WORKID_TBLBEFOREFIRST != _widOut && WORKID_TBLAFTERLAST != _widOut; } WORKID WorkIdFound() const { return _widOut; } ULONG WorkIdOffset() const { return _rowOffset; } LONG ResidualRowCount() const { return _cRowsResidual; } void SetLookInNext( LONG cRowsLeft ) { _cRowsResidual = cRowsLeft; _widOut = WORKID_TBLAFTERLAST; } void SetLookInPrev( LONG cRowsLeft ) { _cRowsResidual = cRowsLeft; _widOut = WORKID_TBLBEFOREFIRST; } void SetRowFound( ULONG rowOffset, WORKID widFound ) { _cRowsResidual = 0; _widOut = widFound; _rowOffset = rowOffset; } void SetAll( WORKID widOut, LONG rowsResidual, ULONG rowOffset = ULONG_MAX ) { _widOut = widOut; _cRowsResidual = rowsResidual; _rowOffset = rowOffset; } private: // // Inputs to the search. // const WORKID _widStart; const LONG _cRowsToMove; // // Output from the search. // LONG _cRowsResidual; WORKID _widOut; ULONG _rowOffset; }; //+------------------------------------------------------------------------- // // Class: CTableBucket // // Purpose: A segment of a large table which only has an identifier // for each row buffered in memory. // It must be converted to a window before it can be // transferred to the user. // // Interface: // //-------------------------------------------------------------------------- class CTableBucket : public CTableSegment { friend class CBucketRowIter; friend class CBucketizeWindows; friend class CLargeTable; public: CTableBucket( const CSortSet & sortSet, CTableKeyCompare & comparator, CColumnMasterSet & masterColSet, ULONG segId ) ; // Virtual methods inherited from CTableSegment BOOL PutRow( CRetriever & obj, CTableRowKey & currKey ); DBCOUNTITEM RowCount() { return _hTable.Count(); } SCODE GetRows( WORKID widStart, CTableColumnSet const & rOutColumns, CGetRowsParams& rGetParams, WORKID& rwidNextRowToTransfer ); // // Sort related methods. // BOOL IsRowInSegment( WORKID wid ) { return _hTable.IsWorkIdPresent( wid ); } // // Notification methods // SCODE GetNotifications(CNotificationParams &Params) { return S_OK; } BOOL IsEmptyForQuery() { return 0 == _hTable.Count(); } BOOL IsGettingFull(); // Virtual methods inherited from CTableSink BOOL IsSortedSplit( ULONG & riSplit ) { return FALSE; } WORKID PathToWorkID( CRetriever & obj, CTableSink::ERowType eRowType ) { Win4Assert( !"Should not be called\n" ); return widInvalid; } BOOL WorkIdToPath( WORKID wid, CInlineVariant & pathVarnt , ULONG & cbVarnt ); void SetLargeTable( CLargeTable * pLargeTable ) { _pLargeTable = pLargeTable; } BOOL PutRow( CRetriever & obj, CTableSink::ERowType eRowType ) { Win4Assert( !"Must not be called" ); return FALSE; } BOOL RemoveRow( PROPVARIANT const & varUnique, WORKID & widNext, CI_TBL_CHAPT & chapt ); // // Sort order // CSortSet const & SortOrder(); BOOL IsSorted() const { return _fSorted; } WORKID WorkIdAtOffset( ULONG offset ) const; BOOL RowOffset( WORKID wid, ULONG & rOffset ); #ifdef CIEXTMODE void CiExtDump(void *ciExtSelf); #endif private: WORKID _minWid, _maxWid; // range of work IDs in table segment BOOL _fSorted; // Set to TRUE if we know for sure // if the wids are in sorted order. // // Array of workids that belong to this bucket. They are stored in the // same order as they are added. This way if a bucket never gets new // rows, we can be sure that it is still sorted. // CDynArrayInPlace _widArray; CDynArrayInPlace _aRank; BOOL _fStoreRank; CDynArrayInPlace _aHitCount; BOOL _fStoreHitCount; // // Hash table used to look up workids in this bucket. // TWidHashTable _hTable; // // For downlevel Wid->Path translation // CCompressedCol * _pPathCompressor; CLargeTable * _pLargeTable; BOOL _AddWorkId( WORKID wid, LONG lRank, LONG lHitCount ); #if DBG==1 void _CheckIfTooBig(); #endif // DBG==1 }; //+--------------------------------------------------------------------------- // // Class: CBucketRowIter // // Purpose: Iterator over wids in a bucket. // // History: 2-17-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- class CBucketRowIter : public PWorkIdIter { public: CBucketRowIter( CTableBucket & bkt, BOOL fRetrievePath ) : _curr(0), _widArray( bkt._widArray ), _aRank( bkt._aRank ), _aHitCount( bkt._aHitCount ), _bucket(bkt), _pathVarnt( * ((CInlineVariant *)&_abPathVarnt[0]) ), _fRetrievePath(fRetrievePath), _cwcCurrPath(0), _pwszPath( (WCHAR *) _pathVarnt.GetVarBuffer() ) {} WORKID WorkId(); // virtual WORKID NextWorkId(); // virtual LONG Rank() { if ( 0 != _aRank.Count() ) { Win4Assert( _curr < _aRank.Count() ); return _aRank[ _curr ]; } else { return MAX_QUERY_RANK; } } LONG HitCount() { if ( 0 != _aHitCount.Count() ) { Win4Assert( _curr < _aHitCount.Count() ); return _aHitCount[ _curr ]; } else { return 0; } } WCHAR const * Path(); // virtual unsigned PathSize(); // virtual private: BOOL _AtEnd() const { Win4Assert( _curr <= _widArray.Count() ); return _curr == _widArray.Count(); } WORKID _Get() { Win4Assert( _curr < _widArray.Count() ); return _widArray.Get( _curr ); } void _Next() { _curr++; } unsigned _curr; CDynArrayInPlace & _widArray; CDynArrayInPlace & _aRank; CDynArrayInPlace & _aHitCount; CTableBucket & _bucket; enum { cbPathVarnt = sizeof(CTableVariant) + (MAX_PATH+1)*sizeof(WCHAR) }; BYTE _abPathVarnt[cbPathVarnt]; CInlineVariant & _pathVarnt; BOOL _fRetrievePath; ULONG _cwcCurrPath; WCHAR * _pwszPath; };