Skip to content

Commit

Permalink
Connector has master Root node. Header cleanups.
Browse files Browse the repository at this point in the history
  • Loading branch information
nfomon committed May 25, 2015
1 parent 67d7548 commit 565d298
Show file tree
Hide file tree
Showing 26 changed files with 252 additions and 103 deletions.
1 change: 1 addition & 0 deletions exstatik/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace exstatik {

typedef boost::ptr_vector<statik::Rule> Compiler;
typedef Compiler::const_iterator Compiler_iter;
typedef Compiler::iterator Compiler_mod_iter;
std::auto_ptr<Compiler> MakeCompiler(const std::string& name);

}
Expand Down
2 changes: 1 addition & 1 deletion exstatik/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ int main(int argc, char *argv[]) {
typedef boost::ptr_vector<Connector> connector_vec;
typedef connector_vec::iterator connector_mod_iter;
connector_vec connectors;
for (Compiler_iter i = compiler->begin(); i != compiler->end(); ++i) {
for (Compiler_mod_iter i = compiler->begin(); i != compiler->end(); ++i) {
g_log.info() << "Compiler item: " << i->Print();
connectors.push_back(new Connector(*i, i->Name(), graphdir));
}
Expand Down
2 changes: 1 addition & 1 deletion istatik/ConnectorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ using std::string;

using namespace istatik;

ConnectorWindow::ConnectorWindow(const statik::Rule& rule, const string& graphdir)
ConnectorWindow::ConnectorWindow(statik::Rule& rule, const string& graphdir)
: m_connector(rule, rule.Name(), graphdir) {
g_log.info() << "Initialized ConnectorWindow for " << rule;
}
Expand Down
2 changes: 1 addition & 1 deletion istatik/ConnectorWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace istatik {

class ConnectorWindow : private boost::noncopyable {
public:
ConnectorWindow(const statik::Rule& rule, const std::string& graphdir);
ConnectorWindow(statik::Rule& rule, const std::string& graphdir);
WindowResponse Input(const statik::Hotlist& hotlist);
private:
statik::Connector m_connector;
Expand Down
2 changes: 1 addition & 1 deletion istatik/IStatik.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void IStatik::run() {
typedef ptr_vector<ConnectorWindow> connectorWindow_vec;
typedef connectorWindow_vec::iterator connectorWindow_mod_iter;
ptr_vector<ConnectorWindow> connectorWindows;
for (exstatik::Compiler::const_iterator i = m_compiler->begin();
for (exstatik::Compiler_mod_iter i = m_compiler->begin();
i != m_compiler->end(); ++i) {
g_log.info() << "Adding connector window for " << i->Name();
connectorWindows.push_back(new ConnectorWindow(*i, m_graphdir));
Expand Down
128 changes: 55 additions & 73 deletions statik/Connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "Grapher.h"
#include "Hotlist.h"
#include "IList.h"
#include "Root.h"
#include "Rule.h"
#include "SLog.h"
#include "STree.h"
Expand All @@ -24,29 +25,31 @@ using namespace statik;

/* public */

Connector::Connector(const Rule& rule, const string& name, const string& graphdir)
: m_rule(rule),
m_root(NULL),
Connector::Connector(Rule& grammar, const string& name, const string& graphdir)
: m_rootRule(name, MakeComputeFunc_Root(name), MakeOutputFunc_Pass()),
m_root(*this, m_rootRule, NULL, MakeComputeFunc_Root(name), MakeOutputFunc_Pass()),
m_grammar(grammar),
m_name(name),
m_needsCleanup(false),
m_sancount(0) {
m_rootRule.AddChildRecursive(&m_grammar); // not "recursive", just unowned
if (!graphdir.empty()) {
m_grapher.reset(new Grapher(graphdir, string(name + "_")));
m_grapher->AddMachine(name, m_rule);
m_grapher->AddMachine(name, m_rootRule);
m_grapher->SaveAndClear();
}
}

void Connector::ExtractHotlist(Hotlist& out_hotlist) {
g_log.debug() << "EXTRACT START: " << m_name;
if (m_touchedNodes.find(m_root) != m_touchedNodes.end()) {
if (m_touchedNodes.find(&m_root) != m_touchedNodes.end()) {
ComputeOutput_Update(m_root, out_hotlist);
}
g_log.debug() << "EXTRACT DONE: " << m_name;
m_touchedNodes.clear();
m_needsCleanup = true;
if (!out_hotlist.IsEmpty()) {
DrawGraph(*m_root, /*inode*/ NULL, &out_hotlist);
DrawGraph(m_root, /*inode*/ NULL, &out_hotlist);
}
}

Expand Down Expand Up @@ -109,7 +112,7 @@ void Connector::Enqueue(ConnectorAction action) {

void Connector::ClearNode(STree& x) {
m_listeners.RemoveAllListenings(&x);
if (&x != m_root) {
if (&x != &m_root) {
g_san.debug() << "xx Unlinking node " << x << " - " << &x;
m_nodePool.Unlink(x);
}
Expand Down Expand Up @@ -140,17 +143,14 @@ STree* Connector::OwnNode(auto_ptr<STree> node) {
}

const IList* Connector::GetFirstINode() const {
if (!m_root || m_root->IsClear() || m_root->GetIConnection().IsClear()) {
if (m_root.IsClear() || m_root.GetIConnection().IsClear()) {
return NULL;
}
return &m_root->IStart();
return &m_root.IStart();
}

const IList* Connector::GetFirstONode() const {
if (!m_root) {
return NULL;
}
return m_root->GetOutputFunc().OStart();
return m_root.GetOutputFunc().OStart();
}

void Connector::TouchNode(const STree& node) {
Expand All @@ -161,15 +161,12 @@ void Connector::DrawGraph(const STree& onode, const IList* inode, const Hotlist*
if (!m_grapher.get()) {
return;
}
if (!m_root) {
return;
}
SanityCheck();
const IList* istart = GetFirstINode();
if (istart) {
m_grapher->AddIList(m_name, *istart, m_name + " input");
}
m_grapher->AddSTree(m_name, *m_root, m_name + " output", initiator);
m_grapher->AddSTree(m_name, m_root, m_name + " output", initiator);
const IList* ostart = GetFirstONode();
if (ostart) {
m_grapher->AddOList(m_name, *ostart, m_name + " olist");
Expand All @@ -194,11 +191,7 @@ void Connector::SanityCheck() {
g_log.debug() << "Sanity check " << m_sancount;
g_san.info();
g_san.info() << "Sanity check " << m_sancount;
if (m_root) {
SanityCheck(m_root);
} else {
g_san.info() << "No root";
}
SanityCheck(&m_root);
++m_sancount;
}

Expand Down Expand Up @@ -244,10 +237,7 @@ void Connector::SanityCheck(const STree* s) const {
/* private */

const STree& Connector::GetRoot() const {
if (!m_root) {
throw SError("Connector " + m_name + "; cannot get root node before it has been initialized");
}
return *m_root;
return m_root;
}

void Connector::InsertNode(const IList& inode) {
Expand All @@ -262,13 +252,9 @@ void Connector::InsertNode(const IList& inode) {
m_grapher->SaveAndClear();
}

if (!m_root) {
g_log.debug() << " - No root; initializing the tree root";
m_root = m_rule.MakeRootNode(*this);
}
if (m_root->IsClear()) {
if (m_root.IsClear()) {
g_log.debug() << " - Clear root; restarting the tree root";
Enqueue(ConnectorAction(ConnectorAction::Start, *m_root, inode));
Enqueue(ConnectorAction(ConnectorAction::Start, m_root, inode));
} else {
if (inode.left) {
g_log.debug() << " - Found left inode " << *inode.left << ": updating listeners of " << inode << "'s left and (if present) right";
Expand All @@ -288,15 +274,15 @@ void Connector::InsertNode(const IList& inode) {
}
} else {
g_log.debug() << " - No left inode: prepending behind the root";
Enqueue(ConnectorAction(ConnectorAction::Restart, *m_root, inode));
Enqueue(ConnectorAction(ConnectorAction::Restart, m_root, inode));
}
}

ProcessActions();

// Assert that the inode has at least one listener in the updated set.
if (!m_listeners.HasAnyListeners(&inode)) {
m_root->GetState().GoBad();
m_root.GetState().GoBad();
}
// Stronger check: every inode has at least one listener :)
g_log.debug() << "Connector: Insert done";
Expand All @@ -313,13 +299,9 @@ void Connector::DeleteNode(const IList& inode) {
m_grapher->SaveAndClear();
}

if (!m_root) {
throw SError("Connector " + m_name + ": cannot delete " + string(inode) + " when the root has not been initialized");
}

if (!inode.left && !inode.right) {
g_log.debug() << "Connector: Deleted node has no left or right; clearing root";
m_root->ClearNode(inode);
m_root.ClearNode(inode);
} else {
if (inode.left) {
g_log.debug() << "Connector: Deleted node has inode.left, so enqueuing INodeDelete actions on its listeners";
Expand Down Expand Up @@ -377,12 +359,12 @@ void Connector::ProcessActions() {
}
}

void Connector::ComputeOutput_Update(const STree* node, Hotlist& out_hotlist) {
g_log.debug() << "Connector " << m_name << ": Computing output UPDATE for node " << *node;
void Connector::ComputeOutput_Update(const STree& node, Hotlist& out_hotlist) {
g_log.debug() << "Connector " << m_name << ": Computing output UPDATE for node " << node;

node->GetOutputFunc()();
const OutputState& os = node->GetOutputFunc().GetState();
output_mod_iter posi = m_outputPerNode.find(node);
node.GetOutputFunc()();
const OutputState& os = node.GetOutputFunc().GetState();
output_mod_iter posi = m_outputPerNode.find(&node);

if (m_outputPerNode.end() == posi) {
// We weren't emitting before, but are emitting now. Insert all.
Expand All @@ -391,16 +373,16 @@ void Connector::ComputeOutput_Update(const STree* node, Hotlist& out_hotlist) {
}

OutputState& pos = posi->second;
g_log.debug() << *node << " was emitting " << pos.onodes.size() << " ONodes and " << pos.children.size() << " children";
g_log.debug() << *node << " is now emitting " << os.onodes.size() << " ONodes and " << os.children.size() << " children";
g_log.debug() << node << " was emitting " << pos.onodes.size() << " ONodes and " << pos.children.size() << " children";
g_log.debug() << node << " is now emitting " << os.onodes.size() << " ONodes and " << os.children.size() << " children";
// ONodes
for (OutputState::onode_iter onode = os.onodes.begin(); onode != os.onodes.end(); ++onode) {
OutputState::onode_iter ponode = pos.onodes.find(*onode);
if (pos.onodes.end() == ponode) {
g_log.debug() << *node << " WAS NOT EMITTING node " << **onode << "; inserting now.";
g_log.debug() << node << " WAS NOT EMITTING node " << **onode << "; inserting now.";
out_hotlist.Insert(**onode);
} else {
g_log.debug() << *node << " WAS EMITTING node " << **onode << "; updating, and erasing from pos.";
g_log.debug() << node << " WAS EMITTING node " << **onode << "; updating, and erasing from pos.";
pos.onodes.erase(ponode);
if (os.value != pos.value) {
out_hotlist.Update(**onode);
Expand All @@ -416,60 +398,60 @@ void Connector::ComputeOutput_Update(const STree* node, Hotlist& out_hotlist) {
for (OutputState::child_iter child = os.children.begin(); child != os.children.end(); ++child) {
OutputState::child_iter pchild = pos.children.find(*child);
if (pos.children.end() == pchild) {
g_log.debug() << *node << " WAS NOT EMITTING child " << **child << "; inserting now.";
ComputeOutput_Insert(*child, out_hotlist);
g_log.debug() << node << " WAS NOT EMITTING child " << **child << "; inserting now.";
ComputeOutput_Insert(**child, out_hotlist);
} else {
g_log.debug() << *node << " WAS EMITTING child " << **child << "; updating child.";
g_log.debug() << node << " WAS EMITTING child " << **child << "; updating child.";
pos.children.erase(pchild);
if (m_touchedNodes.find(*child) != m_touchedNodes.end()) {
ComputeOutput_Update(*child, out_hotlist);
ComputeOutput_Update(**child, out_hotlist);
}
}
}

for (OutputState::child_iter pchild = pos.children.begin(); pchild != pos.children.end(); ++pchild) {
g_log.debug() << "Update causes deletion of pchild " << **pchild;
ComputeOutput_Delete(*pchild, out_hotlist);
ComputeOutput_Delete(**pchild, out_hotlist);
}

if (os.onodes.empty() && os.children.empty()) {
m_outputPerNode.erase(node);
m_outputPerNode.erase(&node);
} else {
m_outputPerNode[node] = os; // copy
m_outputPerNode[&node] = os; // copy
}
g_log.debug() << "Done computing UPDATE output for node " << *node << ". Hotlist so far: " << out_hotlist.Print();
g_log.debug() << "Done computing UPDATE output for node " << node << ". Hotlist so far: " << out_hotlist.Print();
g_log.debug() << " - have " << os.onodes.size() << " ONodes and " << os.children.size() << " children";
node->GetOutputFunc().ConnectONodes();
node.GetOutputFunc().ConnectONodes();
}

void Connector::ComputeOutput_Insert(const STree* node, Hotlist& out_hotlist) {
g_log.debug() << "Connector " << m_name << ": Computing output INSERT for node " << *node;
void Connector::ComputeOutput_Insert(const STree& node, Hotlist& out_hotlist) {
g_log.debug() << "Connector " << m_name << ": Computing output INSERT for node " << node;

node->GetOutputFunc()();
const OutputState& os = node->GetOutputFunc().GetState();
node.GetOutputFunc()();
const OutputState& os = node.GetOutputFunc().GetState();

// Just insert everything, disregard what the prev output says
for (OutputState::onode_iter onode = os.onodes.begin(); onode != os.onodes.end(); ++onode) {
out_hotlist.Insert(**onode);
}
for (OutputState::child_iter child = os.children.begin(); child != os.children.end(); ++child) {
ComputeOutput_Insert(*child, out_hotlist);
ComputeOutput_Insert(**child, out_hotlist);
}

if (os.onodes.empty() && os.children.empty()) {
m_outputPerNode.erase(node);
m_outputPerNode.erase(&node);
} else {
m_outputPerNode[node] = os; // copy
m_outputPerNode[&node] = os; // copy
}
g_log.debug() << "Done computing INSERT output for node " << *node << ". Hotlist so far: " << out_hotlist.Print();
g_log.debug() << m_name << " node " << *node << " is now emitting " << os.onodes.size() << " ONodes and " << os.children.size() << " children.";
node->GetOutputFunc().ConnectONodes();
g_log.debug() << "Done computing INSERT output for node " << node << ". Hotlist so far: " << out_hotlist.Print();
g_log.debug() << m_name << " node " << node << " is now emitting " << os.onodes.size() << " ONodes and " << os.children.size() << " children.";
node.GetOutputFunc().ConnectONodes();
}

void Connector::ComputeOutput_Delete(const STree* node, Hotlist& out_hotlist) {
g_log.debug() << "Connector " << m_name << ": Computing output DELETE for node " << *node;
void Connector::ComputeOutput_Delete(const STree& node, Hotlist& out_hotlist) {
g_log.debug() << "Connector " << m_name << ": Computing output DELETE for node " << node;

output_mod_iter posi = m_outputPerNode.find(node);
output_mod_iter posi = m_outputPerNode.find(&node);
if (m_outputPerNode.end() == posi) {
return;
}
Expand All @@ -480,10 +462,10 @@ void Connector::ComputeOutput_Delete(const STree* node, Hotlist& out_hotlist) {
out_hotlist.Delete(**ponode);
}
for (OutputState::child_iter child = pos.children.begin(); child != pos.children.end(); ++child) {
ComputeOutput_Delete(*child, out_hotlist);
ComputeOutput_Delete(**child, out_hotlist);
}
m_outputPerNode.erase(node);
g_log.debug() << "Done computing DELETE output for node " << *node << ". Hotlist so far: " << out_hotlist.Print();
m_outputPerNode.erase(&node);
g_log.debug() << "Done computing DELETE output for node " << node << ". Hotlist so far: " << out_hotlist.Print();
}

void Connector::CleanupIfNeeded() {
Expand Down
20 changes: 10 additions & 10 deletions statik/Connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ObjectPool.h"
#include "OrderList.h"
#include "OutputFunc.h"
#include "Rule.h"
#include "STree.h"

#include <deque>
Expand All @@ -20,16 +21,16 @@
namespace statik {

class Grapher;
class Rule;

class Connector {
public:
typedef typename ListenerTable<const IList*, STree*>::listener_set listener_set;
typedef typename ListenerTable<const IList*, STree*>::listener_iter listener_iter;

Connector(const Rule& rule, const std::string& name = "", const std::string& graphdir = "");
Connector(Rule& rule, const std::string& name = "", const std::string& graphdir = "");

const STree& GetRoot() const;
const STree& GetRoot() const; // for tests
const State& GetState() const;

void ExtractHotlist(Hotlist& out_hotlist);
listener_set GetListeners(const IList& x) const;
Expand Down Expand Up @@ -97,15 +98,14 @@ class Connector {
void UpdateNode(const IList& inode);

void ProcessActions();
void ComputeOutput_Update(const STree* node, Hotlist& out_hotlist);
void ComputeOutput_Insert(const STree* node, Hotlist& out_hotlist);
void ComputeOutput_Delete(const STree* node, Hotlist& out_hotlist);
void ComputeOutput_Update(const STree& node, Hotlist& out_hotlist);
void ComputeOutput_Insert(const STree& node, Hotlist& out_hotlist);
void ComputeOutput_Delete(const STree& node, Hotlist& out_hotlist);
void CleanupIfNeeded();

// Root of the Rule tree
const Rule& m_rule;
// Root of the output tree
STree* m_root;
Rule m_rootRule; // Rule for the Root node
STree m_root; // Root of the output tree
Rule& m_grammar; // Root of the Grammar
std::string m_name;
bool m_needsCleanup;
std::auto_ptr<Grapher> m_grapher;
Expand Down
Loading

0 comments on commit 565d298

Please sign in to comment.