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.

287 lines
5.6 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. hash.c
  5. Abstract:
  6. Hash Table and support functions.
  7. Environment:
  8. User Mode - Win32
  9. Revision History:
  10. 10-May-1996 DonRyan
  11. Removed banner from Technology Dynamics, Inc.
  12. --*/
  13. //--------------------------- WINDOWS DEPENDENCIES --------------------------
  14. //--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
  15. #include <stdio.h>
  16. //--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
  17. #include <snmp.h>
  18. #include "mib.h"
  19. //--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
  20. #include "hash.h"
  21. //--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
  22. //--------------------------- PRIVATE CONSTANTS -----------------------------
  23. #define HT_SIZE 101
  24. #define HT_RADIX 18
  25. //--------------------------- PRIVATE STRUCTS -------------------------------
  26. //--------------------------- PRIVATE VARIABLES -----------------------------
  27. // Structure of one node in the hash table
  28. typedef struct hash_node
  29. {
  30. MIB_ENTRY *MibEntry;
  31. struct hash_node *Next;
  32. } HASH_NODE;
  33. // Hash table definition
  34. HASH_NODE *MIB_HashTable[HT_SIZE];
  35. //--------------------------- PRIVATE PROTOTYPES ----------------------------
  36. //--------------------------- PRIVATE PROCEDURES ----------------------------
  37. //--------------------------- PUBLIC PROCEDURES -----------------------------
  38. //
  39. // MIB_HashInit
  40. // Initializes hash table.
  41. //
  42. // Notes:
  43. //
  44. // Return Codes:
  45. // SNMPAPI_NOERROR
  46. // SNMPAPI_ERROR
  47. //
  48. // Error Codes:
  49. // None.
  50. //
  51. SNMPAPI MIB_HashInit()
  52. {
  53. UINT I;
  54. UINT HashRes;
  55. HASH_NODE *ht_ptr;
  56. SNMPAPI nResult;
  57. // Initialize hash table
  58. for ( I=0;I < HT_SIZE;I++ )
  59. {
  60. MIB_HashTable[I] = NULL;
  61. }
  62. // Loop MIB hashing the OID's to find position in Hash Table
  63. for ( I=0;I < MIB_num_variables;I++ )
  64. {
  65. HashRes = MIB_Hash( &Mib[I].Oid );
  66. // Check for empty bucket
  67. if ( MIB_HashTable[HashRes] == NULL )
  68. {
  69. // Allocate first node in bucket
  70. MIB_HashTable[HashRes] = SnmpUtilMemAlloc( sizeof(HASH_NODE) );
  71. if ( MIB_HashTable[HashRes] == NULL )
  72. {
  73. SetLastError( SNMP_MEM_ALLOC_ERROR );
  74. nResult = SNMPAPI_ERROR;
  75. goto Exit;
  76. }
  77. // Make copy of position in hash table to save MIB entry
  78. ht_ptr = MIB_HashTable[HashRes];
  79. }
  80. else
  81. {
  82. // Find end of bucket
  83. ht_ptr = MIB_HashTable[HashRes];
  84. while ( ht_ptr->Next != NULL )
  85. {
  86. ht_ptr = ht_ptr->Next;
  87. }
  88. // Alloc space for next node
  89. ht_ptr->Next = SnmpUtilMemAlloc( sizeof(HASH_NODE) );
  90. if ( ht_ptr->Next == NULL )
  91. {
  92. SetLastError( SNMP_MEM_ALLOC_ERROR );
  93. nResult = SNMPAPI_ERROR;
  94. goto Exit;
  95. }
  96. // Make copy of position in hash table to save MIB entry
  97. ht_ptr = ht_ptr->Next;
  98. }
  99. // Save MIB Entry pointer
  100. ht_ptr->MibEntry = &Mib[I];
  101. ht_ptr->Next = NULL;
  102. }
  103. Exit:
  104. return nResult;
  105. } // MIB_HashInit
  106. //
  107. // MIB_Hash
  108. // Hash an Object Identifier to find its position in the Hash Table.
  109. //
  110. // Notes:
  111. //
  112. // Return Codes:
  113. // None.
  114. //
  115. // Error Codes:
  116. // None.
  117. //
  118. UINT MIB_Hash(
  119. IN AsnObjectIdentifier *Oid // OID to hash
  120. )
  121. {
  122. long I;
  123. UINT Sum;
  124. Sum = 0;
  125. for ( I=0;I < (long)Oid->idLength-1;I++ )
  126. {
  127. Sum = Sum * HT_RADIX + Oid->ids[I+1];
  128. }
  129. return Sum % HT_SIZE;
  130. } // MIB_Hash
  131. //
  132. // MIB_HashLookup
  133. // Lookup OID in Hash Table and return pointer to MIB Entry.
  134. //
  135. // Notes:
  136. //
  137. // Return Codes:
  138. // NULL - OID not present in Hash Table.
  139. //
  140. // Error Codes:
  141. // None.
  142. //
  143. MIB_ENTRY *MIB_HashLookup(
  144. IN AsnObjectIdentifier *Oid // OID to lookup
  145. )
  146. {
  147. HASH_NODE *ht_ptr;
  148. MIB_ENTRY *pResult;
  149. UINT HashPos;
  150. // Hash OID to find position in Hash Table
  151. HashPos = MIB_Hash( Oid );
  152. // Search hash bucket for match
  153. ht_ptr = MIB_HashTable[HashPos];
  154. while ( ht_ptr != NULL )
  155. {
  156. if ( !SnmpUtilOidCmp(Oid, &ht_ptr->MibEntry->Oid) )
  157. {
  158. pResult = ht_ptr->MibEntry;
  159. goto Exit;
  160. }
  161. ht_ptr = ht_ptr->Next;
  162. }
  163. // Check for not found error
  164. if ( ht_ptr == NULL )
  165. {
  166. pResult = NULL;
  167. }
  168. Exit:
  169. return pResult;
  170. } // MIB_HashLookup
  171. #if 0 // Left in in case of more testing on hash performance
  172. //
  173. //
  174. // Debugging Code
  175. //
  176. //
  177. void MIB_HashPerformance()
  178. {
  179. UINT I;
  180. UINT LargestBucket;
  181. UINT BucketSize;
  182. HASH_NODE *ht_ptr;
  183. ULONG Sum;
  184. ULONG Count;
  185. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Hash Performance Report\n" );
  186. LargestBucket = 0;
  187. Count = 0;
  188. Sum = 0;
  189. for ( I=0;I < HT_SIZE;I++ )
  190. {
  191. BucketSize = 0;
  192. ht_ptr = MIB_HashTable[I];
  193. // Count nodes in bucket
  194. while ( ht_ptr != NULL )
  195. {
  196. BucketSize++;
  197. ht_ptr = ht_ptr->Next;
  198. }
  199. if ( BucketSize )
  200. {
  201. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: %d -- Bucket Size: %d\n", I, BucketSize ));
  202. Sum += BucketSize;
  203. Count ++;
  204. LargestBucket = max( LargestBucket, BucketSize );
  205. }
  206. }
  207. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Number of Buckets: %d\n", HT_SIZE ));
  208. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Number of MIB Var: %d\n", MIB_num_variables ));
  209. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Hashing Radix : %d\n", HashRadix ));
  210. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Used bucket Count: %d\n", Count ));
  211. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Avg. Bucket Size : %d\n", Sum / Count ));
  212. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Larg. bucket Size: %d\n", LargestBucket ));
  213. } // MIB_HashPerformance
  214. #endif
  215. //-------------------------------- END --------------------------------------