Intrusive Containers
Loading...
Searching...
No Matches
AATreeIn.hpp
Go to the documentation of this file.
1#ifndef AATreeIn_HPP
2#define AATreeIn_HPP
3
4/**
5@file AATreeIn.hpp
6@brief Intrusive Binary Tree (balanced), Implementation.
7
8This file defines a pair of templates (TreeInRoot and TreeInNode) that
9implement an intrusive binary tree.
10
11@copyright (c) 2022-2024 Richard Damon
12@parblock
13MIT License:
14
15Permission is hereby granted, free of charge, to any person obtaining a copy
16of this software and associated documentation files (the "Software"), to deal
17in the Software without restriction, including without limitation the rights
18to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19copies of the Software, and to permit persons to whom the Software is
20furnished to do so, subject to the following conditions:
21
22The above copyright notice and this permission notice shall be included in
23all copies or substantial portions of the Software.
24
25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31THE SOFTWARE.
32@endparblock
33
34@see AATreeIn.h
35@ingroup IntrusiveContainers
36*/
37
38#include "AATreeIn.h"
39#include "BalTreeIn.hpp"
40
41/******************************************************************************************
42Implementation
43
44Note that when we need to use a Root or Node pointer/reference as a AATreeInRoot/AAListInNode
45pointer/reference we need to do an explicit static_cast, to avoid ambiguity in the case of
46classes deriving from multiple versions of TreeInRoot/ListInNode
47*/
48
49template <class R, class N, class K, ContainerThreadSafety s, int n>
51 bool flag = Base::check();
52#if TREEIN_CHECK
53 unsigned save = readLock(false);
54 Node* node;
55 node = left();
56 if(node) {
57 TREEIN_ASSERT(level == node->level+1); // Rule 2
58 } else {
59 if(root()) {
60 TREEIN_ASSERT(level == 1); // Rule 1
61 } else {
62 TREEIN_ASSERT(level == 0); // Rule 0
63 }
64 }
65 node = right();
66 if(node) {
67 TREEIN_ASSERT(level == node->level || level == node->level+1); // Rule 3
68 node = node->right();
69 if(node) {
70 TREEIN_ASSERT(level > node->level);
71 }
72 } else {
73 if(root()) {
74 TREEIN_ASSERT(level == 1); // Rule 1
75 } else {
76 TREEIN_ASSERT(level == 0); // Rule 0
77 }
78 }
79 readUnlock(save);
80#endif
81 return flag;
82}
83
84
85/**
86Constructor.
87
88Starts us as an empty list.
89*/
90template <class R, class N, class K, ContainerThreadSafety s, int n>
93
94/**
95Destructor.
96
97Removes all nodes attached to us.
98
99Doesn't actually call remove on every node to avoid possible unneeded rebalencing, just
100manually unlinks all nodes.
101*/
102template <class R, class N, class K, ContainerThreadSafety s, int n>
105
106/**
107Constructor.
108
109*/
110template <class R, class N, class K, ContainerThreadSafety s, int n>
114
115/**
116Destructor.
117
118Remove us from we are on, if any.
119*/
120template <class R, class N, class K, ContainerThreadSafety s, int n>
124
125/**
126 * @brief AATree Balancing
127 *
128 * Basic Rules
129 * @invariant
130 * @parblock
131 * AATrees have the following invariants:
132 *
133 * 1. leaf nodes have level = 1
134 * 2. left child have level = parent - 1
135 * 3. right child have level = parent - 1, or parent
136 * 4. right child of right child has level < grandparent (only 1 == in a row)
137 * 5. if level > 1, has both left and right.
138 *
139 * Implementation of Rules (reversing to look Up not down)
140 *
141 * Let L be the level of our Left child node
142 * Let R be the level of our Right child node
143 * Let G be the level of our Right-Right grandchild node.
144 *
145 * Non-existent nodes have a level of 0
146 *
147 * 1. Our level needs to be L+1
148 * 2. This value needs to be R+1, or G+1 (so R == L or G == L)
149 * 3. If this isn't possible, need to rotate to make this possible.
150 * 4. If L > R then our children our out of balance and we need to move nodes from
151 * the left to the right, so rotate to the right
152 * 5. if L == R or L == G, then our level = L+1, and can move up the tree
153 * 6. Else (L too much smaller than R) our children are out of balance so rotate
154 * to the left.
155 *
156 * Rule Check:
157 * 1. Satisfied, Leaf Nodes have no Left, or Left+1 = 1
158 * 2. Satisfied, Our basic rule, our level = Left+1
159 * 3. Satisfied, If L == R, then we are Right+1, if L == G then we are Right or Right+1
160 * 4. Satisfied, Since G can't be > L, we can't be == G.
161 * 5. Satisfied, If left empty, we are level 1, if right empty, then left must be
162 * empty or we can't get L == R or L == G
163 * @endparblock
164 */
165
166template <class R, class N, class K, ContainerThreadSafety s,int n>
168 Node* node = this;
169 unsigned save = readLock(true); // rebalence will need to upgrade
170 if(node->root() == nullptr) {
171 level = 0;
172 }
173 while(node) {
174 int levelL = 0, levelR = 0, levelG = 0;
175 Node* nodeL = node->left();
176 if(nodeL) {
177 levelL = nodeL->level;
178 }
179 Node* nodeR = node->right();
180 if(nodeR) {
181 levelR = nodeR->level;
182 nodeR = nodeR->right();
183 if(nodeR) {
184 levelG = nodeR->level;
185 }
186 }
187 if(levelL > levelR) {
188 node->rotateRight();
189 } else if(levelL == levelR || levelL == levelG) {
190 node->level = levelL + 1;
191 node = node->parent();
192 } else {
193 node->rotateLeft();
194 }
195 }
196 readUnlock(save);
197}
198
199#endif
Intrusive Binary Tree (balanced).
Intrusive Binary Tree, Implementation of Balancing Primitives.
virtual ~AATreeInNode()
Destructor.
Definition AATreeIn.hpp:121
bool check() const override
Definition AATreeIn.hpp:50
void rebalance() override
AATree Balancing.
Definition AATreeIn.hpp:167
class AATreeInNode< R, N, K, s, n > Node
Type of DListIInNode.
Definition AATreeIn.h:263
AATreeInNode()
Constructor.
Definition AATreeIn.hpp:111
virtual ~AATreeInRoot()
Destructor.
Definition AATreeIn.hpp:103
AATreeInRoot()
Constructor.
Definition AATreeIn.hpp:91