|
|
/*++
Copyright(c) 1999-2000 Microsoft Corporation
Module Name:
brdghash.h
Abstract:
Ethernet MAC level bridge. Hash table implementation header
Author:
Mark Aiken
Environment:
Kernel mode driver
Revision History:
October 2000 - Original version
--*/
// ===========================================================================
//
// DECLARATIONS
//
// ===========================================================================
#define MAX_SUPPORTED_KEYSIZE 8 // Key can be up to 8 bytes
//
// Structure of a table entry
//
typedef struct _HASH_TABLE_ENTRY {
struct _HASH_TABLE_ENTRY *Next; ULONG LastSeen; // Result of NdisGetSystemUpTime()
UCHAR key[MAX_SUPPORTED_KEYSIZE];
// User's data follows
} HASH_TABLE_ENTRY, *PHASH_TABLE_ENTRY;
// The prototype of a hash function
typedef ULONG (*PHASH_FUNCTION)(PUCHAR pKey);
// The prototype of a matching function
typedef BOOLEAN (*PHASH_MATCH_FUNCTION)(PHASH_TABLE_ENTRY, PVOID);
// The prototype of a data-copy function
typedef VOID (*PHASH_COPY_FUNCTION)(PHASH_TABLE_ENTRY, PUCHAR);
// The prototype of a function used in calls to BrdgHashPrefixMultiMatch
typedef VOID (*PMULTIMATCH_FUNC)(PHASH_TABLE_ENTRY, PVOID);
//
// Structure of the table itself
//
typedef struct _HASH_TABLE { NPAGED_LOOKASIDE_LIST entryPool;
//
// The consistency of the buckets is protected by the tableLock.
//
// The LastSeen field in each entry is volatile and is updated
// with interlocked instructions.
//
NDIS_RW_LOCK tableLock;
// These fields never change after creation
PHASH_FUNCTION pHashFunction; PHASH_TABLE_ENTRY *pBuckets; ULONG numBuckets, entrySize; UINT keySize; BRIDGE_TIMER timer; ULONG_PTR maxEntries; ULONG maxTimeoutAge; // Maximum possible timeoutAge
// These fields change but are protected by the tableLock.
ULONG_PTR numEntries; ULONG nextTimerBucket;
// This field is manipulated with InterlockExchange() instructions
// to avoid having to take the table lock to change it.
ULONG timeoutAge;
// In debug builds, this tracks how many entries are in each bucket
// so we can tell whether the table is well balanced
#if DBG
PUINT bucketSizes; #endif
} HASH_TABLE, *PHASH_TABLE;
// ===========================================================================
//
// PROTOTYPES
//
// ===========================================================================
PHASH_TABLE BrdgHashCreateTable( IN PHASH_FUNCTION pHashFunction, IN ULONG numBuckets, IN ULONG entrySize, IN ULONG maxEntries, IN ULONG startTimeoutAge, IN ULONG maxTimeoutAge, IN UINT keySize );
VOID BrdgHashFreeHashTable( IN PHASH_TABLE pTable );
PHASH_TABLE_ENTRY BrdgHashFindEntry( IN PHASH_TABLE pTable, IN PUCHAR pKey, IN LOCK_STATE *pLockState );
PHASH_TABLE_ENTRY BrdgHashRefreshOrInsert( IN PHASH_TABLE pTable, IN PUCHAR pKey, OUT BOOLEAN *pIsNewEntry, OUT PLOCK_STATE pLockState );
VOID BrdgHashRemoveMatching( IN PHASH_TABLE pTable, IN PHASH_MATCH_FUNCTION pMatchFunc, PVOID pData );
ULONG BrdgHashCopyMatching( IN PHASH_TABLE pTable, IN PHASH_MATCH_FUNCTION pMatchFunc, IN PHASH_COPY_FUNCTION pCopyFunction, IN ULONG copyUnitSize, IN PVOID pData, IN PUCHAR pBuffer, IN ULONG BufferLength );
VOID BrdgHashPrefixMultiMatch( IN PHASH_TABLE pTable, IN PUCHAR pPrefixKey, IN UINT prefixLen, IN PMULTIMATCH_FUNC pFunc, IN PVOID pData );
// ===========================================================================
//
// INLINES
//
// ===========================================================================
//
// Changes the timeout value for a hash table
//
__forceinline VOID BrdgHashChangeTableTimeout( IN PHASH_TABLE pTable, IN ULONG timeout ) { InterlockedExchange( (PLONG)&pTable->timeoutAge, (LONG)timeout ); }
//
// Refreshes a table entry held by the caller.
// ASSUMES the caller holds a read or write lock on the table
// enclosing this entry!
//
__forceinline VOID BrdgHashRefreshEntry( IN PHASH_TABLE_ENTRY pEntry ) { ULONG CurrentTime;
NdisGetSystemUpTime( &CurrentTime ); InterlockedExchange( (PLONG)&pEntry->LastSeen, (LONG)CurrentTime ); }
|