Files
haiku-beta6/headers/private/kernel/util/AVLTreeMap.h
T

663 lines
13 KiB
C++
Raw Normal View History

2007-08-11 14:57:25 +00:00
/*
2009-12-06 15:59:37 +00:00
* Copyright 2003-2009, Ingo Weinhold <[email protected]>.
2007-08-11 14:57:25 +00:00
* Distributed under the terms of the MIT License.
*/
2009-12-06 15:59:37 +00:00
#ifndef _KERNEL_UTIL_AVL_TREE_MAP_H
#define _KERNEL_UTIL_AVL_TREE_MAP_H
2007-08-11 14:57:25 +00:00
#include <util/MallocFreeAllocator.h>
2009-12-06 15:59:37 +00:00
#include <util/AVLTreeBase.h>
2007-08-11 14:57:25 +00:00
// strategies
namespace AVLTreeMapStrategy {
// key orders
template<typename Value> class Ascending;
template<typename Value> class Descending;
//! Automatic node strategy (works like STL containers do)
template <typename Key, typename Value,
typename KeyOrder = Ascending<Key>,
template <typename> class Allocator = MallocFreeAllocator>
class Auto;
2007-08-11 14:57:25 +00:00
/*! NodeStrategy must implement this interface:
typename Node;
inline Node* Allocate(const Key& key, const Value& value)
inline void Free(Node* node)
inline const Key GetKey(const Node* node) const
2007-08-11 14:57:25 +00:00
inline Value& GetValue(Node* node) const
inline AVLTreeNode* GetAVLTreeNode(Node* node) const
inline Node* GetNode(AVLTreeNode* node) const
inline int CompareKeyNode(const Key& a, const Node* b)
inline int CompareNodes(const Node* a, const Node* b)
*/
}
// for convenience
#define _AVL_TREE_MAP_TEMPLATE_LIST template<typename Key, typename Value, \
2007-08-11 14:57:25 +00:00
typename NodeStrategy>
#define _AVL_TREE_MAP_CLASS_NAME AVLTreeMap<Key, Value, NodeStrategy>
2007-08-11 14:57:25 +00:00
// AVLTreeMap
template<typename Key, typename Value,
typename NodeStrategy = AVLTreeMapStrategy::Auto<Key, Value> >
2007-08-11 14:57:25 +00:00
class AVLTreeMap : protected AVLTreeCompare {
private:
typedef typename NodeStrategy::Node Node;
typedef _AVL_TREE_MAP_CLASS_NAME Class;
public:
class Iterator;
class ConstIterator;
public:
2007-08-11 14:57:25 +00:00
AVLTreeMap(const NodeStrategy& strategy
= NodeStrategy());
virtual ~AVLTreeMap();
2007-08-11 14:57:25 +00:00
inline int Count() const { return fTree.Count(); }
inline bool IsEmpty() const { return fTree.IsEmpty(); }
inline void MakeEmpty();
2007-08-11 14:57:25 +00:00
Node* RootNode() const;
Node* Previous(Node* node) const;
Node* Next(Node* node) const;
2007-08-11 14:57:25 +00:00
inline Iterator GetIterator();
inline ConstIterator GetIterator() const;
2007-08-11 14:57:25 +00:00
inline Iterator GetIterator(Node* node);
inline ConstIterator GetIterator(Node* node) const;
2007-08-11 14:57:25 +00:00
Iterator Find(const Key& key);
Iterator FindClose(const Key& key, bool less);
2007-08-11 14:57:25 +00:00
status_t Insert(const Key& key, const Value& value,
Iterator* iterator);
status_t Insert(const Key& key, const Value& value,
Node** _node = NULL);
2007-08-11 14:57:25 +00:00
status_t Remove(const Key& key);
status_t Remove(Node* node);
2007-08-11 14:57:25 +00:00
const NodeStrategy& GetNodeStrategy() const { return fStrategy; }
2007-08-11 14:57:25 +00:00
protected:
// AVLTreeCompare
virtual int CompareKeyNode(const void* key,
const AVLTreeNode* node);
virtual int CompareNodes(const AVLTreeNode* node1,
const AVLTreeNode* node2);
2007-08-11 14:57:25 +00:00
void _FreeTree(AVLTreeNode* node);
// strategy shortcuts
2007-08-11 14:57:25 +00:00
inline Node* _Allocate(const Key& key, const Value& value);
inline void _Free(Node* node);
2011-07-07 15:31:12 +02:00
inline Key _GetKey(Node* node) const;
2007-08-11 14:57:25 +00:00
inline Value& _GetValue(Node* node) const;
inline AVLTreeNode* _GetAVLTreeNode(const Node* node) const;
inline Node* _GetNode(const AVLTreeNode* node) const;
inline int _CompareKeyNode(const Key& a, const Node* b);
inline int _CompareNodes(const Node* a, const Node* b);
protected:
2007-08-11 14:57:25 +00:00
friend class Iterator;
friend class ConstIterator;
2009-12-06 15:59:37 +00:00
AVLTreeBase fTree;
2007-08-11 14:57:25 +00:00
NodeStrategy fStrategy;
2007-08-11 14:57:25 +00:00
public:
// Iterator
2007-08-11 14:57:25 +00:00
// (need to implement it here, otherwise gcc 2.95.3 chokes)
class Iterator : public ConstIterator {
public:
2007-08-11 14:57:25 +00:00
inline Iterator()
: ConstIterator()
{
}
2009-11-05 17:18:12 +00:00
2007-08-11 14:57:25 +00:00
inline Iterator(const Iterator& other)
: ConstIterator(other)
{
}
2009-11-05 17:18:12 +00:00
2007-08-11 14:57:25 +00:00
inline void Remove()
{
if (AVLTreeNode* node = ConstIterator::fTreeIterator.Remove()) {
_AVL_TREE_MAP_CLASS_NAME* parent
= const_cast<_AVL_TREE_MAP_CLASS_NAME*>(
ConstIterator::fParent);
parent->_Free(parent->_GetNode(node));
}
}
2009-11-05 17:18:12 +00:00
private:
2007-08-11 14:57:25 +00:00
inline Iterator(_AVL_TREE_MAP_CLASS_NAME* parent,
const AVLTreeIterator& treeIterator)
: ConstIterator(parent, treeIterator)
{
}
2009-11-05 17:18:12 +00:00
friend class _AVL_TREE_MAP_CLASS_NAME;
};
};
2007-08-11 14:57:25 +00:00
// ConstIterator
_AVL_TREE_MAP_TEMPLATE_LIST
class _AVL_TREE_MAP_CLASS_NAME::ConstIterator {
public:
2007-08-11 14:57:25 +00:00
inline ConstIterator()
: fParent(NULL),
2007-08-11 14:57:25 +00:00
fTreeIterator()
{
}
2007-08-11 14:57:25 +00:00
inline ConstIterator(const ConstIterator& other)
: fParent(other.fParent),
2007-08-11 14:57:25 +00:00
fTreeIterator(other.fTreeIterator)
{
}
2007-08-11 14:57:25 +00:00
inline bool HasCurrent() const
{
2007-08-11 14:57:25 +00:00
return fTreeIterator.Current();
}
2007-08-11 14:57:25 +00:00
inline Key CurrentKey()
{
2007-08-11 14:57:25 +00:00
if (AVLTreeNode* node = fTreeIterator.Current())
return fParent->_GetKey(fParent->_GetNode(node));
return Key();
}
2007-08-11 14:57:25 +00:00
inline Value Current()
{
2007-08-11 14:57:25 +00:00
if (AVLTreeNode* node = fTreeIterator.Current())
return fParent->_GetValue(fParent->_GetNode(node));
return Value();
}
2007-08-11 14:57:25 +00:00
inline Value* CurrentValuePointer()
{
2007-08-11 14:57:25 +00:00
if (AVLTreeNode* node = fTreeIterator.Current())
return &fParent->_GetValue(fParent->_GetNode(node));
return NULL;
}
inline Node* CurrentNode()
{
if (AVLTreeNode* node = fTreeIterator.Current())
return fParent->_GetNode(node);
return NULL;
}
2007-08-11 14:57:25 +00:00
inline bool HasNext() const
{
2007-08-11 14:57:25 +00:00
return fTreeIterator.HasNext();
}
2007-08-11 14:57:25 +00:00
inline Value Next()
{
2007-08-11 14:57:25 +00:00
if (AVLTreeNode* node = fTreeIterator.Next())
return fParent->_GetValue(fParent->_GetNode(node));
return Value();
}
2009-11-05 17:18:12 +00:00
inline Value* NextValuePointer()
{
if (AVLTreeNode* node = fTreeIterator.Next())
return &fParent->_GetValue(fParent->_GetNode(node));
return NULL;
}
2007-08-11 14:57:25 +00:00
inline Value Previous()
{
2007-08-11 14:57:25 +00:00
if (AVLTreeNode* node = fTreeIterator.Previous())
return fParent->_GetValue(fParent->_GetNode(node));
return Value();
}
2007-08-11 14:57:25 +00:00
inline ConstIterator& operator=(const ConstIterator& other)
{
2007-08-11 14:57:25 +00:00
fParent = other.fParent;
fTreeIterator = other.fTreeIterator;
return *this;
}
2007-08-11 14:57:25 +00:00
protected:
inline ConstIterator(const _AVL_TREE_MAP_CLASS_NAME* parent,
const AVLTreeIterator& treeIterator)
{
2007-08-11 14:57:25 +00:00
fParent = parent;
fTreeIterator = treeIterator;
}
2007-08-11 14:57:25 +00:00
friend class _AVL_TREE_MAP_CLASS_NAME;
2007-08-11 14:57:25 +00:00
const _AVL_TREE_MAP_CLASS_NAME* fParent;
AVLTreeIterator fTreeIterator;
};
2007-08-11 14:57:25 +00:00
// constructor
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
_AVL_TREE_MAP_CLASS_NAME::AVLTreeMap(const NodeStrategy& strategy)
: fTree(this),
fStrategy(strategy)
{
}
2007-08-11 14:57:25 +00:00
// destructor
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
_AVL_TREE_MAP_CLASS_NAME::~AVLTreeMap()
{
}
2007-08-11 14:57:25 +00:00
// MakeEmpty
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline void
_AVL_TREE_MAP_CLASS_NAME::MakeEmpty()
{
2007-08-11 14:57:25 +00:00
AVLTreeNode* root = fTree.Root();
_FreeTree(root);
fTree.MakeEmpty();
}
2007-08-11 14:57:25 +00:00
// RootNode
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline typename _AVL_TREE_MAP_CLASS_NAME::Node*
_AVL_TREE_MAP_CLASS_NAME::RootNode() const
{
2007-08-11 14:57:25 +00:00
if (AVLTreeNode* root = fTree.Root())
return _GetNode(root);
return NULL;
}
// Previous
_AVL_TREE_MAP_TEMPLATE_LIST
inline typename _AVL_TREE_MAP_CLASS_NAME::Node*
_AVL_TREE_MAP_CLASS_NAME::Previous(Node* node) const
{
if (node == NULL)
return NULL;
AVLTreeNode* treeNode = fTree.Previous(_GetAVLTreeNode(node));
return treeNode != NULL ? _GetNode(treeNode) : NULL;
}
// Next
_AVL_TREE_MAP_TEMPLATE_LIST
inline typename _AVL_TREE_MAP_CLASS_NAME::Node*
_AVL_TREE_MAP_CLASS_NAME::Next(Node* node) const
{
if (node == NULL)
return NULL;
AVLTreeNode* treeNode = fTree.Next(_GetAVLTreeNode(node));
return treeNode != NULL ? _GetNode(treeNode) : NULL;
}
2007-08-11 14:57:25 +00:00
// GetIterator
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline typename _AVL_TREE_MAP_CLASS_NAME::Iterator
_AVL_TREE_MAP_CLASS_NAME::GetIterator()
{
2007-08-11 14:57:25 +00:00
return Iterator(this, fTree.GetIterator());
}
2007-08-11 14:57:25 +00:00
// GetIterator
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline typename _AVL_TREE_MAP_CLASS_NAME::ConstIterator
_AVL_TREE_MAP_CLASS_NAME::GetIterator() const
{
2007-08-11 14:57:25 +00:00
return ConstIterator(this, fTree.GetIterator());
}
2007-08-11 14:57:25 +00:00
// GetIterator
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline typename _AVL_TREE_MAP_CLASS_NAME::Iterator
_AVL_TREE_MAP_CLASS_NAME::GetIterator(Node* node)
{
2007-08-11 14:57:25 +00:00
return Iterator(this, fTree.GetIterator(_GetAVLTreeNode(node)));
}
2007-08-11 14:57:25 +00:00
// GetIterator
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline typename _AVL_TREE_MAP_CLASS_NAME::ConstIterator
_AVL_TREE_MAP_CLASS_NAME::GetIterator(Node* node) const
{
2007-08-11 14:57:25 +00:00
return ConstIterator(this, fTree.GetIterator(_GetAVLTreeNode(node)));
}
2007-08-11 14:57:25 +00:00
// Find
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
typename _AVL_TREE_MAP_CLASS_NAME::Iterator
_AVL_TREE_MAP_CLASS_NAME::Find(const Key& key)
{
2007-08-11 14:57:25 +00:00
if (AVLTreeNode* node = fTree.Find(&key))
return Iterator(this, fTree.GetIterator(node));
return Iterator();
}
2007-08-11 14:57:25 +00:00
// FindClose
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
typename _AVL_TREE_MAP_CLASS_NAME::Iterator
_AVL_TREE_MAP_CLASS_NAME::FindClose(const Key& key, bool less)
{
2009-12-06 15:59:37 +00:00
if (AVLTreeNode* node = fTree.FindClosest(&key, less))
2007-08-11 14:57:25 +00:00
return Iterator(this, fTree.GetIterator(node));
return Iterator();
}
2007-08-11 14:57:25 +00:00
// Insert
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
status_t
_AVL_TREE_MAP_CLASS_NAME::Insert(const Key& key, const Value& value,
Iterator* iterator)
{
2007-08-11 14:57:25 +00:00
// allocate a node
Node* userNode = _Allocate(key, value);
if (!userNode)
return B_NO_MEMORY;
2007-08-11 14:57:25 +00:00
// insert node
AVLTreeNode* node = _GetAVLTreeNode(userNode);
status_t error = fTree.Insert(node);
if (error != B_OK) {
_Free(userNode);
return error;
}
2007-08-11 14:57:25 +00:00
if (iterator)
*iterator = Iterator(this, fTree.GetIterator(node));
2007-08-11 14:57:25 +00:00
return B_OK;
}
2007-08-11 14:57:25 +00:00
// Insert
_AVL_TREE_MAP_TEMPLATE_LIST
status_t
_AVL_TREE_MAP_CLASS_NAME::Insert(const Key& key, const Value& value,
Node** _node)
{
// allocate a node
Node* userNode = _Allocate(key, value);
if (!userNode)
return B_NO_MEMORY;
// insert node
AVLTreeNode* node = _GetAVLTreeNode(userNode);
status_t error = fTree.Insert(node);
if (error != B_OK) {
_Free(userNode);
return error;
}
if (_node != NULL)
*_node = userNode;
return B_OK;
}
// Remove
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
status_t
_AVL_TREE_MAP_CLASS_NAME::Remove(const Key& key)
{
2007-08-11 14:57:25 +00:00
AVLTreeNode* node = fTree.Remove(&key);
if (!node)
return B_ENTRY_NOT_FOUND;
2007-08-11 14:57:25 +00:00
_Free(_GetNode(node));
return B_OK;
}
// Remove
_AVL_TREE_MAP_TEMPLATE_LIST
status_t
_AVL_TREE_MAP_CLASS_NAME::Remove(Node* node)
{
if (!fTree.Remove(node))
return B_ENTRY_NOT_FOUND;
_Free(node);
return B_OK;
}
2007-08-11 14:57:25 +00:00
// CompareKeyNode
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
int
_AVL_TREE_MAP_CLASS_NAME::CompareKeyNode(const void* key,
const AVLTreeNode* node)
{
2007-08-11 14:57:25 +00:00
return _CompareKeyNode(*(const Key*)key, _GetNode(node));
}
2007-08-11 14:57:25 +00:00
// CompareNodes
_AVL_TREE_MAP_TEMPLATE_LIST
int
2007-08-11 14:57:25 +00:00
_AVL_TREE_MAP_CLASS_NAME::CompareNodes(const AVLTreeNode* node1,
const AVLTreeNode* node2)
{
2007-08-11 14:57:25 +00:00
return _CompareNodes(_GetNode(node1), _GetNode(node2));
}
2007-08-11 14:57:25 +00:00
// _Allocate
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 19:53:20 +00:00
inline typename _AVL_TREE_MAP_CLASS_NAME::Node*
2007-08-11 14:57:25 +00:00
_AVL_TREE_MAP_CLASS_NAME::_Allocate(const Key& key, const Value& value)
{
2007-08-11 14:57:25 +00:00
return fStrategy.Allocate(key, value);
}
2007-08-11 14:57:25 +00:00
// _Free
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline void
_AVL_TREE_MAP_CLASS_NAME::_Free(Node* node)
{
2007-08-11 14:57:25 +00:00
fStrategy.Free(node);
}
2007-08-11 14:57:25 +00:00
// _GetKey
_AVL_TREE_MAP_TEMPLATE_LIST
2011-07-07 15:31:12 +02:00
inline Key
2007-08-11 14:57:25 +00:00
_AVL_TREE_MAP_CLASS_NAME::_GetKey(Node* node) const
{
2007-08-11 14:57:25 +00:00
return fStrategy.GetKey(node);
}
2007-08-11 14:57:25 +00:00
// _GetValue
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline Value&
_AVL_TREE_MAP_CLASS_NAME::_GetValue(Node* node) const
{
2007-08-11 14:57:25 +00:00
return fStrategy.GetValue(node);
}
2007-08-11 14:57:25 +00:00
// _GetAVLTreeNode
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline AVLTreeNode*
_AVL_TREE_MAP_CLASS_NAME::_GetAVLTreeNode(const Node* node) const
{
2007-08-11 14:57:25 +00:00
return fStrategy.GetAVLTreeNode(const_cast<Node*>(node));
}
2007-08-11 14:57:25 +00:00
// _GetNode
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 19:53:20 +00:00
inline typename _AVL_TREE_MAP_CLASS_NAME::Node*
2007-08-11 14:57:25 +00:00
_AVL_TREE_MAP_CLASS_NAME::_GetNode(const AVLTreeNode* node) const
{
2007-08-11 14:57:25 +00:00
return fStrategy.GetNode(const_cast<AVLTreeNode*>(node));
}
2007-08-11 14:57:25 +00:00
// _CompareKeyNode
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline int
_AVL_TREE_MAP_CLASS_NAME::_CompareKeyNode(const Key& a, const Node* b)
{
2007-08-11 14:57:25 +00:00
return fStrategy.CompareKeyNode(a, b);
}
2007-08-11 14:57:25 +00:00
// _CompareNodes
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
inline int
_AVL_TREE_MAP_CLASS_NAME::_CompareNodes(const Node* a, const Node* b)
{
2007-08-11 14:57:25 +00:00
return fStrategy.CompareNodes(a, b);
}
2007-08-11 14:57:25 +00:00
// _FreeTree
_AVL_TREE_MAP_TEMPLATE_LIST
2007-08-11 14:57:25 +00:00
void
_AVL_TREE_MAP_CLASS_NAME::_FreeTree(AVLTreeNode* node)
{
2007-08-11 14:57:25 +00:00
if (node) {
_FreeTree(node->left);
_FreeTree(node->right);
_Free(_GetNode(node));
}
}
2007-08-11 14:57:25 +00:00
// #pragma mark - strategy parameters
// Ascending
namespace AVLTreeMapStrategy {
template<typename Value>
class Ascending {
2007-08-11 14:57:25 +00:00
public:
inline int operator()(const Value &a, const Value &b) const
{
if (a < b)
return -1;
else if (a > b)
return 1;
return 0;
}
};
}
2007-08-11 14:57:25 +00:00
// Descending
namespace AVLTreeMapStrategy {
template<typename Value>
class Descending {
2007-08-11 14:57:25 +00:00
public:
inline int operator()(const Value &a, const Value &b) const
{
if (a < b)
return -1;
else if (a > b)
return 1;
return 0;
}
};
}
2007-08-11 14:57:25 +00:00
// #pragma mark - strategies
// Auto
namespace AVLTreeMapStrategy {
template <typename Key, typename Value, typename KeyOrder,
template <typename> class Allocator>
class Auto {
public:
2007-08-11 14:57:25 +00:00
struct Node : AVLTreeNode {
Node(const Key &key, const Value &value)
2007-08-11 14:57:25 +00:00
: AVLTreeNode(),
key(key),
value(value)
{
}
Key key;
Value value;
};
2007-08-11 14:57:25 +00:00
inline Node* Allocate(const Key& key, const Value& value)
{
2007-08-11 14:57:25 +00:00
Node* result = fAllocator.Allocate();
if (result)
fAllocator.Construct(result, key, value);
return result;
}
2007-08-11 14:57:25 +00:00
inline void Free(Node* node)
{
fAllocator.Destruct(node);
fAllocator.Deallocate(node);
}
inline const Key& GetKey(const Node* node) const
{
return node->key;
}
2007-08-11 14:57:25 +00:00
inline Value& GetValue(Node* node) const
{
return node->value;
}
2007-08-11 14:57:25 +00:00
inline AVLTreeNode* GetAVLTreeNode(Node* node) const
{
return node;
}
inline Node* GetNode(AVLTreeNode* node) const
{
return static_cast<Node*>(node);
}
inline int CompareKeyNode(const Key& a, const Node* b) const
{
2011-07-07 15:31:12 +02:00
return fCompare(a, GetKey(b));
2007-08-11 14:57:25 +00:00
}
inline int CompareNodes(const Node* a, const Node* b) const
{
2011-07-07 15:31:12 +02:00
return fCompare(GetKey(a), GetKey(b));
}
private:
KeyOrder fCompare;
Allocator<Node> fAllocator;
};
}
2009-12-06 15:59:37 +00:00
#endif // _KERNEL_UTIL_AVL_TREE_MAP_H