예제 #1
0
파일: Stage.cpp 프로젝트: cugwhp/PDAL
// 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();
    }
}
예제 #2
0
파일: Stage.cpp 프로젝트: cugwhp/PDAL
void Stage::execute(StreamPointTable& table, std::list<Stage *>& stages)
{
    std::vector<bool> skips(table.capacity());
    std::list<Stage *> filters;
    SpatialReference srs;

    // Separate out the first stage.
    Stage *reader = stages.front();

    // Build a list of all stages except the first.  We may have a writer in
    // this list in addition to filters, but we treat them in the same way.
    auto begin = stages.begin();
    begin++;
    std::copy(begin, stages.end(), std::back_inserter(filters));

    for (Stage *s : stages)
    {
        s->ready(table);
        srs = s->getSpatialReference();
        if (!srs.empty())
            table.setSpatialReference(srs);
    }

    // Loop until we're finished.  We handle the number of points up to
    // the capacity of the StreamPointTable that we've been provided.

    bool finished = false;
    while (!finished)
    {
        // Clear the spatial reference when processing starts.
        table.clearSpatialReferences();
        PointId idx = 0;
        PointRef point(table, idx);
        point_count_t pointLimit = table.capacity();

        // When we get false back from a reader, we're done, so set
        // the point limit to the number of points processed in this loop
        // of the table.
        for (PointId idx = 0; idx < pointLimit; idx++)
        {
            point.setPointId(idx);
            finished = !reader->processOne(point);
            if (finished)
                pointLimit = idx;
        }
        srs = reader->getSpatialReference();
        if (!srs.empty())
            table.setSpatialReference(srs);

        // When we get a false back from a filter, we're filtering out a
        // point, so add it to the list of skips so that it doesn't get
        // processed by subsequent filters.
        for (Stage *s : filters)
        {
            for (PointId idx = 0; idx < pointLimit; idx++)
            {
                if (skips[idx])
                    continue;
                point.setPointId(idx);
                if (!s->processOne(point))
                    skips[idx] = true;
            }
            srs = s->getSpatialReference();
            if (!srs.empty())
                table.setSpatialReference(srs);
        }

        // Yes, vector<bool> is terrible.  Can do something better later.
        for (size_t i = 0; i < skips.size(); ++i)
            skips[i] = false;
        table.reset();
    }

    for (Stage *s : stages)
        s->done(table);
}
예제 #3
0
// 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();
    }
}