mirror of https://github.com/tongzx/nt5src
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.
868 lines
20 KiB
868 lines
20 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 2000.
|
|
//
|
|
// File: twidhash.hxx
|
|
//
|
|
// Contents: WORKID Hash Table (Closed) implementation for mapping
|
|
// WORKIDs to a 32bit value (row offset in the table).
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 11-21-94 srikants Created
|
|
// 2-16-95 srikants Modified to use templates
|
|
//
|
|
// Notes : The "WorkId" itself will be used as a hash value as it is
|
|
// supposed to be unique for this implementation.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
//
|
|
// Bit 32 of an WORKID is not set for any valid wid. It is used by OFS
|
|
// to indicate a deleted WORKID. We will use that fact to mark deleted
|
|
// entries in the hash table.
|
|
//
|
|
const widDeleted = 0x80000000; // Used for marking "deleted" entries
|
|
|
|
#include <pshpack4.h>
|
|
|
|
class CWidHashEntry
|
|
{
|
|
public:
|
|
|
|
CWidHashEntry( WORKID wid = widInvalid ) : _wid(wid) { }
|
|
|
|
void SetWorkId( WORKID wid ) { _wid = wid; }
|
|
|
|
WORKID WorkId() const
|
|
{
|
|
return _wid;
|
|
}
|
|
|
|
ULONG HashValue() const { return _wid; }
|
|
|
|
BOOL IsDeleted() const
|
|
{
|
|
return widDeleted == _wid;
|
|
}
|
|
|
|
BOOL IsFree() const
|
|
{
|
|
return (widInvalid == _wid) || (widDeleted == _wid);
|
|
}
|
|
|
|
BOOL IsValid() const
|
|
{
|
|
return widInvalid != _wid;
|
|
}
|
|
|
|
protected:
|
|
|
|
WORKID _wid; // WorkId being hashed (hash Key)
|
|
|
|
};
|
|
|
|
class CWidValueHashEntry : public CWidHashEntry
|
|
{
|
|
|
|
public:
|
|
|
|
CWidValueHashEntry( WORKID wid=widInvalid, ULONG value = 0 )
|
|
: CWidHashEntry( wid ), _value(value)
|
|
{
|
|
|
|
}
|
|
|
|
void SetValue( ULONG value )
|
|
{
|
|
_value = value;
|
|
}
|
|
|
|
void Get( WORKID & wid, ULONG & value ) const
|
|
{
|
|
wid = _wid;
|
|
value = _value;
|
|
}
|
|
|
|
ULONG Value() const
|
|
{
|
|
return _value;
|
|
}
|
|
|
|
private:
|
|
|
|
ULONG _value; // The value for the BookMark (hash Value)
|
|
|
|
};
|
|
|
|
class CDirWidHashEntry: public CWidHashEntry
|
|
{
|
|
public:
|
|
|
|
CDirWidHashEntry ( WORKID wid=widInvalid, BOOL fDeep=FALSE, BOOL fInScope=FALSE )
|
|
: CWidHashEntry( wid ), _fDeep(fDeep), _fInScope(fInScope)
|
|
{
|
|
}
|
|
|
|
BOOL fInScope()const
|
|
{
|
|
return _fInScope;
|
|
}
|
|
|
|
BOOL fDeep ()const
|
|
{
|
|
return _fDeep;
|
|
}
|
|
|
|
private:
|
|
BOOL _fInScope;
|
|
BOOL _fDeep;
|
|
};
|
|
|
|
|
|
|
|
#include <poppack.h>
|
|
|
|
|
|
const TWID_INIT_HASH_SIZE = 31;
|
|
|
|
const MEASURE_OF_SLACK = 3;
|
|
|
|
template <class T> class TWidHashTable
|
|
{
|
|
|
|
public:
|
|
|
|
TWidHashTable( ULONG cHashInit = TWID_INIT_HASH_SIZE,
|
|
BOOL fReHash = TRUE );
|
|
|
|
~TWidHashTable();
|
|
|
|
BOOL IsWorkIdPresent( WORKID wid )
|
|
{
|
|
ULONG iTable;
|
|
return _LookUp( wid, iTable );
|
|
}
|
|
|
|
ULONG AddEntry( const T & entry );
|
|
|
|
T & FindOrAdd( WORKID wid );
|
|
|
|
void ReplaceOrAddEntry( const T & entry );
|
|
|
|
BOOL DeleteWorkId( WORKID wid );
|
|
|
|
void DeleteItem( T & item );
|
|
|
|
BOOL LookUpWorkId( T & entry );
|
|
|
|
void DeleteAllEntries();
|
|
|
|
const T & GetEntry( ULONG i )
|
|
{
|
|
Win4Assert( i < _size );
|
|
return _pTable[i];
|
|
}
|
|
|
|
ULONG Size() const { return _size; }
|
|
|
|
ULONG Count() const { return _count; }
|
|
|
|
private:
|
|
|
|
BOOL _IsFull() const
|
|
{
|
|
return (_count + _count/MEASURE_OF_SLACK) >= _size;
|
|
}
|
|
|
|
BOOL _LookUp( WORKID wid, ULONG & riTable );
|
|
|
|
ULONG _GrowSize(ULONG count) const;
|
|
|
|
void _GrowAndReHash();
|
|
|
|
BOOL _IsSizeValid( ULONG size, ULONG count ) const;
|
|
|
|
T * _AllocAndInit(ULONG size ) const;
|
|
|
|
static void _InitTable( T * pTable, ULONG size );
|
|
|
|
ULONG _size;
|
|
ULONG _count;
|
|
T * _pTable;
|
|
|
|
//
|
|
// Number of deleted entries. These can be re-used for adding new
|
|
// entries.
|
|
//
|
|
ULONG _cDeleted;
|
|
|
|
BOOL _fReHash;
|
|
|
|
#if DBG==1
|
|
//
|
|
// For keeping track of usage statistics.
|
|
//
|
|
unsigned _cMaxChainLen;
|
|
unsigned _cTotalSearches;
|
|
LONGLONG _cTotalLength;
|
|
#endif // DBG==1
|
|
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CWorkIdHashTable :: ~ctor
|
|
//
|
|
// Synopsis: Constructs the hash table. It allocates a table of size
|
|
// cHashInit and initializes it to be "empty".
|
|
//
|
|
// Arguments: [cHashInit] - Number of buckets to allocate. A minimum of
|
|
// TWID_INIT_HASH_SIZE will be allocated.
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> TWidHashTable<T>::TWidHashTable(
|
|
ULONG cHashInit,
|
|
BOOL fReHash ) : _fReHash( fReHash )
|
|
{
|
|
Win4Assert( 0 != cHashInit );
|
|
|
|
#if DBG==1
|
|
_cMaxChainLen = 0;
|
|
_cTotalSearches = 0;
|
|
_cTotalLength = 0;
|
|
#endif // DBG==1
|
|
|
|
_count = 0;
|
|
_size = max( cHashInit, TWID_INIT_HASH_SIZE ) ;
|
|
_pTable = _AllocAndInit(_size);
|
|
_cDeleted = 0;
|
|
|
|
Win4Assert( !_IsFull() );
|
|
}
|
|
|
|
template<class T> TWidHashTable<T>::~TWidHashTable()
|
|
{
|
|
if ( 0 != _size )
|
|
{
|
|
Win4Assert( 0 != _pTable );
|
|
delete [] ((BYTE *)_pTable);
|
|
}
|
|
}
|
|
|
|
template<class T> T & TWidHashTable<T>::FindOrAdd( WORKID wid )
|
|
{
|
|
ULONG iItem;
|
|
|
|
if ( _LookUp( wid, iItem ) )
|
|
return _pTable[ iItem ];
|
|
|
|
T entry;
|
|
entry.SetWorkId( wid );
|
|
return _pTable[ AddEntry( entry ) ];
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _LookUp
|
|
//
|
|
// Synopsis: Looks up for the specified wid in the hash table.
|
|
//
|
|
// Arguments: [wid] - WorkId to look up.
|
|
// [riTable] - (output) Will contain the index in the hash
|
|
// table of the entry if found.
|
|
//
|
|
// Returns: TRUE if found; FALSE o/w
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> BOOL TWidHashTable<T>::_LookUp( WORKID wid, ULONG &riTable )
|
|
{
|
|
Win4Assert( 0 != _size );
|
|
Win4Assert( widInvalid != wid );
|
|
Win4Assert( !_IsFull() );
|
|
|
|
ULONG cur = wid % _size;
|
|
ULONG start = cur;
|
|
ULONG delta = cur;
|
|
|
|
#if DBG==1
|
|
ULONG cSearchLen = 1;
|
|
#endif // DBG==1
|
|
|
|
BOOL fFound = FALSE;
|
|
while ( !fFound && (widInvalid != _pTable[cur].WorkId()) )
|
|
{
|
|
|
|
if ( wid == _pTable[cur].WorkId() )
|
|
{
|
|
riTable = cur;
|
|
fFound = TRUE;
|
|
}
|
|
else
|
|
{
|
|
cur = (cur + delta) % _size;
|
|
if ( cur == start ) // wrapped around
|
|
{
|
|
if ( 1 != delta )
|
|
{
|
|
delta = 1;
|
|
cur = (cur + 1) % _size;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if DBG==1
|
|
cSearchLen++;
|
|
#endif // DBG==1
|
|
|
|
}
|
|
}
|
|
|
|
#if DBG==1
|
|
_cTotalSearches++;
|
|
_cTotalLength += cSearchLen;
|
|
if (cSearchLen > _cMaxChainLen)
|
|
_cMaxChainLen = cSearchLen;
|
|
#endif // DBG==1
|
|
|
|
return fFound;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: LookUpWorkId
|
|
//
|
|
// Synopsis: Looks up the specified work id in the hash table.
|
|
//
|
|
// Arguments: [wid] - WorkId to look up
|
|
// [value] - (output) Value associated with the wid (if lookup
|
|
// is successful).
|
|
//
|
|
// Returns: TRUE if found; FALSE o/w
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> BOOL TWidHashTable<T>::LookUpWorkId( T & entry )
|
|
{
|
|
const WORKID wid = entry.WorkId();
|
|
|
|
Win4Assert( widInvalid != wid );
|
|
|
|
ULONG iTable;
|
|
BOOL fFound = _LookUp( wid, iTable );
|
|
if ( fFound )
|
|
{
|
|
Win4Assert( iTable < _size );
|
|
entry = _pTable[iTable];
|
|
}
|
|
|
|
return fFound;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: DeleteWorkId
|
|
//
|
|
// Synopsis: Deletes the entry associated with the specified workid from
|
|
// the hash table.
|
|
//
|
|
// Arguments: [wid] - WorkId to delete.
|
|
//
|
|
// Returns: TRUE if the given workid was present in the hash table.
|
|
// FALSE o/w
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes: The entry deleted will be identified as "deleted" and will
|
|
// be later available for "reuse".
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> BOOL TWidHashTable<T>::DeleteWorkId( WORKID wid )
|
|
{
|
|
Win4Assert( widInvalid != wid );
|
|
|
|
ULONG iTable;
|
|
BOOL fFound = _LookUp( wid, iTable );
|
|
if ( fFound )
|
|
{
|
|
Win4Assert( iTable < _size );
|
|
Win4Assert( wid == _pTable[iTable].WorkId() );
|
|
Win4Assert( _count > 0 );
|
|
|
|
_pTable[iTable].SetWorkId( widDeleted );
|
|
_count--;
|
|
_cDeleted++;
|
|
}
|
|
|
|
return fFound;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: DeleteItem
|
|
//
|
|
// Synopsis: Deletes an entry in the hash table.
|
|
//
|
|
// Arguments: [item] - reference to the item to be deleted.
|
|
//
|
|
// History: 28-Feb-96 dlee Created
|
|
//
|
|
// Notes: The entry deleted will be identified as "deleted" and will
|
|
// be later available for "reuse" if there are other items
|
|
// in the hash table. Otherwise it is marked as widInvalid.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> void TWidHashTable<T>::DeleteItem( T & item )
|
|
{
|
|
Win4Assert( widInvalid != item.WorkId() );
|
|
Win4Assert( widDeleted != item.WorkId() );
|
|
|
|
Win4Assert( _count > 0 );
|
|
|
|
_count--;
|
|
|
|
// If there aren't any items in the hash table, don't worry about
|
|
// breaking up a hash chain, especially since finding a wid in an
|
|
// array of widDeleted items is a linear search...
|
|
|
|
if ( 0 == _count )
|
|
item.SetWorkId( widInvalid );
|
|
else
|
|
{
|
|
item.SetWorkId( widDeleted );
|
|
|
|
_cDeleted++;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: AddWorkId
|
|
//
|
|
// Synopsis: Adds the specified workid to the hash table. If one is
|
|
// already present, its value will be modified.
|
|
//
|
|
// Arguments: [wid] - WorkId to be added.
|
|
// [value] - Value associated with the workid.
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes: If the table gets "full" as a result of adding the
|
|
// workid, the table will be re-sized and entries re-hashed.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> ULONG TWidHashTable<T>::AddEntry( const T & entry )
|
|
{
|
|
|
|
const WORKID wid = entry.WorkId();
|
|
|
|
Win4Assert( 0 != _size );
|
|
Win4Assert( widInvalid != wid );
|
|
Win4Assert( widDeleted != wid );
|
|
Win4Assert( !_IsFull() );
|
|
|
|
ULONG cur = wid % _size;
|
|
ULONG start = cur;
|
|
//
|
|
// Initialize use a delta which is not 1 to prevent data from getting
|
|
// clumped in one place.
|
|
//
|
|
ULONG delta = cur;
|
|
|
|
#if DBG==1
|
|
ULONG cSearchLen = 1;
|
|
#endif // DBG==1
|
|
|
|
while ( !_pTable[cur].IsFree() )
|
|
{
|
|
if ( wid == _pTable[cur].WorkId() )
|
|
{
|
|
// just replacing the value of the workid.
|
|
_pTable[cur] = entry;
|
|
return cur;
|
|
}
|
|
|
|
cur = (cur + delta) % _size;
|
|
if ( cur == start ) // wrapped around
|
|
{
|
|
if ( 1 == delta )
|
|
{
|
|
if ( _fReHash )
|
|
{
|
|
Win4Assert( delta != 1 );
|
|
}
|
|
else
|
|
{
|
|
// If no rehashing is turned on, give out any old record
|
|
// and pump out a warning. Clients expect this behavior!
|
|
|
|
ciDebugOut(( DEB_IWARN,
|
|
"TWidHashTable::AddEntry handing out duplicate" ));
|
|
return cur;
|
|
}
|
|
}
|
|
|
|
delta = 1;
|
|
cur = (cur + 1) % _size;
|
|
}
|
|
|
|
#if DBG==1
|
|
cSearchLen++;
|
|
#endif // DBG==1
|
|
|
|
}
|
|
|
|
#if DBG==1
|
|
_cTotalSearches++;
|
|
_cTotalLength += cSearchLen;
|
|
if (cSearchLen > _cMaxChainLen)
|
|
_cMaxChainLen = cSearchLen;
|
|
#endif DBG==1
|
|
|
|
|
|
#if DBG==1
|
|
ULONG iTable;
|
|
Win4Assert( !_LookUp( wid, iTable ) );
|
|
#endif // DBG
|
|
|
|
if ( widDeleted == _pTable[cur].WorkId() )
|
|
{
|
|
Win4Assert( _cDeleted > 0 );
|
|
_cDeleted--;
|
|
}
|
|
|
|
_pTable[cur] = entry;
|
|
_count++;
|
|
|
|
if ( _fReHash && _IsFull() )
|
|
{
|
|
_GrowAndReHash();
|
|
}
|
|
|
|
return cur;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ReplaceOrAddWorkId
|
|
//
|
|
// Synopsis: Replaces the value associated with the given workid if one
|
|
// exists; creates a new one if the given wid is not in the
|
|
// hash table.
|
|
//
|
|
// Arguments: [wid] - Workid to be replaced/added
|
|
// [value] - Value associated with the workid.
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
template<class T> void TWidHashTable<T>::ReplaceOrAddEntry( const T & entry )
|
|
{
|
|
ULONG iTable = _size;
|
|
BOOL fFound = FALSE;
|
|
const WORKID wid = entry.WorkId();
|
|
|
|
if ( _cDeleted )
|
|
{
|
|
//
|
|
// If there are "deleted" entries present, we must first do a
|
|
// look up to see if an entry is already present. AddWorkId
|
|
// will use the first free entry available and may not be able
|
|
// to detect this workid.
|
|
//
|
|
fFound = _LookUp( wid, iTable );
|
|
}
|
|
|
|
if ( fFound )
|
|
{
|
|
Win4Assert( iTable < _size );
|
|
Win4Assert( _pTable[iTable].WorkId() == wid );
|
|
|
|
_pTable[iTable] = entry;
|
|
}
|
|
else
|
|
{
|
|
AddEntry( entry );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: DeleteAllEntries
|
|
//
|
|
// Synopsis: Deletes all the entries in the hash table (efficiently).
|
|
//
|
|
// History: 11-22-94 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> void TWidHashTable<T>::DeleteAllEntries()
|
|
{
|
|
|
|
#if DBG==1
|
|
_cMaxChainLen = 0;
|
|
_cTotalSearches = 0;
|
|
_cTotalLength = 0;
|
|
#endif // DBG==1
|
|
|
|
_InitTable( _pTable, _size );
|
|
_count = 0;
|
|
_cDeleted = 0;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _IsSizeValid
|
|
//
|
|
// Synopsis: Determines if the specified size and count are in agreement
|
|
// or not.
|
|
//
|
|
// Arguments: [size] - The total size of the hash table.
|
|
// [count] - Number of entries used in the hash table.
|
|
//
|
|
// Returns: TRUE if okay; FALSE o/w
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> BOOL TWidHashTable<T>::_IsSizeValid ( ULONG size, ULONG count ) const
|
|
{
|
|
if (size == 0 && count == 0)
|
|
return(TRUE);
|
|
// is it a power of 2 plus 1?
|
|
for (ULONG i = 1; i < size; i *= 2 )
|
|
continue;
|
|
if (i/2 + 1 != size)
|
|
return(FALSE);
|
|
// is there enough slack?
|
|
if (count + count/MEASURE_OF_SLACK > size)
|
|
return(FALSE);
|
|
return(TRUE);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _GrowSize
|
|
//
|
|
// Synopsis: For a given valid hash table entries, this routine figures
|
|
// out the next valid size (close approximation to a prime).
|
|
//
|
|
// Arguments: [count] - Number of valid entries in the hash table.
|
|
//
|
|
// Returns: The size of the hash table for the given number of valid
|
|
// entries.
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> ULONG TWidHashTable<T>::_GrowSize ( ULONG count ) const
|
|
{
|
|
ULONG size = (count + count/MEASURE_OF_SLACK + 1);
|
|
// make it power of two + 1
|
|
// a good approximation of a prime
|
|
for ( unsigned sizeInit = 1; sizeInit < size; sizeInit *= 2 )
|
|
continue;
|
|
return(sizeInit + 1);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _AllocAndInit
|
|
//
|
|
// Synopsis: Helper function to allocate a buffer for the specified number
|
|
// of entries and initialize the buffer with "unused" entries.
|
|
//
|
|
// Arguments: [size] - Number of entries for the hash table.
|
|
//
|
|
// Returns: Pointer to the buffer.
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> T * TWidHashTable<T>::_AllocAndInit( ULONG size ) const
|
|
{
|
|
ULONG cb = sizeof(T)*size;
|
|
//
|
|
// Note that we are not using the new CWorkIdHashEntry [size] because
|
|
// that will call the constructor on all the entries and we have an
|
|
// easier way of initializing the array
|
|
//
|
|
T * pTable = (T *) new BYTE [cb];
|
|
_InitTable( pTable, size );
|
|
|
|
return pTable;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _InitTable
|
|
//
|
|
// Synopsis: Helper function to initialize the hash table array.
|
|
//
|
|
// Arguments: [pTable] - Pointer to the table.
|
|
// [size] - Size (in entries) of the table.
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> void TWidHashTable<T>::_InitTable(
|
|
T * pTable,
|
|
ULONG size )
|
|
{
|
|
ULONG cb = sizeof(T)*size;
|
|
|
|
RtlFillMemory( pTable, cb, 0xFF );
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _GrowAndReHash
|
|
//
|
|
// Synopsis: Grows the current hash table and re-hashes all the entries
|
|
// in the new table.
|
|
//
|
|
// History: 1-09-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class T> void TWidHashTable<T>::_GrowAndReHash()
|
|
{
|
|
ULONG sizeNew = _GrowSize( _count );
|
|
Win4Assert( sizeNew != _size );
|
|
|
|
T * pNewTable = _AllocAndInit( sizeNew );
|
|
|
|
ULONG sizeOld = _size;
|
|
ULONG countOld = _count;
|
|
T * pOldTable = _pTable;
|
|
|
|
//
|
|
// Add the entries from the current table to the new table.
|
|
//
|
|
_size = sizeNew;
|
|
_count = 0;
|
|
_pTable = pNewTable;
|
|
_cDeleted = 0;
|
|
|
|
for ( ULONG i = 0; i < sizeOld; i++ )
|
|
{
|
|
if ( !pOldTable[i].IsFree() )
|
|
{
|
|
Win4Assert( pOldTable[i].WorkId() != widInvalid );
|
|
AddEntry( pOldTable[i] );
|
|
}
|
|
}
|
|
|
|
Win4Assert( _count == countOld );
|
|
|
|
delete [] ((BYTE *) pOldTable);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: TWidHashIter
|
|
//
|
|
// Purpose: Iterator over the TWidHashTable
|
|
//
|
|
// History: 3-10-95 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
template <class T> class TWidHashIter
|
|
{
|
|
public:
|
|
|
|
TWidHashIter( TWidHashTable<T> & hashTable )
|
|
: _hashTable(hashTable)
|
|
{
|
|
for ( _curr = 0 ; !AtEnd() && _hashTable.GetEntry(_curr).IsFree();
|
|
_curr++ )
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
const T & Get()
|
|
{
|
|
return _hashTable.GetEntry(_curr);
|
|
}
|
|
|
|
BOOL AtEnd() const
|
|
{
|
|
Win4Assert( _curr <= _hashTable.Size() );
|
|
return _curr == _hashTable.Size();
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
_curr = 0;
|
|
}
|
|
|
|
void Next()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
for ( _curr++ ; !AtEnd() && _hashTable.GetEntry(_curr).IsFree();
|
|
_curr++ )
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
TWidHashTable<T> & _hashTable;
|
|
ULONG _curr;
|
|
|
|
};
|
|
|