Skip to content
Permalink
Browse files

Some hacky fixes: Seq/Star eject any clear/pending children before pr…

…ocessing any child update (slow!), and removes some unsafe log statements while processing deleted output items.
  • Loading branch information
nfomon committed Oct 11, 2015
1 parent 1ec806b commit 4167a036d3152f1eaea9f4f9c13a90bb459e744b
Showing with 55 additions and 11 deletions.
  1. +5 −5 statik/IncParser.cpp
  2. +2 −2 statik/Or.cpp
  3. +2 −0 statik/OutputFunc.cpp
  4. +14 −0 statik/Seq.cpp
  5. +32 −4 statik/Star.cpp
@@ -401,7 +401,7 @@ void IncParser::ComputeOutput_Update(const STree& node, Batch& out_batch, const
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;
//g_log.debug() << "Removing prev_item " << *prev_item; // UNSAFE
RemoveOutput(*prev_item, out_batch, worst_station);
} else {
nodes.erase(find_del);
@@ -468,7 +468,7 @@ void IncParser::ComputeOutput_Insert(const STree& node, Batch& out_batch, const
}

void IncParser::ComputeOutput_Delete(const STree& node, Batch& out_batch, State::Station worst_station) {
g_log.debug() << "IncParser " << m_name << ": Computing output DELETE for node " << node;
//g_log.debug() << "IncParser " << m_name << ": Computing output DELETE for node " << node; // UNSAFE
worst_station = std::min(node.GetState().GetStation(), worst_station);

output_mod_iter prev_output_i = m_outputPerNode.find(&node);
@@ -484,7 +484,7 @@ void IncParser::ComputeOutput_Delete(const STree& node, Batch& out_batch, State:
RemoveOutput(*prev_item, out_batch, worst_station);
}
m_outputPerNode.erase(&node);
g_log.debug() << "Done computing DELETE output for node " << node << ". Batch so far: " << out_batch;
//g_log.debug() << "Done computing DELETE output for node " << node << ". Batch so far: " << out_batch; // UNSAFE
}

void IncParser::Cleanup() {
@@ -521,10 +521,10 @@ void IncParser::InsertOutput(const OutputItem& item, Batch& out_batch, const Lis

void IncParser::RemoveOutput(const OutputItem& item, Batch& out_batch, State::Station worst_station) {
if (item.onode) {
g_log.debug() << "RemoveOutput for item onode " << *item.onode;
//g_log.debug() << "RemoveOutput for item onode " << *item.onode; // UNSAFE
out_batch.Delete(*item.onode);
} else {
g_log.debug() << "RemoveOutput for item child " << *item.child;
//g_log.debug() << "RemoveOutput for item child " << *item.child; // UNSAFE
ComputeOutput_Delete(*item.child, out_batch, worst_station);
}
}
@@ -72,9 +72,9 @@ void ParseFunc_Or::operator() (ParseAction::Action action, const List& inode, co
STree::child_mod_iter i = m_node->children.begin();
bool haveSetEnd = false;
for (; i != m_node->children.end(); ++i) {
if ((*i)->IsClear()) {
if ((*i)->IsClear() || (*i)->GetState().IsPending()) {
// Clear ourselves!
g_log.info() << "Or: " << *m_node << " child " << **i << " is clear - giving up on entire Or!";
g_log.info() << "Or: " << *m_node << " child " << **i << " is clear or pending - giving up on entire Or!";
m_node->ClearNode(inode);
return;
}
@@ -262,6 +262,8 @@ void OutputFunc_Cap::operator() () {
g_log.debug() << "OutputFunc_Cap() " << *m_node;
(*m_outputFunc)();
m_output = m_outputFunc->GetOutput();
m_output.push_front(m_capStart);
m_output.push_back(m_capEnd);
}

auto_ptr<OutputFunc> OutputFunc_Cap::Clone() {
@@ -51,6 +51,20 @@ void ParseFunc_Seq::operator() (ParseAction::Action action, const List& inode, c
throw SError("Seq failed to process non-ChildUpdate-action properly");
}

// FIXME SLOPPY: erase any clear/pending children. LoL :D
vector<STree::child_mod_iter> children_to_erase;
STree::child_mod_iter clear_child = m_node->children.begin();
for (; clear_child != m_node->children.end(); ++clear_child) {
if ((*clear_child)->IsClear() || (*clear_child)->GetState().IsPending()) {
children_to_erase.push_back(clear_child);
}
}
vector<STree::child_mod_iter>::reverse_iterator i = children_to_erase.rbegin();
for (; i != children_to_erase.rend(); ++i) {
g_log.debug() << "Seq " << *m_node << ": Erasing clear/pending child " << **i;
m_node->children.erase(*i);
}

// Find the initiator child
bool foundInitiator = false;
STree::child_mod_iter child = m_node->children.begin();
@@ -85,6 +85,20 @@ void ParseFunc_Star::operator() (ParseAction::Action action, const List& inode,
throw SError("Star failed to process non-ChildUpdate-action properly");
}

// FIXME SLOPPY: erase any clear/pending children. LoL :D
vector<STree::child_mod_iter> children_to_erase;
STree::child_mod_iter clear_child = m_node->children.begin();
for (; clear_child != m_node->children.end(); ++clear_child) {
if ((*clear_child)->IsClear() || (*clear_child)->GetState().IsPending()) {
children_to_erase.push_back(clear_child);
}
}
vector<STree::child_mod_iter>::reverse_iterator i = children_to_erase.rbegin();
for (; i != children_to_erase.rend(); ++i) {
g_log.debug() << "Star " << *m_node << ": Erasing clear/pending child " << **i;
m_node->children.erase(*i);
}

// Find the initiator child
bool foundInitiator = false;
STree::child_mod_iter child = m_node->children.begin();
@@ -126,11 +140,15 @@ void ParseFunc_Star::operator() (ParseAction::Action action, const List& inode,
return;
}
} else if (prev_child->GetState().IsPending()) {
throw SError("Cannot investigate Pending prev child");
throw SError("Star cannot investigate Pending prev child");
} else if (prev_child->IsClear() || prev_child->GetState().IsPending()) {
throw SError("Would look at clear prev_child");
throw SError("Star would look at clear prev_child");
} else if ((*next)->IsClear() || (*next)->GetState().IsPending()) {
throw SError("Would look at clear next");
throw SError("Star would look at clear next child");
//g_log.info() << "Next child is cleared; enqueueing an update on self to deal with it, followed by a repeat of this update. eeks";
//m_node->GetIncParser().Enqueue(ParseAction(ParseAction::ChildUpdate, *m_node, inode, *next));
//m_node->GetIncParser().Enqueue(ParseAction(ParseAction::ChildUpdate, *m_node, inode, *child));
//return;
} else {
// TODO this chunk might be aggressive; we're using prev_child's IEnd even if it's somehow Bad.
g_log.info() << "Dealing with cleared middle child";
@@ -301,7 +319,17 @@ void ParseFunc_Star::operator() (ParseAction::Action action, const List& inode,
const State& istate = breachChild->GetState();
g_log.debug() << "Investigating breach child " << *breachChild;
if (istate.IsPending()) {
throw SError("Star's breach child is Pending");
g_log.info() << "Star's breach child is Pending; clearing it and recomputing self";
for (STree::child_mod_iter i = m_node->children.begin(); i != m_node->children.end(); ++i) {
if (breachChild == *i) {
m_node->children.erase(i);
g_log.debug() << " - erasing the cleared child!";
state.GoPending();
m_node->GetIncParser().Enqueue(ParseAction(ParseAction::ChildUpdate, *m_node, inode, m_node));
return;
}
}
throw SError("Failed to erase the pending child");
} else if (istate.IsBad()) {
// last child breached, prev children all complete => complete
// otherwise, we're bad

0 comments on commit 4167a03

Please sign in to comment.
You can’t perform that action at this time.