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.

108 lines
2.6 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // attridx.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // Defines the class AttributeIndex
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/04/2000 Original version.
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include <proxypch.h>
  19. #include <attridx.h>
  20. #include <attrdnry.h>
  21. void AttributeIndex::create(
  22. const AttributeDefinition* begin,
  23. const AttributeDefinition* end,
  24. HashFn hash,
  25. EqualFn equal,
  26. FilterFn filterFn
  27. )
  28. {
  29. const AttributeDefinition* i;
  30. // Delete any existing index.
  31. delete[] table;
  32. table = NULL;
  33. // Same the funtion pointers.
  34. hashFn = hash;
  35. equalFn = equal;
  36. // Determine how many entries are in the index.
  37. ULONG count;
  38. if (filterFn)
  39. {
  40. count = 0;
  41. for (i = begin; i != end; ++i)
  42. {
  43. if (filterFn(*i)) { ++count; }
  44. }
  45. }
  46. else
  47. {
  48. count = end - begin;
  49. }
  50. // Buckets should be a power of two.
  51. ULONG buckets = 1;
  52. while (buckets < count) { buckets <<= 1; }
  53. // Set the hash mask.
  54. mask = buckets - 1;
  55. // Allocate the buckets and nodes.
  56. SIZE_T nbyte = sizeof(Bucket) * buckets + sizeof(Node) * count;
  57. table = (Bucket*)operator new(nbyte);
  58. Node* node = (Node*)(table + buckets);
  59. // Zeroize the hash table.
  60. memset(table, 0, sizeof(Bucket) * buckets);
  61. // Iterate through the definitions to be indexed.
  62. for (i = begin; i != end; ++i)
  63. {
  64. // Should we index this one?
  65. if (!filterFn || filterFn(*i))
  66. {
  67. // Yes, so compute the bucket.
  68. Bucket* bucket = table + (hashFn(*i) & mask);
  69. // Insert the node at the head of the linked list.
  70. node->next = *bucket;
  71. *bucket = node;
  72. // Store the definition.
  73. node->def = i;
  74. // Advance to the next node.
  75. ++node;
  76. }
  77. }
  78. }
  79. const AttributeDefinition* AttributeIndex::find(
  80. const AttributeDefinition& key
  81. ) const throw ()
  82. {
  83. // Get the appropriate bucket.
  84. Bucket* bucket = table + (hashFn(key) & mask);
  85. // Iterate through the linked list ...
  86. for (const Node* node = *bucket; node; node = node->next)
  87. {
  88. // ... and look for a match.
  89. if (equalFn(*node->def, key)) { return node->def; }
  90. }
  91. return NULL;
  92. }