diff --git a/statik/Batch.cpp b/statik/Batch.cpp index 1185337..7ee6c8f 100644 --- a/statik/Batch.cpp +++ b/statik/Batch.cpp @@ -29,7 +29,7 @@ std::string Batch::BatchItem::Print() const { s += lexical_cast(node) + " " + node->Print(); } if (pos) { - s += " @ " + pos->Print(); + s += " @ " + lexical_cast(pos) + " " + pos->Print(); } return s; } diff --git a/statik/IncParser.cpp b/statik/IncParser.cpp index 3da1d04..e37f467 100644 --- a/statik/IncParser.cpp +++ b/statik/IncParser.cpp @@ -11,6 +11,9 @@ #include "SLog.h" #include "STree.h" +#include +using boost::lexical_cast; + #include #include #include @@ -370,7 +373,7 @@ void IncParser::ProcessActions() { } void IncParser::ComputeOutput_Update(const STree& node, Batch& out_batch, const List*& behind_node, State::Station worst_station) { - g_log.debug() << "IncParser " << m_name << ": Computing output UPDATE for node " << node; + g_log.debug() << "IncParser " << m_name << ": Computing output UPDATE for node " << node << " with behind node " << behind_node; worst_station = std::min(node.GetState().GetStation(), worst_station); node.GetOutputFunc() (); @@ -391,103 +394,32 @@ void IncParser::ComputeOutput_Update(const STree& node, Batch& out_batch, const g_log.debug() << node << " was emitting " << prev_output.size() << " items"; g_log.debug() << node << " is now emitting " << output.size() << " items"; - // Linear pass through both lists, comparing elements. - OutputList::iterator item = output.begin(); - OutputList::const_iterator prev_item = prev_output.begin(); - while (item != output.end() && prev_item != prev_output.end()) { - if (*item == *prev_item) { - g_log.debug() << "CO_Update for " << node << " linear pass, case 1 (lists match); before call, have batch=" << out_batch; - UpdateOutput(*item, out_batch, behind_node, worst_station); - g_log.debug() << "case 1 " << node << " inner call gave us batch: " << out_batch << " at item " << *item; - behind_node = GetOEnd(*item); - ++item; - ++prev_item; + typedef set node_set; + typedef node_set::iterator node_mod_iter; + node_set nodes(output.begin(), output.end()); + for (OutputList::const_iterator prev_item = prev_output.begin(); + prev_item != prev_output.end(); ++prev_item) { + node_mod_iter find_del = nodes.find(*prev_item); + if (nodes.end() == find_del) { + g_log.debug() << "Removing prev_item " << *prev_item; + RemoveOutput(*prev_item, out_batch, worst_station); } else { - g_log.debug() << "CO_Update for " << node << " linear pass, case 2 (lists don't match)"; - // Buffer both sides, and keep a lookup-set so we can identify if/when we - // find a node in one list that was surpassed in the other. - typedef set node_set; - typedef node_set::const_iterator node_iter; - node_set ins_set; - node_set del_set; - OutputList::iterator ins_item = item; - OutputList::const_iterator del_item = prev_item; - while (ins_item != output.end() && del_item != prev_output.end()) { - g_log.debug() << "while"; - for (node_iter i = ins_set.begin(); i != ins_set.end(); ++i) { - g_log.debug() << " ins set: " << *i; - } - g_log.debug() << "Looking for del item " << &*del_item << ": " << *del_item; - node_iter find_ins = ins_set.find(*del_item); - if (find_ins != ins_set.end()) { - // insert nodes up to find_ins - do { - g_log.debug() << "do1"; - InsertOutput(*item, out_batch, behind_node, worst_station); - behind_node = GetOEnd(*item); - ++item; - } while (*find_ins != *item); - // then remove the nodes up to find_ins from ins_set, and advance item to find_ins+1 - // - actually, we can just nix the ins_set, since we'll break. meh - // - nope? because if we don't break and just finish the list(s(?)), we'll want to Insert/Remove the unprocessed intermediaries - ins_set.clear(); - ++item; - // prev_item stays where it is - // then break - break; - } - for (node_iter i = del_set.begin(); i != del_set.end(); ++i) { - g_log.debug() << " del set: " << *i; - } - g_log.debug() << "Looking for ins item " << &*ins_item << ": " << *ins_item; - node_iter find_del = del_set.find(*ins_item); - if (find_del != del_set.end()) { - do { - g_log.debug() << "do2"; - RemoveOutput(*prev_item, out_batch, worst_station); - ++prev_item; - } while (*find_del != *prev_item); - del_set.clear(); - ++prev_item; - break; - } - ins_set.insert(*ins_item); - del_set.insert(*del_item); - ++ins_item; - ++del_item; - g_log.debug() << "woop"; - } - // grab any remaining items in the ins_set / del_set (no-break case) - for (; item != ins_item; ++item) { - g_log.debug() << "ins wow"; - InsertOutput(*item, out_batch, behind_node, worst_station); - behind_node = GetOEnd(*item); - } - for (; prev_item != del_item; ++prev_item) { - g_log.debug() << "del wow"; - RemoveOutput(*prev_item, out_batch, worst_station); - } - g_log.debug() << "outwhile"; - if (item != output.end()) { - g_log.debug() << " have item"; - } else { - g_log.debug() << " do not have item"; - } - if (prev_item != prev_output.end()) { - g_log.debug() << " have prev_item"; - } else { - g_log.debug() << " do not have prev_item"; - } + nodes.erase(find_del); } } - g_log.info() << " " << node << " ok..."; - for (; item != output.end(); ++item) { - InsertOutput(*item, out_batch, behind_node, worst_station); + for (OutputList::iterator item = output.begin(); + item != output.end(); ++item) { + node_mod_iter find_ins = nodes.find(*item); + if (nodes.end() == find_ins) { + g_log.debug() << "Updating item " << *item << " behind node " << behind_node; + UpdateOutput(*item, out_batch, behind_node, worst_station); + } else { + nodes.erase(find_ins); + g_log.debug() << "Inserting item " << *item << " behind node " << behind_node; + InsertOutput(*item, out_batch, behind_node, worst_station); + } behind_node = GetOEnd(*item); } - for (; prev_item != prev_output.end(); ++prev_item) { - RemoveOutput(*prev_item, out_batch, worst_station); - } if (output.empty()) { m_outputPerNode.erase(&node); diff --git a/statik/test/Star.cpp b/statik/test/Star.cpp index a14ec25..2726c99 100644 --- a/statik/test/Star.cpp +++ b/statik/test/Star.cpp @@ -107,10 +107,11 @@ void Star::run() { { Batch expected_batch; List xca("a", ""); + expected_batch.Delete(ca); expected_batch.Insert(xca, NULL); - expected_batch.Delete(ca); // why does delete come after insert? if (test(out_batch, expected_batch, "output")) { - xca_pos = out_batch.begin()->node; + xca_pos = (out_batch.begin()+1)->node; + g_log.debug() << " xca_pos: " << xca_pos; } } out_batch.Clear(); @@ -131,12 +132,7 @@ void Star::run() { test(root.GetState().GetStation(), statik::State::ST_DONE, "a"); ip.ExtractChanges(out_batch); { - // Both items are deleted, then the remaining one is added back. - // That seems ok. Batch expected_batch; - List xca("a", ""); - expected_batch.Insert(xca, NULL); - expected_batch.Delete(ca3); expected_batch.Delete(ca2); test(out_batch, expected_batch, "output"); }