diff --git a/headers/private/kernel/util/AVLTree.h b/headers/private/kernel/util/AVLTree.h new file mode 100644 index 0000000000..eb8964e627 --- /dev/null +++ b/headers/private/kernel/util/AVLTree.h @@ -0,0 +1,366 @@ +/* + * Copyright 2003-2009, Ingo Weinhold . + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_UTIL_AVL_TREE_H +#define _KERNEL_UTIL_AVL_TREE_H + + +#include + + +/* + To be implemented by the definition: + + typedef int Key; + typedef Foo Value; + + AVLTreeNode* GetAVLTreeNode(Value* value) const; + Value* GetValue(AVLTreeNode* node) const; + int Compare(const Key& a, const Value* b) const; + int Compare(const Value* a, const Value* b) const; +*/ + + + +template +class AVLTree : protected AVLTreeCompare { +private: + typedef typename Definition::Key Key; + typedef typename Definition::Value Value; + +public: + class Iterator; + class ConstIterator; + +public: + AVLTree(); + AVLTree(const Definition& definition); + virtual ~AVLTree(); + + inline int Count() const { return fTree.Count(); } + inline bool IsEmpty() const { return fTree.IsEmpty(); } + inline void Clear(); + + Value* RootNode() const; + + inline Iterator GetIterator(); + inline ConstIterator GetIterator() const; + + inline Iterator GetIterator(Value* value); + inline ConstIterator GetIterator(Value* value) const; + + Value* Find(const Key& key) const; + Value* FindClosest(const Key& key, bool less) const; + + status_t Insert(Value* value, Iterator* iterator = NULL); + Value* Remove(const Key& key); + bool Remove(Value* key); + + void CheckTree() const { fTree.CheckTree(); } + +protected: + // AVLTreeCompare + virtual int CompareKeyNode(const void* key, + const AVLTreeNode* node); + virtual int CompareNodes(const AVLTreeNode* node1, + const AVLTreeNode* node2); + + // definition shortcuts + inline AVLTreeNode* _GetAVLTreeNode(Value* value) const; + inline Value* _GetValue(const AVLTreeNode* node) const; + inline int _Compare(const Key& a, const Value* b); + inline int _Compare(const Value* a, const Value* b); + +protected: + friend class Iterator; + friend class ConstIterator; + + AVLTreeBase fTree; + Definition fDefinition; + +public: + // (need to implement it here, otherwise gcc 2.95.3 chokes) + class Iterator : public ConstIterator { + public: + inline Iterator() + : + ConstIterator() + { + } + + inline Iterator(const Iterator& other) + : + ConstIterator(other) + { + } + + inline void Remove() + { + if (AVLTreeNode* node = ConstIterator::fTreeIterator.Remove()) { + AVLTree* parent + = const_cast*>( + ConstIterator::fParent); + } + } + + private: + inline Iterator(AVLTree* parent, + const AVLTreeIterator& treeIterator) + : ConstIterator(parent, treeIterator) + { + } + + friend class AVLTree; + }; +}; + + +template +class AVLTree::ConstIterator { +public: + inline ConstIterator() + : + fParent(NULL), + fTreeIterator() + { + } + + inline ConstIterator(const ConstIterator& other) + : + fParent(other.fParent), + fTreeIterator(other.fTreeIterator) + { + } + + inline bool HasCurrent() const + { + return fTreeIterator.Current(); + } + + inline Value* Current() + { + if (AVLTreeNode* node = fTreeIterator.Current()) + return fParent->_GetValue(node); + return NULL; + } + + inline bool HasNext() const + { + return fTreeIterator.HasNext(); + } + + inline Value* Next() + { + if (AVLTreeNode* node = fTreeIterator.Next()) + return fParent->_GetValue(node); + return NULL; + } + + inline Value* Previous() + { + if (AVLTreeNode* node = fTreeIterator.Previous()) + return fParent->_GetValue(node); + return NULL; + } + + inline ConstIterator& operator=(const ConstIterator& other) + { + fParent = other.fParent; + fTreeIterator = other.fTreeIterator; + return *this; + } + +protected: + inline ConstIterator(const AVLTree* parent, + const AVLTreeIterator& treeIterator) + { + fParent = parent; + fTreeIterator = treeIterator; + } + + friend class AVLTree; + + const AVLTree* fParent; + AVLTreeIterator fTreeIterator; +}; + + +template +AVLTree::AVLTree() + : + fTree(this), + fDefinition() +{ +} + + +template +AVLTree::AVLTree(const Definition& definition) + : + fTree(this), + fDefinition(definition) +{ +} + + +template +AVLTree::~AVLTree() +{ +} + + +template +inline void +AVLTree::Clear() +{ + fTree.MakeEmpty(); +} + + +template +inline typename AVLTree::Value* +AVLTree::RootNode() const +{ + if (AVLTreeNode* root = fTree.Root()) + return _GetValue(root); + return NULL; +} + + +template +inline typename AVLTree::Iterator +AVLTree::GetIterator() +{ + return Iterator(this, fTree.GetIterator()); +} + + +template +inline typename AVLTree::ConstIterator +AVLTree::GetIterator() const +{ + return ConstIterator(this, fTree.GetIterator()); +} + + +template +inline typename AVLTree::Iterator +AVLTree::GetIterator(Value* value) +{ + return Iterator(this, fTree.GetIterator(_GetAVLTreeNode(value))); +} + + +template +inline typename AVLTree::ConstIterator +AVLTree::GetIterator(Value* value) const +{ + return ConstIterator(this, fTree.GetIterator(_GetAVLTreeNode(value))); +} + + +template +typename AVLTree::Value* +AVLTree::Find(const Key& key) const +{ + if (AVLTreeNode* node = fTree.Find(&key)) + return _GetValue(node); + return NULL; +} + + +template +typename AVLTree::Value* +AVLTree::FindClosest(const Key& key, bool less) const +{ + if (AVLTreeNode* node = fTree.FindClosest(&key, less)) + return _GetValue(node); + return NULL; +} + + +template +status_t +AVLTree::Insert(Value* value, Iterator* iterator) +{ + AVLTreeNode* node = _GetAVLTreeNode(value); + status_t error = fTree.Insert(node); + if (error != B_OK) + return error; + + if (iterator != NULL) + *iterator = Iterator(this, fTree.GetIterator(node)); + + return B_OK; +} + + +template +typename AVLTree::Value* +AVLTree::Remove(const Key& key) +{ + AVLTreeNode* node = fTree.Remove(&key); + return node != NULL ? _GetValue(node) : NULL; +} + + +template +bool +AVLTree::Remove(Value* value) +{ + return fTree.Remove(_GetAVLTreeNode(value)); +} + + +template +int +AVLTree::CompareKeyNode(const void* key, + const AVLTreeNode* node) +{ + return _Compare(*(const Key*)key, _GetValue(node)); +} + + +template +int +AVLTree::CompareNodes(const AVLTreeNode* node1, + const AVLTreeNode* node2) +{ + return _Compare(_GetValue(node1), _GetValue(node2)); +} + + +template +inline AVLTreeNode* +AVLTree::_GetAVLTreeNode(Value* value) const +{ + return fDefinition.GetAVLTreeNode(value); +} + + +template +inline typename AVLTree::Value* +AVLTree::_GetValue(const AVLTreeNode* node) const +{ + return fDefinition.GetValue(const_cast(node)); +} + + +template +inline int +AVLTree::_Compare(const Key& a, const Value* b) +{ + return fDefinition.Compare(a, b); +} + + +template +inline int +AVLTree::_Compare(const Value* a, const Value* b) +{ + return fDefinition.Compare(a, b); +} + + +#endif // _KERNEL_UTIL_AVL_TREE_H diff --git a/headers/private/kernel/util/AVLTreeBase.h b/headers/private/kernel/util/AVLTreeBase.h new file mode 100644 index 0000000000..6c9bd7bbad --- /dev/null +++ b/headers/private/kernel/util/AVLTreeBase.h @@ -0,0 +1,205 @@ +/* + * Copyright 2003-2009, Ingo Weinhold . + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_UTIL_AVL_TREE_BASE_H +#define _KERNEL_UTIL_AVL_TREE_BASE_H + + +#include + + +class AVLTreeIterator; + + +struct AVLTreeNode { + AVLTreeNode* parent; + AVLTreeNode* left; + AVLTreeNode* right; + int balance_factor; +}; + + +class AVLTreeCompare { +public: + virtual ~AVLTreeCompare(); + + virtual int CompareKeyNode(const void* key, + const AVLTreeNode* node) = 0; + virtual int CompareNodes(const AVLTreeNode* node1, + const AVLTreeNode* node2) = 0; +}; + + +class AVLTreeBase { +public: + AVLTreeBase(AVLTreeCompare* compare); + ~AVLTreeBase(); + + inline int Count() const { return fNodeCount; } + inline bool IsEmpty() const { return (fNodeCount == 0); } + void MakeEmpty(); + + inline AVLTreeNode* Root() const { return fRoot; } + + AVLTreeNode* LeftMost(AVLTreeNode* node) const; + AVLTreeNode* RightMost(AVLTreeNode* node) const; + + AVLTreeNode* Previous(AVLTreeNode* node) const; + AVLTreeNode* Next(AVLTreeNode* node) const; + + inline AVLTreeIterator GetIterator() const; + inline AVLTreeIterator GetIterator(AVLTreeNode* node) const; + + AVLTreeNode* Find(const void* key) const; + AVLTreeNode* FindClosest(const void* key, bool less) const; + + status_t Insert(AVLTreeNode* element); + AVLTreeNode* Remove(const void* key); + bool Remove(AVLTreeNode* element); + + void CheckTree() const; + +private: + enum { + NOT_FOUND = -3, + DUPLICATE = -2, + NO_MEMORY = -1, + OK = 0, + HEIGHT_CHANGED = 1, + + LEFT = -1, + BALANCED = 0, + RIGHT = 1, + }; + + // rotations + void _RotateRight(AVLTreeNode** nodeP); + void _RotateLeft(AVLTreeNode** nodeP); + + // insert + int _BalanceInsertLeft(AVLTreeNode** node); + int _BalanceInsertRight(AVLTreeNode** node); + int _Insert(AVLTreeNode* nodeToInsert); + + // remove + int _BalanceRemoveLeft(AVLTreeNode** node); + int _BalanceRemoveRight(AVLTreeNode** node); + int _RemoveRightMostChild(AVLTreeNode** node, + AVLTreeNode** foundNode); + int _Remove(AVLTreeNode* node); + + int _CheckTree(AVLTreeNode* parent, + AVLTreeNode* node, int& _nodeCount) const; + + AVLTreeNode* fRoot; + int fNodeCount; + AVLTreeCompare* fCompare; +}; + + +// AVLTreeIterator +class AVLTreeIterator { +public: + inline AVLTreeIterator() + : + fParent(NULL), + fCurrent(NULL), + fNext(NULL) + { + } + + inline AVLTreeIterator(const AVLTreeIterator& other) + : + fParent(other.fParent), + fCurrent(other.fCurrent), + fNext(other.fNext) + { + } + + inline AVLTreeNode* Current() const + { + return fCurrent; + } + + inline bool HasNext() const + { + return fNext; + } + + inline AVLTreeNode* Next() + { + fCurrent = fNext; + + if (fNext) + fNext = fParent->Next(fNext); + + return fCurrent; + } + + inline AVLTreeNode* Previous() + { + if (fCurrent) { + fNext = fCurrent; + fCurrent = fParent->Previous(fCurrent); + } else if (fNext) + fCurrent = fParent->Previous(fNext); + + return fCurrent; + } + + inline AVLTreeNode* Remove() + { + if (!fCurrent) + return NULL; + + AVLTreeNode* node = fCurrent; + fCurrent = NULL; + + return (const_cast(fParent)->Remove(node) ? node : NULL); + } + + inline AVLTreeIterator& operator=(const AVLTreeIterator& other) + { + fParent = other.fParent; + fCurrent = other.fCurrent; + fNext = other.fNext; + return *this; + } + +private: + inline AVLTreeIterator(const AVLTreeBase* parent, AVLTreeNode* current, + AVLTreeNode* next) + : + fParent(parent), + fCurrent(current), + fNext(next) + { + } + +protected: + friend class AVLTreeBase; + + const AVLTreeBase* fParent; + AVLTreeNode* fCurrent; + AVLTreeNode* fNext; +}; + + +// GetIterator +inline AVLTreeIterator +AVLTreeBase::GetIterator() const +{ + return AVLTreeIterator(this, NULL, LeftMost(fRoot)); +} + + +// GetIterator +inline AVLTreeIterator +AVLTreeBase::GetIterator(AVLTreeNode* node) const +{ + return AVLTreeIterator(this, node, Next(node)); +} + + +#endif // _KERNEL_UTIL_AVL_TREE_BASE_H diff --git a/headers/private/kernel/util/AVLTreeMap.h b/headers/private/kernel/util/AVLTreeMap.h index da25650d7b..a6a978572b 100644 --- a/headers/private/kernel/util/AVLTreeMap.h +++ b/headers/private/kernel/util/AVLTreeMap.h @@ -1,209 +1,13 @@ /* - * Copyright 2003-2007, Ingo Weinhold . + * Copyright 2003-2009, Ingo Weinhold . * Distributed under the terms of the MIT License. */ -#ifndef _AVL_TREE_MAP_H -#define _AVL_TREE_MAP_H +#ifndef _KERNEL_UTIL_AVL_TREE_MAP_H +#define _KERNEL_UTIL_AVL_TREE_MAP_H -#include -#include - #include - - -// maximal height of a tree -static const int kMaxAVLTreeHeight = 32; - -class AVLTreeIterator; - - -// AVLTreeNode -struct AVLTreeNode { - AVLTreeNode* parent; - AVLTreeNode* left; - AVLTreeNode* right; - int balance_factor; -}; - - -// AVLTreeCompare -class AVLTreeCompare { -public: - virtual ~AVLTreeCompare(); - - virtual int CompareKeyNode(const void* key, - const AVLTreeNode* node) = 0; - virtual int CompareNodes(const AVLTreeNode* node1, - const AVLTreeNode* node2) = 0; -}; - - -// AVLTree -class AVLTree { -public: - AVLTree(AVLTreeCompare* compare); - ~AVLTree(); - - inline int Count() const { return fNodeCount; } - inline bool IsEmpty() const { return (fNodeCount == 0); } - void MakeEmpty(); - - inline AVLTreeNode* Root() const { return fRoot; } - - AVLTreeNode* LeftMost(AVLTreeNode* node) const; - AVLTreeNode* RightMost(AVLTreeNode* node) const; - - AVLTreeNode* Previous(AVLTreeNode* node) const; - AVLTreeNode* Next(AVLTreeNode* node) const; - - inline AVLTreeIterator GetIterator() const; - inline AVLTreeIterator GetIterator(AVLTreeNode* node) const; - - AVLTreeNode* Find(const void* key); - AVLTreeNode* FindClose(const void* key, bool less); - - status_t Insert(AVLTreeNode* element); - AVLTreeNode* Remove(const void* key); - bool Remove(AVLTreeNode* element); - -private: - enum { - NOT_FOUND = -3, - DUPLICATE = -2, - NO_MEMORY = -1, - OK = 0, - HEIGHT_CHANGED = 1, - - LEFT = -1, - BALANCED = 0, - RIGHT = 1, - }; - - // rotations - void _RotateRight(AVLTreeNode** nodeP); - void _RotateLeft(AVLTreeNode** nodeP); - - // insert - int _BalanceInsertLeft(AVLTreeNode** node); - int _BalanceInsertRight(AVLTreeNode** node); - int _Insert(AVLTreeNode* nodeToInsert); - - // remove - int _BalanceRemoveLeft(AVLTreeNode** node); - int _BalanceRemoveRight(AVLTreeNode** node); - int _RemoveRightMostChild(AVLTreeNode** node, - AVLTreeNode** foundNode); - int _Remove(AVLTreeNode* node); - - AVLTreeNode* fRoot; - int fNodeCount; - AVLTreeCompare* fCompare; -}; - - -// AVLTreeIterator -class AVLTreeIterator { -public: - inline AVLTreeIterator() - : fParent(NULL), - fCurrent(NULL), - fNext(NULL) - { - } - - inline AVLTreeIterator(const AVLTreeIterator& other) - : fParent(other.fParent), - fCurrent(other.fCurrent), - fNext(other.fNext) - { - } - - inline AVLTreeNode* Current() const - { - return fCurrent; - } - - inline bool HasNext() const - { - return fNext; - } - - inline AVLTreeNode* Next() - { - fCurrent = fNext; - - if (fNext) - fNext = fParent->Next(fNext); - - return fCurrent; - } - - inline AVLTreeNode* Previous() - { - if (fCurrent) { - fNext = fCurrent; - fCurrent = fParent->Previous(fCurrent); - } else if (fNext) - fCurrent = fParent->Previous(fNext); - - return fCurrent; - } - - inline AVLTreeNode* Remove() - { - if (!fCurrent) - return NULL; - - AVLTreeNode* node = fCurrent; - fCurrent = NULL; - - return (const_cast(fParent)->Remove(node) ? node : NULL); - } - - inline AVLTreeIterator& operator=(const AVLTreeIterator& other) - { - fParent = other.fParent; - fCurrent = other.fCurrent; - fNext = other.fNext; - return *this; - } - -private: - inline AVLTreeIterator(const AVLTree* parent, AVLTreeNode* current, - AVLTreeNode* next) - : fParent(parent), - fCurrent(current), - fNext(next) - { - } - -protected: - friend class AVLTree; - - const AVLTree* fParent; - AVLTreeNode* fCurrent; - AVLTreeNode* fNext; -}; - - -// GetIterator -inline AVLTreeIterator -AVLTree::GetIterator() const -{ - return AVLTreeIterator(this, NULL, LeftMost(fRoot)); -} - - -// GetIterator -inline AVLTreeIterator -AVLTree::GetIterator(AVLTreeNode* node) const -{ - return AVLTreeIterator(this, node, Next(node)); -} - - -// #pragma mark - AVLTreeMap and friends +#include // strategies @@ -299,7 +103,7 @@ protected: friend class Iterator; friend class ConstIterator; - AVLTree fTree; + AVLTreeBase fTree; NodeStrategy fStrategy; public: @@ -518,7 +322,7 @@ _AVL_TREE_MAP_TEMPLATE_LIST typename _AVL_TREE_MAP_CLASS_NAME::Iterator _AVL_TREE_MAP_CLASS_NAME::FindClose(const Key& key, bool less) { - if (AVLTreeNode* node = fTree.FindClose(&key, less)) + if (AVLTreeNode* node = fTree.FindClosest(&key, less)) return Iterator(this, fTree.GetIterator(node)); return Iterator(); } @@ -776,4 +580,4 @@ private: }; } -#endif // _AVL_TREE_MAP_H +#endif // _KERNEL_UTIL_AVL_TREE_MAP_H diff --git a/src/system/kernel/util/AVLTreeMap.cpp b/src/system/kernel/util/AVLTreeBase.cpp similarity index 78% rename from src/system/kernel/util/AVLTreeMap.cpp rename to src/system/kernel/util/AVLTreeBase.cpp index e3564cd3e5..91c3ff096e 100644 --- a/src/system/kernel/util/AVLTreeMap.cpp +++ b/src/system/kernel/util/AVLTreeBase.cpp @@ -1,9 +1,32 @@ /* - * Copyright 2003-2007, Ingo Weinhold . + * Copyright 2003-2009, Ingo Weinhold . * Distributed under the terms of the MIT License. */ -#include + +#include + +#include + +#include + + +#ifdef _KERNEL_MODE +# define CHECK_FAILED(message...) panic(message) +#else +# include +# include +# define CHECK_FAILED(message...) \ + do { \ + fprintf(stderr, message); \ + fprintf(stderr, "\n"); \ + debugger("AVLTreeBase check failed"); \ + } while (false) +#endif + + +// maximal height of a tree +static const int kMaxAVLTreeHeight = 32; // #pragma mark - AVLTreeCompare @@ -14,10 +37,10 @@ AVLTreeCompare::~AVLTreeCompare() } -// #pragma mark - AVLTree +// #pragma mark - AVLTreeBase -AVLTree::AVLTree(AVLTreeCompare* compare) +AVLTreeBase::AVLTreeBase(AVLTreeCompare* compare) : fRoot(NULL), fNodeCount(0), fCompare(compare) @@ -25,77 +48,21 @@ AVLTree::AVLTree(AVLTreeCompare* compare) } -AVLTree::~AVLTree() +AVLTreeBase::~AVLTreeBase() { } void -AVLTree::MakeEmpty() +AVLTreeBase::MakeEmpty() { fRoot = NULL; fNodeCount = 0; } -status_t -AVLTree::Insert(AVLTreeNode* nodeToInsert) -{ - int result = _Insert(nodeToInsert); - switch (result) { - case OK: - case HEIGHT_CHANGED: - return B_OK; - case NO_MEMORY: - return B_NO_MEMORY; - case DUPLICATE: - default: - return B_BAD_VALUE; - } -} - - AVLTreeNode* -AVLTree::Remove(const void* key) -{ - // find node - AVLTreeNode* node = fRoot; - while (node) { - int cmp = fCompare->CompareKeyNode(key, node); - if (cmp == 0) - break; - else { - if (cmp < 0) - node = node->left; - else - node = node->right; - } - } - - // remove it - if (node) - _Remove(node); - - return node; -} - - -bool -AVLTree::Remove(AVLTreeNode* node) -{ - switch (_Remove(node)) { - case OK: - case HEIGHT_CHANGED: - return true; - case NOT_FOUND: - default: - return false; - } -} - - -AVLTreeNode* -AVLTree::LeftMost(AVLTreeNode* node) const +AVLTreeBase::LeftMost(AVLTreeNode* node) const { if (node) { while (node->left) @@ -107,7 +74,7 @@ AVLTree::LeftMost(AVLTreeNode* node) const AVLTreeNode* -AVLTree::RightMost(AVLTreeNode* node) const +AVLTreeBase::RightMost(AVLTreeNode* node) const { if (node) { while (node->right) @@ -119,7 +86,7 @@ AVLTree::RightMost(AVLTreeNode* node) const AVLTreeNode* -AVLTree::Previous(AVLTreeNode* node) const +AVLTreeBase::Previous(AVLTreeNode* node) const { if (node) { // The previous node cannot be in the right subtree. @@ -144,7 +111,7 @@ AVLTree::Previous(AVLTreeNode* node) const AVLTreeNode* -AVLTree::Next(AVLTreeNode* node) const +AVLTreeBase::Next(AVLTreeNode* node) const { if (node) { // The next node cannot be in the left subtree. @@ -169,7 +136,7 @@ AVLTree::Next(AVLTreeNode* node) const AVLTreeNode* -AVLTree::Find(const void* key) +AVLTreeBase::Find(const void* key) const { AVLTreeNode* node = fRoot; @@ -189,7 +156,7 @@ AVLTree::Find(const void* key) AVLTreeNode* -AVLTree::FindClose(const void* key, bool less) +AVLTreeBase::FindClosest(const void* key, bool less) const { AVLTreeNode* node = fRoot; AVLTreeNode* parent = NULL; @@ -225,8 +192,76 @@ AVLTree::FindClose(const void* key, bool less) } +status_t +AVLTreeBase::Insert(AVLTreeNode* nodeToInsert) +{ + int result = _Insert(nodeToInsert); + switch (result) { + case OK: + case HEIGHT_CHANGED: + return B_OK; + case NO_MEMORY: + return B_NO_MEMORY; + case DUPLICATE: + default: + return B_BAD_VALUE; + } +} + + +AVLTreeNode* +AVLTreeBase::Remove(const void* key) +{ + // find node + AVLTreeNode* node = fRoot; + while (node) { + int cmp = fCompare->CompareKeyNode(key, node); + if (cmp == 0) + break; + else { + if (cmp < 0) + node = node->left; + else + node = node->right; + } + } + + // remove it + if (node) + _Remove(node); + + return node; +} + + +bool +AVLTreeBase::Remove(AVLTreeNode* node) +{ + switch (_Remove(node)) { + case OK: + case HEIGHT_CHANGED: + return true; + case NOT_FOUND: + default: + return false; + } +} + + void -AVLTree::_RotateRight(AVLTreeNode** nodeP) +AVLTreeBase::CheckTree() const +{ + int nodeCount = 0; + _CheckTree(NULL, fRoot, nodeCount); + if (nodeCount != fNodeCount) { + CHECK_FAILED("AVLTreeBase::CheckTree(): node count mismatch: %d vs %d", + nodeCount, fNodeCount); + } +} + + +void +AVLTreeBase::_RotateRight(AVLTreeNode** nodeP) { // rotate the nodes AVLTreeNode* node = *nodeP; @@ -257,7 +292,7 @@ AVLTree::_RotateRight(AVLTreeNode** nodeP) void -AVLTree::_RotateLeft(AVLTreeNode** nodeP) +AVLTreeBase::_RotateLeft(AVLTreeNode** nodeP) { // rotate the nodes AVLTreeNode* node = *nodeP; @@ -288,7 +323,7 @@ AVLTree::_RotateLeft(AVLTreeNode** nodeP) int -AVLTree::_BalanceInsertLeft(AVLTreeNode** node) +AVLTreeBase::_BalanceInsertLeft(AVLTreeNode** node) { if ((*node)->balance_factor < LEFT) { // tree is left heavy @@ -312,7 +347,7 @@ AVLTree::_BalanceInsertLeft(AVLTreeNode** node) int -AVLTree::_BalanceInsertRight(AVLTreeNode** node) +AVLTreeBase::_BalanceInsertRight(AVLTreeNode** node) { if ((*node)->balance_factor > RIGHT) { // tree is right heavy @@ -336,7 +371,7 @@ AVLTree::_BalanceInsertRight(AVLTreeNode** node) int -AVLTree::_Insert(AVLTreeNode* nodeToInsert) +AVLTreeBase::_Insert(AVLTreeNode* nodeToInsert) { struct node_info { AVLTreeNode** node; @@ -378,10 +413,6 @@ AVLTree::_Insert(AVLTreeNode* nodeToInsert) else (*node)->parent = *top[-1].node; - // init the iterator -// if (iterator) -// *iterator = Iterator(this, *node); - // do the balancing int result = HEIGHT_CHANGED; while (result == HEIGHT_CHANGED && top != bottom) { @@ -403,7 +434,7 @@ AVLTree::_Insert(AVLTreeNode* nodeToInsert) int -AVLTree::_BalanceRemoveLeft(AVLTreeNode** node) +AVLTreeBase::_BalanceRemoveLeft(AVLTreeNode** node) { int result = HEIGHT_CHANGED; @@ -430,7 +461,7 @@ AVLTree::_BalanceRemoveLeft(AVLTreeNode** node) int -AVLTree::_BalanceRemoveRight(AVLTreeNode** node) +AVLTreeBase::_BalanceRemoveRight(AVLTreeNode** node) { int result = HEIGHT_CHANGED; @@ -457,7 +488,7 @@ AVLTree::_BalanceRemoveRight(AVLTreeNode** node) int -AVLTree::_RemoveRightMostChild(AVLTreeNode** node, AVLTreeNode** foundNode) +AVLTreeBase::_RemoveRightMostChild(AVLTreeNode** node, AVLTreeNode** foundNode) { AVLTreeNode** stack[kMaxAVLTreeHeight]; AVLTreeNode*** top = stack; @@ -495,7 +526,7 @@ AVLTree::_RemoveRightMostChild(AVLTreeNode** node, AVLTreeNode** foundNode) int -AVLTree::_Remove(AVLTreeNode* node) +AVLTreeBase::_Remove(AVLTreeNode* node) { if (!node) return NOT_FOUND; @@ -563,3 +594,36 @@ AVLTree::_Remove(AVLTreeNode* node) return result; } + + +int +AVLTreeBase::_CheckTree(AVLTreeNode* parent, AVLTreeNode* node, + int& _nodeCount) const +{ + if (node == NULL) { + _nodeCount = 0; + return 0; + } + + if (parent != node->parent) { + CHECK_FAILED("AVLTreeBase::_CheckTree(): node %p parent mismatch: " + "%p vs %p", node, parent, node->parent); + } + + int leftNodeCount; + int leftDepth = _CheckTree(node, node->left, leftNodeCount); + + int rightNodeCount; + int rightDepth = _CheckTree(node, node->right, rightNodeCount); + + int balance = rightDepth - leftDepth; + if (balance < LEFT || balance > RIGHT) { + CHECK_FAILED("AVLTreeBase::_CheckTree(): unbalanced subtree: %p", node); + } else if (balance != node->balance_factor) { + CHECK_FAILED("AVLTreeBase::_CheckTree(): subtree %p balance mismatch: " + "%d vs %d", node, balance, node->balance_factor); + } + + _nodeCount = leftNodeCount + rightNodeCount + 1; + return std::max(leftDepth, rightDepth) + 1; +} diff --git a/src/system/kernel/util/Jamfile b/src/system/kernel/util/Jamfile index ea99997063..60616440a9 100644 --- a/src/system/kernel/util/Jamfile +++ b/src/system/kernel/util/Jamfile @@ -3,7 +3,7 @@ SubDir HAIKU_TOP src system kernel util ; UsePrivateHeaders [ FDirName kernel util ] ; KernelMergeObject kernel_util.o : - AVLTreeMap.cpp + AVLTreeBase.cpp kernel_cpp.cpp khash.cpp list.cpp