372 lines
8.6 KiB
C++
372 lines
8.6 KiB
C++
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// 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 <tableseg.hxx>
|
||
|
#include <compare.hxx>
|
||
|
#include <widiter.hxx>
|
||
|
#include <tblrowal.hxx> // 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<WORKID> _widArray;
|
||
|
|
||
|
CDynArrayInPlace<LONG> _aRank;
|
||
|
BOOL _fStoreRank;
|
||
|
CDynArrayInPlace<LONG> _aHitCount;
|
||
|
BOOL _fStoreHitCount;
|
||
|
|
||
|
//
|
||
|
// Hash table used to look up workids in this bucket.
|
||
|
//
|
||
|
TWidHashTable<CWidValueHashEntry> _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<WORKID> & _widArray;
|
||
|
CDynArrayInPlace<LONG> & _aRank;
|
||
|
CDynArrayInPlace<LONG> & _aHitCount;
|
||
|
|
||
|
CTableBucket & _bucket;
|
||
|
|
||
|
enum { cbPathVarnt = sizeof(CTableVariant) + (MAX_PATH+1)*sizeof(WCHAR) };
|
||
|
|
||
|
BYTE _abPathVarnt[cbPathVarnt];
|
||
|
CInlineVariant & _pathVarnt;
|
||
|
BOOL _fRetrievePath;
|
||
|
ULONG _cwcCurrPath;
|
||
|
WCHAR * _pwszPath;
|
||
|
};
|
||
|
|