Source code of Windows XP (NT5)
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.
|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: seglist.hxx
//
// Contents: List of CTableSegment objects.
//
// Classes: CTableSegList
//
// Functions:
//
// History: 1-15-95 srikants Created
//
//----------------------------------------------------------------------------
#pragma once
#include <tableseg.hxx>
#include <segmru.hxx>
#include <sglookup.hxx>
//+---------------------------------------------------------------------------
//
// Class: CTableSegList
//
// Purpose: A List of CTableSegments
//
// History: 1-16-95 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
class CTableSegList : public CDoubleList {
friend class CSegListMgr; friend class CFwdTableSegIter; friend class CBackTableSegIter;
public:
CTableSegList() : _cWindows(0), _cBuckets(0){}
~CTableSegList();
CTableSegment* GetTop() { return (CTableSegment *) _Top(); }
unsigned GetWindowsCount() const { return _cWindows; }
unsigned GetBucketsCount() const { return _cBuckets; }
unsigned GetSegmentsCount() const { return _cWindows + _cBuckets; }
CTableSegment * GetFirst() { return !IsEmpty() ? (CTableSegment *) _root.Next() : 0; }
CTableSegment * GetLast() { return !IsEmpty() ? (CTableSegment *) _root.Prev() : 0; }
CTableSegment * GetNext( CTableSegment * pNode ) { Win4Assert( 0 != pNode ); if ( !IsLast( *pNode ) ) { return (CTableSegment *) pNode->Next(); } else { return 0; } }
CTableSegment * GetPrev( CTableSegment * pNode ) { Win4Assert( 0 != pNode ); if ( !IsFirst( *pNode ) ) { return (CTableSegment *) pNode->Prev(); } else { return 0; } }
void Push ( CTableSegment * pTableSeg ) { Win4Assert( 0 != pTableSeg ); _Push ( pTableSeg ); _IncrementCount( *pTableSeg ); }
void Queue( CTableSegment * pTableSeg ) { Win4Assert( 0 != pTableSeg ); _Queue ( pTableSeg ); _IncrementCount( *pTableSeg ); }
void InsertAfter ( CTableSegment * pBefore, CTableSegment * pNew );
void InsertBefore( CTableSegment * pAfter, CTableSegment * pNew );
CTableSegment * RemoveTop();
void RemoveFromList( CTableSegment * pNode );
CTableSegment * Replace( CDoubleIter &it, CTableSegment * pNew );
#ifdef CIEXTMODE
void CiExtDump(void *ciExtSelf); #endif
private:
unsigned _cWindows; // Count of windows
unsigned _cBuckets; // Count of buckets
BOOL _IsNodeInList( CTableSegment * pNode );
void _IncrementCount( const CTableSegment & node );
void _DecrementCount( const CTableSegment & node );
CDoubleLink & _GetRoot() { return _root; } };
//+---------------------------------------------------------------------------
//
// Class: CDoubleTableSegIter
//
// Purpose: Iterator over a table segment list.
//
// History: 25-Jul-95 BartoszM Created.
//
//----------------------------------------------------------------------------
class CDoubleTableSegIter : public CDoubleList::CDoubleIter { public:
CDoubleTableSegIter ( CDoubleLink* pSeg ) : CDoubleIter(pSeg) {} CDoubleTableSegIter ( CDoubleTableSegIter& iter ) : CDoubleIter(iter) {}
CTableSegment* operator->() { return (CTableSegment*) _pLinkCur; } CTableSegment* GetSegment() { return (CTableSegment*) _pLinkCur; }
CTableWindow * GetWindow(); CTableBucket * GetBucket();
};
//+---------------------------------------------------------------------------
//
// Class: CFwdTableSegIter
//
// Purpose: Iterator over a table segment list.
//
// History: 15-Jan-95 SrikantS Created.
//
//----------------------------------------------------------------------------
class CTableWindow; class CTableBucket;
class CFwdTableSegIter : public CDoubleTableSegIter { public:
CFwdTableSegIter ( CTableSegList& list ) : CDoubleTableSegIter(list._GetRoot().Next()) {} // copy constructor
CFwdTableSegIter ( CFwdTableSegIter& iter) : CDoubleTableSegIter(iter) {}
};
//+---------------------------------------------------------------------------
//
// Class: CBackTableSegIter
//
// Purpose: Iterator over a table segment list.
//
// History: 15-Jan-95 SrikantS Created.
//
//----------------------------------------------------------------------------
class CBackTableSegIter : public CDoubleTableSegIter { public:
CBackTableSegIter ( CTableSegList& list ) : CDoubleTableSegIter(list._GetRoot().Prev()) {}
};
inline BOOL IsSpecialWid( WORKID wid ) { Win4Assert( WORKID_TBLBEFOREFIRST == ((WORKID) 0xfffffffb) ); Win4Assert( WORKID_TBLFIRST == ((WORKID) 0xfffffffc) ); Win4Assert( WORKID_TBLLAST == ((WORKID) 0xfffffffd) ); Win4Assert( WORKID_TBLAFTERLAST == ((WORKID) 0xfffffffe) );
return wid >= WORKID_TBLBEFOREFIRST && wid <= WORKID_TBLAFTERLAST; }
//+---------------------------------------------------------------------------
//
// Class: CSegListMgr
//
// Purpose: Manages list of segments and caching of segments that are
// in use by the query or client threads.
//
// History: 4-11-95 srikants Created
//
// Notes: All operations that modify the physical structure of the
// segment list MUST go through this object.
//
//----------------------------------------------------------------------------
class CSegListMgr { public:
CSegListMgr( unsigned nSegsToCache ) : _pCachedPutRowSeg(0) , _clientSegs(nSegsToCache), _bucketSegs(ULONG_MAX) { }
~CSegListMgr();
void Push ( CTableSegment * pTableSeg ) { _list.Push( pTableSeg ); _lookupArray.InsertBefore( 0, pTableSeg ); }
void InsertAfter ( CTableSegment * pBefore, CTableSegment * pNew ) { _list.InsertAfter( pBefore, pNew ); _lookupArray.InsertAfter( pBefore, pNew );
_lookupArray.TestInSync( _list ); }
void InsertBefore( CTableSegment * pAfter, CTableSegment * pNew ) { _list.InsertBefore( pAfter, pNew ); _lookupArray.InsertBefore( pAfter, pNew );
_lookupArray.TestInSync( _list ); }
CTableSegment * RemoveTop() { CTableSegment * pFirst = _list.RemoveTop(); _InvalidateIfCached( pFirst ); _lookupArray.RemoveEntry( pFirst );
_lookupArray.TestInSync( _list );
return pFirst; }
void RemoveFromList( CTableSegment * pNode ) { _list.RemoveFromList( pNode ); _InvalidateIfCached( pNode ); _lookupArray.RemoveEntry( pNode );
_lookupArray.TestInSync( _list );
}
//
// Replaces the node in the iterator with the new node in the iterator
// as well as the list.
//
CTableSegment * Replace( CDoubleList::CDoubleIter & iter, CTableSegment * pNew ) { Win4Assert( 0 != pNew ); Win4Assert( !_list.AtEnd( iter ) );
CTableSegment * pCurrent = _list.Replace(iter, pNew); _InvalidateIfCached( pCurrent ); _lookupArray.Replace( pCurrent, pNew );
_lookupArray.TestInSync( _list );
return pCurrent; }
CTableSegment * Replace( CTableSegment * pOld, CTableSegList & list );
//
// Methods that operate on the cached segment pointers.
//
void SetCachedPutRowSeg( CTableSegment * pSeg ) { _pCachedPutRowSeg = pSeg; }
CTableSegment * GetCachedPutRowSeg() { return _pCachedPutRowSeg; }
void SetInUseByClient( WORKID wid, CTableSegment * pSeg ) { if ( widInvalid != wid && !IsSpecialWid(wid) ) { _clientSegs.AddReplace( wid, pSeg ); } }
void UpdateSegsInUse( CTableSegment * pSeg );
BOOL IsInUseByClient( CTableSegment * pSeg ) { return _clientSegs.IsSegmentInUse( pSeg ); }
BOOL IsRecentlyUsed( CTableSegment * pSeg ) { if ( pSeg == _pCachedPutRowSeg || _clientSegs.IsSegmentInUse( pSeg ) ) { return TRUE; } else if ( !_bucketSegs.IsEmpty() && _bucketSegs.IsSegmentInUse( pSeg ) ) { return TRUE; }
return FALSE; }
void SetInUseByBuckets( WORKID wid ) { if ( widInvalid != wid && !IsSpecialWid(wid) ) { _bucketSegs.AddReplace( wid, 0 ); } }
void ClearInUseByBuckets( WORKID wid ) { if ( widInvalid != wid && !IsSpecialWid(wid) ) { _bucketSegs.Remove( wid ); } }
CTableSegList & GetList() { return _list; }
CSegmentArray & GetSegmentArray() { return _lookupArray; }
#ifdef CIEXTMODE
void CiExtDump(void *ciExtSelf); #endif
private:
CTableSegment * _pCachedPutRowSeg; // Last segment into which a row was
// added.
CTableSegList _list; // List of table segments
CSegmentArray _lookupArray; // Array used to to quick lookups on
// key
CMRUSegments _clientSegs;// List of segments most recently used
// by the client.
CMRUSegments _bucketSegs;// List of segments that are currently
// being converted to windows and so
// should be pinned as windows.
void _InvalidateIfCached( const CTableSegment * const pSeg ); void _UpdateSegsInUse( CWidSegMapList & list , CTableSegment * pSeg );
};
|