<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 */

#include <numeric>
#include <thread>

#include <adios2.h>
#include <adios2/common/ADIOSMacros.h>
#include <adios2/helper/adiosFunctions.h>
#include <gtest/gtest.h>

using namespace adios2;

size_t print_lines = 0;
size_t to_print_lines = 10;

template <class T>
void GenData(std::vector<std::complex<T>> &data, const size_t step)
{
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i] = {static_cast<T>(i + 10000 + step * 100),
                   static_cast<T>(i + 10000)};
    }
}

template <class T>
void GenData(std::vector<T> &data, const size_t step)
{
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i] = i + 10000 + step * 100;
    }
}

template <class T>
void PrintData(const T *data, const size_t size, const size_t step)
{
    std::cout << "Step: " << step << " [";
    size_t printsize = 32;
    if (size < printsize)
    {
        printsize = size;
    }
    for (size_t i = 0; i < printsize; ++i)
    {
        std::cout << data[i] << " ";
    }
    std::cout << "]" << std::endl;
}

template <class T>
void VerifyData(const std::complex<T> *data, const size_t size, size_t step)
{
    std::vector<std::complex<T>> tmpdata(size);
    GenData(tmpdata, step);
    for (size_t i = 0; i < size; ++i)
    {
        ASSERT_EQ(data[i], tmpdata[i]);
    }
}

template <class T>
void VerifyData(const T *data, const size_t size, size_t step)
{
    std::vector<T> tmpdata(size);
    GenData(tmpdata, step);
    for (size_t i = 0; i < size; ++i)
    {
        ASSERT_EQ(data[i], tmpdata[i]);
    }
}

template <class T>
void VerifyData(const std::vector<T> &data, const size_t step)
{
    VerifyData(data.data(), data.size(), step);
}

void DataManWriter(const Dims &shape, const Dims &start, const Dims &count,
                   const size_t steps, const adios2::Params &engineParams)
{
    size_t datasize = std::accumulate(count.begin(), count.end(), 1,
                                      std::multiplies<size_t>());
    adios2::ADIOS adios;
    adios2::IO dataManIO = adios.DeclareIO("WAN");
    dataManIO.SetEngine("DataMan");
    dataManIO.SetParameters(engineParams);
    std::vector<char> myChars(datasize);
    std::vector<unsigned char> myUChars(datasize);
    std::vector<short> myShorts(datasize);
    std::vector<unsigned short> myUShorts(datasize);
    std::vector<int> myInts(datasize);
    std::vector<unsigned int> myUInts(datasize);
    std::vector<float> myFloats(datasize);
    std::vector<double> myDoubles(datasize);
    std::vector<std::complex<float>> myComplexes(datasize);
    std::vector<std::complex<double>> myDComplexes(datasize);
    auto bpChars =
        dataManIO.DefineVariable<char>("bpChars", shape, start, count);
    auto bpUChars = dataManIO.DefineVariable<unsigned char>("bpUChars", shape,
                                                            start, count);
    auto bpShorts =
        dataManIO.DefineVariable<short>("bpShorts", shape, start, count);
    auto bpUShorts = dataManIO.DefineVariable<unsigned short>(
        "bpUShorts", shape, start, count);
    auto bpInts = dataManIO.DefineVariable<int>("bpInts", shape, start, count);
    auto bpUInts =
        dataManIO.DefineVariable<unsigned int>("bpUInts", shape, start, count);
    auto bpFloats =
        dataManIO.DefineVariable<float>("bpFloats", shape, start, count);
    auto bpDoubles =
        dataManIO.DefineVariable<double>("bpDoubles", shape, start, count);
    auto bpComplexes = dataManIO.DefineVariable<std::complex<float>>(
        "bpComplexes", shape, start, count);
    auto bpDComplexes = dataManIO.DefineVariable<std::complex<double>>(
        "bpDComplexes", shape, start, count);
    auto bpUInt64s = dataManIO.DefineVariable<uint64_t>("bpUInt64s");
    dataManIO.DefineAttribute<int>("AttInt", 110);
    adios2::Engine dataManWriter =
        dataManIO.Open("stream", adios2::Mode::Write);
    for (uint64_t i = 0; i < steps; ++i)
    {
        dataManWriter.BeginStep();
        GenData(myChars, i);
        GenData(myUChars, i);
        GenData(myShorts, i);
        GenData(myUShorts, i);
        GenData(myInts, i);
        GenData(myUInts, i);
        GenData(myFloats, i);
        GenData(myDoubles, i);
        GenData(myComplexes, i);
        GenData(myDComplexes, i);
        dataManWriter.Put(bpChars, myChars.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUChars, myUChars.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpShorts, myShorts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUShorts, myUShorts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpInts, myInts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUInts, myUInts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpFloats, myFloats.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpDoubles, myDoubles.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpComplexes, myComplexes.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpDComplexes, myDComplexes.data(),
                          adios2::Mode::Sync);
        dataManWriter.Put(bpUInt64s, i);
        dataManWriter.EndStep();
    }
    dataManWriter.Close();
}

void DataManReader(const Dims &shape, const Dims &start, const Dims &count,
                   const size_t steps, const adios2::Params &engineParams)
{
    size_t datasize = std::accumulate(count.begin(), count.end(), 1,
                                      std::multiplies<size_t>());
    adios2::ADIOS adios;
    adios2::IO dataManIO = adios.DeclareIO("WAN");
    dataManIO.SetEngine("DataMan");
    dataManIO.SetParameters(engineParams);
    adios2::Engine dataManReader = dataManIO.Open("stream", adios2::Mode::Read);

    std::vector<char> myChars(datasize);
    std::vector<unsigned char> myUChars(datasize);
    std::vector<short> myShorts(datasize);
    std::vector<unsigned short> myUShorts(datasize);
    std::vector<int> myInts(datasize);
    std::vector<unsigned int> myUInts(datasize);
    std::vector<float> myFloats(datasize);
    std::vector<double> myDoubles(datasize);
    std::vector<std::complex<float>> myComplexes(datasize);
    std::vector<std::complex<double>> myDComplexes(datasize);
    bool received_steps = false;
    size_t currentStep;
    while (true)
    {
        adios2::StepStatus status = dataManReader.BeginStep(StepMode::Read, 5);
        if (status == adios2::StepStatus::OK)
        {
            received_steps = true;
            const auto &vars = dataManIO.AvailableVariables();
            ASSERT_EQ(vars.size(), 11);
            currentStep = dataManReader.CurrentStep();
            adios2::Variable<char> bpChars =
                dataManIO.InquireVariable<char>("bpChars");
            adios2::Variable<unsigned char> bpUChars =
                dataManIO.InquireVariable<unsigned char>("bpUChars");
            adios2::Variable<short> bpShorts =
                dataManIO.InquireVariable<short>("bpShorts");
            adios2::Variable<unsigned short> bpUShorts =
                dataManIO.InquireVariable<unsigned short>("bpUShorts");
            adios2::Variable<int> bpInts =
                dataManIO.InquireVariable<int>("bpInts");
            adios2::Variable<unsigned int> bpUInts =
                dataManIO.InquireVariable<unsigned int>("bpUInts");
            adios2::Variable<float> bpFloats =
                dataManIO.InquireVariable<float>("bpFloats");
            adios2::Variable<double> bpDoubles =
                dataManIO.InquireVariable<double>("bpDoubles");
            adios2::Variable<std::complex<float>> bpComplexes =
                dataManIO.InquireVariable<std::complex<float>>("bpComplexes");
            adios2::Variable<std::complex<double>> bpDComplexes =
                dataManIO.InquireVariable<std::complex<double>>("bpDComplexes");
            adios2::Variable<uint64_t> bpUInt64s =
                dataManIO.InquireVariable<uint64_t>("bpUInt64s");
            auto charsBlocksInfo = dataManReader.AllStepsBlocksInfo(bpChars);
            bpChars.SetSelection({start, count});
            bpUChars.SetSelection({start, count});
            bpShorts.SetSelection({start, count});
            bpUShorts.SetSelection({start, count});
            bpInts.SetSelection({start, count});
            bpUInts.SetSelection({start, count});
            bpFloats.SetSelection({start, count});
            bpDoubles.SetSelection({start, count});
            bpComplexes.SetSelection({start, count});
            bpDComplexes.SetSelection({start, count});
            dataManReader.Get(bpChars, myChars.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUChars, myUChars.data(), adios2::Mode::Sync);
            dataManReader.Get(bpShorts, myShorts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUShorts, myUShorts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpInts, myInts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUInts, myUInts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpFloats, myFloats.data(), adios2::Mode::Sync);
            dataManReader.Get(bpDoubles, myDoubles.data(), adios2::Mode::Sync);
            dataManReader.Get(bpComplexes, myComplexes.data(),
                              adios2::Mode::Sync);
            dataManReader.Get(bpDComplexes, myDComplexes.data(),
                              adios2::Mode::Sync);
            uint64_t stepValue;
            dataManReader.Get(bpUInt64s, &stepValue, adios2::Mode::Sync);
            ASSERT_EQ(currentStep, stepValue);
            VerifyData(myChars, currentStep);
            VerifyData(myUChars, currentStep);
            VerifyData(myShorts, currentStep);
            VerifyData(myUShorts, currentStep);
            VerifyData(myInts, currentStep);
            VerifyData(myUInts, currentStep);
            VerifyData(myFloats, currentStep);
            VerifyData(myDoubles, currentStep);
            VerifyData(myComplexes, currentStep);
            VerifyData(myDComplexes, currentStep);
            dataManReader.EndStep();
        }
        else if (status == adios2::StepStatus::EndOfStream)
        {
            break;
        }
        else if (status == adios2::StepStatus::NotReady)
        {
            continue;
        }
    }
    if (received_steps)
    {
        auto attInt = dataManIO.InquireAttribute<int>("AttInt");
        ASSERT_EQ(110, attInt.Data()[0]);
        ASSERT_NE(111, attInt.Data()[0]);
    }
    dataManReader.Close();
}

class DataManEngineTest : public ::testing::Test
{
public:
    DataManEngineTest() = default;
};

#ifdef ADIOS2_HAVE_ZEROMQ
TEST_F(DataManEngineTest, 1DSuperLarge)
{
    // set parameters
    Dims shape = {5000000};
    Dims start = {0};
    Dims count = {5000000};
    size_t steps = 10;

    // run workflow
    adios2::Params readerEngineParams = {{"IPAddress", "127.0.0.1"},
                                         {"Port", "13480"},
                                         {"MaxStepBufferSize", "500000000"},
                                         {"TransportMode", "reliable"}};
    auto r = std::thread(DataManReader, shape, start, count, steps,
                         readerEngineParams);
    adios2::Params writerEngineParams = {{"IPAddress", "127.0.0.1"},
                                         {"Port", "13480"},
                                         {"TransportMode", "reliable"}};
    auto w = std::thread(DataManWriter, shape, start, count, steps,
                         writerEngineParams);
    w.join();
    r.join();
}
#endif // ZEROMQ

int main(int argc, char **argv)
{
    int result;
    ::testing::InitGoogleTest(&argc, argv);
    result = RUN_ALL_TESTS();

    return result;
}
<commit_msg>reduced buffer size<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 */

#include <numeric>
#include <thread>

#include <adios2.h>
#include <adios2/common/ADIOSMacros.h>
#include <adios2/helper/adiosFunctions.h>
#include <gtest/gtest.h>

using namespace adios2;

size_t print_lines = 0;
size_t to_print_lines = 10;

template <class T>
void GenData(std::vector<std::complex<T>> &data, const size_t step)
{
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i] = {static_cast<T>(i + 10000 + step * 100),
                   static_cast<T>(i + 10000)};
    }
}

template <class T>
void GenData(std::vector<T> &data, const size_t step)
{
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i] = i + 10000 + step * 100;
    }
}

template <class T>
void PrintData(const T *data, const size_t size, const size_t step)
{
    std::cout << "Step: " << step << " [";
    size_t printsize = 32;
    if (size < printsize)
    {
        printsize = size;
    }
    for (size_t i = 0; i < printsize; ++i)
    {
        std::cout << data[i] << " ";
    }
    std::cout << "]" << std::endl;
}

template <class T>
void VerifyData(const std::complex<T> *data, const size_t size, size_t step)
{
    std::vector<std::complex<T>> tmpdata(size);
    GenData(tmpdata, step);
    for (size_t i = 0; i < size; ++i)
    {
        ASSERT_EQ(data[i], tmpdata[i]);
    }
}

template <class T>
void VerifyData(const T *data, const size_t size, size_t step)
{
    std::vector<T> tmpdata(size);
    GenData(tmpdata, step);
    for (size_t i = 0; i < size; ++i)
    {
        ASSERT_EQ(data[i], tmpdata[i]);
    }
}

template <class T>
void VerifyData(const std::vector<T> &data, const size_t step)
{
    VerifyData(data.data(), data.size(), step);
}

void DataManWriter(const Dims &shape, const Dims &start, const Dims &count,
                   const size_t steps, const adios2::Params &engineParams)
{
    size_t datasize = std::accumulate(count.begin(), count.end(), 1,
                                      std::multiplies<size_t>());
    adios2::ADIOS adios;
    adios2::IO dataManIO = adios.DeclareIO("WAN");
    dataManIO.SetEngine("DataMan");
    dataManIO.SetParameters(engineParams);
    std::vector<char> myChars(datasize);
    std::vector<unsigned char> myUChars(datasize);
    std::vector<short> myShorts(datasize);
    std::vector<unsigned short> myUShorts(datasize);
    std::vector<int> myInts(datasize);
    std::vector<unsigned int> myUInts(datasize);
    std::vector<float> myFloats(datasize);
    std::vector<double> myDoubles(datasize);
    std::vector<std::complex<float>> myComplexes(datasize);
    std::vector<std::complex<double>> myDComplexes(datasize);
    auto bpChars =
        dataManIO.DefineVariable<char>("bpChars", shape, start, count);
    auto bpUChars = dataManIO.DefineVariable<unsigned char>("bpUChars", shape,
                                                            start, count);
    auto bpShorts =
        dataManIO.DefineVariable<short>("bpShorts", shape, start, count);
    auto bpUShorts = dataManIO.DefineVariable<unsigned short>(
        "bpUShorts", shape, start, count);
    auto bpInts = dataManIO.DefineVariable<int>("bpInts", shape, start, count);
    auto bpUInts =
        dataManIO.DefineVariable<unsigned int>("bpUInts", shape, start, count);
    auto bpFloats =
        dataManIO.DefineVariable<float>("bpFloats", shape, start, count);
    auto bpDoubles =
        dataManIO.DefineVariable<double>("bpDoubles", shape, start, count);
    auto bpComplexes = dataManIO.DefineVariable<std::complex<float>>(
        "bpComplexes", shape, start, count);
    auto bpDComplexes = dataManIO.DefineVariable<std::complex<double>>(
        "bpDComplexes", shape, start, count);
    auto bpUInt64s = dataManIO.DefineVariable<uint64_t>("bpUInt64s");
    dataManIO.DefineAttribute<int>("AttInt", 110);
    adios2::Engine dataManWriter =
        dataManIO.Open("stream", adios2::Mode::Write);
    for (uint64_t i = 0; i < steps; ++i)
    {
        dataManWriter.BeginStep();
        GenData(myChars, i);
        GenData(myUChars, i);
        GenData(myShorts, i);
        GenData(myUShorts, i);
        GenData(myInts, i);
        GenData(myUInts, i);
        GenData(myFloats, i);
        GenData(myDoubles, i);
        GenData(myComplexes, i);
        GenData(myDComplexes, i);
        dataManWriter.Put(bpChars, myChars.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUChars, myUChars.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpShorts, myShorts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUShorts, myUShorts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpInts, myInts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUInts, myUInts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpFloats, myFloats.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpDoubles, myDoubles.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpComplexes, myComplexes.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpDComplexes, myDComplexes.data(),
                          adios2::Mode::Sync);
        dataManWriter.Put(bpUInt64s, i);
        dataManWriter.EndStep();
    }
    dataManWriter.Close();
}

void DataManReader(const Dims &shape, const Dims &start, const Dims &count,
                   const size_t steps, const adios2::Params &engineParams)
{
    size_t datasize = std::accumulate(count.begin(), count.end(), 1,
                                      std::multiplies<size_t>());
    adios2::ADIOS adios;
    adios2::IO dataManIO = adios.DeclareIO("WAN");
    dataManIO.SetEngine("DataMan");
    dataManIO.SetParameters(engineParams);
    adios2::Engine dataManReader = dataManIO.Open("stream", adios2::Mode::Read);

    std::vector<char> myChars(datasize);
    std::vector<unsigned char> myUChars(datasize);
    std::vector<short> myShorts(datasize);
    std::vector<unsigned short> myUShorts(datasize);
    std::vector<int> myInts(datasize);
    std::vector<unsigned int> myUInts(datasize);
    std::vector<float> myFloats(datasize);
    std::vector<double> myDoubles(datasize);
    std::vector<std::complex<float>> myComplexes(datasize);
    std::vector<std::complex<double>> myDComplexes(datasize);
    bool received_steps = false;
    size_t currentStep;
    while (true)
    {
        adios2::StepStatus status = dataManReader.BeginStep(StepMode::Read, 5);
        if (status == adios2::StepStatus::OK)
        {
            received_steps = true;
            const auto &vars = dataManIO.AvailableVariables();
            ASSERT_EQ(vars.size(), 11);
            currentStep = dataManReader.CurrentStep();
            adios2::Variable<char> bpChars =
                dataManIO.InquireVariable<char>("bpChars");
            adios2::Variable<unsigned char> bpUChars =
                dataManIO.InquireVariable<unsigned char>("bpUChars");
            adios2::Variable<short> bpShorts =
                dataManIO.InquireVariable<short>("bpShorts");
            adios2::Variable<unsigned short> bpUShorts =
                dataManIO.InquireVariable<unsigned short>("bpUShorts");
            adios2::Variable<int> bpInts =
                dataManIO.InquireVariable<int>("bpInts");
            adios2::Variable<unsigned int> bpUInts =
                dataManIO.InquireVariable<unsigned int>("bpUInts");
            adios2::Variable<float> bpFloats =
                dataManIO.InquireVariable<float>("bpFloats");
            adios2::Variable<double> bpDoubles =
                dataManIO.InquireVariable<double>("bpDoubles");
            adios2::Variable<std::complex<float>> bpComplexes =
                dataManIO.InquireVariable<std::complex<float>>("bpComplexes");
            adios2::Variable<std::complex<double>> bpDComplexes =
                dataManIO.InquireVariable<std::complex<double>>("bpDComplexes");
            adios2::Variable<uint64_t> bpUInt64s =
                dataManIO.InquireVariable<uint64_t>("bpUInt64s");
            auto charsBlocksInfo = dataManReader.AllStepsBlocksInfo(bpChars);
            bpChars.SetSelection({start, count});
            bpUChars.SetSelection({start, count});
            bpShorts.SetSelection({start, count});
            bpUShorts.SetSelection({start, count});
            bpInts.SetSelection({start, count});
            bpUInts.SetSelection({start, count});
            bpFloats.SetSelection({start, count});
            bpDoubles.SetSelection({start, count});
            bpComplexes.SetSelection({start, count});
            bpDComplexes.SetSelection({start, count});
            dataManReader.Get(bpChars, myChars.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUChars, myUChars.data(), adios2::Mode::Sync);
            dataManReader.Get(bpShorts, myShorts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUShorts, myUShorts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpInts, myInts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUInts, myUInts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpFloats, myFloats.data(), adios2::Mode::Sync);
            dataManReader.Get(bpDoubles, myDoubles.data(), adios2::Mode::Sync);
            dataManReader.Get(bpComplexes, myComplexes.data(),
                              adios2::Mode::Sync);
            dataManReader.Get(bpDComplexes, myDComplexes.data(),
                              adios2::Mode::Sync);
            uint64_t stepValue;
            dataManReader.Get(bpUInt64s, &stepValue, adios2::Mode::Sync);
            ASSERT_EQ(currentStep, stepValue);
            VerifyData(myChars, currentStep);
            VerifyData(myUChars, currentStep);
            VerifyData(myShorts, currentStep);
            VerifyData(myUShorts, currentStep);
            VerifyData(myInts, currentStep);
            VerifyData(myUInts, currentStep);
            VerifyData(myFloats, currentStep);
            VerifyData(myDoubles, currentStep);
            VerifyData(myComplexes, currentStep);
            VerifyData(myDComplexes, currentStep);
            dataManReader.EndStep();
        }
        else if (status == adios2::StepStatus::EndOfStream)
        {
            break;
        }
        else if (status == adios2::StepStatus::NotReady)
        {
            continue;
        }
    }
    if (received_steps)
    {
        auto attInt = dataManIO.InquireAttribute<int>("AttInt");
        ASSERT_EQ(110, attInt.Data()[0]);
        ASSERT_NE(111, attInt.Data()[0]);
    }
    dataManReader.Close();
}

class DataManEngineTest : public ::testing::Test
{
public:
    DataManEngineTest() = default;
};

#ifdef ADIOS2_HAVE_ZEROMQ
TEST_F(DataManEngineTest, 1DSuperLarge)
{
    // set parameters
    Dims shape = {2000000};
    Dims start = {0};
    Dims count = {2000000};
    size_t steps = 10;

    // run workflow
    adios2::Params readerEngineParams = {{"IPAddress", "127.0.0.1"},
                                         {"Port", "13480"},
                                         {"MaxStepBufferSize", "200000000"},
                                         {"TransportMode", "reliable"}};
    auto r = std::thread(DataManReader, shape, start, count, steps,
                         readerEngineParams);
    adios2::Params writerEngineParams = {{"IPAddress", "127.0.0.1"},
                                         {"Port", "13480"},
                                         {"TransportMode", "reliable"}};
    auto w = std::thread(DataManWriter, shape, start, count, steps,
                         writerEngineParams);
    w.join();
    r.join();
}
#endif // ZEROMQ

int main(int argc, char **argv)
{
    int result;
    ::testing::InitGoogleTest(&argc, argv);
    result = RUN_ALL_TESTS();

    return result;
}
<|endoftext|>


<commit_before>/*
 * This file is part of the UnTech Editor Suite.
 * Copyright (c) 2016 - 2020, Marcus Rowe <undisbeliever@gmail.com>.
 * Distributed under The MIT License: https://opensource.org/licenses/MIT
 */

#include "scenes-editor-editor.h"
#include "gui/imgui.h"
#include "gui/list-helpers.h"
#include "models/resources/scene-bgmode.hpp"

namespace UnTech::Gui {

const char* bgModeItems[] = {
    "Mode 0",
    "Mode 1",
    "Mode 1 (bg3 priotity)",
    "Mode 2",
    "Mode 3",
    "Mode 4",
};

const char* layerTypeItems[] = {
    "None",
    "Background Image",
    "MetaTile Tileset",
    "Text Console",
};

ScenesEditor::ScenesEditor(ItemIndex itemIndex)
    : AbstractEditor(itemIndex)
{
}

bool ScenesEditor::loadDataFromProject(const Project::ProjectFile& projectFile)
{
    _scenes = projectFile.resourceScenes;

    return true;
}

void ScenesEditor::commitPendingChanges(Project::ProjectFile& projectFile)
{
    projectFile.resourceScenes = _scenes;
}

void ScenesEditor::editorOpened()
{
}

void ScenesEditor::editorClosed()
{
}

void ScenesEditor::settingsWindow()
{
    if (ImGui::Begin("Scene Settings")) {
        ImGui::SetWindowSize(ImVec2(1000, 400), ImGuiCond_FirstUseEver);

        ListButtons(&_settingsSel, &_scenes.settings, 128);

        ImGui::BeginChild("Scroll");

        ImGui::Columns(7);

        ImGui::Separator();
        ImGui::NextColumn();
        ImGui::Text("Name");
        ImGui::NextColumn();
        ImGui::Text("BG Mode");
        ImGui::NextColumn();
        ImGui::Text("Layer 0 Type");
        ImGui::NextColumn();
        ImGui::Text("Layer 1 Type");
        ImGui::NextColumn();
        ImGui::Text("Layer 2 Type");
        ImGui::NextColumn();
        ImGui::Text("Layer 3 Type");
        ImGui::NextColumn();
        ImGui::Separator();

        for (unsigned i = 0; i < _scenes.settings.size(); i++) {
            auto& sceneSettings = _scenes.settings.at(i);

            bool edited = false;

            ImGui::PushID(i);

            ImGui::Selectable(&_settingsSel, i);
            ImGui::NextColumn();

            ImGui::SetNextItemWidth(-1);
            ImGui::InputIdstring("##Name", &sceneSettings.name);
            edited |= ImGui::IsItemDeactivatedAfterEdit();
            ImGui::NextColumn();

            ImGui::SetNextItemWidth(-1);
            edited |= ImGui::EnumCombo("##BgMode", &sceneSettings.bgMode, bgModeItems, IM_ARRAYSIZE(bgModeItems));
            ImGui::NextColumn();

            static const std::array<const char*, 4> layerLabels = { "##LT0", "##LT1", "##LT2", "##LT3" };
            for (unsigned l = 0; l < sceneSettings.layerTypes.size(); l++) {
                ImGui::SetNextItemWidth(-1);
                edited |= ImGui::EnumCombo(layerLabels.at(l), &sceneSettings.layerTypes.at(l),
                                           layerTypeItems, IM_ARRAYSIZE(layerTypeItems));
                ImGui::NextColumn();
            }

            if (edited) {
                ImGui::LogText("Edited Secene Settings");
                this->pendingChanges = true;
            }

            ImGui::PopID();
        }

        ImGui::Columns(1);
        ImGui::Separator();

        ImGui::EndChild();
    }
    ImGui::End();
}

bool ScenesEditor::sceneLayerCombo(const char* label, idstring* value,
                                   const Project::ProjectFile& projectFile, const Resources::SceneSettingsInput& sceneSettings, const unsigned layerId)
{
    using namespace std::string_literals;

    using LayerType = Resources::LayerType;

    const auto layer = sceneSettings.layerTypes.at(layerId);

    switch (layer) {
    case LayerType::None: {
        return false;
    }

    case LayerType::TextConsole: {
        ImGui::TextUnformatted("Text"s);
        return false;
    }

    case LayerType::BackgroundImage: {
        const unsigned bitDepth = Resources::bitDepthForLayer(sceneSettings.bgMode, layerId);

        bool e = ImGui::IdStringCombo(label, value, projectFile.backgroundImages, false,
                                      [&](auto& item) {
                                          return (item.bitDepth == bitDepth) ? &item.name : nullptr;
                                      });
        if (ImGui::IsItemHovered()) {
            ImGui::SetTooltip("Background Image (%d bpp)", bitDepth);
        }
        return e;
    }

    case LayerType::MetaTileTileset: {
        const unsigned bitDepth = Resources::bitDepthForLayer(sceneSettings.bgMode, layerId);

        bool e = ImGui::IdStringCombo(label, value, projectFile.metaTileTilesets, false,
                                      [&](const MetaTiles::MetaTileTilesetInput* mt) {
                                          return (mt->animationFrames.bitDepth == bitDepth) ? &mt->name : nullptr;
                                      });
        if (ImGui::IsItemHovered()) {
            ImGui::SetTooltip("MetaTile Tileset (%d bpp)", bitDepth);
        }
        return e;
    }
    }

    return false;
}

void ScenesEditor::scenesWindow(const Project::ProjectFile& projectFile)
{
    if (ImGui::Begin("Scenes")) {
        ImGui::SetWindowSize(ImVec2(1000, 400), ImGuiCond_FirstUseEver);

        ListButtons(&_settingsSel, &_scenes.settings, 128);

        ImGui::BeginChild("Scroll");

        ImGui::Columns(7);

        ImGui::Separator();
        ImGui::NextColumn();
        ImGui::Text("Name");
        ImGui::NextColumn();
        ImGui::Text("Scene Settings");
        ImGui::NextColumn();
        ImGui::Text("Layer 0");
        ImGui::NextColumn();
        ImGui::Text("Layer 1");
        ImGui::NextColumn();
        ImGui::Text("Layer 2");
        ImGui::NextColumn();
        ImGui::Text("Layer 3");
        ImGui::NextColumn();
        ImGui::Separator();

        for (unsigned i = 0; i < _scenes.scenes.size(); i++) {
            auto& scene = _scenes.scenes.at(i);

            bool edited = false;

            ImGui::PushID(i);

            ImGui::Selectable(&_scenesSel, i);
            ImGui::NextColumn();

            ImGui::SetNextItemWidth(-1);
            ImGui::InputIdstring("##Name", &scene.name);
            edited |= ImGui::IsItemDeactivatedAfterEdit();
            ImGui::NextColumn();

            ImGui::SetNextItemWidth(-1);
            edited |= ImGui::IdStringCombo("##SceneSettings", &scene.sceneSettings, _scenes.settings);
            ImGui::NextColumn();

            const auto sceneSettings = _scenes.settings.find(scene.sceneSettings);

            static const std::array<const char*, 4> layerLabels = { "##LT0", "##LT1", "##LT2", "##LT3" };
            for (unsigned l = 0; l < scene.layers.size(); l++) {
                if (sceneSettings) {
                    ImGui::SetNextItemWidth(-1);
                    edited |= sceneLayerCombo(layerLabels.at(l), &scene.layers.at(l), projectFile, *sceneSettings, l);
                }
                ImGui::NextColumn();
            }

            if (edited) {
                ImGui::LogText("Edited Secene");
                this->pendingChanges = true;
            }

            ImGui::PopID();
        }

        ImGui::Columns(1);
        ImGui::Separator();

        ImGui::EndChild();
    }
    ImGui::End();
}

void ScenesEditor::processGui(const Project::ProjectFile& projectFile)
{
    settingsWindow();
    scenesWindow(projectFile);

    UpdateSelection(&_settingsSel);
    UpdateSelection(&_scenesSel);
}
}
<commit_msg>Fix Scenes list buttons changing the wrong list<commit_after>/*
 * This file is part of the UnTech Editor Suite.
 * Copyright (c) 2016 - 2020, Marcus Rowe <undisbeliever@gmail.com>.
 * Distributed under The MIT License: https://opensource.org/licenses/MIT
 */

#include "scenes-editor-editor.h"
#include "gui/imgui.h"
#include "gui/list-helpers.h"
#include "models/resources/scene-bgmode.hpp"

namespace UnTech::Gui {

const char* bgModeItems[] = {
    "Mode 0",
    "Mode 1",
    "Mode 1 (bg3 priotity)",
    "Mode 2",
    "Mode 3",
    "Mode 4",
};

const char* layerTypeItems[] = {
    "None",
    "Background Image",
    "MetaTile Tileset",
    "Text Console",
};

ScenesEditor::ScenesEditor(ItemIndex itemIndex)
    : AbstractEditor(itemIndex)
{
}

bool ScenesEditor::loadDataFromProject(const Project::ProjectFile& projectFile)
{
    _scenes = projectFile.resourceScenes;

    return true;
}

void ScenesEditor::commitPendingChanges(Project::ProjectFile& projectFile)
{
    projectFile.resourceScenes = _scenes;
}

void ScenesEditor::editorOpened()
{
}

void ScenesEditor::editorClosed()
{
}

void ScenesEditor::settingsWindow()
{
    if (ImGui::Begin("Scene Settings")) {
        ImGui::SetWindowSize(ImVec2(1000, 400), ImGuiCond_FirstUseEver);

        ListButtons(&_settingsSel, &_scenes.settings, 128);

        ImGui::BeginChild("Scroll");

        ImGui::Columns(7);

        ImGui::Separator();
        ImGui::NextColumn();
        ImGui::Text("Name");
        ImGui::NextColumn();
        ImGui::Text("BG Mode");
        ImGui::NextColumn();
        ImGui::Text("Layer 0 Type");
        ImGui::NextColumn();
        ImGui::Text("Layer 1 Type");
        ImGui::NextColumn();
        ImGui::Text("Layer 2 Type");
        ImGui::NextColumn();
        ImGui::Text("Layer 3 Type");
        ImGui::NextColumn();
        ImGui::Separator();

        for (unsigned i = 0; i < _scenes.settings.size(); i++) {
            auto& sceneSettings = _scenes.settings.at(i);

            bool edited = false;

            ImGui::PushID(i);

            ImGui::Selectable(&_settingsSel, i);
            ImGui::NextColumn();

            ImGui::SetNextItemWidth(-1);
            ImGui::InputIdstring("##Name", &sceneSettings.name);
            edited |= ImGui::IsItemDeactivatedAfterEdit();
            ImGui::NextColumn();

            ImGui::SetNextItemWidth(-1);
            edited |= ImGui::EnumCombo("##BgMode", &sceneSettings.bgMode, bgModeItems, IM_ARRAYSIZE(bgModeItems));
            ImGui::NextColumn();

            static const std::array<const char*, 4> layerLabels = { "##LT0", "##LT1", "##LT2", "##LT3" };
            for (unsigned l = 0; l < sceneSettings.layerTypes.size(); l++) {
                ImGui::SetNextItemWidth(-1);
                edited |= ImGui::EnumCombo(layerLabels.at(l), &sceneSettings.layerTypes.at(l),
                                           layerTypeItems, IM_ARRAYSIZE(layerTypeItems));
                ImGui::NextColumn();
            }

            if (edited) {
                ImGui::LogText("Edited Secene Settings");
                this->pendingChanges = true;
            }

            ImGui::PopID();
        }

        ImGui::Columns(1);
        ImGui::Separator();

        ImGui::EndChild();
    }
    ImGui::End();
}

bool ScenesEditor::sceneLayerCombo(const char* label, idstring* value,
                                   const Project::ProjectFile& projectFile, const Resources::SceneSettingsInput& sceneSettings, const unsigned layerId)
{
    using namespace std::string_literals;

    using LayerType = Resources::LayerType;

    const auto layer = sceneSettings.layerTypes.at(layerId);

    switch (layer) {
    case LayerType::None: {
        return false;
    }

    case LayerType::TextConsole: {
        ImGui::TextUnformatted("Text"s);
        return false;
    }

    case LayerType::BackgroundImage: {
        const unsigned bitDepth = Resources::bitDepthForLayer(sceneSettings.bgMode, layerId);

        bool e = ImGui::IdStringCombo(label, value, projectFile.backgroundImages, false,
                                      [&](auto& item) {
                                          return (item.bitDepth == bitDepth) ? &item.name : nullptr;
                                      });
        if (ImGui::IsItemHovered()) {
            ImGui::SetTooltip("Background Image (%d bpp)", bitDepth);
        }
        return e;
    }

    case LayerType::MetaTileTileset: {
        const unsigned bitDepth = Resources::bitDepthForLayer(sceneSettings.bgMode, layerId);

        bool e = ImGui::IdStringCombo(label, value, projectFile.metaTileTilesets, false,
                                      [&](const MetaTiles::MetaTileTilesetInput* mt) {
                                          return (mt->animationFrames.bitDepth == bitDepth) ? &mt->name : nullptr;
                                      });
        if (ImGui::IsItemHovered()) {
            ImGui::SetTooltip("MetaTile Tileset (%d bpp)", bitDepth);
        }
        return e;
    }
    }

    return false;
}

void ScenesEditor::scenesWindow(const Project::ProjectFile& projectFile)
{
    if (ImGui::Begin("Scenes")) {
        ImGui::SetWindowSize(ImVec2(1000, 400), ImGuiCond_FirstUseEver);

        ListButtons(&_scenesSel, &_scenes.scenes, 128);

        ImGui::BeginChild("Scroll");

        ImGui::Columns(7);

        ImGui::Separator();
        ImGui::NextColumn();
        ImGui::Text("Name");
        ImGui::NextColumn();
        ImGui::Text("Scene Settings");
        ImGui::NextColumn();
        ImGui::Text("Layer 0");
        ImGui::NextColumn();
        ImGui::Text("Layer 1");
        ImGui::NextColumn();
        ImGui::Text("Layer 2");
        ImGui::NextColumn();
        ImGui::Text("Layer 3");
        ImGui::NextColumn();
        ImGui::Separator();

        for (unsigned i = 0; i < _scenes.scenes.size(); i++) {
            auto& scene = _scenes.scenes.at(i);

            bool edited = false;

            ImGui::PushID(i);

            ImGui::Selectable(&_scenesSel, i);
            ImGui::NextColumn();

            ImGui::SetNextItemWidth(-1);
            ImGui::InputIdstring("##Name", &scene.name);
            edited |= ImGui::IsItemDeactivatedAfterEdit();
            ImGui::NextColumn();

            ImGui::SetNextItemWidth(-1);
            edited |= ImGui::IdStringCombo("##SceneSettings", &scene.sceneSettings, _scenes.settings);
            ImGui::NextColumn();

            const auto sceneSettings = _scenes.settings.find(scene.sceneSettings);

            static const std::array<const char*, 4> layerLabels = { "##LT0", "##LT1", "##LT2", "##LT3" };
            for (unsigned l = 0; l < scene.layers.size(); l++) {
                if (sceneSettings) {
                    ImGui::SetNextItemWidth(-1);
                    edited |= sceneLayerCombo(layerLabels.at(l), &scene.layers.at(l), projectFile, *sceneSettings, l);
                }
                ImGui::NextColumn();
            }

            if (edited) {
                ImGui::LogText("Edited Secene");
                this->pendingChanges = true;
            }

            ImGui::PopID();
        }

        ImGui::Columns(1);
        ImGui::Separator();

        ImGui::EndChild();
    }
    ImGui::End();
}

void ScenesEditor::processGui(const Project::ProjectFile& projectFile)
{
    settingsWindow();
    scenesWindow(projectFile);

    UpdateSelection(&_settingsSel);
    UpdateSelection(&_scenesSel);
}
}
<|endoftext|>


<commit_before>#include "ROOT/TDataFrame.hxx"
#include "TRandom.h"
#include "TInterpreter.h"

#include "gtest/gtest.h"

using namespace ROOT::Experimental;

namespace TEST_CATEGORY {

int DefineFunction()
{
   return 1;
}

struct DefineStruct {
   int operator()() { return 1; }
};

void FillTree(const char *filename, const char *treeName, int nevents = 0)
{
   TFile f(filename, "RECREATE");
   TTree t(treeName, treeName);
   t.SetAutoFlush(1); // yes, one event per cluster: to make MT more meaningful
   double b1;
   int b2;
   t.Branch("b1", &b1);
   t.Branch("b2", &b2);
   for (int i = 0; i < nevents; ++i) {
      b1 = i;
      b2 = i * i;
      t.Fill();
   }
   t.Write();
   f.Close();
}
}

TEST(TEST_CATEGORY, CreateEmpty)
{
   TDataFrame tdf(10);
   auto c = tdf.Count();
   EXPECT_EQ(10U, *c);
}

TEST(TEST_CATEGORY, CreateZeroEntries)
{
   TDataFrame tdf(0);
   auto c = tdf.Count();
   EXPECT_EQ(0U, *c);
}

TEST(TEST_CATEGORY, CreateZeroEntriesWithBranches)
{
   auto filename = "dataframe_simple_0.root";
   auto treename = "t";
#ifndef testTDF_simple_0_CREATED
#define testTDF_simple_0_CREATED
   TEST_CATEGORY::FillTree(filename, treename);
#endif
   TDataFrame tdf(treename, filename);
   auto c = tdf.Count();
   auto m = tdf.Mean("b1");
   EXPECT_EQ(0U, *c);
   EXPECT_EQ(0., *m);
}

TEST(TEST_CATEGORY, BuildWithTDirectory)
{
   auto filename = "dataframe_simple_1.root";
   auto treename = "t";
#ifndef testTDF_simple_1_CREATED
#define testTDF_simple_1_CREATED
   TEST_CATEGORY::FillTree(filename, treename, 50);
#endif
   TFile f(filename);
   TDataFrame tdf(treename, &f);
   auto c = tdf.Count();
   EXPECT_EQ(50U, *c);
}

// Jitting of column types
TEST(TEST_CATEGORY, TypeGuessing)
{
   auto filename = "dataframe_simple_2.root";
   auto treename = "t";
#ifndef testTDF_simple_2_CREATED
#define testTDF_simple_2_CREATED
   TEST_CATEGORY::FillTree(filename, treename, 50);
#endif
   TDataFrame tdf(treename, filename, {"b1"});
   auto hcompiled = tdf.Histo1D<double>();
   auto hjitted = tdf.Histo1D();
   EXPECT_EQ(50, hcompiled->GetEntries());
   EXPECT_EQ(50, hjitted->GetEntries());
   EXPECT_DOUBLE_EQ(hcompiled->GetMean(), hjitted->GetMean());
}

// Define

TEST(TEST_CATEGORY, Define_lambda)
{
   TDataFrame tdf(10);
   auto d = tdf.Define("i", []() { return 1; });
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST(TEST_CATEGORY, Define_function)
{
   TDataFrame tdf(10);
   auto d = tdf.Define("i", TEST_CATEGORY::DefineFunction);
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST(TEST_CATEGORY, Define_functor)
{
   TDataFrame tdf(10);
   TEST_CATEGORY::DefineStruct def;
   auto d = tdf.Define("i", def);
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST(TEST_CATEGORY, Define_jitted)
{
   TDataFrame tdf(10);
   auto d = tdf.Define("i", "1");
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST(TEST_CATEGORY, Define_jitted_complex)
{
// The test can be run in sequential and MT mode.
#ifndef RNDM_GEN_CREATED
#define RNDM_GEN_CREATED
   gInterpreter->ProcessLine("TRandom r;");
#endif
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("i", "r.Uniform(0.,8.)");
   auto m = d.Max("i");
   EXPECT_EQ(7.867497533559811628, *m);
}

// Define + Filters
TEST(TEST_CATEGORY, Define_Filter)
{
   TRandom r(1);
   TDataFrame tdf(50);
   auto d = tdf.Define("r", [&r]() { return r.Uniform(0., 8.); });
   auto df = d.Filter([](double x) { return x > 5; }, {"r"});
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_Filter_jitted)
{
   TRandom r(1);
   TDataFrame tdf(50);
   auto d = tdf.Define("r", [&r]() { return r.Uniform(0., 8.); });
   auto df = d.Filter("r>5");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_Filter_named)
{
   TRandom r(1);
   TDataFrame tdf(50);
   auto d = tdf.Define("r", [&r]() { return r.Uniform(0., 8.); });
   auto df = d.Filter([](double x) { return x > 5; }, {"r"}, "myFilter");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_Filter_named_jitted)
{
   TRandom r(1);
   TDataFrame tdf(50);
   auto d = tdf.Define("r", [&r]() { return r.Uniform(0., 8.); });
   auto df = d.Filter("r>5", "myFilter");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

// jitted Define + Filters
TEST(TEST_CATEGORY, Define_jitted_Filter)
{
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("r", "r.Uniform(0.,8.)");
   auto df = d.Filter([](double x) { return x > 5; }, {"r"});
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_jitted_Filter_jitted)
{
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("r", "r.Uniform(0.,8.)");
   auto df = d.Filter("r>5");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_jitted_Filter_named)
{
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("r", "r.Uniform(0.,8.)");
   auto df = d.Filter([](double x) { return x > 5; }, {"r"}, "myFilter");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_jitted_Filter_named_jitted)
{
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("r", "r.Uniform(0.,8.)");
   auto df = d.Filter("r>5", "myFilter");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

// This tests the interface but we need to run it both w/ and w/o implicit mt
#ifdef R__USE_IMT
TEST(TEST_CATEGORY, GetNSlots)
{
   EXPECT_EQ(NSLOTS, ROOT::Internal::TDF::GetNSlots());
}
#endif
<commit_msg>Add Google test for snapshot action with options<commit_after>#include "ROOT/TDataFrame.hxx"
#include "Compression.h"
#include "TFile.h"
#include "TInterpreter.h"
#include "TRandom.h"

#include "gtest/gtest.h"

using namespace ROOT::Experimental;

namespace TEST_CATEGORY {

int DefineFunction()
{
   return 1;
}

struct DefineStruct {
   int operator()() { return 1; }
};

void FillTree(const char *filename, const char *treeName, int nevents = 0)
{
   TFile f(filename, "RECREATE");
   TTree t(treeName, treeName);
   t.SetAutoFlush(1); // yes, one event per cluster: to make MT more meaningful
   double b1;
   int b2;
   t.Branch("b1", &b1);
   t.Branch("b2", &b2);
   for (int i = 0; i < nevents; ++i) {
      b1 = i;
      b2 = i * i;
      t.Fill();
   }
   t.Write();
   f.Close();
}
}

TEST(TEST_CATEGORY, CreateEmpty)
{
   TDataFrame tdf(10);
   auto c = tdf.Count();
   EXPECT_EQ(10U, *c);
}

TEST(TEST_CATEGORY, CreateZeroEntries)
{
   TDataFrame tdf(0);
   auto c = tdf.Count();
   EXPECT_EQ(0U, *c);
}

TEST(TEST_CATEGORY, CreateZeroEntriesWithBranches)
{
   auto filename = "dataframe_simple_0.root";
   auto treename = "t";
#ifndef testTDF_simple_0_CREATED
#define testTDF_simple_0_CREATED
   TEST_CATEGORY::FillTree(filename, treename);
#endif
   TDataFrame tdf(treename, filename);
   auto c = tdf.Count();
   auto m = tdf.Mean("b1");
   EXPECT_EQ(0U, *c);
   EXPECT_EQ(0., *m);
}

TEST(TEST_CATEGORY, BuildWithTDirectory)
{
   auto filename = "dataframe_simple_1.root";
   auto treename = "t";
#ifndef testTDF_simple_1_CREATED
#define testTDF_simple_1_CREATED
   TEST_CATEGORY::FillTree(filename, treename, 50);
#endif
   TFile f(filename);
   TDataFrame tdf(treename, &f);
   auto c = tdf.Count();
   EXPECT_EQ(50U, *c);
}

// Jitting of column types
TEST(TEST_CATEGORY, TypeGuessing)
{
   auto filename = "dataframe_simple_2.root";
   auto treename = "t";
#ifndef testTDF_simple_2_CREATED
#define testTDF_simple_2_CREATED
   TEST_CATEGORY::FillTree(filename, treename, 50);
#endif
   TDataFrame tdf(treename, filename, {"b1"});
   auto hcompiled = tdf.Histo1D<double>();
   auto hjitted = tdf.Histo1D();
   EXPECT_EQ(50, hcompiled->GetEntries());
   EXPECT_EQ(50, hjitted->GetEntries());
   EXPECT_DOUBLE_EQ(hcompiled->GetMean(), hjitted->GetMean());
}

// Define

TEST(TEST_CATEGORY, Define_lambda)
{
   TDataFrame tdf(10);
   auto d = tdf.Define("i", []() { return 1; });
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST(TEST_CATEGORY, Define_function)
{
   TDataFrame tdf(10);
   auto d = tdf.Define("i", TEST_CATEGORY::DefineFunction);
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST(TEST_CATEGORY, Define_functor)
{
   TDataFrame tdf(10);
   TEST_CATEGORY::DefineStruct def;
   auto d = tdf.Define("i", def);
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST(TEST_CATEGORY, Define_jitted)
{
   TDataFrame tdf(10);
   auto d = tdf.Define("i", "1");
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST(TEST_CATEGORY, Define_jitted_complex)
{
// The test can be run in sequential and MT mode.
#ifndef RNDM_GEN_CREATED
#define RNDM_GEN_CREATED
   gInterpreter->ProcessLine("TRandom r;");
#endif
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("i", "r.Uniform(0.,8.)");
   auto m = d.Max("i");
   EXPECT_EQ(7.867497533559811628, *m);
}

// Define + Filters
TEST(TEST_CATEGORY, Define_Filter)
{
   TRandom r(1);
   TDataFrame tdf(50);
   auto d = tdf.Define("r", [&r]() { return r.Uniform(0., 8.); });
   auto df = d.Filter([](double x) { return x > 5; }, {"r"});
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_Filter_jitted)
{
   TRandom r(1);
   TDataFrame tdf(50);
   auto d = tdf.Define("r", [&r]() { return r.Uniform(0., 8.); });
   auto df = d.Filter("r>5");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_Filter_named)
{
   TRandom r(1);
   TDataFrame tdf(50);
   auto d = tdf.Define("r", [&r]() { return r.Uniform(0., 8.); });
   auto df = d.Filter([](double x) { return x > 5; }, {"r"}, "myFilter");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_Filter_named_jitted)
{
   TRandom r(1);
   TDataFrame tdf(50);
   auto d = tdf.Define("r", [&r]() { return r.Uniform(0., 8.); });
   auto df = d.Filter("r>5", "myFilter");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

// jitted Define + Filters
TEST(TEST_CATEGORY, Define_jitted_Filter)
{
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("r", "r.Uniform(0.,8.)");
   auto df = d.Filter([](double x) { return x > 5; }, {"r"});
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_jitted_Filter_jitted)
{
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("r", "r.Uniform(0.,8.)");
   auto df = d.Filter("r>5");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_jitted_Filter_named)
{
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("r", "r.Uniform(0.,8.)");
   auto df = d.Filter([](double x) { return x > 5; }, {"r"}, "myFilter");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Define_jitted_Filter_named_jitted)
{
   gInterpreter->ProcessLine("r.SetSeed(1);");
   TDataFrame tdf(50);
   auto d = tdf.Define("r", "r.Uniform(0.,8.)");
   auto df = d.Filter("r>5", "myFilter");
   auto m = df.Max("r");
   EXPECT_EQ(7.867497533559811628, *m);
}

TEST(TEST_CATEGORY, Snapshot_update)
{
   using SnapshotOptions = ROOT::Experimental::TDF::SnapshotOptions;

   SnapshotOptions opts;

   opts.fMode = "UPDATE";

   TDataFrame tdf1(1000);
   auto s1 = tdf1.Define("one", []() { return 1.0; })
               .Snapshot<double>("mytree1", "snapshot_test_update.root", {"one"});

   EXPECT_EQ(1000U, *s1.Count());

   EXPECT_EQ(1.0, *s1.Min("one"));
   EXPECT_EQ(1.0, *s1.Max("one"));
   EXPECT_EQ(1.0, *s1.Mean("one"));

   TDataFrame tdf2(1000);
   auto s2 = tdf2.Define("two", []() { return 2.0; })
               .Snapshot<double>("mytree2", "snapshot_test_update.root", {"two"}, opts);

   EXPECT_EQ(1000U, *s2.Count());

   EXPECT_EQ(2.0, *s2.Min("two"));
   EXPECT_EQ(2.0, *s2.Max("two"));
   EXPECT_EQ(2.0, *s2.Mean("two"));

   TFile *f = TFile::Open("snapshot_test_update.root", "READ");
   auto mytree1 = (TTree*) f->Get("mytree1");
   auto mytree2 = (TTree*) f->Get("mytree2");

   EXPECT_NE(nullptr, mytree1);
   EXPECT_NE(nullptr, mytree2);

   f->Close();
   delete f;
}

TEST(TEST_CATEGORY, Snapshot_action_with_options)
{
   using SnapshotOptions = ROOT::Experimental::TDF::SnapshotOptions;

   SnapshotOptions opts;
   opts.fAutoFlush = 10;
   opts.fMode = "RECREATE";

   for (auto algorithm : { ROOT::kZLIB, ROOT::kLZMA, ROOT::kLZ4 }) {
      TDataFrame tdf(1000);

      opts.fCompress = ROOT::CompressionSettings(algorithm, 6);

      auto s = tdf.Define("one", []() { return 1.0; })
                  .Snapshot<double>("mytree", "snapshot_test_opts.root", {"one"}, opts);

      EXPECT_EQ(1000U, *s.Count());
      EXPECT_EQ(1.0, *s.Min("one"));
      EXPECT_EQ(1.0, *s.Max("one"));
      EXPECT_EQ(1.0, *s.Mean("one"));

      TFile *f = TFile::Open("snapshot_test_opts.root", "READ");

      EXPECT_EQ(algorithm, f->GetCompressionAlgorithm());
      EXPECT_EQ(6, f->GetCompressionLevel());

      f->Close();
      delete f;
   }
}

// This tests the interface but we need to run it both w/ and w/o implicit mt
#ifdef R__USE_IMT
TEST(TEST_CATEGORY, GetNSlots)
{
   EXPECT_EQ(NSLOTS, ROOT::Internal::TDF::GetNSlots());
}
#endif
<|endoftext|>


<commit_before>#include "network_packets.h"

// -------------------- NetworkPacket --------------------------

// serialization
Packet::Packet(int32_t id, uint32_t flag, int derived_size) : id(id), flag(flag) {

  packet_size = header_size + derived_size;
  packet = (char*)malloc(packet_size);

  std::cout << "Packet Created: size: " <<  packet_size << std::endl;

  // set packet header data
  uint32_t* ptr = (uint32_t*)packet;
  ptr[0] = packet_size;
  ptr[1] = id;
  ptr[2] = flag;
}

// deserialization
Packet::Packet(void* buf, ssize_t size) :
  packet_size(size), packet(buf) {

  packet_size = ((uint32_t*)buf)[0];
  id = ((int32_t*)buf)[1];
  flag = ((uint32_t*)buf)[2];
}

Packet::~Packet() {

  //free(packet);
}

int Packet::dataSize() const {
  return header_size;
}

std::ostream& Packet::print(std::ostream& stream) const {

  stream << "Packet" << std::endl;
  stream << "\tpacket_size: " << packet_size << std::endl;
  stream << "\tid: " << id << std::endl;
  stream << "\tflag: " << flag << std::endl;
  return stream;
}

std::ostream& operator<<(std::ostream& stream, const Packet &p) {
  return p.print(stream);
}

// ----------------------------- InitializationPacket ------------------

EspressoInit::EspressoInit(void* buf, ssize_t size) : Packet(buf, size) {

  uint32_t* base = (uint32_t*)(((uint8_t*)buf) + Packet::dataSize());
  node_id = base[0];
}

EspressoInit::EspressoInit(int node_id) : Packet(0, ESPRESSO_INIT, data_size),
  node_id(node_id) {

  uint32_t* base = (uint32_t*)(((uint8_t*)packet) + Packet::dataSize());
  base[0] = node_id;
}

std::ostream& EspressoInit::print(std::ostream& stream) const {

  stream << "EspressoInitializationPacket" << std::endl;
  stream << "\tnode_id: " << node_id << std::endl;
  return Packet::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const EspressoInit &p) {
  return p.print(stream);
}

// -------------------------- DecafsClientInit -----------------------

DecafsClientInit::DecafsClientInit(void* buf, ssize_t size) : Packet(buf, size) {

  uint32_t* base = (uint32_t*)(((uint8_t*)buf) + Packet::dataSize());
  user_id = base[0];
}

DecafsClientInit::DecafsClientInit(int user_id) : Packet(0, DECAFS_CLIENT_INIT, data_size),
  user_id(user_id) {

  uint32_t* base = (uint32_t*)(((uint8_t*)packet) + Packet::dataSize());
  base[0] = user_id;
}

std::ostream& DecafsClientInit::print(std::ostream& stream) const {

  stream << "DecafsClientInit" << std::endl;
  stream << "\tuser_id: " << user_id << std::endl;
  return Packet::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const DecafsClientInit &p) {
  return p.print(stream);
}

// ---------------------- FilePacket --------------------

// constructor from data
// serialization
FilePacket::FilePacket(uint32_t id, int flag, int derived_size, uint32_t fd, uint32_t file_id,
 uint32_t stripe_id, uint32_t chunk_num, uint32_t offset, int32_t count)
 : Packet(id, flag, derived_size + data_size),
   fd(fd),
   file_id(file_id),
   stripe_id(stripe_id),
   chunk_num(chunk_num),
   offset(offset),
   count(count) {

  uint32_t* base = (uint32_t*)(((uint8_t*)packet) + Packet::dataSize());
  base[0] = fd;
  base[1] = file_id;
  base[2] = stripe_id;
  base[3] = chunk_num;
  base[4] = offset;
  base[5] = count;
}

// constructor from a buffer
// deserialization
FilePacket::FilePacket(void* buf, ssize_t size) : Packet(buf, size) {

  uint32_t* base = (uint32_t*)(((uint8_t*)buf) + Packet::dataSize());

  fd = base[0];
  file_id = base[1];
  stripe_id = base[2];
  chunk_num = base[3];
  offset = base[4];
  count = base[5];
}

int FilePacket::dataSize() const {

  return Packet::dataSize() + data_size;
}

std::ostream& FilePacket::print(std::ostream& stream) const {

  stream << "FilePacket" << std::endl;
  stream << "\tfd: " << fd << std::endl;
  stream << "\tfile_id: " << file_id << std::endl;
  stream << "\tstripe_id: " << stripe_id << std::endl;
  stream << "\tchunk_num: " << chunk_num << std::endl;
  stream << "\toffset: " << offset << std::endl;
  stream << "\tcount: " << count << std::endl;
  return Packet::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const FilePacket &packet) {
  return packet.print(stream);
}

// ---------------------- FileDataPacket ------------

FileDataPacket::FileDataPacket(void* buf, ssize_t size) : FilePacket(buf, size) {

  if (count > 0) {
    data_buffer = ((uint8_t*)buf) + FilePacket::dataSize();
  } else {
    data_buffer = NULL;
  }
}

FileDataPacket::FileDataPacket(uint32_t id, int flag, int derived_size, uint32_t fd, uint32_t file_id,
 uint32_t stripe_id, uint32_t chunk_num, uint32_t offset, int32_t count, uint8_t* buf)
 : FilePacket(id, flag, std::max(0, count), fd, file_id, stripe_id, chunk_num, offset, count) {

  data_buffer = buf;

  uint8_t* data_loc = ((uint8_t*)packet) + FilePacket::dataSize();

  if (count > 0) {
    memcpy(data_loc, buf, count);
  }
  // TODO do i need to free buf?
  // or is it the creators responsibility?
}

int FileDataPacket::dataSize() const {

  return FilePacket::dataSize() + data_size;
}

std::ostream& FileDataPacket::print(std::ostream& stream) const {

  stream << "FileDataPacket" << std::endl;
  stream << "data_buffer: ";
  stream.write((const char*)data_buffer, count);
  stream << std::endl;

  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const FileDataPacket &packet) {
  return packet.print(stream);
}

// ------------------------ ReadChunkPacket ------------------

ReadChunkRequest::ReadChunkRequest(void* buf, ssize_t packet_size)
 : FilePacket(buf, packet_size) {

}

ReadChunkRequest::ReadChunkRequest(uint32_t id, uint32_t fd, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num, uint32_t offset, int32_t count)
 : FilePacket(id, READ_CHUNK, 0, fd, file_id, stripe_id, chunk_num, offset, count) {

}

std::ostream& ReadChunkRequest::print(std::ostream& stream) const {

  stream << "ReadChunkRequest" << std::endl;
  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const ReadChunkRequest &req) {
  return req.print(stream);
}

// ------------------------ WriteChunkResponse ------------------

WriteChunkResponse::WriteChunkResponse(void* buf, ssize_t packet_size)
 : FilePacket(buf, packet_size) {

}

WriteChunkResponse::WriteChunkResponse(uint32_t id, uint32_t fd, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num, uint32_t offset, int32_t count)
 : FilePacket(id, WRITE_CHUNK_RESPONSE, 0, fd, file_id, stripe_id, chunk_num, offset, count) {

}

std::ostream& WriteChunkResponse::print(std::ostream& stream) const {

  stream << "WriteChunkResponse" << std::endl;
  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const WriteChunkResponse &req) {
  return req.print(stream);
}

// ------------------------ WriteChunkPacket ---------------------------

WriteChunkRequest::WriteChunkRequest(void* buf, ssize_t packet_size)
 : FileDataPacket(buf, packet_size) {

}

WriteChunkRequest::WriteChunkRequest(uint32_t id, uint32_t fd, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num, uint32_t offset, int32_t count, uint8_t * buf)
 : FileDataPacket(id, WRITE_CHUNK, 0, fd, file_id, stripe_id, chunk_num, offset, count, buf) {

}

std::ostream& WriteChunkRequest::print(std::ostream& stream) const {

  stream << "WriteChunkRequest" << std::endl;
  return FileDataPacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const WriteChunkRequest &req) {
  return req.print(stream);
}

// ------------------------ ReadChunkResponse ---------------------------

ReadChunkResponse::ReadChunkResponse(void* buf, ssize_t packet_size)
 : FileDataPacket(buf, packet_size) {

}

ReadChunkResponse::ReadChunkResponse(uint32_t id, uint32_t fd, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num, uint32_t offset, int32_t count, uint8_t * buf)
 : FileDataPacket(id, READ_CHUNK_RESPONSE, 0, fd, file_id, stripe_id, chunk_num, offset, count, buf) {

}

std::ostream& ReadChunkResponse::print(std::ostream& stream) const {

  stream << "ReadChunkResponse" << std::endl;
  return FileDataPacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const ReadChunkResponse &req) {
  return req.print(stream);
}

// ------------------------------- DeleteChunkPacket -----------------------------

DeleteChunkRequest::DeleteChunkRequest(void* buf, ssize_t size)
 : FilePacket(buf, size) {

}

DeleteChunkRequest::DeleteChunkRequest(uint32_t id, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num)
 : FilePacket(id, DELETE_CHUNK, 0, fd, file_id, stripe_id, chunk_num, -1, -1) {

}

std::ostream& DeleteChunkRequest::print(std::ostream& stream) const {

  stream << "DeleteChunkRequest" << std::endl;
  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const DeleteChunkRequest &req) {
  return req.print(stream);
}

// ------------------------------- DeleteChunkResponse -----------------------------

DeleteChunkResponse::DeleteChunkResponse(void* buf, ssize_t size)
 : FilePacket(buf, size) {

}

DeleteChunkResponse::DeleteChunkResponse(uint32_t id, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num)
 : FilePacket(id, DELETE_CHUNK_RESPONSE, 0, fd, file_id, stripe_id, chunk_num, -1, -1) {

}

std::ostream& DeleteChunkResponse::print(std::ostream& stream) const {

  stream << "DeleteChunkResponse" << std::endl;
  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const DeleteChunkResponse &req) {
  return req.print(stream);
}
<commit_msg>added NULL buffer protection<commit_after>#include "network_packets.h"

// -------------------- NetworkPacket --------------------------

// serialization
Packet::Packet(int32_t id, uint32_t flag, int derived_size) : id(id), flag(flag) {

  packet_size = header_size + derived_size;
  packet = (char*)malloc(packet_size);

  std::cout << "Packet Created: size: " <<  packet_size << std::endl;

  // set packet header data
  uint32_t* ptr = (uint32_t*)packet;
  ptr[0] = packet_size;
  ptr[1] = id;
  ptr[2] = flag;
}

// deserialization
Packet::Packet(void* buf, ssize_t size) :
  packet_size(size), packet(buf) {

  packet_size = ((uint32_t*)buf)[0];
  id = ((int32_t*)buf)[1];
  flag = ((uint32_t*)buf)[2];
}

Packet::~Packet() {

  //free(packet);
}

int Packet::dataSize() const {
  return header_size;
}

std::ostream& Packet::print(std::ostream& stream) const {

  stream << "Packet" << std::endl;
  stream << "\tpacket_size: " << packet_size << std::endl;
  stream << "\tid: " << id << std::endl;
  stream << "\tflag: " << flag << std::endl;
  return stream;
}

std::ostream& operator<<(std::ostream& stream, const Packet &p) {
  return p.print(stream);
}

// ----------------------------- InitializationPacket ------------------

EspressoInit::EspressoInit(void* buf, ssize_t size) : Packet(buf, size) {

  uint32_t* base = (uint32_t*)(((uint8_t*)buf) + Packet::dataSize());
  node_id = base[0];
}

EspressoInit::EspressoInit(int node_id) : Packet(0, ESPRESSO_INIT, data_size),
  node_id(node_id) {

  uint32_t* base = (uint32_t*)(((uint8_t*)packet) + Packet::dataSize());
  base[0] = node_id;
}

std::ostream& EspressoInit::print(std::ostream& stream) const {

  stream << "EspressoInitializationPacket" << std::endl;
  stream << "\tnode_id: " << node_id << std::endl;
  return Packet::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const EspressoInit &p) {
  return p.print(stream);
}

// -------------------------- DecafsClientInit -----------------------

DecafsClientInit::DecafsClientInit(void* buf, ssize_t size) : Packet(buf, size) {

  uint32_t* base = (uint32_t*)(((uint8_t*)buf) + Packet::dataSize());
  user_id = base[0];
}

DecafsClientInit::DecafsClientInit(int user_id) : Packet(0, DECAFS_CLIENT_INIT, data_size),
  user_id(user_id) {

  uint32_t* base = (uint32_t*)(((uint8_t*)packet) + Packet::dataSize());
  base[0] = user_id;
}

std::ostream& DecafsClientInit::print(std::ostream& stream) const {

  stream << "DecafsClientInit" << std::endl;
  stream << "\tuser_id: " << user_id << std::endl;
  return Packet::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const DecafsClientInit &p) {
  return p.print(stream);
}

// ---------------------- FilePacket --------------------

// constructor from data
// serialization
FilePacket::FilePacket(uint32_t id, int flag, int derived_size, uint32_t fd, uint32_t file_id,
 uint32_t stripe_id, uint32_t chunk_num, uint32_t offset, int32_t count)
 : Packet(id, flag, derived_size + data_size),
   fd(fd),
   file_id(file_id),
   stripe_id(stripe_id),
   chunk_num(chunk_num),
   offset(offset),
   count(count) {

  uint32_t* base = (uint32_t*)(((uint8_t*)packet) + Packet::dataSize());
  base[0] = fd;
  base[1] = file_id;
  base[2] = stripe_id;
  base[3] = chunk_num;
  base[4] = offset;
  base[5] = count;
}

// constructor from a buffer
// deserialization
FilePacket::FilePacket(void* buf, ssize_t size) : Packet(buf, size) {

  uint32_t* base = (uint32_t*)(((uint8_t*)buf) + Packet::dataSize());

  fd = base[0];
  file_id = base[1];
  stripe_id = base[2];
  chunk_num = base[3];
  offset = base[4];
  count = base[5];
}

int FilePacket::dataSize() const {

  return Packet::dataSize() + data_size;
}

std::ostream& FilePacket::print(std::ostream& stream) const {

  stream << "FilePacket" << std::endl;
  stream << "\tfd: " << fd << std::endl;
  stream << "\tfile_id: " << file_id << std::endl;
  stream << "\tstripe_id: " << stripe_id << std::endl;
  stream << "\tchunk_num: " << chunk_num << std::endl;
  stream << "\toffset: " << offset << std::endl;
  stream << "\tcount: " << count << std::endl;
  return Packet::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const FilePacket &packet) {
  return packet.print(stream);
}

// ---------------------- FileDataPacket ------------

FileDataPacket::FileDataPacket(void* buf, ssize_t size) : FilePacket(buf, size) {

  if (count > 0) {
    data_buffer = ((uint8_t*)buf) + FilePacket::dataSize();
  } else {
    data_buffer = NULL;
  }
}

FileDataPacket::FileDataPacket(uint32_t id, int flag, int derived_size, uint32_t fd, uint32_t file_id,
 uint32_t stripe_id, uint32_t chunk_num, uint32_t offset, int32_t count, uint8_t* buf)
 : FilePacket(id, flag, std::max(0, count), fd, file_id, stripe_id, chunk_num, offset, count) {

  data_buffer = buf;

  uint8_t* data_loc = ((uint8_t*)packet) + FilePacket::dataSize();

  if (count > 0) {
    memcpy(data_loc, buf, count);
  }
  // TODO do i need to free buf?
  // or is it the creators responsibility?
}

int FileDataPacket::dataSize() const {

  return FilePacket::dataSize() + data_size;
}

std::ostream& FileDataPacket::print(std::ostream& stream) const {

  stream << "FileDataPacket" << std::endl;
  stream << "data_buffer: ";
  if (data_buffer) {
    stream.write((const char*)data_buffer, count);
  } else {
    stream << "<NULL>";
  }
  stream << std::endl;

  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const FileDataPacket &packet) {
  return packet.print(stream);
}

// ------------------------ ReadChunkPacket ------------------

ReadChunkRequest::ReadChunkRequest(void* buf, ssize_t packet_size)
 : FilePacket(buf, packet_size) {

}

ReadChunkRequest::ReadChunkRequest(uint32_t id, uint32_t fd, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num, uint32_t offset, int32_t count)
 : FilePacket(id, READ_CHUNK, 0, fd, file_id, stripe_id, chunk_num, offset, count) {

}

std::ostream& ReadChunkRequest::print(std::ostream& stream) const {

  stream << "ReadChunkRequest" << std::endl;
  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const ReadChunkRequest &req) {
  return req.print(stream);
}

// ------------------------ WriteChunkResponse ------------------

WriteChunkResponse::WriteChunkResponse(void* buf, ssize_t packet_size)
 : FilePacket(buf, packet_size) {

}

WriteChunkResponse::WriteChunkResponse(uint32_t id, uint32_t fd, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num, uint32_t offset, int32_t count)
 : FilePacket(id, WRITE_CHUNK_RESPONSE, 0, fd, file_id, stripe_id, chunk_num, offset, count) {

}

std::ostream& WriteChunkResponse::print(std::ostream& stream) const {

  stream << "WriteChunkResponse" << std::endl;
  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const WriteChunkResponse &req) {
  return req.print(stream);
}

// ------------------------ WriteChunkPacket ---------------------------

WriteChunkRequest::WriteChunkRequest(void* buf, ssize_t packet_size)
 : FileDataPacket(buf, packet_size) {

}

WriteChunkRequest::WriteChunkRequest(uint32_t id, uint32_t fd, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num, uint32_t offset, int32_t count, uint8_t * buf)
 : FileDataPacket(id, WRITE_CHUNK, 0, fd, file_id, stripe_id, chunk_num, offset, count, buf) {

}

std::ostream& WriteChunkRequest::print(std::ostream& stream) const {

  stream << "WriteChunkRequest" << std::endl;
  return FileDataPacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const WriteChunkRequest &req) {
  return req.print(stream);
}

// ------------------------ ReadChunkResponse ---------------------------

ReadChunkResponse::ReadChunkResponse(void* buf, ssize_t packet_size)
 : FileDataPacket(buf, packet_size) {

}

ReadChunkResponse::ReadChunkResponse(uint32_t id, uint32_t fd, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num, uint32_t offset, int32_t count, uint8_t * buf)
 : FileDataPacket(id, READ_CHUNK_RESPONSE, 0, fd, file_id, stripe_id, chunk_num, offset, count, buf) {

}

std::ostream& ReadChunkResponse::print(std::ostream& stream) const {

  stream << "ReadChunkResponse" << std::endl;
  return FileDataPacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const ReadChunkResponse &req) {
  return req.print(stream);
}

// ------------------------------- DeleteChunkPacket -----------------------------

DeleteChunkRequest::DeleteChunkRequest(void* buf, ssize_t size)
 : FilePacket(buf, size) {

}

DeleteChunkRequest::DeleteChunkRequest(uint32_t id, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num)
 : FilePacket(id, DELETE_CHUNK, 0, fd, file_id, stripe_id, chunk_num, -1, -1) {

}

std::ostream& DeleteChunkRequest::print(std::ostream& stream) const {

  stream << "DeleteChunkRequest" << std::endl;
  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const DeleteChunkRequest &req) {
  return req.print(stream);
}

// ------------------------------- DeleteChunkResponse -----------------------------

DeleteChunkResponse::DeleteChunkResponse(void* buf, ssize_t size)
 : FilePacket(buf, size) {

}

DeleteChunkResponse::DeleteChunkResponse(uint32_t id, uint32_t file_id, uint32_t stripe_id,
 uint32_t chunk_num)
 : FilePacket(id, DELETE_CHUNK_RESPONSE, 0, fd, file_id, stripe_id, chunk_num, -1, -1) {

}

std::ostream& DeleteChunkResponse::print(std::ostream& stream) const {

  stream << "DeleteChunkResponse" << std::endl;
  return FilePacket::print(stream);
}

std::ostream& operator<<(std::ostream& stream, const DeleteChunkResponse &req) {
  return req.print(stream);
}
<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <tuple>
#include <array>
#include <Eigen/Dense>
#include <iod/symbols.hh>
#include <vpp/core/image2d.hh>
#include <vpp/core/vector.hh>
#include <vpp/core/liie.hh>
#include <vpp/core/box_nbh2d.hh>
#include <vpp/core/make_array.hh>

namespace vpp
{

  template <typename T, typename U>
  void euclide_distance_transform(image2d<T>& input, image2d<U>& sedt)
  {
    image2d<vshort2> R(input.domain(), _border = 1);
    fill_with_border(R, vshort2{0,0});

    auto forward4 = [] () { return make_array(vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{0, -1}); };
    auto backward4 = [] () { return make_array(vint2{1, 1}, vint2{1, 0}, vint2{1, -1}, vint2{0, 1}); };

    fill_with_border(sedt, input.nrows() + input.ncols());
    pixel_wise(input, sedt) | [] (auto& i, auto& s) { if (i == 0) s = 0; };

    auto run = [&] (auto neighborhood, auto col_direction,
                    auto row_direction1, auto row_direction2, auto spn) {

      row_wise(sedt, R)(col_direction) | [&] (auto sedt_row, auto R_row)
      {
        // Forward pass
        auto sedt_row_nbh = box_nbh2d<U, 3, 3>(sedt_row);
        auto R_row_nbh = box_nbh2d<vshort2, 3, 3>(R_row);

        pixel_wise(sedt_row_nbh, R_row_nbh)(row_direction1)
        | [&] (auto& sedt_nbh, auto& R_nbh)
        {
          vint2 min_rel_coord = neighborhood()[0];
          int min_dist = INT_MAX;
          for (vint2 nc : neighborhood())
          {
            int d = sedt_nbh(nc) + 2 * (std::abs(R_nbh(nc)[0] * nc[0]) +
                                        std::abs(R_nbh(nc)[1] * nc[1]))
              + nc.cwiseAbs().sum();

            if (d < min_dist)
            {
              min_dist = d;
              min_rel_coord = nc;
            }
          }

          if (min_dist < sedt_nbh(0, 0))
          {
            R_nbh(0, 0) = (R_nbh(min_rel_coord) + min_rel_coord.cast<short>()).template cast<short>();
            sedt_nbh(0, 0) = min_dist;
          }
        };

        // Backward pass
        pixel_wise(sedt_row_nbh, R_row_nbh)(row_direction2, _no_threads) | [&] (auto& sedt_nbh, auto& R_nbh)
        {
          int d = sedt_nbh(spn()) + 2 * std::abs(R_nbh(spn())[1]) + 1;
          if (d < sedt_nbh(0, 0))
          {
            sedt_nbh(0, 0) = d;
            R_nbh(0, 0) = (R_nbh(spn()) + spn().template cast<short>()).template cast<short>();
          }
        };

      };

    };

    run(forward4, _top_to_bottom, _left_to_right, _right_to_left, [] () { return vint2{0, 1}; });
    run(backward4, _bottom_to_top, _right_to_left, _left_to_right, [] () { return vint2{0, -1}; });

    // pixel_wise(sedt) | [] (auto& p) { p/=100; };
  }

  // template <typename T, typename U>
  // void euclide_distance_transform(image2d<T>& input, image2d<U>& sedt)
  // {
  //   image2d<vshort2> R(input.domain(), _border = 1);
  //   fill_with_border(R, vshort2{0,0});

  //   auto forward4 = [] () { return make_array(vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{0, -1}); };
  //   auto backward4 = [] () { return make_array(vint2{1, 1}, vint2{1, 0}, vint2{1, -1}, vint2{0, 1}); };

  //   fill_with_border(sedt, INT_MAX / 2);
  //   pixel_wise(input, sedt) | [] (auto& i, auto& s) { if (i == 0) s = 0; };

  //   auto run = [&] (auto neighborhood, auto col_direction,
  //                   auto row_direction1, auto row_direction2, auto spn) {

  //     row_wise(sedt, R)(col_direction) | [&] (auto sedt_row, auto R_row)
  //     {
  //       // Forward pass
  //       auto sedt_row_nbh = box_nbh2d<int, 3, 3>(sedt_row);
  //       auto R_row_nbh = box_nbh2d<vshort2, 3, 3>(R_row);

  //       pixel_wise(sedt_row_nbh, R_row_nbh)(row_direction1, _no_threads)
  //       | [&] (auto& sedt_nbh, auto& R_nbh)
  //       {
  //         int min_dist = INT_MAX;
  //         for (vint2 nc : neighborhood())
  //         {
  //           int d = sedt_nbh(nc) + 1;
  //           if (d < min_dist)
  //             min_dist = d;
  //         }

  //         if (min_dist < sedt_nbh(0, 0))
  //           sedt_nbh(0, 0) = min_dist;
  //       };

  //     };

  //   };

  //   run(forward4, _top_to_bottom, _left_to_right, _right_to_left, [] () { return vint2{0, 1}; });
  //   run(backward4, _bottom_to_top, _right_to_left, _left_to_right, [] () { return vint2{0, -1}; });

  //   // pixel_wise(sedt) | [] (auto& p) { p/=100; };
  // }

  template <unsigned N, typename F>
  void loop_unroll(F f, std::enable_if_t<N == 0>* = 0) { f(N); }

  template <unsigned N, typename F>
  void loop_unroll(F f, std::enable_if_t<N != 0>* = 0) { f(N); loop_unroll<N-1>(f); }

  template <typename T, typename U, typename F, typename FW, typename B, typename BW, int WS = 3>
  void generic_incremental_distance_transform(image2d<T>& input, image2d<U>& sedt,
                                              F forward,
                                              FW forward_ws,
                                              B backward,
                                              BW backward_ws,
                                              std::integral_constant<int, WS> = std::integral_constant<int, WS>())
  {
    fill_with_border(sedt, input.nrows() + input.ncols());
    pixel_wise(input, sedt) | [] (auto& i, auto& s) { if (i == 0) s = 0; };

    auto run = [&] (auto neighb, auto ws,
                    auto col_direction,
                    auto row_direction) {
      auto sedt_nbh = box_nbh2d<int, WS, WS>(sedt);
      pixel_wise(sedt_nbh)(col_direction, row_direction) | [neighb, ws] (auto sn) {
        int min_dist = sn(0,0);

        auto nbh = neighb();

        // if (neighb().size() < 6)
        auto it = [&] (int i) {
          min_dist = std::min(min_dist, ws()[i] + sn(neighb()[i]));
        };

        typedef decltype(nbh) NBH;
        loop_unroll<std::tuple_size<NBH>::value - 1>(it);
        sn(0,0) = min_dist;
      };
    };

    run(forward, forward_ws, _top_to_bottom, _left_to_right);
    run(backward, backward_ws, _bottom_to_top, _right_to_left);
  }

  const auto d4_distance_transform = [] (auto& a, auto& b) {
    generic_incremental_distance_transform(a, b,
                                 [] () { return make_array(vint2{-1, 0}, vint2{0, -1}); },
                                 [] () { return make_array(1, 1); },
                                 [] () { return make_array(vint2{1, 0}, vint2{0, 1}); },
                                 [] () { return make_array(1, 1); });
  };

  const auto d8_distance_transform = [] (auto& a, auto& b) {
    generic_incremental_distance_transform(a, b,
                                 [] () { return make_array(vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{0, -1}); },
                                 [] () { return make_array(1,1,1,1); },
                                 [] () { return make_array(vint2{1, 1}, vint2{1, 0}, vint2{1, -1}, vint2{0, 1}); },
                                           [] () { return make_array(1, 1, 1, 1); });
  };

  const auto d3_4_distance_transform = [] (auto& a, auto& b) {
    generic_incremental_distance_transform(a, b,
                                           [] () { return make_array(vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{0, -1}); },
                                           [] () { return make_array(4,3,4,3); },
                                           [] () { return make_array(vint2{1, 1}, vint2{1, 0}, vint2{1, -1}, vint2{0, 1}); },
                                           [] () { return make_array(4, 3, 4, 3); }, std::integral_constant<int, 5>());
  };

  const auto d5_7_11_distance_transform = [] (auto& a, auto& b) {
    generic_incremental_distance_transform(a, b,

                                           [] () { return make_array(vint2{-2, -1}, vint2{-2, 1}, vint2{-1, -2}, vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{-1, 2}, vint2{0, -1}); },
                                           [] () { return make_array(11,11,11,7,5,7,11,5); },
                                           [] () { return make_array(vint2{0, 1}, vint2{1, -2}, vint2{1, -1}, vint2{1, 0}, vint2{1, 1}, vint2{1, 2}, vint2{2, -1}, vint2{2, 1}); },
                                           [] () { return make_array(5,11,7,5,7,11,11,11); },
                                           std::integral_constant<int, 5>());
  };

}
<commit_msg>Remove box_nbh2d from distance_transforms.<commit_after>#pragma once

#include <vector>
#include <tuple>
#include <array>
#include <Eigen/Dense>
#include <iod/symbols.hh>
#include <vpp/core/image2d.hh>
#include <vpp/core/vector.hh>
#include <vpp/core/liie.hh>
#include <vpp/core/make_array.hh>

namespace vpp
{

  template <typename T, typename U>
  void euclide_distance_transform(image2d<T>& input, image2d<U>& sedt)
  {
    image2d<vshort2> R(input.domain(), _border = 1);
    fill_with_border(R, vshort2{0,0});

    auto forward4 = [] () { return make_array(vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{0, -1}); };
    auto backward4 = [] () { return make_array(vint2{1, 1}, vint2{1, 0}, vint2{1, -1}, vint2{0, 1}); };

    fill_with_border(sedt, input.nrows() + input.ncols());
    pixel_wise(input, sedt) | [] (auto& i, auto& s) { if (i == 0) s = 0; };

    auto run = [&] (auto neighborhood, auto col_direction,
                    auto row_direction1, auto row_direction2, auto spn) {

      row_wise(sedt, R)(col_direction) | [&] (auto sedt_row, auto R_row)
      {
        // Forward pass
        pixel_wise(relative_access(sedt_row), relative_access(R_row))(row_direction1)
        | [&] (auto& sedt_nbh, auto& R_nbh)
        {
          vint2 min_rel_coord = neighborhood()[0];
          int min_dist = INT_MAX;
          for (vint2 nc : neighborhood())
          {
            int d = sedt_nbh(nc) + 2 * (std::abs(R_nbh(nc)[0] * nc[0]) +
                                        std::abs(R_nbh(nc)[1] * nc[1]))
              + nc.cwiseAbs().sum();

            if (d < min_dist)
            {
              min_dist = d;
              min_rel_coord = nc;
            }
          }

          if (min_dist < sedt_nbh(0, 0))
          {
            R_nbh(0, 0) = (R_nbh(min_rel_coord) + min_rel_coord.cast<short>()).template cast<short>();
            sedt_nbh(0, 0) = min_dist;
          }
        };

        // Backward pass
        pixel_wise(relative_access(sedt_row), relative_access(R_row))
        (row_direction2, _no_threads) | [&] (auto sedt_nbh, auto R_nbh)
        {
          int d = sedt_nbh(spn()) + 2 * std::abs(R_nbh(spn())[1]) + 1;
          if (d < sedt_nbh(0, 0))
          {
            sedt_nbh(0, 0) = d;
            R_nbh(0, 0) = (R_nbh(spn()) + spn().template cast<short>()).template cast<short>();
          }
        };

      };

    };

    run(forward4, _top_to_bottom, _left_to_right, _right_to_left, [] () { return vint2{0, 1}; });
    run(backward4, _bottom_to_top, _right_to_left, _left_to_right, [] () { return vint2{0, -1}; });

    // pixel_wise(sedt) | [] (auto& p) { p/=100; };
  }

  template <unsigned N, typename F>
  void loop_unroll(F f, std::enable_if_t<N == 0>* = 0) { f(N); }

  template <unsigned N, typename F>
  void loop_unroll(F f, std::enable_if_t<N != 0>* = 0) { f(N); loop_unroll<N-1>(f); }

  template <typename T, typename U, typename F, typename FW, typename B, typename BW, int WS = 3>
  void generic_incremental_distance_transform(image2d<T>& input, image2d<U>& sedt,
                                              F forward,
                                              FW forward_ws,
                                              B backward,
                                              BW backward_ws,
                                              std::integral_constant<int, WS> = std::integral_constant<int, WS>())
  {
    fill_with_border(sedt, input.nrows() + input.ncols());
    pixel_wise(input, sedt) | [] (auto& i, auto& s) { if (i == 0) s = 0; };

    auto run = [&] (auto neighb, auto ws,
                    auto col_direction,
                    auto row_direction) {
      pixel_wise(relative_access(sedt))(col_direction, row_direction) | [neighb, ws] (auto sn) {
        int min_dist = sn(0,0);

        auto nbh = neighb();

        // if (neighb().size() < 6)
        auto it = [&] (int i) {
          min_dist = std::min(min_dist, ws()[i] + sn(neighb()[i]));
        };

        typedef decltype(nbh) NBH;
        loop_unroll<std::tuple_size<NBH>::value - 1>(it);
        sn(0,0) = min_dist;
      };
    };

    run(forward, forward_ws, _top_to_bottom, _left_to_right);
    run(backward, backward_ws, _bottom_to_top, _right_to_left);
  }

  const auto d4_distance_transform = [] (auto& a, auto& b) {
    generic_incremental_distance_transform(a, b,
                                 [] () { return make_array(vint2{-1, 0}, vint2{0, -1}); },
                                 [] () { return make_array(1, 1); },
                                 [] () { return make_array(vint2{1, 0}, vint2{0, 1}); },
                                 [] () { return make_array(1, 1); });
  };

  const auto d8_distance_transform = [] (auto& a, auto& b) {
    generic_incremental_distance_transform(a, b,
                                 [] () { return make_array(vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{0, -1}); },
                                 [] () { return make_array(1,1,1,1); },
                                 [] () { return make_array(vint2{1, 1}, vint2{1, 0}, vint2{1, -1}, vint2{0, 1}); },
                                           [] () { return make_array(1, 1, 1, 1); });
  };

  const auto d3_4_distance_transform = [] (auto& a, auto& b) {
    generic_incremental_distance_transform(a, b,
                                           [] () { return make_array(vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{0, -1}); },
                                           [] () { return make_array(4,3,4,3); },
                                           [] () { return make_array(vint2{1, 1}, vint2{1, 0}, vint2{1, -1}, vint2{0, 1}); },
                                           [] () { return make_array(4, 3, 4, 3); }, std::integral_constant<int, 5>());
  };

  const auto d5_7_11_distance_transform = [] (auto& a, auto& b) {
    generic_incremental_distance_transform(a, b,

                                           [] () { return make_array(vint2{-2, -1}, vint2{-2, 1}, vint2{-1, -2}, vint2{-1, -1}, vint2{-1, 0}, vint2{-1, 1}, vint2{-1, 2}, vint2{0, -1}); },
                                           [] () { return make_array(11,11,11,7,5,7,11,5); },
                                           [] () { return make_array(vint2{0, 1}, vint2{1, -2}, vint2{1, -1}, vint2{1, 0}, vint2{1, 1}, vint2{1, 2}, vint2{2, -1}, vint2{2, 1}); },
                                           [] () { return make_array(5,11,7,5,7,11,11,11); },
                                           std::integral_constant<int, 5>());
  };

}
<|endoftext|>


<commit_before>// Copyright (C) 2014 sails Authors.
// All rights reserved.
//
// Official git repository and contact information can be found at
// https://github.com/sails/sails and http://www.sailsxu.com/.
//
// Filename: monitor.cc
//
// Author: sailsxu <sailsxu@gmail.com>
// Created: 2014-10-20 17:14:50

#include "src/monitor.h"
#include <string>
#include <vector>
#ifdef __linux__
#include "sails/system/cpu_usage.h"
#endif
#include "sails/system/mem_usage.h"
#include "src/service_register.h"
#include "cpptempl/src/cpptempl.h"

namespace sails {

void ServerStatProcessor::serverstat(sails::net::HttpRequest*,
                sails::net::HttpResponse* response) {
  cpptempl::auto_data dict;
  pid_t pid = getpid();
  dict["PID"] = pid;
  dict["PORT"] = server->ListenPort();
  // cpu info
#ifdef __linux__
  double cpu = 0;
  if (sails::system::GetProcessCpuUsage(pid, 100, &cpu)) {
    dict["CPU"] = cpu;
  }
#endif

  // memory info
  uint64_t vm_size, mem_size;
  if (sails::system::GetMemoryUsedKiloBytes(pid, &vm_size, &mem_size)) {
    dict["VMSIZE"] = (int64_t)vm_size;
    dict["MEMSIZE"] = (int64_t)mem_size;
  }
  char run_mode[2];
  snprintf(run_mode, sizeof(run_mode), "%d", server->RunMode());
  dict["run_mode"] = run_mode;
  dict["recv_queue_size"] = (int64_t)server->GetRecvDataNum();
  // 网络线程信息
  dict["NetThreadNum"] = (int64_t)server->NetThreadNum();

  for (size_t i = 0; i < server->NetThreadNum(); i++) {
    cpptempl::auto_data netthread_dict;
    net::NetThread<sails::ReqMessage>::NetThreadStatus netstatus =
        server->GetNetThreadStatus(i);

    netthread_dict["NetThread_NO"] = i;
    netthread_dict["NetThread_status"] = netstatus.status;
    netthread_dict["NetThread_connector_num"] = netstatus.connector_num;
    netthread_dict["NetThread_accept_times"] = (int64_t)netstatus.accept_times;
    netthread_dict["NetThread_reject_times"] = (int64_t)netstatus.reject_times;
    netthread_dict["NetThread_send_queue_capacity"] =
        (int64_t)netstatus.send_queue_capacity;
    netthread_dict["NetThread_send_queue_size"] =
        (int64_t)netstatus.send_queue_size;
    dict["net_threads"].push_back(netthread_dict);
  }

  // 处理线程信息
  dict["HandleThreadNum"] = (int64_t)server->HandleThreadNum();
  for (size_t i = 0; i < server->HandleThreadNum(); i++) {
    cpptempl::auto_data handlethread_dict;

    net::HandleThread<sails::ReqMessage>::HandleThreadStatus handlestatus =
        server->GetHandleThreadStatus(i);

    handlethread_dict["HandleThread_NO"] = i;
    handlethread_dict["HandleThread_status"] = handlestatus.status;
    handlethread_dict["HandleThread_handle_times"] =
        (int64_t)handlestatus.handle_times;
    if (server->RunMode() == 2) {
      handlethread_dict["HandleThread_handle_queue_capacity"] =
          (int64_t)handlestatus.handle_queue_capacity;
      handlethread_dict["HandleThread_handle_queue_size"] =
          (int64_t)handlestatus.handle_queue_size;
    }
    dict["handle_threads"].push_back(handlethread_dict);
  }

  // service
  std::vector<ServiceRegister::ServiceStat> services =
      ServiceRegister::instance()->GetAllServiceStat();
  dict["serivcesNum"] = services.size();
  for (size_t i = 0; i < services.size(); ++i) {
    cpptempl::auto_data service_dict;
    service_dict["serviceName"] = services[i].name;
    service_dict["callTimes"] = (int64_t)services[i].call_times;
    service_dict["failedTimes"] = (int64_t)services[i].failed_times;
    service_dict["successTimes"] = (int64_t)services[i].success_times;
    for (int index = 0; index < 11; index++) {
      char time_name[5] = {"\0"};
      snprintf(time_name, sizeof(time_name), "L%d", index);
      service_dict[std::string(time_name)] = services[i].spendTime[index];
    }
    dict["services"].push_back(service_dict);
  }

  FILE* file = fopen("../static/stat.html", "r");
  if (file == NULL) {
    printf("can't open file\n");
  }
  char buf[5000] = {'\0'};
  int readNum = fread(buf, 1, 5000, file);
  std::string str(buf, readNum);
  std::string body = cpptempl::parse(str, dict);
  response->SetBody(body.c_str(), body.size());
}

void ServerStatProcessor::index(sails::net::HttpRequest*,
           sails::net::HttpResponse* response) {
  response->SetBody("saf index");
}

Monitor::Monitor(sails::Server* server, int port) {
  thread = NULL;
  status = Monitor::STOPING;
  isTerminate = false;

  this->server = server;
  this->port = port;
}

Monitor::~Monitor() {
  if (processor != NULL) {
    delete processor;
    processor = NULL;
  }
  if (thread != NULL) {
    Terminate();
    Join();
  }
  if (http_server != NULL) {
    delete http_server;
    http_server = NULL;
  }
}

void Monitor::Run() {
  isTerminate = false;
  thread = new std::thread(Start, this);
  status = Monitor::RUNING;
}
void Monitor::Terminate() {
  http_server->Stop();
  isTerminate = true;
}
void Monitor::Join() {
  if (thread != NULL) {
    thread->join();
    status = Monitor::STOPING;
    delete thread;
    thread = NULL;
  }
}

void Monitor::Start(Monitor* monitor) {
  monitor->http_server = new sails::net::HttpServer();
  monitor->http_server->Init(monitor->port, 1, 10, 1);
  monitor->http_server->SetStaticResourcePath(std::string("../static/"));
  // 请求处理器与url映射
  monitor->processor = new ServerStatProcessor(monitor->server);
  HTTPBIND(monitor->http_server,
           "/stat", monitor->processor, ServerStatProcessor::serverstat);
  HTTPBIND(monitor->http_server,
           "/", monitor->processor, ServerStatProcessor::index);

  while (!monitor->isTerminate) {
    sleep(1);
  }
}

}  // namespace sails

<commit_msg>update<commit_after>// Copyright (C) 2014 sails Authors.
// All rights reserved.
//
// Official git repository and contact information can be found at
// https://github.com/sails/sails and http://www.sailsxu.com/.
//
// Filename: monitor.cc
//
// Author: sailsxu <sailsxu@gmail.com>
// Created: 2014-10-20 17:14:50

#include "src/monitor.h"
#include <string>
#include <vector>
#ifdef __linux__
#include "sails/system/cpu_usage.h"
#endif
#include "sails/system/mem_usage.h"
#include "src/service_register.h"
#include "cpptempl/src/cpptempl.h"

namespace sails {

void ServerStatProcessor::serverstat(sails::net::HttpRequest*,
                sails::net::HttpResponse* response) {
  cpptempl::auto_data dict;
  pid_t pid = getpid();
  dict["PID"] = pid;
  dict["PORT"] = server->ListenPort();
  // cpu info
#ifdef __linux__
  double cpu = 0;
  if (sails::system::GetProcessCpuUsage(pid, 100, &cpu)) {
    dict["CPU"] = cpu;
  }
#endif

  // memory info
  uint64_t vm_size, mem_size;
  if (sails::system::GetMemoryUsedKiloBytes(pid, &vm_size, &mem_size)) {
    dict["VMSIZE"] = (int64_t)vm_size;
    dict["MEMSIZE"] = (int64_t)mem_size;
  }
  char run_mode[2];
  snprintf(run_mode, sizeof(run_mode), "%d", server->RunMode());
  dict["run_mode"] = run_mode;
  dict["recv_queue_size"] = (int64_t)server->GetRecvDataNum();
  // 网络线程信息
  dict["NetThreadNum"] = (int64_t)server->NetThreadNum();

  for (size_t i = 0; i < server->NetThreadNum(); i++) {
    cpptempl::auto_data netthread_dict;
    net::NetThread<sails::ReqMessage>::NetThreadStatus netstatus =
        server->GetNetThreadStatus(i);

    netthread_dict["NetThread_NO"] = i;
    netthread_dict["NetThread_status"] = netstatus.status;
    netthread_dict["NetThread_connector_num"] = netstatus.connector_num;
    netthread_dict["NetThread_accept_times"] = (int64_t)netstatus.accept_times;
    netthread_dict["NetThread_reject_times"] = (int64_t)netstatus.reject_times;
    netthread_dict["NetThread_send_queue_capacity"] =
        (int64_t)netstatus.send_queue_capacity;
    netthread_dict["NetThread_send_queue_size"] =
        (int64_t)netstatus.send_queue_size;
    dict["net_threads"].push_back(netthread_dict);
  }

  // 处理线程信息
  dict["HandleThreadNum"] = (int64_t)server->HandleThreadNum();
  for (size_t i = 0; i < server->HandleThreadNum(); i++) {
    cpptempl::auto_data handlethread_dict;

    net::HandleThread<sails::ReqMessage>::HandleThreadStatus handlestatus =
        server->GetHandleThreadStatus(i);

    handlethread_dict["HandleThread_NO"] = i;
    handlethread_dict["HandleThread_status"] = handlestatus.status;
    handlethread_dict["HandleThread_handle_times"] =
        (int64_t)handlestatus.handle_times;
    if (server->RunMode() == 2) {
      handlethread_dict["HandleThread_handle_queue_capacity"] =
          (int64_t)handlestatus.handle_queue_capacity;
      handlethread_dict["HandleThread_handle_queue_size"] =
          (int64_t)handlestatus.handle_queue_size;
    }
    dict["handle_threads"].push_back(handlethread_dict);
  }

  // service
  std::vector<ServiceRegister::ServiceStat> services =
      ServiceRegister::instance()->GetAllServiceStat();
  dict["serivcesNum"] = services.size();
  for (size_t i = 0; i < services.size(); ++i) {
    cpptempl::auto_data service_dict;
    service_dict["serviceName"] = services[i].name;
    service_dict["callTimes"] = (int64_t)services[i].call_times;
    service_dict["failedTimes"] = (int64_t)services[i].failed_times;
    service_dict["successTimes"] = (int64_t)services[i].success_times;
    for (int index = 0; index < 11; index++) {
      char time_name[5] = {"\0"};
      snprintf(time_name, sizeof(time_name), "L%d", index);
      service_dict[std::string(time_name)] = services[i].spendTime[index];
    }
    dict["services"].push_back(service_dict);
  }

  FILE* file = fopen("../static/stat.html", "r");
  if (file == NULL) {
    printf("can't open file\n");
  }
  static std::string fileconent = "";
  static time_t lastReloadTime = time(NULL);
  bool reloadFile = true;
  if (fileconent.length() > 0) {
    // 已经有内容了
    time_t now = time(NULL);
    if (now - lastReloadTime < 60) {  // 一分钟重新加载一次
      reloadFile = false;
    }
  }
  if (reloadFile) {
    lastReloadTime = time(NULL);
    char buf[5000] = {'\0'};
    int readNum = fread(buf, 1, 5000, file);
    fileconent = std::string(buf, readNum);
  }
  std::string body = cpptempl::parse(fileconent, dict);
  response->SetBody(body.c_str(), body.size());
}

void ServerStatProcessor::index(sails::net::HttpRequest*,
           sails::net::HttpResponse* response) {
  response->SetBody("saf index");
}

Monitor::Monitor(sails::Server* server, int port) {
  thread = NULL;
  status = Monitor::STOPING;
  isTerminate = false;

  this->server = server;
  this->port = port;
}

Monitor::~Monitor() {
  if (processor != NULL) {
    delete processor;
    processor = NULL;
  }
  if (thread != NULL) {
    Terminate();
    Join();
  }
  if (http_server != NULL) {
    delete http_server;
    http_server = NULL;
  }
}

void Monitor::Run() {
  isTerminate = false;
  thread = new std::thread(Start, this);
  status = Monitor::RUNING;
}
void Monitor::Terminate() {
  http_server->Stop();
  isTerminate = true;
}
void Monitor::Join() {
  if (thread != NULL) {
    thread->join();
    status = Monitor::STOPING;
    delete thread;
    thread = NULL;
  }
}

void Monitor::Start(Monitor* monitor) {
  monitor->http_server = new sails::net::HttpServer();
  monitor->http_server->Init(monitor->port, 1, 10, 1);
  monitor->http_server->SetStaticResourcePath(std::string("../static/"));
  // 请求处理器与url映射
  monitor->processor = new ServerStatProcessor(monitor->server);
  HTTPBIND(monitor->http_server,
           "/stat", monitor->processor, ServerStatProcessor::serverstat);
  HTTPBIND(monitor->http_server,
           "/", monitor->processor, ServerStatProcessor::index);

  while (!monitor->isTerminate) {
    sleep(1);
  }
}

}  // namespace sails

<|endoftext|>