2 * Copyright 2003-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
3 * Distributed under the terms of the MIT License.
5 #ifndef _KERNEL_UTIL_AVL_TREE_MAP_H
6 #define _KERNEL_UTIL_AVL_TREE_MAP_H
9 #include <util/MallocFreeAllocator.h>
10 #include <util/AVLTreeBase.h>
14 namespace AVLTreeMapStrategy
{
16 template<typename Value
> class Ascending
;
17 template<typename Value
> class Descending
;
19 //! Automatic node strategy (works like STL containers do)
20 template <typename Key
, typename Value
,
21 typename KeyOrder
= Ascending
<Key
>,
22 template <typename
> class Allocator
= MallocFreeAllocator
>
25 /*! NodeStrategy must implement this interface:
27 inline Node* Allocate(const Key& key, const Value& value)
28 inline void Free(Node* node)
29 inline const Key GetKey(const Node* node) const
30 inline Value& GetValue(Node* node) const
31 inline AVLTreeNode* GetAVLTreeNode(Node* node) const
32 inline Node* GetNode(AVLTreeNode* node) const
33 inline int CompareKeyNode(const Key& a, const Node* b)
34 inline int CompareNodes(const Node* a, const Node* b)
40 #define _AVL_TREE_MAP_TEMPLATE_LIST template<typename Key, typename Value, \
41 typename NodeStrategy>
42 #define _AVL_TREE_MAP_CLASS_NAME AVLTreeMap<Key, Value, NodeStrategy>
46 template<typename Key
, typename Value
,
47 typename NodeStrategy
= AVLTreeMapStrategy::Auto
<Key
, Value
> >
48 class AVLTreeMap
: protected AVLTreeCompare
{
50 typedef typename
NodeStrategy::Node Node
;
51 typedef _AVL_TREE_MAP_CLASS_NAME Class
;
58 AVLTreeMap(const NodeStrategy
& strategy
60 virtual ~AVLTreeMap();
62 inline int Count() const { return fTree
.Count(); }
63 inline bool IsEmpty() const { return fTree
.IsEmpty(); }
64 inline void MakeEmpty();
66 Node
* RootNode() const;
68 Node
* Previous(Node
* node
) const;
69 Node
* Next(Node
* node
) const;
71 inline Iterator
GetIterator();
72 inline ConstIterator
GetIterator() const;
74 inline Iterator
GetIterator(Node
* node
);
75 inline ConstIterator
GetIterator(Node
* node
) const;
77 Iterator
Find(const Key
& key
);
78 Iterator
FindClose(const Key
& key
, bool less
);
80 status_t
Insert(const Key
& key
, const Value
& value
,
82 status_t
Insert(const Key
& key
, const Value
& value
,
84 status_t
Remove(const Key
& key
);
85 status_t
Remove(Node
* node
);
87 const NodeStrategy
& GetNodeStrategy() const { return fStrategy
; }
91 virtual int CompareKeyNode(const void* key
,
92 const AVLTreeNode
* node
);
93 virtual int CompareNodes(const AVLTreeNode
* node1
,
94 const AVLTreeNode
* node2
);
96 void _FreeTree(AVLTreeNode
* node
);
99 inline Node
* _Allocate(const Key
& key
, const Value
& value
);
100 inline void _Free(Node
* node
);
101 inline Key
_GetKey(Node
* node
) const;
102 inline Value
& _GetValue(Node
* node
) const;
103 inline AVLTreeNode
* _GetAVLTreeNode(const Node
* node
) const;
104 inline Node
* _GetNode(const AVLTreeNode
* node
) const;
105 inline int _CompareKeyNode(const Key
& a
, const Node
* b
);
106 inline int _CompareNodes(const Node
* a
, const Node
* b
);
109 friend class Iterator
;
110 friend class ConstIterator
;
113 NodeStrategy fStrategy
;
117 // (need to implement it here, otherwise gcc 2.95.3 chokes)
118 class Iterator
: public ConstIterator
{
125 inline Iterator(const Iterator
& other
)
126 : ConstIterator(other
)
132 if (AVLTreeNode
* node
= ConstIterator::fTreeIterator
.Remove()) {
133 _AVL_TREE_MAP_CLASS_NAME
* parent
134 = const_cast<_AVL_TREE_MAP_CLASS_NAME
*>(
135 ConstIterator::fParent
);
136 parent
->_Free(parent
->_GetNode(node
));
141 inline Iterator(_AVL_TREE_MAP_CLASS_NAME
* parent
,
142 const AVLTreeIterator
& treeIterator
)
143 : ConstIterator(parent
, treeIterator
)
147 friend class _AVL_TREE_MAP_CLASS_NAME
;
153 _AVL_TREE_MAP_TEMPLATE_LIST
154 class _AVL_TREE_MAP_CLASS_NAME::ConstIterator
{
156 inline ConstIterator()
162 inline ConstIterator(const ConstIterator
& other
)
163 : fParent(other
.fParent
),
164 fTreeIterator(other
.fTreeIterator
)
168 inline bool HasCurrent() const
170 return fTreeIterator
.Current();
173 inline Key
CurrentKey()
175 if (AVLTreeNode
* node
= fTreeIterator
.Current())
176 return fParent
->_GetKey(fParent
->_GetNode(node
));
180 inline Value
Current()
182 if (AVLTreeNode
* node
= fTreeIterator
.Current())
183 return fParent
->_GetValue(fParent
->_GetNode(node
));
187 inline Value
* CurrentValuePointer()
189 if (AVLTreeNode
* node
= fTreeIterator
.Current())
190 return &fParent
->_GetValue(fParent
->_GetNode(node
));
194 inline Node
* CurrentNode()
196 if (AVLTreeNode
* node
= fTreeIterator
.Current())
197 return fParent
->_GetNode(node
);
201 inline bool HasNext() const
203 return fTreeIterator
.HasNext();
208 if (AVLTreeNode
* node
= fTreeIterator
.Next())
209 return fParent
->_GetValue(fParent
->_GetNode(node
));
213 inline Value
* NextValuePointer()
215 if (AVLTreeNode
* node
= fTreeIterator
.Next())
216 return &fParent
->_GetValue(fParent
->_GetNode(node
));
220 inline Value
Previous()
222 if (AVLTreeNode
* node
= fTreeIterator
.Previous())
223 return fParent
->_GetValue(fParent
->_GetNode(node
));
227 inline ConstIterator
& operator=(const ConstIterator
& other
)
229 fParent
= other
.fParent
;
230 fTreeIterator
= other
.fTreeIterator
;
235 inline ConstIterator(const _AVL_TREE_MAP_CLASS_NAME
* parent
,
236 const AVLTreeIterator
& treeIterator
)
239 fTreeIterator
= treeIterator
;
242 friend class _AVL_TREE_MAP_CLASS_NAME
;
244 const _AVL_TREE_MAP_CLASS_NAME
* fParent
;
245 AVLTreeIterator fTreeIterator
;
250 _AVL_TREE_MAP_TEMPLATE_LIST
251 _AVL_TREE_MAP_CLASS_NAME::AVLTreeMap(const NodeStrategy
& strategy
)
259 _AVL_TREE_MAP_TEMPLATE_LIST
260 _AVL_TREE_MAP_CLASS_NAME::~AVLTreeMap()
266 _AVL_TREE_MAP_TEMPLATE_LIST
268 _AVL_TREE_MAP_CLASS_NAME::MakeEmpty()
270 AVLTreeNode
* root
= fTree
.Root();
277 _AVL_TREE_MAP_TEMPLATE_LIST
278 inline typename
_AVL_TREE_MAP_CLASS_NAME::Node
*
279 _AVL_TREE_MAP_CLASS_NAME::RootNode() const
281 if (AVLTreeNode
* root
= fTree
.Root())
282 return _GetNode(root
);
288 _AVL_TREE_MAP_TEMPLATE_LIST
289 inline typename
_AVL_TREE_MAP_CLASS_NAME::Node
*
290 _AVL_TREE_MAP_CLASS_NAME::Previous(Node
* node
) const
295 AVLTreeNode
* treeNode
= fTree
.Previous(_GetAVLTreeNode(node
));
296 return treeNode
!= NULL
? _GetNode(treeNode
) : NULL
;
301 _AVL_TREE_MAP_TEMPLATE_LIST
302 inline typename
_AVL_TREE_MAP_CLASS_NAME::Node
*
303 _AVL_TREE_MAP_CLASS_NAME::Next(Node
* node
) const
308 AVLTreeNode
* treeNode
= fTree
.Next(_GetAVLTreeNode(node
));
309 return treeNode
!= NULL
? _GetNode(treeNode
) : NULL
;
314 _AVL_TREE_MAP_TEMPLATE_LIST
315 inline typename
_AVL_TREE_MAP_CLASS_NAME::Iterator
316 _AVL_TREE_MAP_CLASS_NAME::GetIterator()
318 return Iterator(this, fTree
.GetIterator());
323 _AVL_TREE_MAP_TEMPLATE_LIST
324 inline typename
_AVL_TREE_MAP_CLASS_NAME::ConstIterator
325 _AVL_TREE_MAP_CLASS_NAME::GetIterator() const
327 return ConstIterator(this, fTree
.GetIterator());
332 _AVL_TREE_MAP_TEMPLATE_LIST
333 inline typename
_AVL_TREE_MAP_CLASS_NAME::Iterator
334 _AVL_TREE_MAP_CLASS_NAME::GetIterator(Node
* node
)
336 return Iterator(this, fTree
.GetIterator(_GetAVLTreeNode(node
)));
341 _AVL_TREE_MAP_TEMPLATE_LIST
342 inline typename
_AVL_TREE_MAP_CLASS_NAME::ConstIterator
343 _AVL_TREE_MAP_CLASS_NAME::GetIterator(Node
* node
) const
345 return ConstIterator(this, fTree
.GetIterator(_GetAVLTreeNode(node
)));
350 _AVL_TREE_MAP_TEMPLATE_LIST
351 typename
_AVL_TREE_MAP_CLASS_NAME::Iterator
352 _AVL_TREE_MAP_CLASS_NAME::Find(const Key
& key
)
354 if (AVLTreeNode
* node
= fTree
.Find(&key
))
355 return Iterator(this, fTree
.GetIterator(node
));
361 _AVL_TREE_MAP_TEMPLATE_LIST
362 typename
_AVL_TREE_MAP_CLASS_NAME::Iterator
363 _AVL_TREE_MAP_CLASS_NAME::FindClose(const Key
& key
, bool less
)
365 if (AVLTreeNode
* node
= fTree
.FindClosest(&key
, less
))
366 return Iterator(this, fTree
.GetIterator(node
));
372 _AVL_TREE_MAP_TEMPLATE_LIST
374 _AVL_TREE_MAP_CLASS_NAME::Insert(const Key
& key
, const Value
& value
,
378 Node
* userNode
= _Allocate(key
, value
);
383 AVLTreeNode
* node
= _GetAVLTreeNode(userNode
);
384 status_t error
= fTree
.Insert(node
);
391 *iterator
= Iterator(this, fTree
.GetIterator(node
));
398 _AVL_TREE_MAP_TEMPLATE_LIST
400 _AVL_TREE_MAP_CLASS_NAME::Insert(const Key
& key
, const Value
& value
,
404 Node
* userNode
= _Allocate(key
, value
);
409 AVLTreeNode
* node
= _GetAVLTreeNode(userNode
);
410 status_t error
= fTree
.Insert(node
);
424 _AVL_TREE_MAP_TEMPLATE_LIST
426 _AVL_TREE_MAP_CLASS_NAME::Remove(const Key
& key
)
428 AVLTreeNode
* node
= fTree
.Remove(&key
);
430 return B_ENTRY_NOT_FOUND
;
432 _Free(_GetNode(node
));
438 _AVL_TREE_MAP_TEMPLATE_LIST
440 _AVL_TREE_MAP_CLASS_NAME::Remove(Node
* node
)
442 if (!fTree
.Remove(node
))
443 return B_ENTRY_NOT_FOUND
;
451 _AVL_TREE_MAP_TEMPLATE_LIST
453 _AVL_TREE_MAP_CLASS_NAME::CompareKeyNode(const void* key
,
454 const AVLTreeNode
* node
)
456 return _CompareKeyNode(*(const Key
*)key
, _GetNode(node
));
461 _AVL_TREE_MAP_TEMPLATE_LIST
463 _AVL_TREE_MAP_CLASS_NAME::CompareNodes(const AVLTreeNode
* node1
,
464 const AVLTreeNode
* node2
)
466 return _CompareNodes(_GetNode(node1
), _GetNode(node2
));
471 _AVL_TREE_MAP_TEMPLATE_LIST
472 inline typename
_AVL_TREE_MAP_CLASS_NAME::Node
*
473 _AVL_TREE_MAP_CLASS_NAME::_Allocate(const Key
& key
, const Value
& value
)
475 return fStrategy
.Allocate(key
, value
);
480 _AVL_TREE_MAP_TEMPLATE_LIST
482 _AVL_TREE_MAP_CLASS_NAME::_Free(Node
* node
)
484 fStrategy
.Free(node
);
489 _AVL_TREE_MAP_TEMPLATE_LIST
491 _AVL_TREE_MAP_CLASS_NAME::_GetKey(Node
* node
) const
493 return fStrategy
.GetKey(node
);
498 _AVL_TREE_MAP_TEMPLATE_LIST
500 _AVL_TREE_MAP_CLASS_NAME::_GetValue(Node
* node
) const
502 return fStrategy
.GetValue(node
);
507 _AVL_TREE_MAP_TEMPLATE_LIST
509 _AVL_TREE_MAP_CLASS_NAME::_GetAVLTreeNode(const Node
* node
) const
511 return fStrategy
.GetAVLTreeNode(const_cast<Node
*>(node
));
516 _AVL_TREE_MAP_TEMPLATE_LIST
517 inline typename
_AVL_TREE_MAP_CLASS_NAME::Node
*
518 _AVL_TREE_MAP_CLASS_NAME::_GetNode(const AVLTreeNode
* node
) const
520 return fStrategy
.GetNode(const_cast<AVLTreeNode
*>(node
));
525 _AVL_TREE_MAP_TEMPLATE_LIST
527 _AVL_TREE_MAP_CLASS_NAME::_CompareKeyNode(const Key
& a
, const Node
* b
)
529 return fStrategy
.CompareKeyNode(a
, b
);
534 _AVL_TREE_MAP_TEMPLATE_LIST
536 _AVL_TREE_MAP_CLASS_NAME::_CompareNodes(const Node
* a
, const Node
* b
)
538 return fStrategy
.CompareNodes(a
, b
);
543 _AVL_TREE_MAP_TEMPLATE_LIST
545 _AVL_TREE_MAP_CLASS_NAME::_FreeTree(AVLTreeNode
* node
)
548 _FreeTree(node
->left
);
549 _FreeTree(node
->right
);
550 _Free(_GetNode(node
));
555 // #pragma mark - strategy parameters
558 namespace AVLTreeMapStrategy
{
559 template<typename Value
>
562 inline int operator()(const Value
&a
, const Value
&b
) const
575 namespace AVLTreeMapStrategy
{
576 template<typename Value
>
579 inline int operator()(const Value
&a
, const Value
&b
) const
591 // #pragma mark - strategies
595 namespace AVLTreeMapStrategy
{
596 template <typename Key
, typename Value
, typename KeyOrder
,
597 template <typename
> class Allocator
>
600 struct Node
: AVLTreeNode
{
601 Node(const Key
&key
, const Value
&value
)
612 inline Node
* Allocate(const Key
& key
, const Value
& value
)
614 Node
* result
= fAllocator
.Allocate();
616 fAllocator
.Construct(result
, key
, value
);
620 inline void Free(Node
* node
)
622 fAllocator
.Destruct(node
);
623 fAllocator
.Deallocate(node
);
626 inline const Key
& GetKey(const Node
* node
) const
631 inline Value
& GetValue(Node
* node
) const
636 inline AVLTreeNode
* GetAVLTreeNode(Node
* node
) const
641 inline Node
* GetNode(AVLTreeNode
* node
) const
643 return static_cast<Node
*>(node
);
646 inline int CompareKeyNode(const Key
& a
, const Node
* b
) const
648 return fCompare(a
, GetKey(b
));
651 inline int CompareNodes(const Node
* a
, const Node
* b
) const
653 return fCompare(GetKey(a
), GetKey(b
));
658 Allocator
<Node
> fAllocator
;
662 #endif // _KERNEL_UTIL_AVL_TREE_MAP_H