Intrusive Containers
Loading...
Searching...
No Matches
AATreeIn.h
Go to the documentation of this file.
1#ifndef AATreeIn_H
2#define AATreeIn_H
3
4/**
5@file AATreeIn.h
6@brief Intrusive Binary Tree (balanced).
7
8This file defines a pair of templates (AATreeInRoot and AATreeInNode) 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@par Overview
35@parblock
36AATreeInRoot and AATreeInNode provide a simple API to allow classes to provide a
37basic Tree <-> Node relationship (1 Tree Root holding many Nodes) as a Binary Tree.
38
39Note that this class implement a balanced AA Tree as described at https://en.wikipedia.org/wiki/AA_tree
40which is a simple form of balanced tree
41
42To create this relationship, the class to act as the tree root derives from the template TreeInRoot,
43and the class to act as the Node from TreeInNode, both with a first parameter of the class name
44of the List class, a second parameter of the Node class, and a 3rd type parameter for the type for the
45Key to use in searching the tree. There is an optional integral 4rd parameter
46to allow the classes to inherent from these multiple times if you need to represent multiple simultaneous
47relationships. This inheritance should be public, or you need to add the TreeInRoot and TreeInNode templates as
48friends.
49
50At the point of declaration, both classes need to be declared, so you will typically have a forward of the other
51class before the definition of the class. At the point of usage of members, generally the full definition of both
52classes is needed to instance the code for the template.
53
54The user of the class will need to define two member functions to configure the tree.
55int TreeInRoot::compare(N& node1, N& node2) const;
56and
57int TreeInRoot::compare(N& node, K key) const;
58
59Inside this file, the following types have the following meanings:
60
61R: The "user" type that will be derived from TreeInRoot
62
63N: The "user" type that will be derived from TreeInNode
64
65K: The "user" type that represents the Key for the tree.
66
67n: The integer parameter for the template to allow multiple usage
68
69List: The particular instance of TreeInRoot<R, N, K, n> being used
70
71Node: The particular instance of TreeInNode<R, N, K, n> being used
72
73node: will have type N*, to be used when walking the list.
74@endparblock
75
76@invariant
77@parblock
78Given:
79+ R& root
80+ N& node
81
82New:
83AATreeInNode
84+ if node.m_right == nullptr: // leaf node
85 + node.level == 1
86 + mode.m_left == nullptr
87+ if node. m_left != nullptr:
88 + node.m_left->m_level + 1 == node.m_level
89 + node.m_right != nullptr
90= if node.m_right != nullptr:
91 + node.m_right->m_level == node.m_level || node.m_right->m_level + 1 == node.m_level
92 + if node.m_right->m_right != nullptr:
93 + node.m_right->m_right->m_level < node.m_level // only 1 stay at level in a row in a row)
94+ if level > 1:
95 + node.m_left != nullptr
96 + node.m_right != nullptr
97
98Simplified if null items have level == 0
99+ m_level == m_left->m_level + 1
100+ m_level == m_right->m_level + 1 || m_right->m_right->m_level + 1
101
102
103From TreeIn.h:
104
105TreeInRoot
106+ if root.m_base != nullptr:
107 + root.m_base-> m_root == &root
108 + root.m_base-> m_parent == nullptr
109
110TreeInNode
111+ if node.m_root == NULL: // Free Node
112 + node.m_parent == NULL
113 + node.m_left == NULL
114 + node.m_right == NULL
115+ if node.m_root != NULL and node.m_parent == NULL // Base Node
116 + node.m_root->m_base == &node
117+ if node.m_parent != nullptr: // Child Node
118 + Either node.m_parent->m_left or node.m_parent->m_right == &node
119+ if node.m_left != nullptr
120 + node.m_left->m_parent = &node
121 + node.m_left->m_root == node.m_root
122 + node.m_root->compare(node, *m_left) <= 0
123 + node.m_root->compare(*m_left, node) >= 0
124+ if node.m_right != nullptr:
125 + node.m_right->m_parent = &node
126 + node.m_right->m_root == node.m_root
127 + node.m_root->compare(node, *m_right) >= 0
128 + node.m_root->compare(*m_right, node) <= 0
129@endparblock
130
131@ingroup IntrusiveContainers
132*/
133
134#include "BalTreeIn.h"
135
136template <class R, class N, class K, ContainerThreadSafety s=ContainerNoSafety, int n = 0> class AATreeInNode;
137template <class R, class N, class K, ContainerThreadSafety s=ContainerNoSafety, int n = 0> class AATreeInRoot;
138
139/**
140@class AATreeInRoot
141
142Intrusive Binary Tree, Root.
143
144@tparam R The class that will be the owner of the Tree. Must derive from TreeInRoot<R, N, K, n>
145@tparam N The class that will be the nodes of the Tree. Must derive from TreeInNode<R, N, K, n>
146@tparam K The class defining the Key used to lookup Nodes in the tree.
147@tparam s The ContainerThreadSafety value to define the thread safety model of the Container
148@tparam n A numerical parameter to allow a give List/Node combination to have multiple list-node relationships. Defaults to 0 if not provided.
149
150@invariant
151@parblock
152From TreeIn:
153+ if m_base != nullptr:
154 + m_base-> m_root == this
155 + m_base-> m_parent == nullptr
156
157@endparblock
158
159@see TreeInNode
160@ingroup IntrusiveContainers
161
162*/
163template <class R, class N, class K, ContainerThreadSafety s, int n> class AATreeInRoot :
164 public BalTreeInRoot<R,N,K,s,n> {
165
166 friend class AATreeInNode<R, N, K, s, n>;
167 typedef class BalTreeInRoot<R, N, K, s, n> Base;
168 typedef class AATreeInRoot<R, N, K, s, n> Root; ///< Type of TreeInRoot
169 typedef class AATreeInNode<R, N, K, s, n> Node; ///< Type of DListIInNode
170protected:
171 AATreeInRoot();
172 virtual ~AATreeInRoot();
173
174 int compare(N const& node1, N const& node2) const {
175 return Base::compare(node1, node2);
176 }
177 int compareKey(N const& node, K key) const {
178 return Base::compareKey(node, key);
179 }
180
181// virtual void add(N& node);
182// void add(N* node);
183// void remove(N& node);
184// void remove(N* node);
185// N* find(K key) const;
186
187 N* base() const { return Base::base(); }
188 N* first() const { return Base::first(); }
189 N* last() const { return Base::last(); }
190
191 // virtual bool check() const;
192 // Critical Sections used to Update the Container
193 unsigned writeLock() const { return Container<s>::writeLock(); }
194 void writeUnlock(unsigned save) const { Container<s>::writeUnlock(save); }
195 // Critical Section used to Read/Search the Container
196 unsigned readLock() const { return Container<s>::readLock(); }
197 void readUnlock(unsigned save) const { Container<s>::readUnlock(save);}
198};
199
200/**
201@class AATreeInNode
202
203Intrusive Binary Tree, Node.
204
205@tparam R The class that will be the owner of the List. Must derive from TreeInRoot<R, N, K, n>
206@tparam N The class that will be the nodes of the List. Must derive from TreeInNode<R, N, K, n>
207@tparam K The class defining the Key used to lookup Nodes in the tree.
208@tparam s The ContainerThreadSafety value to define the thread safety model of the Container
209@tparam n A numerical parameter to allow a give List/Node combination to have multiple list-node relationships. Defaults to 0 if not provided.
210
211@invariant
212@parblock
213 New:
214 + if m_right == nullptr:
215 + level == 1
216 + m_left == nullptr
217 + if m_left != nullptr:
218 + m_left->m_level + 1 == level
219 + m_right != nullptr
220 = if m_right != nullptr:
221 + m_right->m_level == m_level || m_right->m_level + 1 == m_level
222 + if m_right->m_right != nullptr:
223 + m_right->m_right->m_level < m_level // only 1 stay at level in a row in a row)
224 + if level > 1:
225 + m_left != nullptr
226 + m_right != nullptr
227
228Simplified if null items have level == 0
229+ m_level == m_left->m_level + 1
230+ m_level == m_right->m_level + 1 || m_right->m_right->m_level + 1
231
232From TreeInNode:
233 + if m_root == NULL: // Free Node
234 + m_parent == NULL
235 + m_left == NULL
236 + m_right == NULL
237+ if m_root != NULL and m_parent == NULL // Base Node
238 + m_root->m_base == this
239+ if m_parent != nullptr: // Child Node
240 + Either m_parent->m_left or parent->m_right == this
241+ if m_left != nullptr
242 + m_left->m_parent = this
243 + m_left->m_root == m_root
244 + m_root->compare(*this, *m_left) <= 0
245 + m_root->compare(*m_left, *this) >= 0
246+ if m_right != nullptr:
247 + m_right->m_parent = this
248 + m_right->m_root == m_root
249 + m_root->compare(*this, *m_right) >= 0
250 + m_root->compare(*m_right, *this) <= 0
251
252@endparblock
253
254@see AATreeInRoot
255@ingroup IntrusiveContainers
256
257*/
258template <class R, class N, class K, ContainerThreadSafety s, int n> class AATreeInNode :
259 public BalTreeInNode<R, N, K, s, n> {
260 friend class AATreeInRoot<R, N, K, s, n>;
261 typedef class BalTreeInNode<R, N, K, s, n> Base;
262 typedef class AATreeInRoot<R, N, K, s, n> Root; ///< Type of TreeInRoot
263 typedef class AATreeInNode<R, N, K, s, n> Node; ///< Type of DListIInNode
264protected:
265 AATreeInNode(); // No default add as that needs our Parent already constructed
266 virtual ~AATreeInNode();
267
268// void addTo(R& root);
269// void addTo(R* root);
270// virtual void remove(); // Virtual so "fancier" trees can be rebalanced
271
272 R* root() const { return Base::root(); }
273 N* parent() const { return Base::parent(); }
274 N* left() const { return Base::left(); }
275 N* right() const { return Base::right(); }
276 N* next() const { return Base::next(); }
277 N* prev() const { return Base::prev(); }
278
279 N* rotateRight() { return Base::rotateRight(); }
280 N* rotateLeft() { return Base::rotateLeft(); }
281
282 bool check() const override;
283 void rebalance() override;
284
285 // Critical Sections used to Update the Container
286 unsigned writeLock(bool upgrade) const { return ContainerNode<s>::writeLock(upgrade); }
287 void writeUnlock(unsigned save) const { ContainerNode<s>::writeUnlock(save); }
288 // Critical Section used to Read/Search the Container
289 unsigned readLock(bool upgrade) const { return ContainerNode<s>::readLock(upgrade); }
290 void readUnlock(unsigned save) const { ContainerNode<s>::readUnlock(save);}
291
292protected:
293 int level = 0; ///< Node Level
294};
295
296#endif
Intrusive Binary Tree (balenced).
Intrusive Binary Tree, Node.
Definition AATreeIn.h:259
virtual ~AATreeInNode()
Destructor.
Definition AATreeIn.hpp:121
bool check() const override
Definition AATreeIn.hpp:50
R * root() const
Definition AATreeIn.h:272
class AATreeInRoot< R, N, K, s, n > Root
Type of TreeInRoot.
Definition AATreeIn.h:262
void readUnlock(unsigned save) const
Definition AATreeIn.h:290
N * rotateLeft()
Definition AATreeIn.h:280
unsigned readLock(bool upgrade) const
Definition AATreeIn.h:289
N * next() const
Definition AATreeIn.h:276
void rebalance() override
AATree Balancing.
Definition AATreeIn.hpp:167
unsigned writeLock(bool upgrade) const
Definition AATreeIn.h:286
class AATreeInNode< R, N, K, s, n > Node
Type of DListIInNode.
Definition AATreeIn.h:263
class BalTreeInNode< R, N, K, s, n > Base
Definition AATreeIn.h:261
N * parent() const
Definition AATreeIn.h:273
N * left() const
Definition AATreeIn.h:274
N * right() const
Definition AATreeIn.h:275
int level
Node Level.
Definition AATreeIn.h:293
N * rotateRight()
Definition AATreeIn.h:279
AATreeInNode()
Constructor.
Definition AATreeIn.hpp:111
N * prev() const
Definition AATreeIn.h:277
void writeUnlock(unsigned save) const
Definition AATreeIn.h:287
Intrusive Binary Tree, Root.
Definition AATreeIn.h:164
unsigned writeLock() const
Definition AATreeIn.h:193
class AATreeInNode< R, N, K, s, n > Node
Type of DListIInNode.
Definition AATreeIn.h:169
unsigned readLock() const
Definition AATreeIn.h:196
class BalTreeInRoot< R, N, K, s, n > Base
Definition AATreeIn.h:167
N * first() const
Definition AATreeIn.h:188
class AATreeInRoot< R, N, K, s, n > Root
Type of TreeInRoot.
Definition AATreeIn.h:168
virtual ~AATreeInRoot()
Destructor.
Definition AATreeIn.hpp:103
void writeUnlock(unsigned save) const
Definition AATreeIn.h:194
N * base() const
Definition AATreeIn.h:187
int compareKey(N const &node, K key) const
Definition AATreeIn.h:177
AATreeInRoot()
Constructor.
Definition AATreeIn.hpp:91
int compare(N const &node1, N const &node2) const
Definition AATreeIn.h:174
N * last() const
Definition AATreeIn.h:189
void readUnlock(unsigned save) const
Definition AATreeIn.h:197
Intrusive Binary Tree, Node.
Definition BalTreeIn.h:222
Intrusive Binary Tree, Root.
Definition BalTreeIn.h:145
unsigned writeLock(bool upgrade) const
Obtain a write lock.
unsigned readLock(bool upgradable) const
Obtain a read lock.
void readUnlock(unsigned code) const
Release the read lock that was held.
void writeUnlock(unsigned code) const
Release write lock.
unsigned readLock(bool upgradable) const
void readUnlock(unsigned code) const
unsigned writeLock(bool upgrade) const
void writeUnlock(unsigned code) const