xref: /haiku/headers/private/kernel/util/SplayTree.h (revision f9a8f3e72773095d5d7b2f2e1ff3eb3e58122f14)
1 /*
2  * Copyright 2008-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
3  * Distributed under the terms of the MIT License.
4  *
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
12 
13 /*!	Implements two classes:
14 
15 	SplayTree: A top-down splay tree.
16 
17 	IteratableSplayTree: Extends SplayTree by a singly-linked list to make it
18 	cheaply iteratable (requires another pointer per node).
19 
20 	Both classes are templatized over a definition parameter with the following
21 	(or a compatible) interface:
22 
23 	struct SplayTreeDefinition {
24 		typedef xxx KeyType;
25 		typedef	yyy NodeType;
26 
27 		static const KeyType& GetKey(const NodeType* node);
28 		static SplayTreeLink<NodeType>* GetLink(NodeType* node);
29 
30 		static int Compare(const KeyType& key, const NodeType* node);
31 
32 		// for IteratableSplayTree only
33 		static NodeType** GetListLink(NodeType* node);
34 	};
35 */
36 
37 
38 template<typename Node>
39 struct SplayTreeLink {
40 	Node*	left;
41 	Node*	right;
42 };
43 
44 
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;
51 
52 public:
SplayTree()53 	SplayTree()
54 		:
55 		fRoot(NULL)
56 	{
57 	}
58 
59 	/*!
60 		Insert into the tree.
61 		\param node the item to insert.
62 	*/
Insert(Node * node)63 	bool Insert(Node* node)
64 	{
65 		Link* nodeLink = Definition::GetLink(node);
66 
67 		if (fRoot == NULL) {
68 			fRoot = node;
69 			nodeLink->left = NULL;
70 			nodeLink->right = NULL;
71 			return true;
72 		}
73 
74 		Key key = Definition::GetKey(node);
75 		_Splay(key);
76 
77 		int c = Definition::Compare(key, fRoot);
78 		if (c == 0)
79 			return false;
80 
81 		Link* rootLink = Definition::GetLink(fRoot);
82 
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;
91 		}
92 
93 		fRoot = node;
94 		return true;
95 	}
96 
Remove(const Key & key)97 	Node* Remove(const Key& key)
98 	{
99 		if (fRoot == NULL)
100 			return NULL;
101 
102 		_Splay(key);
103 
104 		if (Definition::Compare(key, fRoot) != 0)
105 			return NULL;
106 
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;
117 		}
118 
119 		return node;
120 	}
121 
122 	/*!
123 		Remove from the tree.
124 		\param node the item to remove.
125 	*/
Remove(Node * node)126 	bool Remove(Node* node)
127 	{
128 		Key key = Definition::GetKey(node);
129 		_Splay(key);
130 
131 		if (node != fRoot)
132 			return false;
133 
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;
143 		}
144 
145 		return true;
146 	}
147 
148 	/*!
149 		Find the smallest item in the tree.
150 	*/
FindMin()151 	Node* FindMin()
152 	{
153 		if (fRoot == NULL)
154 			return NULL;
155 
156 		Node* node = fRoot;
157 
158 		while (Node* left = Definition::GetLink(node)->left)
159 			node = left;
160 
161 		_Splay(Definition::GetKey(node));
162 
163 		return node;
164 	}
165 
166 	/*!
167 		Find the largest item in the tree.
168 	*/
FindMax()169 	Node* FindMax()
170 	{
171 		if (fRoot == NULL)
172 			return NULL;
173 
174 		Node* node = fRoot;
175 
176 		while (Node* right = Definition::GetLink(node)->right)
177 			node = right;
178 
179 		_Splay(Definition::GetKey(node));
180 
181 		return node;
182 	}
183 
184 	/*!
185 		Find an item in the tree.
186 	*/
Lookup(const Key & key)187 	Node* Lookup(const Key& key)
188 	{
189 		if (fRoot == NULL)
190 			return NULL;
191 
192 		_Splay(key);
193 
194 		return Definition::Compare(key, fRoot) == 0 ? fRoot : NULL;
195 	}
196 
Root()197 	Node* Root() const
198 	{
199 		return fRoot;
200 	}
201 
202 	/*!
203 		Test if the tree is logically empty.
204 		\return true if empty, false otherwise.
205 	*/
IsEmpty()206 	bool IsEmpty() const
207 	{
208 		return fRoot == NULL;
209 	}
210 
PreviousDontSplay(const Key & key)211 	Node* PreviousDontSplay(const Key& key) const
212 	{
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;
221 		}
222 
223 		return closestNode;
224 	}
225 
FindClosest(const Key & key,bool greater,bool orEqual)226 	Node* FindClosest(const Key& key, bool greater, bool orEqual)
227 	{
228 		if (fRoot == NULL)
229 			return NULL;
230 
231 		_Splay(key);
232 
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;
239 
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;
252 			}
253 		}
254 
255 		return closestNode;
256 	}
257 
258 	SplayTree& operator=(const SplayTree& other)
259 	{
260 		fRoot = other.fRoot;
261 		return *this;
262 	}
263 
264 private:
265 	/*!
266 		Internal method to perform a top-down splay.
267 
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.
273 
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.
278 	*/
_Splay(const Key & key)279 	void _Splay(const Key& key) {
280 		Link headerLink;
281 		headerLink.left = headerLink.right = NULL;
282 
283 		Link* lLink = &headerLink;
284 		Link* rLink = &headerLink;
285 
286 		Node* l = NULL;
287 		Node* r = NULL;
288 		Node* t = fRoot;
289 
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;
296 
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;
306 				}
307 
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;
317 
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;
327 				}
328 
329 				// link left
330 				lLink->right = t;
331 				l = t;
332 				lLink = Definition::GetLink(l);
333 				t = lLink->right;
334 			} else
335 				break;
336 		}
337 
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;
345 	}
346 
347 protected:
348 	Node*	fRoot;
349 };
350 
351 
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;
359 
360 public:
361 	class Iterator {
362 	public:
Iterator()363 		Iterator()
364 		{
365 		}
366 
Iterator(const Iterator & other)367 		Iterator(const Iterator& other)
368 		{
369 			*this = other;
370 		}
371 
Iterator(Tree * tree)372 		Iterator(Tree* tree)
373 			:
374 			fTree(tree)
375 		{
376 			Rewind();
377 		}
378 
Iterator(Tree * tree,Node * next)379 		Iterator(Tree* tree, Node* next)
380 			:
381 			fTree(tree),
382 			fCurrent(NULL),
383 			fNext(next)
384 		{
385 		}
386 
HasNext()387 		bool HasNext() const
388 		{
389 			return fNext != NULL;
390 		}
391 
Next()392 		Node* Next()
393 		{
394 			fCurrent = fNext;
395 			if (fNext != NULL)
396 				fNext = *Definition::GetListLink(fNext);
397 			return fCurrent;
398 		}
399 
Current()400 		Node* Current()
401 		{
402 			return fCurrent;
403 		}
404 
Remove()405 		Node* Remove()
406 		{
407 			Node* element = fCurrent;
408 			if (fCurrent) {
409 				fTree->Remove(fCurrent);
410 				fCurrent = NULL;
411 			}
412 			return element;
413 		}
414 
415 		Iterator &operator=(const Iterator &other)
416 		{
417 			fTree = other.fTree;
418 			fCurrent = other.fCurrent;
419 			fNext = other.fNext;
420 			return *this;
421 		}
422 
Rewind()423 		void Rewind()
424 		{
425 			fCurrent = NULL;
426 			fNext = fTree->fFirst;
427 		}
428 
429 	private:
430 		Tree*	fTree;
431 		Node*	fCurrent;
432 		Node*	fNext;
433 	};
434 
435 	class ConstIterator {
436 	public:
ConstIterator()437 		ConstIterator()
438 		{
439 		}
440 
ConstIterator(const ConstIterator & other)441 		ConstIterator(const ConstIterator& other)
442 		{
443 			*this = other;
444 		}
445 
ConstIterator(const Tree * tree)446 		ConstIterator(const Tree* tree)
447 			:
448 			fTree(tree)
449 		{
450 			Rewind();
451 		}
452 
ConstIterator(const Tree * tree,Node * next)453 		ConstIterator(const Tree* tree, Node* next)
454 			:
455 			fTree(tree),
456 			fNext(next)
457 		{
458 		}
459 
HasNext()460 		bool HasNext() const
461 		{
462 			return fNext != NULL;
463 		}
464 
Next()465 		Node* Next()
466 		{
467 			Node* node = fNext;
468 			if (fNext != NULL)
469 				fNext = *Definition::GetListLink(fNext);
470 			return node;
471 		}
472 
473 		ConstIterator &operator=(const ConstIterator &other)
474 		{
475 			fTree = other.fTree;
476 			fNext = other.fNext;
477 			return *this;
478 		}
479 
Rewind()480 		void Rewind()
481 		{
482 			fNext = fTree->fFirst;
483 		}
484 
485 	private:
486 		const Tree*	fTree;
487 		Node*		fNext;
488 	};
489 
IteratableSplayTree()490 	IteratableSplayTree()
491 		:
492 		fTree(),
493 		fFirst(NULL)
494 	{
495 	}
496 
Insert(Node * node)497 	bool Insert(Node* node)
498 	{
499 		if (!fTree.Insert(node))
500 			return false;
501 
502 		Node** previousNext;
503 		if (Node* previous = fTree.PreviousDontSplay(Definition::GetKey(node)))
504 			previousNext = Definition::GetListLink(previous);
505 		else
506 			previousNext = &fFirst;
507 
508 		*Definition::GetListLink(node) = *previousNext;
509 		*previousNext = node;
510 
511 		return true;
512 	}
513 
Remove(const Key & key)514 	Node* Remove(const Key& key)
515 	{
516 		Node* node = fTree.Remove(key);
517 		if (node == NULL)
518 			return NULL;
519 
520 		Node** previousNext;
521 		if (Node* previous = fTree.PreviousDontSplay(key))
522 			previousNext = Definition::GetListLink(previous);
523 		else
524 			previousNext = &fFirst;
525 
526 		*previousNext = *Definition::GetListLink(node);
527 
528 		return node;
529 	}
530 
Remove(Node * node)531 	bool Remove(Node* node)
532 	{
533 		if (!fTree.Remove(node))
534 			return false;
535 
536 		Node** previousNext;
537 		if (Node* previous = fTree.PreviousDontSplay(Definition::GetKey(node)))
538 			previousNext = Definition::GetListLink(previous);
539 		else
540 			previousNext = &fFirst;
541 
542 		*previousNext = *Definition::GetListLink(node);
543 
544 		return true;
545 	}
546 
Lookup(const Key & key)547 	Node* Lookup(const Key& key)
548 	{
549 		return fTree.Lookup(key);
550 	}
551 
Root()552 	Node* Root() const
553 	{
554 		return fTree.Root();
555 	}
556 
557 	/*!
558 		Test if the tree is logically empty.
559 		\return true if empty, false otherwise.
560 	*/
IsEmpty()561 	bool IsEmpty() const
562 	{
563 		return fTree.IsEmpty();
564 	}
565 
FindClosest(const Key & key,bool greater,bool orEqual)566 	Node* FindClosest(const Key& key, bool greater, bool orEqual)
567 	{
568 		return fTree.FindClosest(key, greater, orEqual);
569 	}
570 
FindMin()571 	Node* FindMin()
572 	{
573 		return fTree.FindMin();
574 	}
575 
FindMax()576 	Node* FindMax()
577 	{
578 		return fTree.FindMax();
579 	}
580 
GetIterator()581 	Iterator GetIterator()
582 	{
583 		return Iterator(this);
584 	}
585 
GetIterator()586 	ConstIterator GetIterator() const
587 	{
588 		return ConstIterator(this);
589 	}
590 
GetIterator(const Key & key,bool greater,bool orEqual)591 	Iterator GetIterator(const Key& key, bool greater, bool orEqual)
592 	{
593 		return Iterator(this, fTree.FindClosest(key, greater, orEqual));
594 	}
595 
GetIterator(const Key & key,bool greater,bool orEqual)596 	ConstIterator GetIterator(const Key& key, bool greater, bool orEqual) const
597 	{
598 		return ConstIterator(this, FindClosest(key, greater, orEqual));
599 	}
600 
601 	IteratableSplayTree& operator=(const IteratableSplayTree& other)
602 	{
603 		fTree = other.fTree;
604 		fFirst = other.fFirst;
605 		return *this;
606 	}
607 
608 protected:
609 	friend class Iterator;
610 	friend class ConstIterator;
611 		// needed for gcc 2.95.3 only
612 
613 	SplayTree<Definition>	fTree;
614 	Node*					fFirst;
615 };
616 
617 
618 #endif	// KERNEL_UTIL_SPLAY_TREE_H
619