2025-04-27 07:49:33 -04:00

272 lines
5.2 KiB
C++

/*++
Copyright (c) 1996-1997 Microsoft Corporation
Module Name:
GenTable.hxx
Abstract:
Generic wrapper for a bucket hash class, and its template friends.
Author:
Satish Thatte [SatishT] 02-12-96
--*/
#ifndef __GENERIC_TABLE_HXX
#define __GENERIC_TABLE_HXX
#if DBG
#define MAX_BUCKETS 0x10000 // for DBG validation checking only
#endif
struct ISearchKey
{
virtual DWORD Hash() = 0;
virtual BOOL Compare(ISearchKey &tk) = 0;
BOOL operator==(ISearchKey &tk)
{
return Compare(tk);
}
BOOL operator!=(ISearchKey &tk)
{
return !Compare(tk);
}
};
class CTableElement : public CReferencedObject
{
public:
virtual operator ISearchKey&() = 0;
};
// We don't use DEFINE_LIST here because CTableElement is an abstract class
#define CTableElementList TCSafeLinkList<CTableElement>
#define CTableElementListIterator TCSafeLinkListIterator<CTableElement>
/*++
Class Definition:
CResolverHashTable
Abstract:
This is a simple hash table class. Items are kept in buckets reached by
hashing. Each bucket is a linked list object. The name is designed to
avoid a clash with the specialized CHashTable in ole32\com\dcomrem\hash.hxx,
with which we must coexist.
--*/
class CResolverHashTable
{
public:
#if DBG
void IsValid();
DECLARE_VALIDITY_CLASS(CResolverHashTable)
#endif
CResolverHashTable(UINT start_size = 32 );
~CResolverHashTable();
// declare the page-allocator-based new and delete operators
DECL_NEW_AND_DELETE
ORSTATUS Add(CTableElement * element);
CTableElement *Lookup(ISearchKey &tk);
CTableElement *Remove(ISearchKey &tk);
void RemoveAll();
DWORD Size() { return(_cElements); }
protected:
DWORD BucketSize() { return _cBuckets; }
private:
friend class CResolverHashTableIterator;
ORSTATUS PrivAdd(CTableElement * element);
ORSTATUS Init();
DWORD _cBuckets;
DWORD _cElements;
BOOL _fInitialized;
CTableElementList *_buckets;
// declare the members needed for a page static allocator
DECL_PAGE_ALLOCATOR
};
// Forward declaration
template <class Data> class TCSafeResolverHashTableIterator;
/*++
Template Class Definition:
TCResolverHashTable
Abstract:
The usual template wrapper for type safety. Data must be a subtype of
CTableElement. I wish I could express that constraint in the code!
--*/
template <class Data>
class TCSafeResolverHashTable : private CResolverHashTable
{
friend class TCSafeResolverHashTableIterator<Data>;
public:
#if DBG
void IsValid()
{
CResolverHashTable::IsValid();
}
#endif // DBG
TCSafeResolverHashTable(UINT start_size = 32 )
: CResolverHashTable(start_size)
{}
// We don't want to allocate this -- use "new CResolverHashTable"
// and cast it so that all these tables stay together in memory
void * operator new(size_t s)
{
return NULL;
}
ORSTATUS Add(Data * element)
{
return CResolverHashTable::Add(element);
}
Data *Lookup(ISearchKey &tk)
{
return (Data *) CResolverHashTable::Lookup(tk);
}
Data *Remove(ISearchKey &tk)
{
return (Data *) CResolverHashTable::Remove(tk);
}
void RemoveAll()
{
CResolverHashTable::RemoveAll();
}
DWORD Size()
{
return CResolverHashTable::Size();
}
BOOL IsEmpty()
{
return Size() == 0;
}
private:
DWORD BucketSize() { return CResolverHashTable::BucketSize(); }
};
/*++
Class Definition:
CResolverHashTableIterator
Abstract:
This is a simple iterator class for hash tables.
It is assumed that the table is static during iteration.
Note that the iterator performs no memory allocation.
--*/
class CResolverHashTableIterator
{
private:
CResolverHashTable& _table;
DWORD _currentBucketIndex;
// iterator for the current bucket
CTableElementListIterator _BucketIter;
void NextBucket(); // helper -- setup next bucket iterator
public:
CResolverHashTableIterator(CResolverHashTable& source)
: _table(source), _currentBucketIndex(0)
{}
IDataItem * Next();
};
/*++
Template Class Definition:
TCSafeResolverHashTableIterator
Abstract:
This is the usual template wrapper for CResolverHashTableIterator
for type safety. Data must be a subtype of CTableElement.
--*/
template <class Data>
class TCSafeResolverHashTableIterator : private CResolverHashTableIterator
{
public:
TCSafeResolverHashTableIterator(TCSafeResolverHashTable<Data>& source)
: CResolverHashTableIterator(source)
{}
Data * Next()
{
return (Data *) CResolverHashTableIterator::Next();
}
};
#define DEFINE_TABLE(DATA) \
typedef TCSafeResolverHashTable<DATA> DATA##Table; \
typedef TCSafeResolverHashTableIterator<DATA> DATA##TableIterator;
#endif // __GENERIC_TABLE_HXX