Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

371 lines
8.9 KiB

//+-------------------------------------------------------------------------
//
// 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;
};