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.

231 lines
3.7 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1994 - 1999
  6. //
  7. // File: hashtabl.hxx
  8. //
  9. //--------------------------------------------------------------------------
  10. /*++
  11. Module Name:
  12. hashtabl.hxx
  13. Abstract:
  14. interface for a hash table indexed by UUID
  15. Author:
  16. Jeff Roberts (jroberts) 9-Nov-1994
  17. Revision History:
  18. 9-Nov-1994 jroberts
  19. Created this module.
  20. --*/
  21. #ifndef _HASHTABL_HXX_
  22. #define _HASHTABL_HXX_
  23. #define NO_HASH ((unsigned)(-1))
  24. #define INVALID_NODE ((UUID_HASH_TABLE_NODE *) (-1))
  25. class UUID_HASH_TABLE_NODE
  26. {
  27. public:
  28. UUID_HASH_TABLE_NODE * pNext;
  29. UUID_HASH_TABLE_NODE * pPrev;
  30. RPC_UUID Uuid;
  31. UUID_HASH_TABLE_NODE(
  32. )
  33. {
  34. #ifdef DEBUGRPC
  35. pNext = INVALID_NODE;
  36. pPrev = INVALID_NODE;
  37. #endif
  38. }
  39. UUID_HASH_TABLE_NODE(
  40. RPC_UUID * pNewUuid
  41. )
  42. {
  43. Initialize(pNewUuid);
  44. #ifdef DEBUGRPC
  45. pNext = INVALID_NODE;
  46. pPrev = INVALID_NODE;
  47. #endif
  48. }
  49. inline void
  50. Initialize(
  51. RPC_UUID * pNewUuid
  52. )
  53. {
  54. Uuid = *pNewUuid;
  55. }
  56. int
  57. CompareUuid(
  58. void * Buffer
  59. )
  60. {
  61. RPC_UUID * UuidBuffer = (RPC_UUID *) Buffer;
  62. return Uuid.MatchUuid(UuidBuffer);
  63. }
  64. inline void
  65. VerifyFree(
  66. )
  67. {
  68. ASSERT(pNext == INVALID_NODE);
  69. ASSERT(pPrev == INVALID_NODE);
  70. }
  71. void
  72. QueryUuid(
  73. void * Buffer
  74. )
  75. {
  76. RPC_UUID * UuidBuffer = (RPC_UUID *) Buffer;
  77. *UuidBuffer = Uuid;
  78. }
  79. };
  80. class UUID_HASH_TABLE
  81. {
  82. public:
  83. UUID_HASH_TABLE(
  84. RPC_STATUS * pStatus,
  85. unsigned long SpinCount = 0
  86. );
  87. ~UUID_HASH_TABLE();
  88. unsigned
  89. Add(
  90. UUID_HASH_TABLE_NODE * pNode,
  91. unsigned Hash = NO_HASH
  92. );
  93. void
  94. Remove(
  95. UUID_HASH_TABLE_NODE * pNode,
  96. unsigned Hash = NO_HASH
  97. );
  98. inline UUID_HASH_TABLE_NODE *
  99. Lookup(
  100. RPC_UUID * Uuid,
  101. unsigned Hash = NO_HASH
  102. );
  103. inline unsigned
  104. MakeHash(
  105. RPC_UUID * Uuid
  106. )
  107. {
  108. return (Uuid->HashUuid() & BUCKET_COUNT_MASK);
  109. }
  110. protected:
  111. inline void
  112. RequestHashMutex(
  113. unsigned Hash
  114. )
  115. {
  116. BucketMutexes[Hash % MUTEX_COUNT]->Request();
  117. }
  118. inline void
  119. ReleaseHashMutex(
  120. unsigned Hash
  121. )
  122. {
  123. BucketMutexes[Hash % MUTEX_COUNT]->Clear();
  124. }
  125. enum
  126. {
  127. // number of hash buckets
  128. //
  129. BUCKET_COUNT = 128,
  130. // XOR this with any number to get a hash bucket index
  131. //
  132. BUCKET_COUNT_MASK = 0x007f,
  133. MUTEX_COUNT = 4
  134. };
  135. #ifdef DEBUGRPC
  136. unsigned Counts[BUCKET_COUNT];
  137. #endif
  138. // hash buckets - each bucket has a linked list of nodes
  139. // in no particular order
  140. //
  141. UUID_HASH_TABLE_NODE * Buckets[BUCKET_COUNT];
  142. // a mutex protexts each bucket
  143. //
  144. MUTEX * BucketMutexes[MUTEX_COUNT];
  145. };
  146. UUID_HASH_TABLE_NODE *
  147. UUID_HASH_TABLE::Lookup(
  148. RPC_UUID * Uuid,
  149. unsigned Hash
  150. )
  151. {
  152. if (Hash == NO_HASH)
  153. {
  154. Hash = MakeHash(Uuid);
  155. }
  156. ASSERT( Hash < BUCKET_COUNT );
  157. UUID_HASH_TABLE_NODE * pScan = Buckets[Hash];
  158. while (pScan)
  159. {
  160. if (0 == Uuid->MatchUuid(&pScan->Uuid))
  161. {
  162. return pScan;
  163. }
  164. if (pScan->pNext && pScan->pNext->pPrev != pScan)
  165. {
  166. #ifdef NTENV
  167. DbgBreakPoint();
  168. #else
  169. RpcpBreakPoint();
  170. #endif
  171. }
  172. pScan = pScan->pNext;
  173. }
  174. return 0;
  175. }
  176. #endif // _HASHTABL_HXX_