470 lines
12 KiB
C++
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;
|
|
|