HashBase.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #ifdef URHO3D_IS_BUILDING
  5. #include "Urho3D.h"
  6. #else
  7. #include <Urho3D/Urho3D.h>
  8. #endif
  9. #include "../Container/Allocator.h"
  10. #include "../Container/Hash.h"
  11. #include "../Container/Swap.h"
  12. namespace Urho3D
  13. {
  14. /// Hash set/map node base class.
  15. struct HashNodeBase
  16. {
  17. /// Construct.
  18. HashNodeBase() :
  19. down_(nullptr),
  20. prev_(nullptr),
  21. next_(nullptr)
  22. {
  23. }
  24. /// Next node in the bucket.
  25. HashNodeBase* down_;
  26. /// Previous node.
  27. HashNodeBase* prev_;
  28. /// Next node.
  29. HashNodeBase* next_;
  30. };
  31. /// Hash set/map iterator base class.
  32. struct HashIteratorBase
  33. {
  34. /// Construct.
  35. HashIteratorBase() :
  36. ptr_(nullptr)
  37. {
  38. }
  39. /// Construct with a node pointer.
  40. explicit HashIteratorBase(HashNodeBase* ptr) :
  41. ptr_(ptr)
  42. {
  43. }
  44. /// Test for equality with another iterator.
  45. bool operator ==(const HashIteratorBase& rhs) const { return ptr_ == rhs.ptr_; }
  46. /// Test for inequality with another iterator.
  47. bool operator !=(const HashIteratorBase& rhs) const { return ptr_ != rhs.ptr_; }
  48. /// Go to the next node.
  49. void GotoNext()
  50. {
  51. if (ptr_)
  52. ptr_ = ptr_->next_;
  53. }
  54. /// Go to the previous node.
  55. void GotoPrev()
  56. {
  57. if (ptr_)
  58. ptr_ = ptr_->prev_;
  59. }
  60. /// Node pointer.
  61. HashNodeBase* ptr_;
  62. };
  63. /// Hash set/map base class.
  64. /** Note that to prevent extra memory use due to vtable pointer, %HashBase intentionally does not declare a virtual destructor
  65. and therefore %HashBase pointers should never be used.
  66. */
  67. class URHO3D_API HashBase
  68. {
  69. public:
  70. /// Initial amount of buckets.
  71. static inline constexpr i32 MIN_BUCKETS = 8;
  72. /// Maximum load factor.
  73. static inline constexpr i32 MAX_LOAD_FACTOR = 4;
  74. /// Construct.
  75. HashBase() :
  76. head_(nullptr),
  77. tail_(nullptr),
  78. ptrs_(nullptr),
  79. allocator_(nullptr)
  80. {
  81. }
  82. /// Swap with another hash set or map.
  83. void Swap(HashBase& rhs)
  84. {
  85. Urho3D::Swap(head_, rhs.head_);
  86. Urho3D::Swap(tail_, rhs.tail_);
  87. Urho3D::Swap(ptrs_, rhs.ptrs_);
  88. Urho3D::Swap(allocator_, rhs.allocator_);
  89. }
  90. /// Return number of elements.
  91. i32 Size() const { return ptrs_ ? (reinterpret_cast<i32*>(ptrs_))[0] : 0; }
  92. /// Return number of buckets.
  93. i32 NumBuckets() const { return ptrs_ ? (reinterpret_cast<i32*>(ptrs_))[1] : 0; }
  94. /// Return whether has no elements.
  95. bool Empty() const { return Size() == 0; }
  96. protected:
  97. /// Allocate bucket head pointers + room for size and bucket count variables.
  98. void AllocateBuckets(i32 size, i32 numBuckets);
  99. /// Reset bucket head pointers.
  100. void ResetPtrs();
  101. /// Set new size.
  102. void SetSize(i32 size);
  103. /// Return bucket head pointers.
  104. HashNodeBase** Ptrs() const { return ptrs_ ? ptrs_ + 2 : nullptr; }
  105. /// List head node pointer.
  106. HashNodeBase* head_;
  107. /// List tail node pointer.
  108. HashNodeBase* tail_;
  109. /// Bucket head pointers.
  110. HashNodeBase** ptrs_;
  111. /// Node allocator.
  112. AllocatorBlock* allocator_;
  113. };
  114. }