// Streamed execution. void Stage::execute(StreamPointTable& table) { typedef std::list<Stage *> StageList; std::list<StageList> lists; StageList stages; table.finalize(); // Walk from the current stage backwards. As we add each input, copy // the list of stages and push it on a list. We then pull a list from the // front of list and keep going. Placing on the back and pulling from the // front insures that the stages will be executed in the order that they // were added. If we hit stage with no previous stages, we execute // the stage list. // All this often amounts to a bunch of list copying for // no reason, but it's more simple than what we might otherwise do and // this should be a nit in the grand scheme of execution time. // // As an example, if there are four paths from the end stage (writer) to // reader stages, there will be four stage lists and execute(table, stages) // will be called four times. Stage *s = this; stages.push_front(s); while (true) { if (s->m_inputs.empty()) execute(table, stages); else { for (auto s2 : s->m_inputs) { StageList newStages(stages); newStages.push_front(s2); lists.push_front(newStages); } } if (lists.empty()) break; stages = lists.back(); lists.pop_back(); s = stages.front(); } }
// Streamed execution. void Stage::execute(StreamPointTable& table) { typedef std::list<Stage *> StageList; SpatialReference srs; std::list<StageList> lists; StageList stages; StageList readies; table.finalize(); // Walk from the current stage backwards. As we add each input, copy // the list of stages and push it on a list. We then pull a list from the // back of list and keep going. Pushing on the front and pulling from the // back insures that the stages will be executed in the order that they // were added. If we hit stage with no previous stages, we execute // the stage list. // All this often amounts to a bunch of list copying for // no reason, but it's more simple than what we might otherwise do and // this should be a nit in the grand scheme of execution time. // // As an example, if there are four paths from the end stage (writer) to // reader stages, there will be four stage lists and execute(table, stages) // will be called four times. Stage *s = this; stages.push_front(s); while (true) { if (s->m_inputs.empty()) { // Ready stages before we execute. for (auto s2 : stages) if (!Utils::contains(readies, s2)) { s2->pushLogLeader(); s2->ready(table); s2->pushLogLeader(); readies.push_back(s2); srs = s2->getSpatialReference(); if (!srs.empty()) table.setSpatialReference(srs); } execute(table, stages); } else { for (auto s2 : s->m_inputs) { StageList newStages(stages); newStages.push_front(s2); lists.push_front(newStages); } } if (lists.empty()) break; stages = lists.back(); lists.pop_back(); s = stages.front(); } for (auto s2 : stages) { s2->pushLogLeader(); s2->l_done(table); s2->popLogLeader(); } }