X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=nucleus%2Flibrary%2Fnodes%2Ftree.cpp;h=2a88061cada797e432fc2108d0c4874395db22e7;hb=37cab48c3be29e1b41929cae3f5fb63d65fd344e;hp=a087b0b74edaeb032771f1b725eb80d3a4e000bb;hpb=457b128b77b5b4a0b7dd3094de543de2ce1477ad;p=feisty_meow.git diff --git a/nucleus/library/nodes/tree.cpp b/nucleus/library/nodes/tree.cpp index a087b0b7..2a88061c 100644 --- a/nucleus/library/nodes/tree.cpp +++ b/nucleus/library/nodes/tree.cpp @@ -50,7 +50,7 @@ bool tree::iterator::next_node(tree *&to_return) #ifdef DEBUG_TREE FUNCDEF("next_node"); #endif - to_return = NIL; + to_return = NULL_POINTER; #ifdef DEBUG_TREE if ( (_order != to_branches) && (_order != reverse_branches) ) { @@ -255,7 +255,7 @@ tree *tree::iterator::next() #ifdef DEBUG_TREE FUNCDEF("next"); #endif - tree *to_return = NIL; + tree *to_return = NULL_POINTER; bool found_tree = false; while (!found_tree) { bool still_running = next_node(to_return); @@ -270,7 +270,7 @@ tree *tree::iterator::next() tree::tree() : node(1) -{ set_link(BACKWARDS_BRANCH, NIL); } +{ set_link(BACKWARDS_BRANCH, NULL_POINTER); } tree::~tree() { @@ -278,10 +278,61 @@ tree::~tree() // cousin. tree *my_parent = parent(); if (my_parent) my_parent->prune(this); + my_parent = NULL_POINTER; // disavow since we are loose now. + +#if 0 + + //original version suffers from being too recursive on windoze, + //which blows out the stack. linux never showed this problem. so, i + //guess i'm glad i tested on windows. + //anyway, it's a general problem for a degenerate tree like the one + //i've constructed. current version has ~40000 direct descendants of + //the root in a single line, so the stack has to support 40000 frames + //for the delete implementation below to work. // iterate over the child nodes and whack each individually. while (branches()) delete branch(0); // this relies on the child getting out of our branch list. +#else + + // newer version of delete doesn't recurse; it just iterates instead, + // which avoids the massive recursive depth of the original approach. + tree *curr_node = this; + while (curr_node != NULL_POINTER) { + // make a breadcrumb for getting back to 'here' in the tree. + tree *way_back = curr_node; + // our main operation here is to go down a node without using any + // stack frames. so we just pick the first kid; it's either valid + // or there are no kids at all. + curr_node = curr_node->branch(0); + + if (curr_node == NULL_POINTER) { + // wayback has no children, so we can take action. + + // if wayback is the same as "this", then we exit from iterations since + // we've cleaned all the kids out. + if (way_back == this) { + break; + } + + // we want to whack the wayback node at this point, since it's a parent + // with no kids, i.e. a leaf. we've guaranteed we're not going beyond + // our remit, since wayback is not the same node as the top level one + // in the destructor (as long as there are no cycles in the tree...). + curr_node = way_back->parent(); // go up in tree on next iteration. + delete way_back; // whack a node, finally. + + } else { + // okay, there's a node below here. we will spider down to it. + continue; + } + + + } + +#endif + + } tree *tree::parent() const { return (tree *)get_link(BACKWARDS_BRANCH); } @@ -291,7 +342,7 @@ int tree::branches() const { return links() - 1; } tree *tree::branch(int branch_number) const { branch_number++; - bounds_return(branch_number, 1, branches(), NIL); + bounds_return(branch_number, 1, branches(), NULL_POINTER); return (tree *)get_link(branch_number); } @@ -301,8 +352,8 @@ int tree::which(tree *branch_to_find) const tree *tree::root() const { const tree *traveler = this; - // keep looking at the backwards branch until it is a NIL. the tree with - // a NIL BACKWARDS_BRANCH is the root. return that tree. + // keep looking at the backwards branch until it is a NULL_POINTER. the tree with + // a NULL_POINTER BACKWARDS_BRANCH is the root. return that tree. while (traveler->get_link(BACKWARDS_BRANCH)) traveler = (tree *)traveler->get_link(BACKWARDS_BRANCH); return const_cast(traveler); @@ -318,7 +369,7 @@ void tree::attach(tree *new_branch) void tree::insert(int branch_place, tree *new_branch) { branch_place++; - insert_link(links(), NIL); + insert_link(links(), NULL_POINTER); if (branch_place >= links()) branch_place = links() - 1; for (int i = links() - 1; i > branch_place; i--) @@ -339,7 +390,7 @@ outcome tree::prune_index(int branch_to_cut) branch_to_cut++; bounds_return(branch_to_cut, 1, branches(), basis::common::NOT_FOUND); tree *that_branch = (tree *)get_link(branch_to_cut); - that_branch->set_link(BACKWARDS_BRANCH, NIL); + that_branch->set_link(BACKWARDS_BRANCH, NULL_POINTER); zap_link(branch_to_cut); return basis::common::OKAY; } @@ -364,7 +415,7 @@ if (to_follow.size()) {} /* tree *traveller = this; path to_accumulate(root()); - while (traveller->parent() != NIL) { + while (traveller->parent() != NULL_POINTER) { // int branch_number = traveller->parent()->which(traveller); // if (branch_number == BRANCH_NOT_FOUND) non_continuable_error // (class_name(), "generate_path", "branch not found during path construction");