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.

157 lines
3.7 KiB

  1. /*++ Copyright(c) 2001 Microsoft Corporation
  2. Module Name:
  3. NLB Driver
  4. File Name:
  5. diplist.h
  6. Abstract:
  7. Code to lookup if a DIP is in a list of DIPs, without holding any locks.
  8. History:
  9. 04/24/2002 JosephJ Created
  10. --*/
  11. #include <ntddk.h>
  12. #define NULL_VALUE 0 // Illegal value; may be used to clear an item.
  13. #define MAX_ITEMS CVY_MAX_HOSTS // maximum number of DIPs in our list
  14. #define HASH1_SIZE 257 // size (in bits) of bit-vector (make it a prime)
  15. #define HASH2_SIZE 59 // size of hashtable (make it a prime)
  16. //
  17. // I've tested with the following "boundary case"
  18. //
  19. // #define MAX_ITEMS 1
  20. // #define HASH1_SIZE 1
  21. // #define HASH2_SIZE 1
  22. //
  23. #pragma pack(4)
  24. typedef struct
  25. {
  26. //
  27. // NOTE: All fields in this structure should be treated as
  28. // OPAQUE (private members) to callers of the DipList APIs.
  29. //
  30. //
  31. // The "master copy" of values, indexed by the "Index" field in
  32. // DipListSetItem.
  33. //
  34. ULONG Items[MAX_ITEMS];
  35. //
  36. // A bit vector used for a quick check to see if the value MAY exist
  37. // in the dip list.
  38. //
  39. // To lookup a bit based on value "Value", do the following:
  40. //
  41. // Hash1 = Value % HASH1_SIZE;
  42. // u = Hash1/32 // 32 is the number of bits in a ULONG
  43. // bit = BitVector[u] & ( (1<<Hash1) % 32)
  44. //
  45. ULONG BitVector[(HASH1_SIZE+sizeof(ULONG))/sizeof(ULONG)];
  46. //
  47. // A hash table to lookup a value -- to look up a value, "Value",
  48. // do the following:
  49. //
  50. // Hash2 = Value % HASH2_SIZE;
  51. // UCHAR *pb = HashTable+Hash2;
  52. // while (*pb != 0)
  53. // {
  54. // if (Items[*pb-1] == Value)
  55. // {
  56. // break; // Found it!
  57. // }
  58. // }
  59. //
  60. // Notes:
  61. // 1. The values in HashTable are 1+index,
  62. // where "index" is the index into Items[] where the value is located.
  63. // 2. The reason for the "1+" above is to allow the use of
  64. // 0 as a sentinel in HashTable.
  65. // 3. Note the fact that the hash table (HashTable) is extended
  66. // by MAX_ITEMS -- this is to allow overflow of hash buckets without
  67. // requiring us to wrap-around to look for items.
  68. // 4. The LAST entry of HashTable is ALWAYS 0, ensuring that the
  69. // while loop above will always terminate properly.
  70. //
  71. UCHAR HashTable[HASH2_SIZE+MAX_ITEMS];
  72. //
  73. // Keeps stats on the lookups (only in DBG version)
  74. //
  75. struct
  76. {
  77. ULONG NumChecks; // total number of calls to DipListCheckItem
  78. ULONG NumFastChecks; // times we just checked the bit vector
  79. ULONG NumArrayLookups; // times we looked up an item in HashTable
  80. } stats;
  81. } DIPLIST;
  82. #pragma pack()
  83. VOID
  84. DipListInitialize(
  85. DIPLIST *pDL
  86. );
  87. //
  88. // Initialize a DIP List
  89. // Must be called with lock held and before calls to any other DIP List
  90. // function.
  91. //
  92. VOID
  93. DipListDeinitialize(
  94. DIPLIST *pDL
  95. );
  96. //
  97. // Deinitialize a DIP List
  98. // Must be called with lock held and should be the last call to the DipList.
  99. //
  100. VOID
  101. DipListClear(
  102. DIPLIST *pDL
  103. );
  104. //
  105. // Clear all the items in a dip list.
  106. // Must be called with lock held.
  107. // Does not clear the stats.
  108. //
  109. VOID
  110. DipListSetItem(
  111. DIPLIST *pDL,
  112. ULONG Index,
  113. ULONG Value
  114. );
  115. //
  116. // Set the value of a specific iten the the DIP list.
  117. // Must be called with lock held.
  118. //
  119. BOOLEAN
  120. DipListCheckItem(
  121. DIPLIST *pDL,
  122. ULONG Value
  123. );
  124. //
  125. // Returns TRUE IFF an item exists with the specified value.
  126. // May NOT be called with the lock held. If it's called concurrently
  127. // with one of the other functions, the return value is indeterminate.
  128. //