btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / private / kernel / util / SplayTree.h
blob4a2c8c7efb2f31d8df3c07ed763d65faa1ae8756
1 /*
2 * Copyright 2008-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
3 * Distributed under the terms of the MIT License.
5 * Original Java implementation:
6 * Available at http://www.link.cs.cmu.edu/splay/
7 * Author: Danny Sleator <sleator@cs.cmu.edu>
8 * This code is in the public domain.
9 */
10 #ifndef KERNEL_UTIL_SPLAY_TREE_H
11 #define KERNEL_UTIL_SPLAY_TREE_H
13 /*! Implements two classes:
15 SplayTree: A top-down splay tree.
17 IteratableSplayTree: Extends SplayTree by a singly-linked list to make it
18 cheaply iteratable (requires another pointer per node).
20 Both classes are templatized over a definition parameter with the following
21 (or a compatible) interface:
23 struct SplayTreeDefinition {
24 typedef xxx KeyType;
25 typedef yyy NodeType;
27 static const KeyType& GetKey(const NodeType* node);
28 static SplayTreeLink<NodeType>* GetLink(NodeType* node);
30 static int Compare(const KeyType& key, const NodeType* node);
32 // for IteratableSplayTree only
33 static NodeType** GetListLink(NodeType* node);
38 template<typename Node>
39 struct SplayTreeLink {
40 Node* left;
41 Node* right;
45 template<typename Definition>
46 class SplayTree {
47 protected:
48 typedef typename Definition::KeyType Key;
49 typedef typename Definition::NodeType Node;
50 typedef SplayTreeLink<Node> Link;
52 public:
53 SplayTree()
55 fRoot(NULL)
59 /*!
60 Insert into the tree.
61 \param node the item to insert.
63 bool Insert(Node* node)
65 Link* nodeLink = Definition::GetLink(node);
67 if (fRoot == NULL) {
68 fRoot = node;
69 nodeLink->left = NULL;
70 nodeLink->right = NULL;
71 return true;
74 Key key = Definition::GetKey(node);
75 _Splay(key);
77 int c = Definition::Compare(key, fRoot);
78 if (c == 0)
79 return false;
81 Link* rootLink = Definition::GetLink(fRoot);
83 if (c < 0) {
84 nodeLink->left = rootLink->left;
85 nodeLink->right = fRoot;
86 rootLink->left = NULL;
87 } else {
88 nodeLink->right = rootLink->right;
89 nodeLink->left = fRoot;
90 rootLink->right = NULL;
93 fRoot = node;
94 return true;
97 Node* Remove(const Key& key)
99 if (fRoot == NULL)
100 return NULL;
102 _Splay(key);
104 if (Definition::Compare(key, fRoot) != 0)
105 return NULL;
107 // Now delete the root
108 Node* node = fRoot;
109 Link* rootLink = Definition::GetLink(fRoot);
110 if (rootLink->left == NULL) {
111 fRoot = rootLink->right;
112 } else {
113 Node* temp = rootLink->right;
114 fRoot = rootLink->left;
115 _Splay(key);
116 Definition::GetLink(fRoot)->right = temp;
119 return node;
123 Remove from the tree.
124 \param node the item to remove.
126 bool Remove(Node* node)
128 Key key = Definition::GetKey(node);
129 _Splay(key);
131 if (node != fRoot)
132 return false;
134 // Now delete the root
135 Link* rootLink = Definition::GetLink(fRoot);
136 if (rootLink->left == NULL) {
137 fRoot = rootLink->right;
138 } else {
139 Node* temp = rootLink->right;
140 fRoot = rootLink->left;
141 _Splay(key);
142 Definition::GetLink(fRoot)->right = temp;
145 return true;
149 Find the smallest item in the tree.
151 Node* FindMin()
153 if (fRoot == NULL)
154 return NULL;
156 Node* node = fRoot;
158 while (Node* left = Definition::GetLink(node)->left)
159 node = left;
161 _Splay(Definition::GetKey(node));
163 return node;
167 Find the largest item in the tree.
169 Node* FindMax()
171 if (fRoot == NULL)
172 return NULL;
174 Node* node = fRoot;
176 while (Node* right = Definition::GetLink(node)->right)
177 node = right;
179 _Splay(Definition::GetKey(node));
181 return node;
185 Find an item in the tree.
187 Node* Lookup(const Key& key)
189 if (fRoot == NULL)
190 return NULL;
192 _Splay(key);
194 return Definition::Compare(key, fRoot) == 0 ? fRoot : NULL;
197 Node* Root() const
199 return fRoot;
203 Test if the tree is logically empty.
204 \return true if empty, false otherwise.
206 bool IsEmpty() const
208 return fRoot == NULL;
211 Node* PreviousDontSplay(const Key& key) const
213 Node* closestNode = NULL;
214 Node* node = fRoot;
215 while (node != NULL) {
216 if (Definition::Compare(key, node) > 0) {
217 closestNode = node;
218 node = Definition::GetLink(node)->right;
219 } else
220 node = Definition::GetLink(node)->left;
223 return closestNode;
226 Node* FindClosest(const Key& key, bool greater, bool orEqual)
228 if (fRoot == NULL)
229 return NULL;
231 _Splay(key);
233 Node* closestNode = NULL;
234 Node* node = fRoot;
235 while (node != NULL) {
236 int compare = Definition::Compare(key, node);
237 if (compare == 0 && orEqual)
238 return node;
240 if (greater) {
241 if (compare < 0) {
242 closestNode = node;
243 node = Definition::GetLink(node)->left;
244 } else
245 node = Definition::GetLink(node)->right;
246 } else {
247 if (compare > 0) {
248 closestNode = node;
249 node = Definition::GetLink(node)->right;
250 } else
251 node = Definition::GetLink(node)->left;
255 return closestNode;
258 SplayTree& operator=(const SplayTree& other)
260 fRoot = other.fRoot;
261 return *this;
264 private:
266 Internal method to perform a top-down splay.
268 _Splay(key) does the splay operation on the given key.
269 If key is in the tree, then the node containing
270 that key becomes the root. If key is not in the tree,
271 then after the splay, key.root is either the greatest key
272 < key in the tree, or the least key > key in the tree.
274 This means, among other things, that if you splay with
275 a key that's larger than any in the tree, the rightmost
276 node of the tree becomes the root. This property is used
277 in the Remove() method.
279 void _Splay(const Key& key) {
280 Link headerLink;
281 headerLink.left = headerLink.right = NULL;
283 Link* lLink = &headerLink;
284 Link* rLink = &headerLink;
286 Node* l = NULL;
287 Node* r = NULL;
288 Node* t = fRoot;
290 for (;;) {
291 int c = Definition::Compare(key, t);
292 if (c < 0) {
293 Node*& left = Definition::GetLink(t)->left;
294 if (left == NULL)
295 break;
297 if (Definition::Compare(key, left) < 0) {
298 // rotate right
299 Node* y = left;
300 Link* yLink = Definition::GetLink(y);
301 left = yLink->right;
302 yLink->right = t;
303 t = y;
304 if (yLink->left == NULL)
305 break;
308 // link right
309 rLink->left = t;
310 r = t;
311 rLink = Definition::GetLink(r);
312 t = rLink->left;
313 } else if (c > 0) {
314 Node*& right = Definition::GetLink(t)->right;
315 if (right == NULL)
316 break;
318 if (Definition::Compare(key, right) > 0) {
319 // rotate left
320 Node* y = right;
321 Link* yLink = Definition::GetLink(y);
322 right = yLink->left;
323 yLink->left = t;
324 t = y;
325 if (yLink->right == NULL)
326 break;
329 // link left
330 lLink->right = t;
331 l = t;
332 lLink = Definition::GetLink(l);
333 t = lLink->right;
334 } else
335 break;
338 // assemble
339 Link* tLink = Definition::GetLink(t);
340 lLink->right = tLink->left;
341 rLink->left = tLink->right;
342 tLink->left = headerLink.right;
343 tLink->right = headerLink.left;
344 fRoot = t;
347 protected:
348 Node* fRoot;
352 template<typename Definition>
353 class IteratableSplayTree {
354 protected:
355 typedef typename Definition::KeyType Key;
356 typedef typename Definition::NodeType Node;
357 typedef SplayTreeLink<Node> Link;
358 typedef IteratableSplayTree<Definition> Tree;
360 public:
361 class Iterator {
362 public:
363 Iterator()
367 Iterator(const Iterator& other)
369 *this = other;
372 Iterator(Tree* tree)
374 fTree(tree)
376 Rewind();
379 Iterator(Tree* tree, Node* next)
381 fTree(tree),
382 fCurrent(NULL),
383 fNext(next)
387 bool HasNext() const
389 return fNext != NULL;
392 Node* Next()
394 fCurrent = fNext;
395 if (fNext != NULL)
396 fNext = *Definition::GetListLink(fNext);
397 return fCurrent;
400 Node* Current()
402 return fCurrent;
405 Node* Remove()
407 Node* element = fCurrent;
408 if (fCurrent) {
409 fTree->Remove(fCurrent);
410 fCurrent = NULL;
412 return element;
415 Iterator &operator=(const Iterator &other)
417 fTree = other.fTree;
418 fCurrent = other.fCurrent;
419 fNext = other.fNext;
420 return *this;
423 void Rewind()
425 fCurrent = NULL;
426 fNext = fTree->fFirst;
429 private:
430 Tree* fTree;
431 Node* fCurrent;
432 Node* fNext;
435 class ConstIterator {
436 public:
437 ConstIterator()
441 ConstIterator(const ConstIterator& other)
443 *this = other;
446 ConstIterator(const Tree* tree)
448 fTree(tree)
450 Rewind();
453 ConstIterator(const Tree* tree, Node* next)
455 fTree(tree),
456 fNext(next)
460 bool HasNext() const
462 return fNext != NULL;
465 Node* Next()
467 Node* node = fNext;
468 if (fNext != NULL)
469 fNext = *Definition::GetListLink(fNext);
470 return node;
473 ConstIterator &operator=(const ConstIterator &other)
475 fTree = other.fTree;
476 fNext = other.fNext;
477 return *this;
480 void Rewind()
482 fNext = fTree->fFirst;
485 private:
486 const Tree* fTree;
487 Node* fNext;
490 IteratableSplayTree()
492 fTree(),
493 fFirst(NULL)
497 bool Insert(Node* node)
499 if (!fTree.Insert(node))
500 return false;
502 Node** previousNext;
503 if (Node* previous = fTree.PreviousDontSplay(Definition::GetKey(node)))
504 previousNext = Definition::GetListLink(previous);
505 else
506 previousNext = &fFirst;
508 *Definition::GetListLink(node) = *previousNext;
509 *previousNext = node;
511 return true;
514 Node* Remove(const Key& key)
516 Node* node = fTree.Remove(key);
517 if (node == NULL)
518 return NULL;
520 Node** previousNext;
521 if (Node* previous = fTree.PreviousDontSplay(key))
522 previousNext = Definition::GetListLink(previous);
523 else
524 previousNext = &fFirst;
526 *previousNext = *Definition::GetListLink(node);
528 return node;
531 bool Remove(Node* node)
533 if (!fTree.Remove(node))
534 return false;
536 Node** previousNext;
537 if (Node* previous = fTree.PreviousDontSplay(Definition::GetKey(node)))
538 previousNext = Definition::GetListLink(previous);
539 else
540 previousNext = &fFirst;
542 *previousNext = *Definition::GetListLink(node);
544 return true;
547 Node* Lookup(const Key& key)
549 return fTree.Lookup(key);
552 Node* Root() const
554 return fTree.Root();
558 Test if the tree is logically empty.
559 \return true if empty, false otherwise.
561 bool IsEmpty() const
563 return fTree.IsEmpty();
566 Node* FindClosest(const Key& key, bool greater, bool orEqual)
568 return fTree.FindClosest(key, greater, orEqual);
571 Node* FindMin()
573 return fTree.FindMin();
576 Node* FindMax()
578 return fTree.FindMax();
581 Iterator GetIterator()
583 return Iterator(this);
586 ConstIterator GetIterator() const
588 return ConstIterator(this);
591 Iterator GetIterator(const Key& key, bool greater, bool orEqual)
593 return Iterator(this, fTree.FindClosest(key, greater, orEqual));
596 ConstIterator GetIterator(const Key& key, bool greater, bool orEqual) const
598 return ConstIterator(this, FindClosest(key, greater, orEqual));
601 IteratableSplayTree& operator=(const IteratableSplayTree& other)
603 fTree = other.fTree;
604 fFirst = other.fFirst;
605 return *this;
608 protected:
609 friend class Iterator;
610 friend class ConstIterator;
611 // needed for gcc 2.95.3 only
613 SplayTree<Definition> fTree;
614 Node* fFirst;
618 #endif // KERNEL_UTIL_SPLAY_TREE_H