Leaked source code of windows server 2003
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.

416 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. sample\hashtable.c
  5. Abstract:
  6. The file contains a hash table implementation.
  7. --*/
  8. #include "pchsample.h"
  9. #pragma hdrstop
  10. DWORD
  11. HT_Create(
  12. IN HANDLE hHeap,
  13. IN ULONG ulNumBuckets,
  14. IN PDISPLAY_FUNCTION pfnDisplay OPTIONAL,
  15. IN PFREE_FUNCTION pfnFree,
  16. IN PHASH_FUNCTION pfnHash,
  17. IN PCOMPARE_FUNCTION pfnCompare,
  18. OUT PHASH_TABLE *pphtHashTable)
  19. /*++
  20. Routine Description
  21. Creates a hash table.
  22. Locks
  23. None
  24. Arguments
  25. hHeap heap to use for allocation
  26. ulNumBuckets # buckets in the hash table
  27. pfnDisplay function used to display a hash table entry
  28. pfnFree function used to free a hash table entry
  29. pfnHash function used to compute the hash of an entry
  30. pfnCompare function used to compare two hash table entries
  31. pphtHashTable pointer to the hash table address
  32. Return Value
  33. NO_ERROR if success
  34. Failure code o/w
  35. --*/
  36. {
  37. DWORD dwErr = NO_ERROR;
  38. ULONG i = 0, ulSize = 0;
  39. PHASH_TABLE phtTable;
  40. // validate parameters
  41. if (!hHeap or
  42. !ulNumBuckets or
  43. !pfnFree or
  44. !pfnHash or
  45. !pfnCompare or
  46. !pphtHashTable)
  47. return ERROR_INVALID_PARAMETER;
  48. *pphtHashTable = NULL;
  49. do // breakout loop
  50. {
  51. // allocate the hash table structure
  52. ulSize = sizeof(HASH_TABLE);
  53. phtTable = HeapAlloc(hHeap, 0, ulSize);
  54. if (phtTable is NULL)
  55. {
  56. dwErr = GetLastError();
  57. break;
  58. }
  59. // allocate the buckets
  60. ulSize = ulNumBuckets * sizeof(LIST_ENTRY);
  61. phtTable->pleBuckets = HeapAlloc(hHeap, 0, ulSize);
  62. if (phtTable->pleBuckets is NULL)
  63. {
  64. HeapFree(hHeap, 0, phtTable); // undo allocation
  65. dwErr = GetLastError();
  66. break;
  67. }
  68. // initialize the buckets
  69. for (i = 0; i < ulNumBuckets; i++)
  70. InitializeListHead(phtTable->pleBuckets + i);
  71. // initialize the hash table structure's members
  72. phtTable->ulNumBuckets = ulNumBuckets;
  73. phtTable->ulNumEntries = 0;
  74. phtTable->pfnDisplay = pfnDisplay;
  75. phtTable->pfnFree = pfnFree;
  76. phtTable->pfnHash = pfnHash;
  77. phtTable->pfnCompare = pfnCompare;
  78. *pphtHashTable = phtTable;
  79. } while (FALSE);
  80. return dwErr;
  81. }
  82. DWORD
  83. HT_Destroy(
  84. IN HANDLE hHeap,
  85. IN PHASH_TABLE phtHashTable)
  86. /*++
  87. Routine Description
  88. Destroys a hash table.
  89. Frees up memory allocated for hash table entries.
  90. Locks
  91. Assumes the hash table is locked for writing.
  92. Arguments
  93. hHeap heap to use for deallocation
  94. phtHashTable pointer to the hash table to be destroyed
  95. Return Value
  96. NO_ERROR always
  97. --*/
  98. {
  99. ULONG i;
  100. PLIST_ENTRY pleList = NULL;
  101. // validate parameters
  102. if (!hHeap or
  103. !phtHashTable)
  104. return NO_ERROR;
  105. // deallocate the entries
  106. for (i = 0; i < phtHashTable->ulNumBuckets; i++)
  107. {
  108. pleList = phtHashTable->pleBuckets + i;
  109. FreeList(pleList, phtHashTable->pfnFree);
  110. }
  111. // deallocate the buckets
  112. HeapFree(hHeap, 0, phtHashTable->pleBuckets);
  113. // deallocate the hash table structure
  114. HeapFree(hHeap, 0, phtHashTable);
  115. return NO_ERROR;
  116. }
  117. DWORD
  118. HT_Cleanup(
  119. IN PHASH_TABLE phtHashTable)
  120. /*++
  121. Routine Description
  122. Cleans up all hash table entries.
  123. Locks
  124. Assumes the hash table is locked for writing.
  125. Arguments
  126. phtHashTable pointer to the hash table to be cleaned up
  127. Return Value
  128. NO_ERROR always
  129. --*/
  130. {
  131. ULONG i;
  132. PLIST_ENTRY pleList = NULL;
  133. // validate parameters
  134. if (!phtHashTable)
  135. return NO_ERROR;
  136. // deallocate the entries
  137. for (i = 0; i < phtHashTable->ulNumBuckets; i++)
  138. {
  139. pleList = phtHashTable->pleBuckets + i;
  140. FreeList(pleList, phtHashTable->pfnFree);
  141. }
  142. phtHashTable->ulNumEntries = 0;
  143. return NO_ERROR;
  144. }
  145. DWORD
  146. HT_InsertEntry(
  147. IN PHASH_TABLE phtHashTable,
  148. IN PLIST_ENTRY pleEntry)
  149. /*++
  150. Routine Description
  151. Inserts the specified entry in the hash table.
  152. Memory for the entry should already have been allocated.
  153. Locks
  154. Assumes the hash table is locked for writing.
  155. Arguments
  156. phtHashTable pointer to the hash table to be modified
  157. pleEntry entry to be inserted
  158. Return Value
  159. NO_ERROR if success
  160. Error code o/w (entry exists)
  161. --*/
  162. {
  163. DWORD dwErr = NO_ERROR;
  164. PLIST_ENTRY pleList = NULL;
  165. // validate parameters
  166. if (!phtHashTable or !pleEntry)
  167. return ERROR_INVALID_PARAMETER;
  168. do // breakout loop
  169. {
  170. // entry exists, fail
  171. if (HT_IsPresentEntry(phtHashTable, pleEntry))
  172. {
  173. dwErr = ERROR_INVALID_PARAMETER;
  174. break;
  175. }
  176. // insert the entry in the hash table
  177. pleList = phtHashTable->pleBuckets +
  178. (*phtHashTable->pfnHash)(pleEntry);
  179. InsertHeadList(pleList, pleEntry);
  180. phtHashTable->ulNumEntries++;
  181. } while (FALSE);
  182. return dwErr;
  183. }
  184. DWORD
  185. HT_GetEntry(
  186. IN PHASH_TABLE phtHashTable,
  187. IN PLIST_ENTRY pleKey,
  188. OUT PLIST_ENTRY *ppleEntry)
  189. /*++
  190. Routine Description
  191. Gets the hash table entry with the given key.
  192. Locks
  193. Assumes the hash table is locked for reading.
  194. Arguments
  195. phtHashTable pointer to the hash table to be searched
  196. pleKey key to be searched for
  197. ppleEntry pointer to matching entry's address
  198. Return Value
  199. NO_ERROR entry exisits
  200. ERROR_INVALID_PARAMETER o/w (entry does not exist)
  201. --*/
  202. {
  203. DWORD dwErr = NO_ERROR;
  204. PLIST_ENTRY pleList = NULL;
  205. // validate parameters
  206. if (!phtHashTable or !pleKey or !ppleEntry)
  207. return ERROR_INVALID_PARAMETER;
  208. pleList = phtHashTable->pleBuckets +
  209. (*phtHashTable->pfnHash)(pleKey);
  210. FindList(pleList, pleKey, ppleEntry, phtHashTable->pfnCompare);
  211. // entry not found, fail
  212. if (*ppleEntry is NULL)
  213. dwErr = ERROR_INVALID_PARAMETER;
  214. return dwErr;
  215. }
  216. DWORD
  217. HT_DeleteEntry(
  218. IN PHASH_TABLE phtHashTable,
  219. IN PLIST_ENTRY pleKey,
  220. OUT PLIST_ENTRY *ppleEntry)
  221. /*++
  222. Routine Description
  223. Deletes the entry with the given key from the hash table.
  224. Memory for the entry is not deleted.
  225. Locks
  226. Assumes the hash table is locked for writing.
  227. Arguments
  228. phtHashTable pointer to the hash table to be searched
  229. pleKey key to be deleted
  230. ppleEntry pointer to matching entry's address
  231. Return Value
  232. NO_ERROR entry exisits
  233. ERROR_INVALID_PARAMETER o/w (entry does not exist)
  234. --*/
  235. {
  236. DWORD dwErr = NO_ERROR;
  237. // validate parameters
  238. if (!phtHashTable or !pleKey or !ppleEntry)
  239. return ERROR_INVALID_PARAMETER;
  240. do // breakout loop
  241. {
  242. dwErr = HT_GetEntry(phtHashTable, pleKey, ppleEntry);
  243. // entry not found, fail
  244. if (dwErr != NO_ERROR)
  245. break;
  246. // entry found, delete from hash table and reset pointers
  247. RemoveEntryList(*ppleEntry);
  248. phtHashTable->ulNumEntries--;
  249. } while (FALSE);
  250. return dwErr;
  251. }
  252. BOOL
  253. HT_IsPresentEntry(
  254. IN PHASH_TABLE phtHashTable,
  255. IN PLIST_ENTRY pleKey)
  256. /*++
  257. Routine Description
  258. Is key present in the hash table?
  259. Locks
  260. Assumes the hash table is locked for reading.
  261. Arguments
  262. phtHashTable pointer to the hash table to be searched
  263. pleKey key to be deleted
  264. Return Value
  265. TRUE entry exisits
  266. FALSE o/w
  267. --*/
  268. {
  269. DWORD dwErr;
  270. PLIST_ENTRY pleEntry = NULL;
  271. // validate parameters
  272. if (!phtHashTable or !pleKey)
  273. return FALSE;
  274. dwErr = HT_GetEntry(phtHashTable, pleKey, &pleEntry);
  275. // entry not found, fail
  276. if (dwErr != NO_ERROR)
  277. return FALSE;
  278. // entry found, delete from hash table
  279. return TRUE;
  280. }
  281. DWORD
  282. HT_MapCar(
  283. IN PHASH_TABLE phtHashTable,
  284. IN PVOID_FUNCTION pfnVoidFunction
  285. )
  286. /*++
  287. Routine Description
  288. Applies the specified function to all entries in a hash table.
  289. Locks
  290. Assumes the hash table is locked for reading.
  291. Arguments
  292. phtHashTable pointer to the hash table to be mapcar'ed
  293. pfnVoidFunction pointer to function to apply to all entries
  294. Return Value
  295. NO_ERROR always
  296. --*/
  297. {
  298. ULONG i;
  299. PLIST_ENTRY pleList = NULL;
  300. // validate parameters
  301. if (!phtHashTable or !pfnVoidFunction)
  302. return NO_ERROR;
  303. for (i = 0; i < phtHashTable->ulNumBuckets; i++)
  304. {
  305. pleList = phtHashTable->pleBuckets + i;
  306. MapCarList(pleList, pfnVoidFunction);
  307. }
  308. return NO_ERROR;
  309. }