diff options
Diffstat (limited to 'src/common/intrusive_red_black_tree.h')
| -rw-r--r-- | src/common/intrusive_red_black_tree.h | 99 |
1 files changed, 37 insertions, 62 deletions
diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h index fb55de94e..c0bbcd457 100644 --- a/src/common/intrusive_red_black_tree.h +++ b/src/common/intrusive_red_black_tree.h | |||
| @@ -16,17 +16,30 @@ class IntrusiveRedBlackTreeImpl; | |||
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | struct IntrusiveRedBlackTreeNode { | 18 | struct IntrusiveRedBlackTreeNode { |
| 19 | public: | ||
| 20 | using EntryType = RBEntry<IntrusiveRedBlackTreeNode>; | ||
| 21 | |||
| 22 | constexpr IntrusiveRedBlackTreeNode() = default; | ||
| 23 | |||
| 24 | void SetEntry(const EntryType& new_entry) { | ||
| 25 | entry = new_entry; | ||
| 26 | } | ||
| 27 | |||
| 28 | [[nodiscard]] EntryType& GetEntry() { | ||
| 29 | return entry; | ||
| 30 | } | ||
| 31 | |||
| 32 | [[nodiscard]] const EntryType& GetEntry() const { | ||
| 33 | return entry; | ||
| 34 | } | ||
| 19 | 35 | ||
| 20 | private: | 36 | private: |
| 21 | RB_ENTRY(IntrusiveRedBlackTreeNode) entry{}; | 37 | EntryType entry{}; |
| 22 | 38 | ||
| 23 | friend class impl::IntrusiveRedBlackTreeImpl; | 39 | friend class impl::IntrusiveRedBlackTreeImpl; |
| 24 | 40 | ||
| 25 | template <class, class, class> | 41 | template <class, class, class> |
| 26 | friend class IntrusiveRedBlackTree; | 42 | friend class IntrusiveRedBlackTree; |
| 27 | |||
| 28 | public: | ||
| 29 | constexpr IntrusiveRedBlackTreeNode() = default; | ||
| 30 | }; | 43 | }; |
| 31 | 44 | ||
| 32 | template <class T, class Traits, class Comparator> | 45 | template <class T, class Traits, class Comparator> |
| @@ -35,17 +48,12 @@ class IntrusiveRedBlackTree; | |||
| 35 | namespace impl { | 48 | namespace impl { |
| 36 | 49 | ||
| 37 | class IntrusiveRedBlackTreeImpl { | 50 | class IntrusiveRedBlackTreeImpl { |
| 38 | |||
| 39 | private: | 51 | private: |
| 40 | template <class, class, class> | 52 | template <class, class, class> |
| 41 | friend class ::Common::IntrusiveRedBlackTree; | 53 | friend class ::Common::IntrusiveRedBlackTree; |
| 42 | 54 | ||
| 43 | private: | 55 | using RootType = RBHead<IntrusiveRedBlackTreeNode>; |
| 44 | RB_HEAD(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode); | 56 | RootType root; |
| 45 | using RootType = IntrusiveRedBlackTreeRoot; | ||
| 46 | |||
| 47 | private: | ||
| 48 | IntrusiveRedBlackTreeRoot root; | ||
| 49 | 57 | ||
| 50 | public: | 58 | public: |
| 51 | template <bool Const> | 59 | template <bool Const> |
| @@ -121,57 +129,45 @@ public: | |||
| 121 | } | 129 | } |
| 122 | }; | 130 | }; |
| 123 | 131 | ||
| 124 | protected: | ||
| 125 | // Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot. | ||
| 126 | RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry); | ||
| 127 | |||
| 128 | private: | 132 | private: |
| 129 | // Define accessors using RB_* functions. | 133 | // Define accessors using RB_* functions. |
| 130 | constexpr void InitializeImpl() { | ||
| 131 | RB_INIT(&this->root); | ||
| 132 | } | ||
| 133 | |||
| 134 | bool EmptyImpl() const { | 134 | bool EmptyImpl() const { |
| 135 | return RB_EMPTY(&this->root); | 135 | return root.IsEmpty(); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | IntrusiveRedBlackTreeNode* GetMinImpl() const { | 138 | IntrusiveRedBlackTreeNode* GetMinImpl() const { |
| 139 | return RB_MIN(IntrusiveRedBlackTreeRoot, | 139 | return RB_MIN(const_cast<RootType*>(&root)); |
| 140 | const_cast<IntrusiveRedBlackTreeRoot*>(&this->root)); | ||
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | IntrusiveRedBlackTreeNode* GetMaxImpl() const { | 142 | IntrusiveRedBlackTreeNode* GetMaxImpl() const { |
| 144 | return RB_MAX(IntrusiveRedBlackTreeRoot, | 143 | return RB_MAX(const_cast<RootType*>(&root)); |
| 145 | const_cast<IntrusiveRedBlackTreeRoot*>(&this->root)); | ||
| 146 | } | 144 | } |
| 147 | 145 | ||
| 148 | IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) { | 146 | IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) { |
| 149 | return RB_REMOVE(IntrusiveRedBlackTreeRoot, &this->root, node); | 147 | return RB_REMOVE(&root, node); |
| 150 | } | 148 | } |
| 151 | 149 | ||
| 152 | public: | 150 | public: |
| 153 | static IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) { | 151 | static IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) { |
| 154 | return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node); | 152 | return RB_NEXT(node); |
| 155 | } | 153 | } |
| 156 | 154 | ||
| 157 | static IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) { | 155 | static IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) { |
| 158 | return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node); | 156 | return RB_PREV(node); |
| 159 | } | 157 | } |
| 160 | 158 | ||
| 161 | static IntrusiveRedBlackTreeNode const* GetNext(const IntrusiveRedBlackTreeNode* node) { | 159 | static const IntrusiveRedBlackTreeNode* GetNext(const IntrusiveRedBlackTreeNode* node) { |
| 162 | return static_cast<const IntrusiveRedBlackTreeNode*>( | 160 | return static_cast<const IntrusiveRedBlackTreeNode*>( |
| 163 | GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node))); | 161 | GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node))); |
| 164 | } | 162 | } |
| 165 | 163 | ||
| 166 | static IntrusiveRedBlackTreeNode const* GetPrev(const IntrusiveRedBlackTreeNode* node) { | 164 | static const IntrusiveRedBlackTreeNode* GetPrev(const IntrusiveRedBlackTreeNode* node) { |
| 167 | return static_cast<const IntrusiveRedBlackTreeNode*>( | 165 | return static_cast<const IntrusiveRedBlackTreeNode*>( |
| 168 | GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node))); | 166 | GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node))); |
| 169 | } | 167 | } |
| 170 | 168 | ||
| 171 | public: | 169 | public: |
| 172 | constexpr IntrusiveRedBlackTreeImpl() : root() { | 170 | constexpr IntrusiveRedBlackTreeImpl() {} |
| 173 | this->InitializeImpl(); | ||
| 174 | } | ||
| 175 | 171 | ||
| 176 | // Iterator accessors. | 172 | // Iterator accessors. |
| 177 | iterator begin() { | 173 | iterator begin() { |
| @@ -269,8 +265,6 @@ private: | |||
| 269 | ImplType impl{}; | 265 | ImplType impl{}; |
| 270 | 266 | ||
| 271 | public: | 267 | public: |
| 272 | struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot {}; | ||
| 273 | |||
| 274 | template <bool Const> | 268 | template <bool Const> |
| 275 | class Iterator; | 269 | class Iterator; |
| 276 | 270 | ||
| @@ -363,11 +357,6 @@ public: | |||
| 363 | }; | 357 | }; |
| 364 | 358 | ||
| 365 | private: | 359 | private: |
| 366 | // Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. | ||
| 367 | RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode, | ||
| 368 | entry, CompareImpl, LightCompareImpl); | ||
| 369 | |||
| 370 | private: | ||
| 371 | static int CompareImpl(const IntrusiveRedBlackTreeNode* lhs, | 360 | static int CompareImpl(const IntrusiveRedBlackTreeNode* lhs, |
| 372 | const IntrusiveRedBlackTreeNode* rhs) { | 361 | const IntrusiveRedBlackTreeNode* rhs) { |
| 373 | return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs)); | 362 | return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs)); |
| @@ -379,41 +368,27 @@ private: | |||
| 379 | 368 | ||
| 380 | // Define accessors using RB_* functions. | 369 | // Define accessors using RB_* functions. |
| 381 | IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { | 370 | IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { |
| 382 | return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare, | 371 | return RB_INSERT(&impl.root, node, CompareImpl); |
| 383 | static_cast<IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root), | ||
| 384 | node); | ||
| 385 | } | 372 | } |
| 386 | 373 | ||
| 387 | IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const { | 374 | IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const { |
| 388 | return RB_FIND( | 375 | return RB_FIND(const_cast<ImplType::RootType*>(&impl.root), |
| 389 | IntrusiveRedBlackTreeRootWithCompare, | 376 | const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl); |
| 390 | const_cast<IntrusiveRedBlackTreeRootWithCompare*>( | ||
| 391 | static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)), | ||
| 392 | const_cast<IntrusiveRedBlackTreeNode*>(node)); | ||
| 393 | } | 377 | } |
| 394 | 378 | ||
| 395 | IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const { | 379 | IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const { |
| 396 | return RB_NFIND( | 380 | return RB_NFIND(const_cast<ImplType::RootType*>(&impl.root), |
| 397 | IntrusiveRedBlackTreeRootWithCompare, | 381 | const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl); |
| 398 | const_cast<IntrusiveRedBlackTreeRootWithCompare*>( | ||
| 399 | static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)), | ||
| 400 | const_cast<IntrusiveRedBlackTreeNode*>(node)); | ||
| 401 | } | 382 | } |
| 402 | 383 | ||
| 403 | IntrusiveRedBlackTreeNode* FindLightImpl(const_light_pointer lelm) const { | 384 | IntrusiveRedBlackTreeNode* FindLightImpl(const_light_pointer lelm) const { |
| 404 | return RB_FIND_LIGHT( | 385 | return RB_FIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root), |
| 405 | IntrusiveRedBlackTreeRootWithCompare, | 386 | static_cast<const void*>(lelm), LightCompareImpl); |
| 406 | const_cast<IntrusiveRedBlackTreeRootWithCompare*>( | ||
| 407 | static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)), | ||
| 408 | static_cast<const void*>(lelm)); | ||
| 409 | } | 387 | } |
| 410 | 388 | ||
| 411 | IntrusiveRedBlackTreeNode* NFindLightImpl(const_light_pointer lelm) const { | 389 | IntrusiveRedBlackTreeNode* NFindLightImpl(const_light_pointer lelm) const { |
| 412 | return RB_NFIND_LIGHT( | 390 | return RB_NFIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root), |
| 413 | IntrusiveRedBlackTreeRootWithCompare, | 391 | static_cast<const void*>(lelm), LightCompareImpl); |
| 414 | const_cast<IntrusiveRedBlackTreeRootWithCompare*>( | ||
| 415 | static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)), | ||
| 416 | static_cast<const void*>(lelm)); | ||
| 417 | } | 392 | } |
| 418 | 393 | ||
| 419 | public: | 394 | public: |