Intrusive Containers
Loading...
Searching...
No Matches
BalTreeIn.h
Go to the documentation of this file.
1#ifndef BalTreeIn_H
2#define BalTreeIn_H
3
4/**
5@file BalTreeIn.h
6@brief Intrusive Binary Tree (balenced).
7
8This file defines a pair of templates (BalTreeInRoot and BalTreeInNode) 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
36BalTreeInRoot and BalTreeInNode 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 makes no attempt to "balence" the tree, but is designed that it can be derived
40from by a class to implement any needed balencing, but does supply the rotations to do that balencing.
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
78From TreeIn.h:
79
80Given:
81+ R& root
82+ N& node
83
84TreeInRoot:
85+ if root.m_base != nullptr:
86 + root.m_base-> m_root == &root
87 + root.m_base-> m_parent == nullptr
88
89TreeInNode:
90+ if node.m_root == NULL: // Free Node
91 + node.m_parent == NULL
92 + node.m_left == NULL
93 + node.m_right == NULL
94+ if node.m_root != NULL and node.m_parent == NULL // Base Node
95 + node.m_root->m_base == &node
96+ if node.m_parent != nullptr: // Child Node
97 + Either node.m_parent->m_left or node.m_parent->m_right == &node
98+ if node.m_left != nullptr
99 + node.m_left->m_parent = &node
100 + node.m_left->m_root == node.m_root
101 + node.m_root->compare(node, *m_left) <= 0
102 + node.m_root->compare(*m_left, node) >= 0
103+ if node.m_right != nullptr:
104 + node.m_right->m_parent = &node
105 + node.m_right->m_root == node.m_root
106 + node.m_root->compare(node, *m_right) >= 0
107 + node.m_root->compare(*m_right, node) <= 0
108@endparblock
109
110@ingroup IntrusiveContainers
111*/
112
113#include <Containers/TreeIn.H>
114
115template <class R, class N, class K, ContainerThreadSafety s=ContainerNoSafety, int n> class BalTreeInNode;
116template <class R, class N, class K, ContainerThreadSafety s=ContainerNoSafety, int n = 0> class BalTreeInRoot;
117
118/**
119@class BalTreeInRoot
120
121Intrusive Binary Tree, Root.
122
123@tparam R The class that will be the owner of the Tree. Must derive from TreeInRoot<R, N, K, n>
124@tparam N The class that will be the nodes of the Tree. Must derive from TreeInNode<R, N, K, n>
125@tparam K The class defining the Key used to lookup Nodes in the tree.
126@tparam s The ContainerThreadSafety value to define the thread safety model of the Container
127@tparam n A numerical parameter to allow a give List/Node combination to have multiple list-node relationships. Defaults to 0 if not provided.
128
129
130@invariant
131@parblock
132 From TreeInRoot:
133 + if m_base not nullptr:
134 + m_base->m_root == this.
135 + m_base->m_parent == nullptr
136@endparblock
137
138@see BalTreeInNode
139@ingroup IntrusiveContainers
140
141Note, because base class is a template, we have many forwarding functions to that
142base to avoid errors and warnings about thing missing.
143*/
144template <class R, class N, class K, ContainerThreadSafety s, int n> class BalTreeInRoot :
145 public TreeInRoot<R,N,K,s, n> {
146
147 friend class BalTreeInNode<R, N, K, s, n>;
148 typedef class TreeInRoot<R, N, K, s, n> Base;
149 typedef class BalTreeInRoot<R, N, K, s, n> Root; ///< Type of TreeInRoot
150 typedef class BalTreeInNode<R, N, K, s, n> Node; ///< Type of DListIInNode
151
152public:
154 virtual ~BalTreeInRoot();
155
156 int compare(N const& node1, N const& node2) const {
157 return Base::compare(node1, node2);
158 }
159 int compareKey(N const& node, K key) const {
160 return Base::compareKey(node, key);
161 }
162
163// virtual void add(N& node);
164// void add(N* node);
165// void remove(N& node);
166// void remove(N* node);
167// N* find(K key) const;
168
169 N* base() const { return Base::base(); }
170 N* first() const { return Base::first(); }
171 N* last() const { return Base::last(); }
172
173 bool check() const override;
174
175 // Critical Sections used to Update the Container
176 unsigned writeLock(bool upgrade) const { return Container<s>::writeLock(upgrade); }
177 void writeUnlock(unsigned save) const { Container<s>::writeUnlock(save); }
178 // Critical Section used to Read/Search the Container
179 unsigned readLock(bool upgrade) const { return Container<s>::readLock(upgrade); }
180 void readUnlock(unsigned save) const { Container<s>::readUnlock(save);}
181};
182
183/**
184@class BalTreeInNode
185
186Intrusive Binary Tree, Node.
187
188@tparam R The class that will be the owner of the List. Must derive from TreeInRoot<R, N, K, n>
189@tparam N The class that will be the nodes of the List. Must derive from TreeInNode<R, N, K, n>
190@tparam K The class defining the Key used to lookup Nodes in the tree.
191@tparam s The ContainerThreadSafety value to define the thread safety model of the Container
192@tparam n A numerical parameter to allow a give List/Node combination to have multiple list-node relationships. Defaults to 0 if not provided.
193
194@invariant
195@parblock
196From TreeInNode:
197 + if m_root == NULL: // Free Node
198 + m_parent == NULL
199 + m_left == NULL
200 + m_right == NULL
201+ if m_root != NULL and m_parent == NULL // Base Node
202 + m_root->m_base == this
203+ if m_parent != nullptr: // Child Node
204 + Either m_parent->m_left or parent->m_right == this
205+ if m_left != nullptr
206 + m_left->m_parent = this
207 + m_left->m_root == m_root
208 + m_root->compare(*this, *m_left) <= 0
209 + m_root->compare(*m_left, *this) >= 0
210+ if m_right != nullptr:
211 + m_right->m_parent = this
212 + m_right->m_root == m_root
213 + m_root->compare(*this, *m_right) >= 0
214 + m_root->compare(*m_right, *this) <= 0
215@endparblock
216
217@see BalTreeInRoot
218@ingroup IntrusiveContainers
219
220*/
221template <class R, class N, class K, ContainerThreadSafety s, int n> class BalTreeInNode :
222 public TreeInNode<R, N, K, s, n> {
223 friend class BalTreeInRoot<R, N, K, s, n>;
224 typedef class TreeInNode<R, N, K, s, n> Base;
225 typedef class BalTreeInRoot<R, N, K, s, n> Root; ///< Type of Root
226 typedef class BalTreeInNode<R, N, K, s, n> Node; ///< Type of Node
227protected:
228 BalTreeInNode(); // No default add as that needs our Parent already constructed
229 virtual ~BalTreeInNode();
230
231// void addTo(R& root);
232// void addTo(R* root);
233// virtual void remove(); // Virtual so "fancier" trees can rebalence
234
235 R* root() const { return Base::root(); }
236 N* parent() const { return Base::parent(); }
237 N* left() const { return Base::left(); }
238 N* right() const { return Base::right(); }
239 N* next() const { return Base::next(); }
240 N* prev() const { return Base::prev(); }
241
242 N* rotateRight();
243 N* rotateLeft();
244
245 bool check() const override;
246 void rebalance() override = 0;
247
248 // Critical Sections used to Update the Container
249 unsigned writeLock(bool upgrade) const { return ContainerNode<s>::writeLock(upgrade); }
250 void writeUnlock(unsigned save) const { ContainerNode<s>::writeUnlock(save); }
251 // Critical Section used to Read/Search the Container
252 unsigned readLock(bool upgrade) const { return ContainerNode<s>::readLock(upgrade); }
253 void readUnlock(unsigned save) const { ContainerNode<s>::readUnlock(save);}
254};
255
256#endif
Intrusive Binary Tree (unbalanced).
Intrusive Binary Tree, Node.
Definition BalTreeIn.h:222
BalTreeInNode()
Constructor.
Definition BalTreeIn.hpp:133
virtual ~BalTreeInNode()
Destructor.
Definition BalTreeIn.hpp:141
unsigned readLock(bool upgrade) const
Definition BalTreeIn.h:252
N * right() const
Definition BalTreeIn.h:238
R * root() const
Definition BalTreeIn.h:235
unsigned writeLock(bool upgrade) const
Definition BalTreeIn.h:249
N * next() const
Definition BalTreeIn.h:239
N * rotateLeft()
Balance tree with a Left Rotate.
Definition BalTreeIn.hpp:175
N * rotateRight()
Balance Tree with a Right Rotate.
Definition BalTreeIn.hpp:216
void rebalance() override=0
Hook to allow Balanced trees to rebalance from current node, just changed.
class BalTreeInNode< R, N, K, s, n > Node
Type of Node.
Definition BalTreeIn.h:226
class TreeInNode< R, N, K, s, n > Base
Definition BalTreeIn.h:224
class BalTreeInRoot< R, N, K, s, n > Root
Type of Root.
Definition BalTreeIn.h:225
N * left() const
Definition BalTreeIn.h:237
N * parent() const
Definition BalTreeIn.h:236
N * prev() const
Definition BalTreeIn.h:240
bool check() const override
Definition BalTreeIn.hpp:106
void readUnlock(unsigned save) const
Definition BalTreeIn.h:253
void writeUnlock(unsigned save) const
Definition BalTreeIn.h:250
Intrusive Binary Tree, Root.
Definition BalTreeIn.h:145
N * base() const
Definition BalTreeIn.h:169
class BalTreeInRoot< R, N, K, s, n > Root
Type of TreeInRoot.
Definition BalTreeIn.h:149
class BalTreeInNode< R, N, K, s, n > Node
Type of DListIInNode.
Definition BalTreeIn.h:150
N * last() const
Definition BalTreeIn.h:171
bool check() const override
Definition BalTreeIn.hpp:107
class TreeInRoot< R, N, K, s, n > Base
Definition BalTreeIn.h:148
int compare(N const &node1, N const &node2) const
Definition BalTreeIn.h:156
N * first() const
Definition BalTreeIn.h:170
unsigned writeLock(bool upgrade) const
Definition BalTreeIn.h:176
void readUnlock(unsigned save) const
Definition BalTreeIn.h:180
virtual ~BalTreeInRoot()
Destructor.
Definition BalTreeIn.hpp:125
void writeUnlock(unsigned save) const
Definition BalTreeIn.h:177
int compareKey(N const &node, K key) const
Definition BalTreeIn.h:159
unsigned readLock(bool upgrade) const
Definition BalTreeIn.h:179
BalTreeInRoot()
Constructor.
Definition BalTreeIn.hpp:116
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
Intrusive Binary Tree, Node.
Definition TreeIn.h:276
Intrusive Binary Tree, Root.
Definition TreeIn.h:154