Source code of Windows XP (NT5)
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.

296 lines
5.3 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. hash.h
  5. Abstract:
  6. contains prototypes for functions in hash.c
  7. Author:
  8. Paul McDaniel (paulmcd) 28-Apr-2000
  9. Revision History:
  10. --*/
  11. #ifndef _HASH_H_
  12. #define _HASH_H_
  13. //
  14. // The hash key is the file name, but we need to track both the file
  15. // component of the name in addition to the stream component of the name (if
  16. // there is one). The buffer in the FileName UNICODE_STRING contains the
  17. // full name with stream information, but the length is set to just designate
  18. // the file portion of the name.
  19. //
  20. // Note: The keys will be hashed based on the FileName only, not the stream
  21. // portion of the name. This is done so that we can easily find all the
  22. // entries related to a given file if that file has multiple data streams.
  23. //
  24. typedef struct _HASH_KEY
  25. {
  26. UNICODE_STRING FileName;
  27. USHORT StreamNameLength;
  28. USHORT Reserved;
  29. } HASH_KEY, *PHASH_KEY;
  30. //
  31. // a hash list entry .
  32. //
  33. typedef struct _HASH_ENTRY
  34. {
  35. //
  36. // the hash value
  37. //
  38. ULONG HashValue;
  39. //
  40. // the key
  41. //
  42. HASH_KEY Key;
  43. //
  44. // a context stored with this hash entry
  45. //
  46. PVOID pContext;
  47. } HASH_ENTRY, *PHASH_ENTRY;
  48. //
  49. // a hash bucket, which is basically an array of hash entries
  50. // sorted by (HashValue, Key.Length, Key.Buffer) .
  51. //
  52. #define IS_VALID_HASH_BUCKET(pObject) \
  53. (((pObject) != NULL) && ((pObject)->Signature == HASH_BUCKET_TAG))
  54. typedef struct _HASH_BUCKET
  55. {
  56. //
  57. // = HASH_BUCKET_TAG
  58. //
  59. ULONG Signature;
  60. ULONG AllocCount;
  61. ULONG UsedCount;
  62. HASH_ENTRY Entries[0];
  63. } HASH_BUCKET, *PHASH_BUCKET;
  64. #define HASH_ENTRY_DEFAULT_WIDTH 10
  65. //
  66. // a destructor for hash entries
  67. //
  68. typedef
  69. VOID
  70. (*PHASH_ENTRY_DESTRUCTOR) (
  71. IN PHASH_KEY pKey,
  72. IN PVOID pContext
  73. );
  74. typedef
  75. PVOID
  76. (*PHASH_ENTRY_CALLBACK) (
  77. IN PHASH_KEY pKey,
  78. IN PVOID pEntryContext,
  79. IN PVOID pCallbackContext
  80. );
  81. //
  82. // and a hash header, an array of buckets which is hashed into.
  83. //
  84. #define IS_VALID_HASH_HEADER(pObject) \
  85. (((pObject) != NULL) && ((pObject)->Signature == HASH_HEADER_TAG))
  86. typedef struct _HASH_HEADER
  87. {
  88. //
  89. // NonPagedPool
  90. //
  91. //
  92. // = HASH_HEADER_TAG
  93. //
  94. ULONG Signature;
  95. //
  96. // the count of buckets the hash table has
  97. //
  98. ULONG BucketCount;
  99. //
  100. // the memory this hash table is taking
  101. //
  102. ULONG UsedLength;
  103. //
  104. // the memory this hash table is allowed to use
  105. //
  106. ULONG AllowedLength;
  107. //
  108. // how many times we've trimmed due to memory
  109. //
  110. ULONG TrimCount;
  111. //
  112. // the last time we trim'd
  113. //
  114. LARGE_INTEGER LastTrimTime;
  115. //
  116. // OPTIONAL the length in bytes of the duplicate prefix (if any)
  117. // all keys share in this lists. This will be skipped for all manual
  118. // comparisons as an optimization. this can be 0
  119. //
  120. ULONG PrefixLength;
  121. //
  122. // the lock for this list
  123. //
  124. ERESOURCE Lock;
  125. //
  126. // OPTIONAL destructor
  127. //
  128. PHASH_ENTRY_DESTRUCTOR pDestructor;
  129. //
  130. // and the actual buckets
  131. //
  132. PHASH_BUCKET Buckets[0];
  133. } HASH_HEADER, *PHASH_HEADER;
  134. //
  135. // Function Prototypes.
  136. //
  137. NTSTATUS
  138. HashCreateList (
  139. IN ULONG BucketCount,
  140. IN ULONG AllowedLength,
  141. IN ULONG PrefixLength OPTIONAL,
  142. IN PHASH_ENTRY_DESTRUCTOR pDestructor OPTIONAL,
  143. OUT PHASH_HEADER * ppHashList
  144. );
  145. VOID
  146. HashDestroyList (
  147. IN PHASH_HEADER pHashList
  148. );
  149. NTSTATUS
  150. HashAddEntry (
  151. IN PHASH_HEADER pHashList,
  152. IN PHASH_KEY pKey,
  153. IN PVOID pContext
  154. );
  155. NTSTATUS
  156. HashFindEntry (
  157. IN PHASH_HEADER pHashList,
  158. IN PHASH_KEY pKey,
  159. OUT PVOID * ppContext
  160. );
  161. VOID
  162. HashClearEntries (
  163. IN PHASH_HEADER pHashList
  164. );
  165. NTSTATUS
  166. HashClearAllFileEntries (
  167. IN PHASH_HEADER pHeader,
  168. IN PUNICODE_STRING pFileName
  169. );
  170. VOID
  171. HashProcessEntries (
  172. IN PHASH_HEADER pHeader,
  173. IN PHASH_ENTRY_CALLBACK pfnCallback,
  174. IN PVOID pCallbackContext
  175. );
  176. #if 0
  177. #define HashCompute(Key) HashScramble(HashUnicodeString((Key)))
  178. __inline ULONG
  179. HashUnicodeString(
  180. PUNICODE_STRING pKey
  181. )
  182. {
  183. ULONG Hash = 0;
  184. ULONG Index;
  185. ULONG CharCount;
  186. CharCount = pKey->Length/sizeof(WCHAR);
  187. for (Index = 0 ; Index < CharCount; ++Index)
  188. {
  189. Hash = 37 * Hash + (pKey->Buffer[Index] & 0xFFDF);
  190. }
  191. return Hash;
  192. }
  193. // Produce a scrambled, randomish number in the range 0 to RANDOM_PRIME-1.
  194. // Applying this to the results of the other hash functions is likely to
  195. // produce a much better distribution, especially for the identity hash
  196. // functions such as Hash(char c), where records will tend to cluster at
  197. // the low end of the hashtable otherwise. LKHash applies this internally
  198. // to all hash signatures for exactly this reason.
  199. __inline ULONG
  200. HashScramble(ULONG dwHash)
  201. {
  202. // Here are 10 primes slightly greater than 10^9
  203. // 1000000007, 1000000009, 1000000021, 1000000033, 1000000087,
  204. // 1000000093, 1000000097, 1000000103, 1000000123, 1000000181.
  205. // default value for "scrambling constant"
  206. const ULONG RANDOM_CONSTANT = 314159269UL;
  207. // large prime number, also used for scrambling
  208. const ULONG RANDOM_PRIME = 1000000007UL;
  209. return (RANDOM_CONSTANT * dwHash) % RANDOM_PRIME ;
  210. }
  211. #endif // 0
  212. #endif // _HASH_H_