windows-nt/Source/XPSP1/NT/net/homenet/bridge/sys/brdghash.h
2020-09-26 16:20:57 +08:00

204 lines
5.1 KiB
C

/*++
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 );
}