summaryrefslogtreecommitdiffstats
path: root/src/libs/engine/TreeImplementation.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-10-07 17:34:19 +0000
committerDavid Robillard <d@drobilla.net>2007-10-07 17:34:19 +0000
commit91031b8f5a4bf86b39e4c4a02412a16e247f8b15 (patch)
treedaa980b9768b0e9e87bedaa0cc64e1f3abfb5860 /src/libs/engine/TreeImplementation.hpp
parentf2d5d172ff5f0ff02e6dfe0d0bd472b068192244 (diff)
downloadingen-91031b8f5a4bf86b39e4c4a02412a16e247f8b15.tar.gz
ingen-91031b8f5a4bf86b39e4c4a02412a16e247f8b15.tar.bz2
ingen-91031b8f5a4bf86b39e4c4a02412a16e247f8b15.zip
Start building a common (client/server) abstract interface for graph objects.
git-svn-id: http://svn.drobilla.net/lad/ingen@834 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs/engine/TreeImplementation.hpp')
-rw-r--r--src/libs/engine/TreeImplementation.hpp395
1 files changed, 0 insertions, 395 deletions
diff --git a/src/libs/engine/TreeImplementation.hpp b/src/libs/engine/TreeImplementation.hpp
deleted file mode 100644
index 681079ac..00000000
--- a/src/libs/engine/TreeImplementation.hpp
+++ /dev/null
@@ -1,395 +0,0 @@
-/* This file is part of Ingen.
- * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "Tree.hpp"
-#include <cstdlib>
-#include <iostream>
-#include <cassert>
-using std::cerr; using std::endl;
-
-
-/* FIXME: this is all in horrible need of a rewrite. */
-
-
-/** Destroy the tree.
- *
- * Note that this does not delete any TreeNodes still inside the tree,
- * that is the user's responsibility.
- */
-template <typename T>
-Tree<T>::~Tree()
-{
-}
-
-
-/** Insert a node into the tree. Realtime safe.
- *
- * @a n will be inserted using the key() field for searches.
- * n->key() must not be the empty string.
- */
-template<typename T>
-void
-Tree<T>::insert(TreeNode<T>* const n)
-{
- assert(n != NULL);
- assert(n->left_child() == NULL);
- assert(n->right_child() == NULL);
- assert(n->parent() == NULL);
- assert(n->key().length() > 0);
- assert(find_treenode(n->key()) == NULL);
-
- if (_root == NULL) {
- _root = n;
- } else {
- bool left = false; // which child to insert at
- bool right = false;
- TreeNode<T>* i = _root;
- while (true) {
- assert(i != NULL);
- if (n->key() <= i->key()) {
- if (i->left_child() == NULL) {
- left = true;
- break;
- } else {
- i = i->left_child();
- }
- } else {
- if (i->right_child() == NULL) {
- right = true;
- break;
- } else {
- i = i->right_child();
- }
- }
- }
-
- assert(i != NULL);
- assert(left || right);
- assert( ! (left && right) );
-
- if (left) {
- assert(i->left_child() == NULL);
- i->left_child(n);
- } else if (right) {
- assert(i->right_child() == NULL);
- i->right_child(n);
- }
- n->parent(i);
- }
- ++_size;
-}
-
-
-/** Remove a node from the tree.
- *
- * Realtime safe, caller is responsible to delete returned value.
- *
- * @return NULL if object with @a key is not in tree.
- */
-template<typename T>
-TreeNode<T>*
-Tree<T>::remove(const string& key)
-{
- TreeNode<T>* node = find_treenode(key);
- TreeNode<T>* n = node;
- TreeNode<T>* swap = NULL;
- T temp_node;
- string temp_key;
-
- if (node == NULL)
- return NULL;
-
- // Node is not even in tree
- if (node->parent() == NULL && _root != node)
- return NULL;
- // FIXME: What if the node is in a different tree? Check for this?
-
-#ifndef NDEBUG
- const T& remove_node = node->node(); // for error checking
-#endif // NDEBUG
-
- // n has two children
- if (n->left_child() != NULL && n->right_child() != NULL) {
- if (rand()%2)
- swap = _find_largest(n->left_child());
- else
- swap = _find_smallest(n->right_child());
-
- // Swap node's elements
- temp_node = swap->_node;
- swap->_node = n->_node;
- n->_node = temp_node;
-
- // Swap node's keys
- temp_key = swap->_key;
- swap->_key = n->_key;
- n->_key = temp_key;
-
- n = swap;
- assert(n != NULL);
- }
-
- // be sure we swapped correctly (ie right node is getting removed)
- assert(n->node() == remove_node);
-
- // n now has at most one child
- assert(n->left_child() == NULL || n->right_child() == NULL);
-
- if (n->is_leaf()) {
- if (n->is_left_child())
- n->parent()->left_child(NULL);
- else if (n->is_right_child())
- n->parent()->right_child(NULL);
-
- if (_root == n) _root = NULL;
- } else { // has a single child
- TreeNode<T>* child = NULL;
- if (n->left_child() != NULL)
- child = n->left_child();
- else if (n->right_child() != NULL)
- child = n->right_child();
- else
- exit(EXIT_FAILURE);
-
- assert(child != n);
- assert(child != NULL);
- assert(n->parent() != n);
-
- if (n->is_left_child()) {
- assert(n->parent() != child);
- n->parent()->left_child(child);
- child->parent(n->parent());
- } else if (n->is_right_child()) {
- assert(n->parent() != child);
- n->parent()->right_child(child);
- child->parent(n->parent());
- } else {
- child->parent(NULL);
- }
- if (_root == n) _root = child;
- }
-
- // Be sure node is cut off completely
- assert(n != NULL);
- assert(n->parent() == NULL || n->parent()->left_child() != n);
- assert(n->parent() == NULL || n->parent()->right_child() != n);
- assert(n->left_child() == NULL || n->left_child()->parent() != n);
- assert(n->right_child() == NULL || n->right_child()->parent() != n);
- assert(_root != n);
-
- n->parent(NULL);
- n->left_child(NULL);
- n->right_child(NULL);
-
- --_size;
-
- if (_size == 0) _root = NULL;
-
- // Be sure right node is being removed
- assert(n->node() == remove_node);
-
- return n;
-}
-
-
-template<typename T>
-T
-Tree<T>::find(const string& name) const
-{
- TreeNode<T>* tn = find_treenode(name);
-
- return (tn == NULL) ? NULL : tn->node();
-}
-
-
-template<typename T>
-TreeNode<T>*
-Tree<T>::find_treenode(const string& name) const
-{
- TreeNode<T>* i = _root;
- int cmp = 0;
-
- while (i != NULL) {
- cmp = name.compare(i->key());
- if (cmp < 0)
- i = i->left_child();
- else if (cmp > 0)
- i = i->right_child();
- else
- break;
- }
-
- return i;
-}
-
-
-/** Finds the smallest (key) node in the subtree rooted at "root"
- */
-template<typename T>
-TreeNode<T>*
-Tree<T>::_find_smallest(TreeNode<T>* root)
-{
- TreeNode<T>* r = root;
-
- while (r->left_child() != NULL)
- r = r->left_child();
-
- return r;
-}
-
-
-/** Finds the largest (key) node in the subtree rooted at "root".
- */
-template<typename T>
-TreeNode<T>*
-Tree<T>::_find_largest(TreeNode<T>* root)
-{
- TreeNode<T>* r = root;
-
- while (r->right_child() != NULL)
- r = r->right_child();
-
- return r;
-
-}
-
-
-
-//// Iterator Stuff ////
-
-
-
-template<typename T>
-Tree<T>::iterator::iterator(const Tree *tree, size_t size)
-: _depth(-1),
- _size(size),
- _stack(NULL),
- _tree(tree)
-{
- if (size > 0)
- _stack = new TreeNode<T>*[size];
-}
-
-
-template<typename T>
-Tree<T>::iterator::~iterator()
-{
- delete[] _stack;
-}
-
-
-/* FIXME: Make these next two not memcpy (possibly have to force a single
- * iterator existing at any given time) for speed.
- */
-
-// Copy constructor (for the typical for loop usage)
-template<typename T>
-Tree<T>::iterator::iterator(const Tree<T>::iterator& copy)
-: _depth(copy._depth),
- _size(copy._size),
- _tree(copy._tree)
-{
- if (_size > 0) {
- _stack = new TreeNode<T>*[_size];
- memcpy(_stack, copy._stack, _size * sizeof(TreeNode<T>*));
- }
-}
-
-
-// Assignment operator
-template<typename T>
-typename Tree<T>::iterator&
-Tree<T>::iterator::operator=(const Tree<T>::iterator& copy) {
- _depth = copy._depth;
- _size = copy._size;
- _tree = copy._tree;
-
- if (_size > 0) {
- _stack = new TreeNode<T>*[_size];
- memcpy(_stack, copy._stack, _size * sizeof(TreeNode<T>*));
- }
- return *this;
-}
-
-
-template<typename T>
-T
-Tree<T>::iterator::operator*() const
-{
- assert(_depth >= 0);
- return _stack[_depth]->node();
-}
-
-
-template<typename T>
-typename Tree<T>::iterator&
-Tree<T>::iterator::operator++()
-{
- assert(_depth >= 0);
-
- TreeNode<T>* tn = _stack[_depth];
- --_depth;
-
- tn = tn->right_child();
- while (tn != NULL) {
- ++_depth;
- _stack[_depth] = tn;
- tn = tn->left_child();
- }
-
- return *this;
-}
-
-
-template<typename T>
-bool
-Tree<T>::iterator::operator!=(const Tree<T>::iterator& iter) const
-{
- // (DeMorgan's Law)
- return (_tree != iter._tree || _depth != iter._depth);
-}
-
-
-template<typename T>
-typename Tree<T>::iterator
-Tree<T>::begin() const
-{
- typename Tree<T>::iterator iter(this, _size);
- iter._depth = -1;
-
- TreeNode<T> *ptr = _root;
- while (ptr != NULL) {
- iter._depth++;
- iter._stack[iter._depth] = ptr;
- ptr = ptr->left_child();
- }
-
- return iter;
-}
-
-
-template<typename T>
-typename Tree<T>::iterator
-Tree<T>::end() const
-{
- typename Tree<T>::iterator iter(this, 0);
- iter._depth = -1;
-
- return iter;
-}
-
-