source: tags/testbuild/PARSIMONY/AP_main.cxx

Last change on this file was 13267, checked in by westram, 10 years ago
  • renamed AP_main::push/pop/clear into remember/revert/accept
  • added convenience wrappers accept_if/revert_if
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : AP_main.cxx                                       //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "ap_tree_nlen.hxx"
12#include "ap_main.hxx"
13#include <aw_msg.hxx>
14
15using namespace std;
16
17// ----------------
18//      AP_main
19
20GB_ERROR AP_main::open(const char *db_server) {
21    GB_ERROR error      = 0;
22    gb_main             = GB_open(db_server, "rwt");
23    if (!gb_main) error = GB_await_error();
24    return error;
25}
26
27void AP_main::user_push() {
28    frameData.user_push_counter = frameLevel + 1;
29    remember();
30}
31
32void AP_main::user_pop() {
33    // checks if user_pop possible
34    if (frameData.user_push_counter == frameLevel) {
35        revert();    // changes user_push_counter if user pop
36    }
37    else {
38        aw_message("No user-pop possible");
39    }
40}
41
42void AP_main::remember() {
43    /*! remember current tree state
44     * @see revert() and accept()
45     */
46
47    frameLevel ++;
48    if (currFrame) frames.push(currFrame);
49
50    currFrame = new NodeStack(frameData);
51
52#if defined(AVOID_MULTI_ROOT_PUSH)
53    frameData.root_pushed = false;
54#endif
55#if defined(CHECK_ROOT_POPS)
56    currFrame->root_at_create = DOWNCAST(AP_tree_nlen*, get_tree_root()->get_root_node());
57#endif
58}
59
60void AP_main::revert() {
61    /*! revert tree to last remembered state
62     * @see remember() and accept()
63     */
64    if (!currFrame) GBK_terminate("AP_main::pop on empty stack");
65
66    {
67        AP_tree_nlen *node;
68        while ((node = currFrame->pop())) {
69            if (frameLevel != node->get_pushed_to_frame()) {
70                cerr << "Main frame level=" << frameLevel << " node frame level=" << node->get_pushed_to_frame() << endl;
71                GBK_terminate("AP_main::pop: main/node frame-level inconsistency");
72            }
73            node->pop(frameLevel);
74        }
75    }
76
77#if defined(CHECK_ROOT_POPS)
78    ap_assert(currFrame->root_at_create == get_tree_root()->get_root_node()); // root has been restored!
79#endif
80
81    delete currFrame;
82    frameLevel --;
83
84    currFrame = frames.pop();
85    frameData = currFrame ? currFrame->get_previous_frame_data() : StackFrameData();
86}
87
88void AP_main::accept() {
89    /*! accept changes performed on tree (since last remember())
90     * @see revert()
91     */
92
93    // @@@ outdated
94    // removes count(?) elements from the list because the current tree is used
95    //
96    // if stack_counter greater than last user_push then
97    // moves all not previous buffered nodes in the
98    // previous stack
99
100    if (!currFrame) GBK_terminate("AP_main::clear on empty stack");
101
102    AP_tree_nlen *node;
103
104    // @@@ ensure test coverage -> DRY cases below (they are nearly the same)
105
106    if (frameData.user_push_counter >= frameLevel) {
107        while (!currFrame->empty()) {
108            UNCOVERED();
109            node = currFrame->pop();
110            node->clear(frameLevel, frameData.user_push_counter);
111        }
112        delete currFrame;
113        currFrame = frames.pop();
114    }
115    else {
116        NodeStack *prev_frame = frames.pop();
117        while ((node = currFrame->pop())) {
118            // UNCOVERED();
119            if (node->clear(frameLevel, frameData.user_push_counter) != true) {
120                // node was not cleared (because also buffered in previous node stack).
121                // @@@ has to be done independent of user_push_counter
122                // if revert() gets called for previous stack, it is necessary to revert
123                // the current change as well -> move into previous frame
124                // UNCOVERED();
125                if (prev_frame) {
126                    // UNCOVERED();
127                    prev_frame->push(node); // @@@ frames are pushed in reverted order (seems to be wrong)
128                }
129            }
130        }
131        delete currFrame;
132        currFrame = prev_frame;
133    }
134    frameLevel --;
135
136    frameData = currFrame ? currFrame->get_previous_frame_data() : StackFrameData();
137}
138
139void AP_main::push_node(AP_tree_nlen *node, AP_STACK_MODE mode) {
140    //
141    //  stores node
142    //
143    if (!currFrame) {
144        if (mode & SEQUENCE)    node->unhash_sequence();
145        return;
146    }
147
148    if (frameLevel < node->get_pushed_to_frame()) {
149        cerr << "Main frame level=" << frameLevel << " node frame level=" << node->get_pushed_to_frame() << endl;
150        GBK_terminate("AP_main::push_node: main/node frame-level inconsistency");
151    }
152
153    if (mode == ROOT) {
154        // test that it is really root what is pushed
155        ap_assert(!node->father);
156        ap_assert(node->is_root_node());
157
158#if defined(AVOID_MULTI_ROOT_PUSH)
159        if (frameData.root_pushed) {
160            // do not push root twice in same frame
161            mode = BOTH;
162        }
163        else {
164            frameData.root_pushed = true;
165#if defined(CHECK_ROOT_POPS)
166            ap_assert(node == currFrame->root_at_create); // make sure the pushed root is the correct one
167#endif
168        }
169#endif
170    }
171
172    if (node->push(mode, frameLevel)) currFrame->push(node);
173    if (mode == ROOT) {
174        // In AP_main::pop(), root-node has to be restored after everything else has been restored.
175        // Move node to bottom of stack now to ensure that.
176        currFrame->remove(node);
177        currFrame->shift(node);
178    }
179}
180
181void AP_main::set_tree_root(AWT_graphic_parsimony *agt_) {
182    ap_assert(agt == 0 && agt_ != 0);               // do only once
183    agt = agt_;
184}
185
186const char *AP_main::get_aliname() const {
187    return get_tree_root()->get_aliview()->get_aliname();
188}
189
Note: See TracBrowser for help on using the repository browser.