412 lines
10 KiB
C++
412 lines
10 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1994.
|
||
|
//
|
||
|
// File: seglist.cxx
|
||
|
//
|
||
|
// Contents: List of CTableSegment objects
|
||
|
//
|
||
|
// Classes: CTableSegList
|
||
|
//
|
||
|
// History: 1-15-95 srikants Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
#include "pch.cxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <seglist.hxx>
|
||
|
|
||
|
#include "tblwindo.hxx"
|
||
|
#include "tblbuket.hxx"
|
||
|
|
||
|
CTableSegList::~CTableSegList()
|
||
|
{
|
||
|
for ( CTableSegment * pSegment = RemoveTop();
|
||
|
0 != pSegment;
|
||
|
pSegment = RemoveTop() )
|
||
|
{
|
||
|
delete pSegment;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: RemoveTop
|
||
|
//
|
||
|
// Synopsis: Removes the top most element from the list and returns it.
|
||
|
//
|
||
|
// Returns: A pointer to the top most element from the list.
|
||
|
//
|
||
|
// History: 1-16-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
CTableSegment * CTableSegList::RemoveTop()
|
||
|
{
|
||
|
// tbDebugOut (( DEB_ITRACE, "TableSegList::RemoveTop\n" ));
|
||
|
|
||
|
CTableSegment* pSegment = (CTableSegment*) _Pop();
|
||
|
if ( pSegment )
|
||
|
_DecrementCount( *pSegment );
|
||
|
return pSegment;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: RemoveFromList
|
||
|
//
|
||
|
// Synopsis: Removes the indicated node from the list.
|
||
|
//
|
||
|
// Arguments: [pNodeToRemove] -
|
||
|
//
|
||
|
// History: 1-16-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CTableSegList::RemoveFromList( CTableSegment * pNodeToRemove )
|
||
|
{
|
||
|
Win4Assert( _IsNodeInList( pNodeToRemove ) &&
|
||
|
"CTableSegList::pNodeToRemove not is list" );
|
||
|
|
||
|
pNodeToRemove->Unlink();
|
||
|
_DecrementCount( *pNodeToRemove );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: InsertAfter
|
||
|
//
|
||
|
// Synopsis: Inserts "pNew" node after "pBefore" node.
|
||
|
//
|
||
|
// Arguments: [pBefore] - The node already in list.
|
||
|
// [pNew] - The new node to be inserted.
|
||
|
//
|
||
|
// History: 1-16-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CTableSegList::InsertAfter( CTableSegment * pBefore, CTableSegment * pNew )
|
||
|
{
|
||
|
Win4Assert( 0 != pBefore && 0 != pNew );
|
||
|
pNew->InsertAfter( pBefore );
|
||
|
_IncrementCount( *pNew );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: InsertBefore
|
||
|
//
|
||
|
// Synopsis: Inserts "pNew" node before "pAfter" node.
|
||
|
//
|
||
|
// Arguments: [pAfter] - The node already in the list.
|
||
|
// [pNew] - The new node to be inserted.
|
||
|
//
|
||
|
// History: 1-16-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CTableSegList::InsertBefore( CTableSegment * pAfter, CTableSegment * pNew )
|
||
|
{
|
||
|
Win4Assert( 0 != pAfter && 0 != pNew );
|
||
|
pNew->InsertBefore( pAfter );
|
||
|
_IncrementCount( *pNew );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: Replace
|
||
|
//
|
||
|
// Synopsis: Replaces the current entry in the iterator with the new
|
||
|
// entry. It also replaces it in the list.
|
||
|
//
|
||
|
// Arguments: [it] - Iterator
|
||
|
// [pNew] - The new entry that replaces the entry in the
|
||
|
// iterator.
|
||
|
//
|
||
|
// Returns: The old segment that was replaced in the list.
|
||
|
//
|
||
|
// History: 4-10-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
CTableSegment* CTableSegList::Replace( CDoubleIter & it, CTableSegment * pNew )
|
||
|
{
|
||
|
Win4Assert( 0 != pNew );
|
||
|
CTableSegment * pCurr = (CTableSegment *) _Replace( it, pNew );
|
||
|
|
||
|
_DecrementCount( *pCurr );
|
||
|
_IncrementCount( *pNew );
|
||
|
|
||
|
return pCurr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: _IncrementCount
|
||
|
//
|
||
|
// Synopsis: Increments the appropriate count depending upon the type of the
|
||
|
// segment (node)
|
||
|
//
|
||
|
// Arguments: [node] -
|
||
|
//
|
||
|
// History: 1-16-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CTableSegList::_IncrementCount( const CTableSegment & node )
|
||
|
{
|
||
|
switch( node.GetSegmentType() )
|
||
|
{
|
||
|
case CTableSegment::eWindow :
|
||
|
_cWindows++;
|
||
|
break;
|
||
|
|
||
|
case CTableSegment::eBucket :
|
||
|
_cBuckets++;
|
||
|
break;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: _DecrementCount
|
||
|
//
|
||
|
// Synopsis: Decrements the count of the given node type.
|
||
|
//
|
||
|
// Arguments: [node] -
|
||
|
//
|
||
|
// History: 1-16-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CTableSegList::_DecrementCount( const CTableSegment & node )
|
||
|
{
|
||
|
switch( node.GetSegmentType() )
|
||
|
{
|
||
|
case CTableSegment::eWindow :
|
||
|
Win4Assert( _cWindows > 0 );
|
||
|
_cWindows--;
|
||
|
break;
|
||
|
|
||
|
case CTableSegment::eBucket :
|
||
|
Win4Assert( _cBuckets > 0 );
|
||
|
_cBuckets--;
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: _IsNodeInList
|
||
|
//
|
||
|
// Synopsis: Determines if a given node is in the list.
|
||
|
//
|
||
|
// Arguments: [pNode] - Node whose existence in the list is being tested.
|
||
|
//
|
||
|
// Returns: TRUE if found; FALSE o/w
|
||
|
//
|
||
|
// History: 1-16-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL CTableSegList::_IsNodeInList( CTableSegment * pNode )
|
||
|
{
|
||
|
for ( CFwdTableSegIter iter(*this); !AtEnd(iter); Advance(iter) )
|
||
|
{
|
||
|
if ( iter.GetSegment() == pNode )
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
CTableWindow * CDoubleTableSegIter::GetWindow()
|
||
|
{
|
||
|
Win4Assert( GetSegment()->GetSegmentType() == CTableSegment::eWindow );
|
||
|
return (CTableWindow *) _pLinkCur;
|
||
|
}
|
||
|
|
||
|
CTableBucket * CDoubleTableSegIter::GetBucket()
|
||
|
{
|
||
|
Win4Assert( GetSegment()->GetSegmentType() == CTableSegment::eBucket );
|
||
|
return (CTableBucket *) _pLinkCur;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ~CSegListMgr
|
||
|
//
|
||
|
// Synopsis: Destroys all the segments in the list.
|
||
|
//
|
||
|
// History: 4-11-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
CSegListMgr::~CSegListMgr()
|
||
|
{
|
||
|
for ( CTableSegment * pSegment = _list.RemoveTop();
|
||
|
0 != pSegment;
|
||
|
pSegment = _list.RemoveTop() )
|
||
|
{
|
||
|
delete pSegment;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: _InvalidateIfCached
|
||
|
//
|
||
|
// Synopsis: If the given segment's pointer is cached, invalidate it.
|
||
|
//
|
||
|
// Arguments: [pSeg] - The segment which is going to go away and so must
|
||
|
// be invalidated.
|
||
|
//
|
||
|
// History: 4-11-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CSegListMgr::_InvalidateIfCached( const CTableSegment * const pSeg )
|
||
|
{
|
||
|
Win4Assert( 0 != pSeg );
|
||
|
|
||
|
if ( _pCachedPutRowSeg == pSeg )
|
||
|
{
|
||
|
_pCachedPutRowSeg = 0;
|
||
|
}
|
||
|
|
||
|
_clientSegs.Invalidate( pSeg );
|
||
|
_bucketSegs.Invalidate( pSeg );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: _UpdateSegsInUse
|
||
|
//
|
||
|
// Synopsis: Updates the wid->Segment mapping for wids that are cached.
|
||
|
// For such wids, if they are present in the new segment, the
|
||
|
// mapping is updated.
|
||
|
//
|
||
|
// Arguments: [list] - The list to update in.
|
||
|
// [pSeg] - Pointer to the segment which is the new segment
|
||
|
//
|
||
|
// History: 5-30-95 srikants Created
|
||
|
//
|
||
|
// Notes: Helper function for UpdateSegsInUse()
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CSegListMgr::_UpdateSegsInUse( CWidSegMapList & list,
|
||
|
CTableSegment * pSeg )
|
||
|
{
|
||
|
for ( CFwdWidSegMapIter iter(list); !list.AtEnd(iter);
|
||
|
list.Advance(iter) )
|
||
|
{
|
||
|
WORKID wid = iter->GetWorkId();
|
||
|
if ( widInvalid != wid &&
|
||
|
pSeg->IsRowInSegment( wid ) )
|
||
|
{
|
||
|
Win4Assert( 0 == iter->GetSegment() );
|
||
|
iter->Set( pSeg );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: UpdateSegsInUse
|
||
|
//
|
||
|
// Synopsis: Updates the wid->Segment mapping for wids that are cached.
|
||
|
// For such wids, if they are present in the new segment, the
|
||
|
// mapping is updated.
|
||
|
//
|
||
|
// Arguments: [pSeg] - Pointer to a new segment that is coming into
|
||
|
// existence.
|
||
|
//
|
||
|
// History: 4-11-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CSegListMgr::UpdateSegsInUse( CTableSegment * pSeg )
|
||
|
{
|
||
|
Win4Assert( 0 != pSeg );
|
||
|
|
||
|
CWidSegMapList & clientList = _clientSegs.GetList();
|
||
|
_UpdateSegsInUse( clientList, pSeg );
|
||
|
|
||
|
|
||
|
if ( !_bucketSegs.IsEmpty() )
|
||
|
{
|
||
|
CWidSegMapList & bktList = _bucketSegs.GetList();
|
||
|
_UpdateSegsInUse( bktList, pSeg );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CSegListMgr::Replace
|
||
|
//
|
||
|
// Synopsis: Replaces the given segment in the _list with the new segments
|
||
|
// passed in the list.
|
||
|
//
|
||
|
// Arguments: [pSeg] - The segment to replace
|
||
|
// [list] - The new list of segments.
|
||
|
//
|
||
|
// History: 10-20-95 srikants Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
CTableSegment * CSegListMgr::Replace( CTableSegment * pSeg, CTableSegList & list )
|
||
|
{
|
||
|
|
||
|
_lookupArray.Replace( pSeg, list );
|
||
|
|
||
|
CTableSegment * pCurr = pSeg;
|
||
|
CTableSegment * pFirst = list.RemoveTop();
|
||
|
|
||
|
while ( 0 != pFirst )
|
||
|
{
|
||
|
_list.InsertAfter( pCurr, pFirst );
|
||
|
pCurr = pFirst;
|
||
|
pFirst = list.RemoveTop();
|
||
|
}
|
||
|
|
||
|
_list.RemoveFromList( pSeg );
|
||
|
_InvalidateIfCached( pSeg );
|
||
|
|
||
|
_lookupArray.TestInSync( _list );
|
||
|
|
||
|
return pSeg;
|
||
|
}
|