280 lines
6.4 KiB
C++
280 lines
6.4 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation 1995 - 1998
|
|
//
|
|
// File: RowMan.hxx
|
|
//
|
|
// Contents: Distributed HROW manager.
|
|
//
|
|
// Classes: CHRowManager
|
|
//
|
|
// History: 05-Jun-95 KyleP Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CHRowManager
|
|
//
|
|
// Purpose: Distributed HROW manager.
|
|
//
|
|
// History: 05-Jun-95 KyleP Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CHRowManager
|
|
{
|
|
public:
|
|
|
|
CHRowManager();
|
|
|
|
~CHRowManager();
|
|
|
|
//
|
|
// For bookmark hints
|
|
//
|
|
|
|
void TrackSiblings( unsigned cChild );
|
|
inline BOOL IsTrackingSiblings();
|
|
|
|
//
|
|
// Set modification
|
|
//
|
|
|
|
HROW Add( unsigned iChild, HROW hrow );
|
|
HROW Add( unsigned iChild, HROW const * ahrow );
|
|
void AddRef( HROW hrow );
|
|
void Release( HROW hrow );
|
|
|
|
//
|
|
// Row access
|
|
//
|
|
|
|
inline HROW ChildHROW( HROW hrow );
|
|
|
|
inline unsigned GetChildAndHROW( HROW hrow, HROW & hrowChild );
|
|
|
|
HROW * GetChildAndHROWs( HROW hrow, unsigned & iChild );
|
|
|
|
BOOL IsSame( HROW hrow1, HROW hrow2 );
|
|
|
|
private:
|
|
|
|
inline unsigned ConvertAndValidate( HROW hrow );
|
|
inline int InnerAdd( unsigned iChild, HROW hrow );
|
|
void Grow();
|
|
|
|
//
|
|
// Tracks single row
|
|
//
|
|
|
|
class CHRow
|
|
{
|
|
public:
|
|
|
|
CHRow() : _cRef(0) {}
|
|
|
|
void Init( unsigned iChild, HROW hrow )
|
|
{
|
|
Win4Assert( !IsInUse() );
|
|
_cRef = 1;
|
|
_iChild = iChild;
|
|
_hrow = hrow;
|
|
}
|
|
|
|
//
|
|
// Refcounting
|
|
//
|
|
|
|
void AddRef() { _cRef++; }
|
|
void Release() { _cRef--; }
|
|
BOOL IsInUse() { return _cRef > 0; }
|
|
|
|
//
|
|
// Member access
|
|
//
|
|
|
|
int Child() { return _iChild; }
|
|
HROW HRow() { return _hrow; }
|
|
|
|
//
|
|
// Linking
|
|
//
|
|
|
|
void Link( int iNext )
|
|
{
|
|
Win4Assert( _cRef == 0 );
|
|
_iChild = iNext;
|
|
}
|
|
|
|
int Next()
|
|
{
|
|
Win4Assert( _cRef == 0 );
|
|
return _iChild;
|
|
}
|
|
|
|
private:
|
|
|
|
unsigned _cRef;
|
|
unsigned _iChild;
|
|
HROW _hrow;
|
|
};
|
|
|
|
//
|
|
// Dynamic array of HROW, linked into a free list.
|
|
//
|
|
|
|
CHRow * _aHRow;
|
|
unsigned _cHRow;
|
|
int _iFirstFree;
|
|
|
|
//
|
|
// For tracking siblings. Two dimensional array: _cChild x _cHRow.
|
|
//
|
|
|
|
HROW * _ahrowHint;
|
|
unsigned _cChild;
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHRowManager::IsTrackingSiblings, public
|
|
//
|
|
// Returns: TRUE if the row manager is tracking HROW 'hints' for other
|
|
// cursors.
|
|
//
|
|
// History: 05-Jun-95 KyleP Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
inline BOOL CHRowManager::IsTrackingSiblings()
|
|
{
|
|
return( 0 != _ahrowHint );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHRowManager::ChildHROW, public
|
|
//
|
|
// Arguments: [hrow] -- Distributed HROW
|
|
//
|
|
// Returns: HROW used by child cursor.
|
|
//
|
|
// History: 05-Jun-95 KyleP Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
inline HROW CHRowManager::ChildHROW( HROW hrow )
|
|
{
|
|
unsigned iRow = ConvertAndValidate( hrow );
|
|
|
|
return( _aHRow[iRow].HRow() );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHRowManager::GetChildAndHROW, public
|
|
//
|
|
// Arguments: [hrow] -- Distributed HROW
|
|
// [hrowChild] -- HROW used by child cursor returned here.
|
|
//
|
|
// Returns: Index of child cursor for [hrow].
|
|
//
|
|
// History: 05-Jun-95 KyleP Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
inline unsigned CHRowManager::GetChildAndHROW( HROW hrow, HROW & hrowChild )
|
|
{
|
|
unsigned iRow = ConvertAndValidate( hrow );
|
|
|
|
hrowChild = _aHRow[iRow].HRow();
|
|
return _aHRow[iRow].Child();
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHRowManager::GetChildAndHROWs, public
|
|
//
|
|
// Arguments: [hrow] -- Distributed HROW
|
|
// [iChild] -- Index of child cursor returned here.
|
|
//
|
|
// Returns: Array of HROW 'hints', one per cursor. The [iChild] element
|
|
// is not a hint. It is the HROW for the owning cursor.
|
|
//
|
|
// History: 05-Jun-95 KyleP Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
inline HROW * CHRowManager::GetChildAndHROWs( HROW hrow, unsigned & iChild )
|
|
{
|
|
Win4Assert( IsTrackingSiblings() );
|
|
|
|
unsigned iRow = ConvertAndValidate( hrow );
|
|
|
|
iChild = _aHRow[iRow].Child();
|
|
|
|
return _ahrowHint + iRow * _cChild;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHRowManager::ConvertAndValidate, public
|
|
//
|
|
// Arguments: [hrow] -- Distributed HROW
|
|
//
|
|
// Returns: Index into _aHRow of row.
|
|
//
|
|
// History: 05-Jun-95 KyleP Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
inline unsigned CHRowManager::ConvertAndValidate( HROW hrow )
|
|
{
|
|
unsigned iRow = (unsigned)hrow - 1; // we are 0 based while hrow is 1 based
|
|
|
|
if ( iRow >= _cHRow || !_aHRow[iRow].IsInUse() )
|
|
{
|
|
Win4Assert( !"Invalid HROW" );
|
|
vqDebugOut(( DEB_ERROR, "Invalid HROW 0x%x\n", iRow ));
|
|
THROW( CException( DB_E_BADROWHANDLE ) );
|
|
}
|
|
|
|
return iRow;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CHRowManager::InnerAdd, public
|
|
//
|
|
// Synopsis: The guts of Add*
|
|
//
|
|
// Arguments: [iChild] -- Index of governing child cursor.
|
|
// [hrow] -- HROW used by child cursor
|
|
//
|
|
// Returns: Index of row in _aHRow
|
|
//
|
|
// History: 05-Jun-95 KyleP Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
inline int CHRowManager::InnerAdd( unsigned iChild, HROW hrow )
|
|
{
|
|
if ( _iFirstFree == -1 )
|
|
Grow();
|
|
|
|
Win4Assert( _iFirstFree != -1 );
|
|
|
|
int iCurrent = _iFirstFree;
|
|
|
|
_iFirstFree = _aHRow[iCurrent].Next();
|
|
|
|
_aHRow[iCurrent].Init( iChild, hrow );
|
|
|
|
return iCurrent;
|
|
}
|
|
|