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.
269 lines
6.1 KiB
269 lines
6.1 KiB
/*++
|
|
|
|
Copyright (c) 1998-2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
hashp.h
|
|
|
|
Abstract:
|
|
|
|
The private definition of response cache hash table.
|
|
|
|
Author:
|
|
|
|
Alex Chen (alexch) 28-Mar-2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#ifndef _HASHP_H_
|
|
#define _HASHP_H_
|
|
|
|
#include "hash.h"
|
|
|
|
|
|
// Global Variables
|
|
|
|
extern ULONG g_UlHashTableBits;
|
|
extern ULONG g_UlHashTableSize;
|
|
extern ULONG g_UlHashTableMask;
|
|
extern ULONG g_UlHashIndexShift;
|
|
|
|
extern ULONG g_UlNumOfHashUriKeys;
|
|
|
|
// If we're using PagedPool for the hashtable, we must not access the
|
|
// hashtable at dispatch level.
|
|
|
|
#define HASH_PAGED_CODE(pHashTable) \
|
|
do { \
|
|
if ((pHashTable)->PoolType == PagedPool) { \
|
|
PAGED_CODE(); \
|
|
} \
|
|
} while (0)
|
|
|
|
|
|
// Set some parameters to small values to ensure the single list code
|
|
// gets exercised
|
|
|
|
#undef HASH_TEST
|
|
|
|
|
|
// Turn HASH_FULL_ASSERTS on if you make any changes to hashtable internal
|
|
// data structures to get rigorous-but-time-consuming assertions
|
|
|
|
#undef HASH_FULL_ASSERTS
|
|
|
|
|
|
//
|
|
// Hash Table Bucket Stored UriKey definitions
|
|
//
|
|
|
|
#define INVALID_SLOT_INDEX ((LONG) (-1))
|
|
|
|
typedef struct _HASH_URIKEY
|
|
{
|
|
PUL_URI_CACHE_ENTRY pUriCacheEntry;
|
|
|
|
ULONG Hash; // Hash signature
|
|
|
|
} HASHURIKEY, *PHASHURIKEY;
|
|
|
|
|
|
//
|
|
// Hash Table Bucket definitions
|
|
//
|
|
|
|
typedef struct _HASH_BUCKET
|
|
{
|
|
RWSPINLOCK RWSpinLock;
|
|
|
|
PUL_URI_CACHE_ENTRY pUriCacheEntry;
|
|
|
|
ULONG_PTR Entries; // force alignment
|
|
|
|
// followed immediately by HASHURIKEY HashUriKey[g_UlNumOfHashUriKeys];
|
|
|
|
} HASHBUCKET, *PHASHBUCKET;
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Get the indexed bucket
|
|
|
|
Return Value:
|
|
|
|
--***************************************************************************/
|
|
__inline
|
|
PHASHBUCKET
|
|
UlpHashTableIndexedBucket(
|
|
IN PHASHTABLE pHashTable,
|
|
IN ULONG Index
|
|
)
|
|
{
|
|
PHASHBUCKET pBucket;
|
|
|
|
ASSERT(Index < g_UlHashTableSize);
|
|
ASSERT(NULL != pHashTable->pBuckets);
|
|
|
|
pBucket = (PHASHBUCKET) (((PBYTE) pHashTable->pBuckets)
|
|
+ (Index << g_UlHashIndexShift));
|
|
|
|
ASSERT((PBYTE) pBucket
|
|
< (PBYTE) pHashTable->pBuckets + pHashTable->NumberOfBytes);
|
|
|
|
return pBucket;
|
|
} // UlpHashTableIndexedBucket
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve the bucket associated with a URI_KEY hash
|
|
|
|
Return Value:
|
|
|
|
--***************************************************************************/
|
|
__inline
|
|
PHASHBUCKET
|
|
UlpHashTableBucketFromUriKeyHash(
|
|
IN PHASHTABLE pHashTable,
|
|
IN ULONG UriKeyHash
|
|
)
|
|
{
|
|
ASSERT(HASH_INVALID_SIGNATURE != UriKeyHash);
|
|
|
|
return UlpHashTableIndexedBucket(
|
|
pHashTable,
|
|
UriKeyHash & g_UlHashTableMask
|
|
);
|
|
|
|
} // UlpHashTableBucketFromUriKeyHash
|
|
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Get the address of the inline array of HASHURIKEYs at the end of
|
|
the HASHBUCKET
|
|
|
|
Return Value:
|
|
|
|
--***************************************************************************/
|
|
__inline
|
|
PHASHURIKEY
|
|
UlpHashTableUriKeyFromBucket(
|
|
IN PHASHBUCKET pBucket
|
|
)
|
|
{
|
|
return (PHASHURIKEY) ((PBYTE) pBucket + sizeof(HASHBUCKET));
|
|
}
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Compare two URI_KEYS that have identical hashes to see if the
|
|
URIs also match (case-insensitively).
|
|
(Hashes must have been computed with HashStringNoCaseW or
|
|
HashCharNoCaseW.)
|
|
|
|
Return Value:
|
|
|
|
--***************************************************************************/
|
|
__inline
|
|
BOOLEAN
|
|
UlpEqualUriKeys(
|
|
IN PURI_KEY pUriKey1,
|
|
IN PURI_KEY pUriKey2
|
|
)
|
|
{
|
|
ASSERT(pUriKey1->Hash == pUriKey2->Hash);
|
|
|
|
if (pUriKey1->Length == pUriKey2->Length
|
|
&& UlEqualUnicodeString(
|
|
pUriKey1->pUri,
|
|
pUriKey2->pUri,
|
|
pUriKey1->Length,
|
|
TRUE
|
|
))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Compare an EXTENDED_URI_KEY against a URI_KEY that have identical hashes
|
|
to see if the URIs also match (case-insensitively).
|
|
|
|
(Hashes must have been computed with HashStringNoCaseW or
|
|
HashCharNoCaseW.)
|
|
|
|
--***************************************************************************/
|
|
__inline
|
|
BOOLEAN
|
|
UlpEqualUriKeysEx(
|
|
IN PEX_URI_KEY pExtKey,
|
|
IN PURI_KEY pUriKey
|
|
)
|
|
{
|
|
ASSERT(pExtKey->Hash == pUriKey->Hash);
|
|
|
|
if ((pExtKey->TokenLength + pExtKey->AbsPathLength)
|
|
== pUriKey->Length
|
|
&& UlEqualUnicodeStringEx(
|
|
pExtKey->pToken, // Routing token
|
|
pExtKey->TokenLength, // Routing token length
|
|
pExtKey->pAbsPath, // AbsPath
|
|
pExtKey->AbsPathLength,// AbsPath length
|
|
pUriKey->pUri, // Fully qualified url (in cache)
|
|
TRUE // Case sensitive comparison
|
|
))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
UlpGetHashTableSize(
|
|
IN LONG HashTableBits
|
|
);
|
|
|
|
BOOLEAN
|
|
UlpHashBucketIsCompact(
|
|
IN const PHASHBUCKET pBucket);
|
|
|
|
BOOLEAN
|
|
UlpFilterFlushHashBucket(
|
|
IN PHASHBUCKET pBucket,
|
|
IN PUL_URI_FILTER pFilterRoutine,
|
|
IN PVOID pContext,
|
|
OUT PULONG pDeletedCount
|
|
);
|
|
|
|
VOID
|
|
UlpClearHashBucket(
|
|
IN PHASHBUCKET pBucket
|
|
);
|
|
|
|
|
|
#endif // _HASHP_H_
|