windows-nt/Source/XPSP1/NT/inetsrv/query/h/tableseg.hxx
2020-09-26 16:20:57 +08:00

470 lines
12 KiB
C++

//+---------------------------------------------------------------------------
//
// 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 <tblsink.hxx>
#include <querydef.hxx>
#include <coldesc.hxx>
#include <tablecol.hxx>
#include <tbrowkey.hxx>
//+-------------------------------------------------------------------------
//
// 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<CTableSegment> XTableSegment;