<commit_before>/* @cpp.file.header */

/*  _________        _____ __________________        _____
 *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
 *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
 *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
 *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
 */

#include <vector>

#include <gridgain/gridgain.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>
#include <boost/timer.hpp>

#include "gridtestcommon.hpp"
#include "gridgain/impl/gridclientpartitionedaffinity.hpp"

/** Global atomic used to calculate statistics. */
TGridAtomicInt gIters;

/** Maximum number of distinct keys. */
const int KEY_COUNT = 1000000;

/** Map of command line arguments */
boost::program_options::variables_map vm;

/** GridGain client interface. */
TGridClientPtr client;

/** Used to stop worker threads. */
TGridAtomicBool gExit;

/** Used to stop only collect status after warmup. */
TGridAtomicBool gWarmupDone;

/** Test types enumerator. */
enum GridClientCacheTestType {
    PUT = 0,
    GET,
    PUT_TX,
    GET_TX,
    NUM_TEST_TYPES
};

/**
 * Threadproc that prints out performance statistics every second.
 *
 */
void StatsPrinterThreadProc() {

	int LastIters = gIters.load(); // Save global iterations count so while
    while (true) {
    	boost::this_thread::sleep(boost::posix_time::seconds(1));

    	int CurIters = gIters.load();
        std::cout << "Operations for last second: " << CurIters - LastIters << std::endl;
        LastIters = CurIters;
    }
}

/**
 * Converts string int test type enum.
 *
 * @param typeName String representation of test type.
 * @param Enum representation of test type.
 */
GridClientCacheTestType testTypeFromString(std::string typeName) {
    if (!strcmp(typeName.c_str(), "PUT"))
        return PUT;
    else if (!strcmp(typeName.c_str(), "PUT_TX"))
        return PUT_TX;
    else if (!strcmp(typeName.c_str(), "GET_TX"))
        return GET_TX;
    else if (!strcmp(typeName.c_str(), "GET"))
        return GET;
    return NUM_TEST_TYPES;
}

/**
 * Returns a random int between 0 and max, thread safe.
 *
 * @param max A maximum value of a random integer.
 * @param seed A seed to use. Modifiable. Needs to be passed each time.
 */
int randomInt(int max, unsigned int* seed) {
    return rand_r(seed) % (max + 1);
}

/**
 * Class representing one thread working with the client.
 */
class TestThread: private boost::noncopyable {
public:
    /**
     * Constructs the test thread.
     *
     * @param iterationCnt How many iterations to perform.
     */
    TestThread(GridClientCacheTestType op) {
        iters = 1;

        seed = time(NULL);

        thread = boost::thread(boost::bind(&TestThread::run, this, op));
    }

    /**
     * Thread proc for running specific type of test.
     *
     * @param opType Type of test to run
     */
    void run(GridClientCacheTestType opType) {
        try {
            TGridClientDataPtr data = client->data(vm["cachename"].as<string>());

            switch (opType) {
                case PUT: { // block of code to avoid "jump to the case label" compilation error
                        TGridClientVariantMap theMap;

                        theMap[randomInt(KEY_COUNT - 1, &seed)] = 42;

                        while (!gExit) {
                            data->putAll(theMap);
                            ++gIters;
                        }
                    }

                    break;

                case GET:
                    while (!gExit && ++iters) {
                        data->get((int16_t) randomInt(KEY_COUNT - 1, &seed));
                        ++gIters;
                    }

                    break;

                case PUT_TX:
                case GET_TX:
                    std::cerr << "Unsupported test operation.\n";

                    break;

                default:
                    std::cerr << "Invalid test operation.\n";

                    break;
            }
        }
        catch (GridClientException& e) {
            std::cerr << "GridClientException: " << e.what() << "\n";
        }
        catch (...) {
            std::cerr << "Unknown exception.\n";
        }
    }

    /** Joins the test thread. */
    void join() {
        thread.join();
    }

    /** Returns number of iterations completed. */
    int getIters() {
        return iters;
    }

private:
    /** Thread implementation. */
    boost::thread thread;

    /** Number of completed iterations. */
    int iters;

    /** A random seed used as a state for thread-safe random functions. */
    unsigned int seed;
};

typedef std::shared_ptr<TestThread> TestThreadPtr;

int main(int argc, const char** argv) {

	gIters = 0;
    gExit = false;
    gWarmupDone = false;

    using namespace std;
    using namespace boost::program_options;

    // initialize random seed
    srand(time(NULL));

    // Declare the supported options.
    options_description desc("Allowed options");
    desc.add_options()
    		("help",	"produce help message")
    		("host",	value<string>()->required(),	"Host to connect to")
    		("port",	value<int>()->required(),	"Port to connect to")
    		("threads",	value<int>()->required(),	"Number of threads")
    		("testtype",	value<string>()->required(),	"Type of operations to run")
    		("cachename",	value<string>()->required(),	"Cache name")
    		("warmupseconds",	value<int>()->required(),	"Seconds to warm up")
    		("runseconds",	value<int>()->required(),	"Seconds to run")
    		("usetransactions",	boost::program_options::value<bool>()->required(),	"Use transactions (bool)");

    try {
    store(parse_command_line(argc, argv, desc), vm);
    notify(vm);
    } catch (exception &e)
    {
    	cerr << "Error parsing arguments: " << e.what() << endl;
    	cerr << desc << endl;
    	return 1;
    }
    if (vm.count("help"))
    {
    	cout << desc << endl;
    	return 0;
    }

    GridClientConfiguration cfg = clientConfig();

    std::vector<GridClientSocketAddress> servers;
    servers.push_back(GridClientSocketAddress(vm["host"].as<string>(), vm["port"].as<int>()));

    cfg.servers(servers);

    GridClientDataConfiguration cacheCfg;

    // Set remote cache name.
    cacheCfg.name(vm["cachename"].as<string>());

    std::shared_ptr<GridClientDataAffinity> ptrAffinity(new GridClientPartitionAffinity());

    // Set client partitioned affinity for this cache.
    cacheCfg.affinity(ptrAffinity);

    std::vector<GridClientDataConfiguration> dataConfigurations;
    dataConfigurations.push_back(cacheCfg);

    cfg.dataConfiguration(dataConfigurations);

    client = GridClientFactory::start(cfg);
    std::vector<TestThreadPtr> workers;

    boost::thread printerThread(StatsPrinterThreadProc);

    int numThreads = vm["threads"].as<int>();

    for (int i = 0; i < numThreads; i++) {
        workers.push_back(TestThreadPtr(new TestThread(testTypeFromString(vm["testtype"].as<string>()))));
    }

    // let it warm up for requested amount of time and start gathering stats
    boost::this_thread::sleep(boost::posix_time::seconds(vm["warmupseconds"].as<int>()));
    gWarmupDone = true;

    int ItersBefore = gIters.load(); // Save Iterations before final benchmark

    // Let tests run for requested amount of time and then signal the exit
    boost::this_thread::sleep(boost::posix_time::seconds(vm["runseconds"].as<int>()));
    gExit = true;

    int ItersAfter = gIters.load(); // Save iterations after final benchmark

    //join all threads
    for (std::vector<TestThreadPtr>::iterator i = workers.begin(); i != workers.end(); i++) {
        (*i)->join();
    }

    workers.clear();
    client.reset();

    GridClientFactory::stopAll();

    cout << "Average operations/s :" << (ItersAfter - ItersBefore) / vm["runseconds"].as<int>() << endl;

    return EXIT_SUCCESS;
}
<commit_msg>gg-7432 Fix coding conventions<commit_after>/* @cpp.file.header */

/*  _________        _____ __________________        _____
 *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
 *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
 *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
 *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
 */

#include <vector>

#include <gridgain/gridgain.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>
#include <boost/timer.hpp>

#include "gridtestcommon.hpp"
#include "gridgain/impl/gridclientpartitionedaffinity.hpp"

/** Global atomic used to calculate statistics. */
TGridAtomicInt gIters;

/** Maximum number of distinct keys. */
const int KEY_COUNT = 1000000;

/** Map of command line arguments */
boost::program_options::variables_map vm;

/** GridGain client interface. */
TGridClientPtr client;

/** Used to stop worker threads. */
TGridAtomicBool gExit;

/** Used to stop only collect status after warmup. */
TGridAtomicBool gWarmupDone;

/** Test types enumerator. */
enum GridClientCacheTestType {
    PUT = 0,
    GET,
    PUT_TX,
    GET_TX,
    NUM_TEST_TYPES
};

/**
 * Threadproc that prints out performance statistics every second.
 *
 */
void StatsPrinterThreadProc() {

	int LastIters = gIters.load(); // Save global iterations count so while
    while (true) {
    	boost::this_thread::sleep(boost::posix_time::seconds(1));

    	int CurIters = gIters.load();
        std::cout << "Operations for last second: " << CurIters - LastIters << std::endl;
        LastIters = CurIters;
    }
}

/**
 * Converts string int test type enum.
 *
 * @param typeName String representation of test type.
 * @param Enum representation of test type.
 */
GridClientCacheTestType testTypeFromString(std::string typeName) {
    if (!strcmp(typeName.c_str(), "PUT"))
        return PUT;
    else if (!strcmp(typeName.c_str(), "PUT_TX"))
        return PUT_TX;
    else if (!strcmp(typeName.c_str(), "GET_TX"))
        return GET_TX;
    else if (!strcmp(typeName.c_str(), "GET"))
        return GET;
    return NUM_TEST_TYPES;
}

/**
 * Returns a random int between 0 and max, thread safe.
 *
 * @param max A maximum value of a random integer.
 * @param seed A seed to use. Modifiable. Needs to be passed each time.
 */
int randomInt(int max, unsigned int* seed) {
    return rand_r(seed) % (max + 1);
}

/**
 * Class representing one thread working with the client.
 */
class TestThread: private boost::noncopyable {
public:
    /**
     * Constructs the test thread.
     *
     * @param iterationCnt How many iterations to perform.
     */
    TestThread(GridClientCacheTestType op) {
        iters = 1;

        seed = time(NULL);

        thread = boost::thread(boost::bind(&TestThread::run, this, op));
    }

    /**
     * Thread proc for running specific type of test.
     *
     * @param opType Type of test to run
     */
    void run(GridClientCacheTestType opType) {
        try {
            TGridClientDataPtr data = client->data(vm["cachename"].as<string>());

            switch (opType) {
                case PUT: { // block of code to avoid "jump to the case label" compilation error
                        TGridClientVariantMap theMap;

                        theMap[randomInt(KEY_COUNT - 1, &seed)] = 42;

                        while (!gExit) {
                            data->putAll(theMap);
                            ++gIters;
                        }
                    }

                    break;

                case GET:
                    while (!gExit && ++iters) {
                        data->get((int16_t) randomInt(KEY_COUNT - 1, &seed));
                        ++gIters;
                    }

                    break;

                case PUT_TX:
                case GET_TX:
                    std::cerr << "Unsupported test operation.\n";

                    break;

                default:
                    std::cerr << "Invalid test operation.\n";

                    break;
            }
        }
        catch (GridClientException& e) {
            std::cerr << "GridClientException: " << e.what() << "\n";
        }
        catch (...) {
            std::cerr << "Unknown exception.\n";
        }
    }

    /** Joins the test thread. */
    void join() {
        thread.join();
    }

    /** Returns number of iterations completed. */
    int getIters() {
        return iters;
    }

private:
    /** Thread implementation. */
    boost::thread thread;

    /** Number of completed iterations. */
    int iters;

    /** A random seed used as a state for thread-safe random functions. */
    unsigned int seed;
};

typedef std::shared_ptr<TestThread> TestThreadPtr;

int main(int argc, const char** argv) {

	gIters = 0;
    gExit = false;
    gWarmupDone = false;

    using namespace std;
    using namespace boost::program_options;

    // initialize random seed
    srand(time(NULL));

    // Declare the supported options.
    options_description desc("Allowed options");
    desc.add_options()
    		("help",	"produce help message")
    		("host",	value<string>()->required(),	"Host to connect to")
    		("port",	value<int>()->required(),	"Port to connect to")
    		("threads",	value<int>()->required(),	"Number of threads")
    		("testtype",	value<string>()->required(),	"Type of operations to run")
    		("cachename",	value<string>()->required(),	"Cache name")
    		("warmupseconds",	value<int>()->required(),	"Seconds to warm up")
    		("runseconds",	value<int>()->required(),	"Seconds to run")
    		("usetransactions",	boost::program_options::value<bool>()->required(),	"Use transactions (bool)");

    try {
    store(parse_command_line(argc, argv, desc), vm);
    notify(vm);
    } catch (exception &e)
    {
    	cerr << "Error parsing arguments: " << e.what() << endl;
    	cerr << desc << endl;
    	return 1;
    }
    if (vm.count("help"))
    {
    	cout << desc << endl;
    	return 0;
    }

    GridClientConfiguration cfg = clientConfig();

    std::vector<GridClientSocketAddress> servers;
    servers.push_back(GridClientSocketAddress(vm["host"].as<string>(), vm["port"].as<int>()));

    cfg.servers(servers);

    GridClientDataConfiguration cacheCfg;

    // Set remote cache name.
    cacheCfg.name(vm["cachename"].as<string>());

    std::shared_ptr<GridClientDataAffinity> ptrAffinity(new GridClientPartitionAffinity());

    // Set client partitioned affinity for this cache.
    cacheCfg.affinity(ptrAffinity);

    std::vector<GridClientDataConfiguration> dataConfigurations;
    dataConfigurations.push_back(cacheCfg);

    cfg.dataConfiguration(dataConfigurations);

    client = GridClientFactory::start(cfg);
    std::vector<TestThreadPtr> workers;

    boost::thread printerThread(StatsPrinterThreadProc);

    int numThreads = vm["threads"].as<int>();

    for (int i = 0; i < numThreads; i++) {
        workers.push_back(TestThreadPtr(new TestThread(testTypeFromString(vm["testtype"].as<string>()))));
    }

    // let it warm up for requested amount of time and start gathering stats
    boost::this_thread::sleep(boost::posix_time::seconds(vm["warmupseconds"].as<int>()));
    gWarmupDone = true;

    int itersBeforeTest = gIters.load(); // Save Iterations before final benchmark

    // Let tests run for requested amount of time and then signal the exit
    boost::this_thread::sleep(boost::posix_time::seconds(vm["runseconds"].as<int>()));
    gExit = true;

    int itersAfterTest = gIters.load(); // Save iterations after final benchmark

    //join all threads
    for (std::vector<TestThreadPtr>::iterator i = workers.begin(); i != workers.end(); i++) {
        (*i)->join();
    }

    workers.clear();
    client.reset();

    GridClientFactory::stopAll();

    cout << "Average operations/s :" << (itersAfterTest - itersBeforeTest) / vm["runseconds"].as<int>() << endl;

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 *  Copyright 2017 Oluwatobi Adeyinka
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

#include "top_podcasts_panel.h"
#include "discover_item_panel.h"

TopPodcastsPanel::TopPodcastsPanel(wxWindow * parent, DiscoveryPanelManager & panelManager) : wxScrolledWindow(parent) {
    mainSizer = new wxBoxSizer(wxVERTICAL);
    topPodcasts = panelManager.getTopPodcasts();

    setupSectionHeader();
    setupFirstRow();
    setupSecondRow();

    this->SetBackgroundColour(wxColour(wxT("#ffffff")));
    this->SetSizer(mainSizer);

    // this part makes the scrollbars show up
    this->FitInside(); // ask the sizer about the needed size
    this->SetScrollRate(5, 5);

}

void TopPodcastsPanel::setupSectionHeader() {
    auto * titlePanel = new wxPanel(this);
    auto * titlePanelSizer = new wxBoxSizer(wxHORIZONTAL);
    auto * sectionTitle = new wxStaticText(titlePanel, wxID_ANY, wxT("Top Podcasts"));

    wxFont sectionTitleFont = sectionTitle->GetFont();
    sectionTitleFont.SetPointSize(16);
    sectionTitle->SetFont(sectionTitleFont);

    titlePanel->SetBackgroundColour(wxColour(wxT("#ffffff")));
    titlePanelSizer->Add(sectionTitle, 1, wxALL, 5);
    titlePanel->SetSizer(titlePanelSizer);

    mainSizer->Add(titlePanel, 1, wxEXPAND, 5);
}

void TopPodcastsPanel::setupFirstRow() {
    auto * rowPanel = new wxPanel(this);
    auto * rowPanelSizer = new wxBoxSizer(wxHORIZONTAL);

    for (std::vector<int>::size_type i = 0; i != topPodcasts.size()/2; i++) {
        Podcast podcast = topPodcasts[i];
        auto * itemPanel = new DiscoverItemPanel(rowPanel, podcast);
        rowPanelSizer->Add(itemPanel, wxID_ANY, wxRIGHT | wxEXPAND, 10);
    }

    rowPanel->SetSizer(rowPanelSizer);
    mainSizer->Add(rowPanel, 1, wxALL | wxEXPAND, 5);
}

void TopPodcastsPanel::setupSecondRow() {
    auto * rowPanel = new wxPanel(this);
    auto * rowPanelSizer = new wxBoxSizer(wxHORIZONTAL);

    for (std::vector<int>::size_type i = 24; i != topPodcasts.size(); i++) {
        Podcast podcast = topPodcasts[i];
        auto * itemPanel = new DiscoverItemPanel(rowPanel, podcast);
        rowPanelSizer->Add(itemPanel, wxID_ANY, wxRIGHT | wxEXPAND, 10);
    }

    rowPanel->SetSizer(rowPanelSizer);
    mainSizer->Add(rowPanel, 1, wxALL | wxEXPAND, 5);
}
<commit_msg>dev progress: discovery panel<commit_after>/*
 *  Copyright 2017 Oluwatobi Adeyinka
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

#include "top_podcasts_panel.h"
#include "discover_item_panel.h"

TopPodcastsPanel::TopPodcastsPanel(wxWindow * parent, DiscoveryPanelManager & panelManager) : wxScrolledWindow(parent) {
    mainSizer = new wxBoxSizer(wxVERTICAL);
    topPodcasts = panelManager.getTopPodcasts();

    setupSectionHeader();
    setupFirstRow();
    setupSecondRow();

    this->SetBackgroundColour(wxColour(wxT("#ffffff")));
    this->SetSizer(mainSizer);

    // this part makes the scrollbars show up
    this->FitInside(); // ask the sizer about the needed size
    this->SetScrollRate(5, 5);

}

void TopPodcastsPanel::setupSectionHeader() {
    auto * titlePanel = new wxPanel(this);
    titlePanel->SetBackgroundColour(wxColour(wxT("#ffffff")));

    auto * sectionTitle = new wxStaticText(titlePanel, wxID_ANY, wxT("Top Podcasts"));
    wxFont sectionTitleFont = sectionTitle->GetFont();
    sectionTitleFont.SetPointSize(16);
    sectionTitle->SetFont(sectionTitleFont);

    mainSizer->Add(titlePanel, 0, wxLEFT | wxBOTTOM, 5);
}

void TopPodcastsPanel::setupFirstRow() {
    auto * rowPanel = new wxPanel(this);
    auto * rowPanelSizer = new wxBoxSizer(wxHORIZONTAL);

    for (std::vector<int>::size_type i = 0; i != topPodcasts.size()/2; i++) {
        Podcast podcast = topPodcasts[i];
        auto * itemPanel = new DiscoverItemPanel(rowPanel, podcast);
        rowPanelSizer->Add(itemPanel, wxID_ANY, wxRIGHT | wxEXPAND, 10);
    }

    rowPanel->SetSizer(rowPanelSizer);
    mainSizer->Add(rowPanel, 1, wxALL | wxEXPAND, 5);
}

void TopPodcastsPanel::setupSecondRow() {
    auto * rowPanel = new wxPanel(this);
    auto * rowPanelSizer = new wxBoxSizer(wxHORIZONTAL);

    for (std::vector<int>::size_type i = 24; i != topPodcasts.size(); i++) {
        Podcast podcast = topPodcasts[i];
        auto * itemPanel = new DiscoverItemPanel(rowPanel, podcast);
        rowPanelSizer->Add(itemPanel, wxID_ANY, wxRIGHT | wxEXPAND, 10);
    }

    rowPanel->SetSizer(rowPanelSizer);
    mainSizer->Add(rowPanel, 1, wxALL | wxEXPAND, 5);
}
<|endoftext|>


<commit_before>/**
 *  A command-line calculator that uses a sequental grammar instead of left-recursion.
 */

#include <iostream>
#include <unordered_map>
#include <cmath>
#include <numeric>

#include <lars/parser/generator.h>

int main() {
  using namespace std;
  using VariableMap = unordered_map<string, float>;

  lars::ParserGenerator<float, VariableMap &> calculator;

  auto &g = calculator;
  g.setSeparator(g["Whitespace"] << "[\t ]");

  g["Expression"] << "Set | Sum";

  g["Set"] << "Name '=' Sum" >> [](auto e, auto &v){ return v[e[0].string()] = e[1].evaluate(v); };

  g["Sum"] << "Product Summand*" >> [=](auto e, auto &v){
    return std::accumulate(e.begin(), e.end(), 0, [&](auto a, auto b){ return a+b.evaluate(v); });
  };

  g["Product"] << "Power Term*" >> [](auto e, auto &v){
    return std::accumulate(e.begin(), e.end(), 1, [&](auto a, auto b){ return a*b.evaluate(v); });
  };

  g["Power"] << "Atomic ('^' Power) | Atomic" >> [](auto e, auto &v){
    return e.size() == 2 ? pow(e[0].evaluate(v), e[1].evaluate(v)) : e[0].evaluate(v);
  };

  g["Atomic"    ] << "Number | Brackets | Variable";

  shared_ptr<lars::peg::Rule> sumOp = g["SumOp"] << "'+'", subOp = g["SubOp"] << "'-'";
  g["Summand"] << "(SumOp | SubOp) Product" >> [=](auto e, auto &v){
    return e[0].rule() == subOp ? -e[1].evaluate(v) : e[1].evaluate(v);
  };

  shared_ptr<lars::peg::Rule> mulOp = g["MulOp"] << "'*'", divOp = g["DivOp"] << "'/'";
  g["Term"] << "(MulOp | DivOp) Power" >> [=](auto e, auto &v){
    return e[0].rule() == divOp ? 1/e[1].evaluate(v) : e[1].evaluate(v);
  };

  g["Brackets"  ] << "'(' Sum ')'";
  g["Variable"  ] << "Name" >> [](auto e, auto &v){ return v[e[0].string()]; };
  g["Name"      ] << "[a-zA-Z] [a-zA-Z0-9]*";

  // We can re-use previously defined programs as rules
  g.setProgramRule("Number", lars::peg::createFloatProgram());

  g.setStart(g["Expression"]);

  cout << "Enter an expression to be evaluated.\n";

  VariableMap variables;

  while (true) {
    string str;
    cout << "> ";
    getline(cin,str);
    if(str == "q" || str == "quit"){ break; }
    try {
      auto result = calculator.run(str, variables);
      cout << str << " = " << result << endl;
    } catch (lars::SyntaxError error) {
      auto syntax = error.syntax;
      cout << "  ";
      cout << string(syntax->begin, ' ');
      cout << string(syntax->length(), '~');
      cout << "^\n";
      cout << "  " << "Syntax error while parsing " << syntax->rule->name << endl;
    }
  }

  return 0;
}

<commit_msg>simplify sequental example (#29)<commit_after>/**
 *  A command-line calculator that uses a sequental grammar instead of left-recursion.
 */

#include <iostream>
#include <unordered_map>
#include <cmath>
#include <numeric>

#include <lars/parser/generator.h>

int main() {
  using namespace std;
  using VariableMap = unordered_map<string, float>;

  lars::ParserGenerator<float, VariableMap &> calculator;

  auto &g = calculator;
  g.setSeparator(g["Whitespace"] << "[\t ]");

  g["Expression"] << "Assign | Sum";

  g["Assign"] << "Name '=' Sum" >> [](auto e, auto &v){ return v[e[0].string()] = e[1].evaluate(v); };

  g["Sum"] << "Product Summand*" >> [=](auto e, auto &v){
    return std::accumulate(e.begin(), e.end(), 0, [&](auto a, auto b){ return a+b.evaluate(v); });
  };
  g["PositiveSummand"] << "'+' Product" >> [=](auto e, auto &v){ return e[0].evaluate(v); };
  g["NegativeSummand"] << "'-' Product" >> [=](auto e, auto &v){ return -e[0].evaluate(v); };
  g["Summand"] << "PositiveSummand | NegativeSummand";

  g["Product"] << "Power Term*" >> [](auto e, auto &v){
    return std::accumulate(e.begin(), e.end(), 1, [&](auto a, auto b){ return a*b.evaluate(v); });
  };
  g["NormalTerm"] << "'*' Power" >> [=](auto e, auto &v){ return e[0].evaluate(v); };
  g["InverseTerm"] << "'/' Power" >> [=](auto e, auto &v){ return 1/e[0].evaluate(v); };
  g["Term"] << "NormalTerm | InverseTerm";

  g["Power"] << "Atomic ('^' Power) | Atomic" >> [](auto e, auto &v){
    return e.size() == 2 ? pow(e[0].evaluate(v), e[1].evaluate(v)) : e[0].evaluate(v);
  };

  g["Atomic"    ] << "Number | Brackets | Variable";

  g["Brackets"  ] << "'(' Sum ')'";
  g["Variable"  ] << "Name" >> [](auto e, auto &v){ return v[e[0].string()]; };
  g["Name"      ] << "[a-zA-Z] [a-zA-Z0-9]*";

  // We can also use other programs as rules
  g.setProgramRule("Number", lars::peg::createFloatProgram());

  g.setStart(g["Expression"]);

  cout << "Enter an expression to be evaluated.\n";

  VariableMap variables;

  while (true) {
    string str;
    cout << "> ";
    getline(cin,str);
    if(str == "q" || str == "quit"){ break; }
    try {
      auto result = calculator.run(str, variables);
      cout << str << " = " << result << endl;
    } catch (lars::SyntaxError error) {
      auto syntax = error.syntax;
      cout << "  ";
      cout << string(syntax->begin, ' ');
      cout << string(syntax->length(), '~');
      cout << "^\n";
      cout << "  " << "Syntax error while parsing " << syntax->rule->name << endl;
    }
  }

  return 0;
}

<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__

#include "opencv2/opencv_modules.hpp"
#include "cvconfig.h"

#include "opencv2/core/utility.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/core/cuda.hpp"
#include "opencv2/core/opengl.hpp"
#include "opencv2/core/va_intel.hpp"

#include "opencv2/core/private.hpp"
#include "opencv2/core/private.cuda.hpp"
#ifdef HAVE_OPENCL
#include "opencv2/core/ocl.hpp"
#endif

#include <assert.h>
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <float.h>
#include <cstring>
#include <cassert>

#define USE_SSE2  (cv::checkHardwareSupport(CV_CPU_SSE2))
#define USE_SSE4_2  (cv::checkHardwareSupport(CV_CPU_SSE4_2))
#define USE_AVX  (cv::checkHardwareSupport(CV_CPU_AVX))
#define USE_AVX2  (cv::checkHardwareSupport(CV_CPU_AVX2))

#include "opencv2/core/hal/hal.hpp"
#include "opencv2/core/hal/intrin.hpp"
#include "opencv2/core/sse_utils.hpp"
#include "opencv2/core/neon_utils.hpp"
#include "opencv2/core/vsx_utils.hpp"
#include "hal_replacement.hpp"

#define GET_OPTIMIZED(func) (func)

namespace cv
{

// -128.f ... 255.f
extern const float g_8x32fTab[];
#define CV_8TO32F(x)  cv::g_8x32fTab[(x)+128]

extern const ushort g_8x16uSqrTab[];
#define CV_SQR_8U(x)  cv::g_8x16uSqrTab[(x)+255]

extern const uchar g_Saturate8u[];
#define CV_FAST_CAST_8U(t)   (assert(-256 <= (t) && (t) <= 512), cv::g_Saturate8u[(t)+256])
#define CV_MIN_8U(a,b)       ((a) - CV_FAST_CAST_8U((a) - (b)))
#define CV_MAX_8U(a,b)       ((a) + CV_FAST_CAST_8U((b) - (a)))

template<typename T1, typename T2=T1, typename T3=T1> struct OpAdd
{
    typedef T1 type1;
    typedef T2 type2;
    typedef T3 rtype;
    T3 operator ()(const T1 a, const T2 b) const { return saturate_cast<T3>(a + b); }
};

template<typename T1, typename T2=T1, typename T3=T1> struct OpSub
{
    typedef T1 type1;
    typedef T2 type2;
    typedef T3 rtype;
    T3 operator ()(const T1 a, const T2 b) const { return saturate_cast<T3>(a - b); }
};

template<typename T1, typename T2=T1, typename T3=T1> struct OpRSub
{
    typedef T1 type1;
    typedef T2 type2;
    typedef T3 rtype;
    T3 operator ()(const T1 a, const T2 b) const { return saturate_cast<T3>(b - a); }
};

template<typename T> struct OpMin
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator ()(const T a, const T b) const { return std::min(a, b); }
};

template<typename T> struct OpMax
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator ()(const T a, const T b) const { return std::max(a, b); }
};

template<typename T> struct OpAbsDiff
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()(T a, T b) const { return a > b ? a - b : b - a; }
};

// specializations to prevent "-0" results
template<> struct OpAbsDiff<float>
{
    typedef float type1;
    typedef float type2;
    typedef float rtype;
    float operator()(float a, float b) const { return std::abs(a - b); }
};
template<> struct OpAbsDiff<double>
{
    typedef double type1;
    typedef double type2;
    typedef double rtype;
    double operator()(double a, double b) const { return std::abs(a - b); }
};

template<typename T> struct OpAnd
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()( T a, T b ) const { return a & b; }
};

template<typename T> struct OpOr
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()( T a, T b ) const { return a | b; }
};

template<typename T> struct OpXor
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()( T a, T b ) const { return a ^ b; }
};

template<typename T> struct OpNot
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()( T a, T ) const { return ~a; }
};

template<> inline uchar OpAdd<uchar>::operator ()(uchar a, uchar b) const
{ return CV_FAST_CAST_8U(a + b); }

template<> inline uchar OpSub<uchar>::operator ()(uchar a, uchar b) const
{ return CV_FAST_CAST_8U(a - b); }

template<> inline short OpAbsDiff<short>::operator ()(short a, short b) const
{ return saturate_cast<short>(std::abs(a - b)); }

template<> inline schar OpAbsDiff<schar>::operator ()(schar a, schar b) const
{ return saturate_cast<schar>(std::abs(a - b)); }

template<> inline uchar OpMin<uchar>::operator ()(uchar a, uchar b) const { return CV_MIN_8U(a, b); }

template<> inline uchar OpMax<uchar>::operator ()(uchar a, uchar b) const { return CV_MAX_8U(a, b); }

typedef void (*UnaryFunc)(const uchar* src1, size_t step1,
                       uchar* dst, size_t step, Size sz,
                       void*);

typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
                       const uchar* src2, size_t step2,
                       uchar* dst, size_t step, Size sz,
                       void*);

typedef void (*BinaryFuncC)(const uchar* src1, size_t step1,
                       const uchar* src2, size_t step2,
                       uchar* dst, size_t step, int width, int height,
                       void*);

BinaryFunc getConvertFunc(int sdepth, int ddepth);
BinaryFunc getConvertScaleFunc(int sdepth, int ddepth);
BinaryFunc getCopyMaskFunc(size_t esz);

/* default memory block for sparse array elements */
#define  CV_SPARSE_MAT_BLOCK     (1<<12)

/* initial hash table size */
#define  CV_SPARSE_HASH_SIZE0    (1<<10)

/* maximal average node_count/hash_size ratio beyond which hash table is resized */
#define  CV_SPARSE_HASH_RATIO    3

// There is some mess in code with vectors representation.
// Both vector-column / vector-rows are used with dims=2 (as Mat2D always).
// Reshape matrices if necessary (in case of vectors) and returns size with scaled width.
Size getContinuousSize2D(Mat& m1, int widthScale=1);
Size getContinuousSize2D(Mat& m1, Mat& m2, int widthScale=1);
Size getContinuousSize2D(Mat& m1, Mat& m2, Mat& m3, int widthScale=1);

void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool autoSteps=false );
void finalizeHdr(Mat& m);
int updateContinuityFlag(int flags, int dims, const int* size, const size_t* step);

struct NoVec
{
    size_t operator()(const void*, const void*, void*, size_t) const { return 0; }
};

#define CV_SPLIT_MERGE_MAX_BLOCK_SIZE(cn) ((INT_MAX/4)/(cn)) // HAL implementation accepts 'int' len, so INT_MAX doesn't work here

enum { BLOCK_SIZE = 1024 };

#if defined HAVE_IPP && (IPP_VERSION_X100 >= 700)
#define ARITHM_USE_IPP 1
#else
#define ARITHM_USE_IPP 0
#endif

inline bool checkScalar(const Mat& sc, int atype, _InputArray::KindFlag sckind, _InputArray::KindFlag akind)
{
    if( sc.dims > 2 || !sc.isContinuous() )
        return false;
    Size sz = sc.size();
    if(sz.width != 1 && sz.height != 1)
        return false;
    int cn = CV_MAT_CN(atype);
    if( akind == _InputArray::MATX && sckind != _InputArray::MATX )
        return false;
    return sz == Size(1, 1) || sz == Size(1, cn) || sz == Size(cn, 1) ||
           (sz == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
}

inline bool checkScalar(InputArray sc, int atype, _InputArray::KindFlag sckind, _InputArray::KindFlag akind)
{
    if( sc.dims() > 2 || !sc.isContinuous() )
        return false;
    Size sz = sc.size();
    if(sz.width != 1 && sz.height != 1)
        return false;
    int cn = CV_MAT_CN(atype);
    if( akind == _InputArray::MATX && sckind != _InputArray::MATX )
        return false;
    return sz == Size(1, 1) || sz == Size(1, cn) || sz == Size(cn, 1) ||
           (sz == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
}

void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t blocksize );

#ifdef CV_COLLECT_IMPL_DATA
struct ImplCollector
{
    ImplCollector()
    {
        useCollection   = false;
        implFlags       = 0;
    }
    bool useCollection; // enable/disable impl data collection

    int implFlags;
    std::vector<int>    implCode;
    std::vector<String> implFun;

    cv::Mutex mutex;
};
#endif

struct CoreTLSData
{
    CoreTLSData() :
//#ifdef HAVE_OPENCL
        device(0), useOpenCL(-1),
//#endif
        useIPP(-1),
        useIPP_NE(-1)
#ifdef HAVE_OPENVX
        ,useOpenVX(-1)
#endif
    {}

    RNG rng;
//#ifdef HAVE_OPENCL
    int device; // device index of an array of devices in a context, see also Device::getDefault
    ocl::Queue oclQueue; // the queue used for running a kernel, see also getQueue, Kernel::run
    int useOpenCL; // 1 - use, 0 - do not use, -1 - auto/not initialized
//#endif
    int useIPP;    // 1 - use, 0 - do not use, -1 - auto/not initialized
    int useIPP_NE; // 1 - use, 0 - do not use, -1 - auto/not initialized
#ifdef HAVE_OPENVX
    int useOpenVX; // 1 - use, 0 - do not use, -1 - auto/not initialized
#endif
};

CoreTLSData& getCoreTlsData();

#if defined(BUILD_SHARED_LIBS)
#if defined _WIN32 || defined WINCE
#define CL_RUNTIME_EXPORT __declspec(dllexport)
#elif defined __GNUC__ && __GNUC__ >= 4
#define CL_RUNTIME_EXPORT __attribute__ ((visibility ("default")))
#else
#define CL_RUNTIME_EXPORT
#endif
#else
#define CL_RUNTIME_EXPORT
#endif

extern CV_EXPORTS
bool __termination;  // skip some cleanups, because process is terminating
                     // (for example, if ExitProcess() was already called)

cv::Mutex& getInitializationMutex();

// TODO Memory barriers?
#define CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, RET_VALUE) \
    static TYPE* volatile instance = NULL; \
    if (instance == NULL) \
    { \
        cv::AutoLock lock(cv::getInitializationMutex()); \
        if (instance == NULL) \
            instance = INITIALIZER; \
    } \
    return RET_VALUE;

#define CV_SINGLETON_LAZY_INIT(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, instance)
#define CV_SINGLETON_LAZY_INIT_REF(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, *instance)

int cv_snprintf(char* buf, int len, const char* fmt, ...);
int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args);
}

#endif /*_CXCORE_INTERNAL_H_*/
<commit_msg>use C++11 static variables as memory barrier<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__

#include "opencv2/opencv_modules.hpp"
#include "cvconfig.h"

#include "opencv2/core/utility.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/core/cuda.hpp"
#include "opencv2/core/opengl.hpp"
#include "opencv2/core/va_intel.hpp"

#include "opencv2/core/private.hpp"
#include "opencv2/core/private.cuda.hpp"
#ifdef HAVE_OPENCL
#include "opencv2/core/ocl.hpp"
#endif

#include <assert.h>
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <float.h>
#include <cstring>
#include <cassert>

#define USE_SSE2  (cv::checkHardwareSupport(CV_CPU_SSE2))
#define USE_SSE4_2  (cv::checkHardwareSupport(CV_CPU_SSE4_2))
#define USE_AVX  (cv::checkHardwareSupport(CV_CPU_AVX))
#define USE_AVX2  (cv::checkHardwareSupport(CV_CPU_AVX2))

#include "opencv2/core/hal/hal.hpp"
#include "opencv2/core/hal/intrin.hpp"
#include "opencv2/core/sse_utils.hpp"
#include "opencv2/core/neon_utils.hpp"
#include "opencv2/core/vsx_utils.hpp"
#include "hal_replacement.hpp"

#define GET_OPTIMIZED(func) (func)

namespace cv
{

// -128.f ... 255.f
extern const float g_8x32fTab[];
#define CV_8TO32F(x)  cv::g_8x32fTab[(x)+128]

extern const ushort g_8x16uSqrTab[];
#define CV_SQR_8U(x)  cv::g_8x16uSqrTab[(x)+255]

extern const uchar g_Saturate8u[];
#define CV_FAST_CAST_8U(t)   (assert(-256 <= (t) && (t) <= 512), cv::g_Saturate8u[(t)+256])
#define CV_MIN_8U(a,b)       ((a) - CV_FAST_CAST_8U((a) - (b)))
#define CV_MAX_8U(a,b)       ((a) + CV_FAST_CAST_8U((b) - (a)))

template<typename T1, typename T2=T1, typename T3=T1> struct OpAdd
{
    typedef T1 type1;
    typedef T2 type2;
    typedef T3 rtype;
    T3 operator ()(const T1 a, const T2 b) const { return saturate_cast<T3>(a + b); }
};

template<typename T1, typename T2=T1, typename T3=T1> struct OpSub
{
    typedef T1 type1;
    typedef T2 type2;
    typedef T3 rtype;
    T3 operator ()(const T1 a, const T2 b) const { return saturate_cast<T3>(a - b); }
};

template<typename T1, typename T2=T1, typename T3=T1> struct OpRSub
{
    typedef T1 type1;
    typedef T2 type2;
    typedef T3 rtype;
    T3 operator ()(const T1 a, const T2 b) const { return saturate_cast<T3>(b - a); }
};

template<typename T> struct OpMin
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator ()(const T a, const T b) const { return std::min(a, b); }
};

template<typename T> struct OpMax
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator ()(const T a, const T b) const { return std::max(a, b); }
};

template<typename T> struct OpAbsDiff
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()(T a, T b) const { return a > b ? a - b : b - a; }
};

// specializations to prevent "-0" results
template<> struct OpAbsDiff<float>
{
    typedef float type1;
    typedef float type2;
    typedef float rtype;
    float operator()(float a, float b) const { return std::abs(a - b); }
};
template<> struct OpAbsDiff<double>
{
    typedef double type1;
    typedef double type2;
    typedef double rtype;
    double operator()(double a, double b) const { return std::abs(a - b); }
};

template<typename T> struct OpAnd
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()( T a, T b ) const { return a & b; }
};

template<typename T> struct OpOr
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()( T a, T b ) const { return a | b; }
};

template<typename T> struct OpXor
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()( T a, T b ) const { return a ^ b; }
};

template<typename T> struct OpNot
{
    typedef T type1;
    typedef T type2;
    typedef T rtype;
    T operator()( T a, T ) const { return ~a; }
};

template<> inline uchar OpAdd<uchar>::operator ()(uchar a, uchar b) const
{ return CV_FAST_CAST_8U(a + b); }

template<> inline uchar OpSub<uchar>::operator ()(uchar a, uchar b) const
{ return CV_FAST_CAST_8U(a - b); }

template<> inline short OpAbsDiff<short>::operator ()(short a, short b) const
{ return saturate_cast<short>(std::abs(a - b)); }

template<> inline schar OpAbsDiff<schar>::operator ()(schar a, schar b) const
{ return saturate_cast<schar>(std::abs(a - b)); }

template<> inline uchar OpMin<uchar>::operator ()(uchar a, uchar b) const { return CV_MIN_8U(a, b); }

template<> inline uchar OpMax<uchar>::operator ()(uchar a, uchar b) const { return CV_MAX_8U(a, b); }

typedef void (*UnaryFunc)(const uchar* src1, size_t step1,
                       uchar* dst, size_t step, Size sz,
                       void*);

typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
                       const uchar* src2, size_t step2,
                       uchar* dst, size_t step, Size sz,
                       void*);

typedef void (*BinaryFuncC)(const uchar* src1, size_t step1,
                       const uchar* src2, size_t step2,
                       uchar* dst, size_t step, int width, int height,
                       void*);

BinaryFunc getConvertFunc(int sdepth, int ddepth);
BinaryFunc getConvertScaleFunc(int sdepth, int ddepth);
BinaryFunc getCopyMaskFunc(size_t esz);

/* default memory block for sparse array elements */
#define  CV_SPARSE_MAT_BLOCK     (1<<12)

/* initial hash table size */
#define  CV_SPARSE_HASH_SIZE0    (1<<10)

/* maximal average node_count/hash_size ratio beyond which hash table is resized */
#define  CV_SPARSE_HASH_RATIO    3

// There is some mess in code with vectors representation.
// Both vector-column / vector-rows are used with dims=2 (as Mat2D always).
// Reshape matrices if necessary (in case of vectors) and returns size with scaled width.
Size getContinuousSize2D(Mat& m1, int widthScale=1);
Size getContinuousSize2D(Mat& m1, Mat& m2, int widthScale=1);
Size getContinuousSize2D(Mat& m1, Mat& m2, Mat& m3, int widthScale=1);

void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool autoSteps=false );
void finalizeHdr(Mat& m);
int updateContinuityFlag(int flags, int dims, const int* size, const size_t* step);

struct NoVec
{
    size_t operator()(const void*, const void*, void*, size_t) const { return 0; }
};

#define CV_SPLIT_MERGE_MAX_BLOCK_SIZE(cn) ((INT_MAX/4)/(cn)) // HAL implementation accepts 'int' len, so INT_MAX doesn't work here

enum { BLOCK_SIZE = 1024 };

#if defined HAVE_IPP && (IPP_VERSION_X100 >= 700)
#define ARITHM_USE_IPP 1
#else
#define ARITHM_USE_IPP 0
#endif

inline bool checkScalar(const Mat& sc, int atype, _InputArray::KindFlag sckind, _InputArray::KindFlag akind)
{
    if( sc.dims > 2 || !sc.isContinuous() )
        return false;
    Size sz = sc.size();
    if(sz.width != 1 && sz.height != 1)
        return false;
    int cn = CV_MAT_CN(atype);
    if( akind == _InputArray::MATX && sckind != _InputArray::MATX )
        return false;
    return sz == Size(1, 1) || sz == Size(1, cn) || sz == Size(cn, 1) ||
           (sz == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
}

inline bool checkScalar(InputArray sc, int atype, _InputArray::KindFlag sckind, _InputArray::KindFlag akind)
{
    if( sc.dims() > 2 || !sc.isContinuous() )
        return false;
    Size sz = sc.size();
    if(sz.width != 1 && sz.height != 1)
        return false;
    int cn = CV_MAT_CN(atype);
    if( akind == _InputArray::MATX && sckind != _InputArray::MATX )
        return false;
    return sz == Size(1, 1) || sz == Size(1, cn) || sz == Size(cn, 1) ||
           (sz == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
}

void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t blocksize );

#ifdef CV_COLLECT_IMPL_DATA
struct ImplCollector
{
    ImplCollector()
    {
        useCollection   = false;
        implFlags       = 0;
    }
    bool useCollection; // enable/disable impl data collection

    int implFlags;
    std::vector<int>    implCode;
    std::vector<String> implFun;

    cv::Mutex mutex;
};
#endif

struct CoreTLSData
{
    CoreTLSData() :
//#ifdef HAVE_OPENCL
        device(0), useOpenCL(-1),
//#endif
        useIPP(-1),
        useIPP_NE(-1)
#ifdef HAVE_OPENVX
        ,useOpenVX(-1)
#endif
    {}

    RNG rng;
//#ifdef HAVE_OPENCL
    int device; // device index of an array of devices in a context, see also Device::getDefault
    ocl::Queue oclQueue; // the queue used for running a kernel, see also getQueue, Kernel::run
    int useOpenCL; // 1 - use, 0 - do not use, -1 - auto/not initialized
//#endif
    int useIPP;    // 1 - use, 0 - do not use, -1 - auto/not initialized
    int useIPP_NE; // 1 - use, 0 - do not use, -1 - auto/not initialized
#ifdef HAVE_OPENVX
    int useOpenVX; // 1 - use, 0 - do not use, -1 - auto/not initialized
#endif
};

CoreTLSData& getCoreTlsData();

#if defined(BUILD_SHARED_LIBS)
#if defined _WIN32 || defined WINCE
#define CL_RUNTIME_EXPORT __declspec(dllexport)
#elif defined __GNUC__ && __GNUC__ >= 4
#define CL_RUNTIME_EXPORT __attribute__ ((visibility ("default")))
#else
#define CL_RUNTIME_EXPORT
#endif
#else
#define CL_RUNTIME_EXPORT
#endif

extern CV_EXPORTS
bool __termination;  // skip some cleanups, because process is terminating
                     // (for example, if ExitProcess() was already called)

cv::Mutex& getInitializationMutex();

#define CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, RET_VALUE) \
    static TYPE* const instance = INITIALIZER; \
    return RET_VALUE;

#define CV_SINGLETON_LAZY_INIT(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, instance)
#define CV_SINGLETON_LAZY_INIT_REF(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, *instance)

int cv_snprintf(char* buf, int len, const char* fmt, ...);
int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args);
}

#endif /*_CXCORE_INTERNAL_H_*/
<|endoftext|>


<commit_before>
// Locals
#include "dns_server.hpp"
#include <stdlib.h>

// EASTL new/delete
//void* operator new[](size_t size, const char* pName, int flags, unsigned debugFlags, const char* file, int line)
void* operator new[](size_t size, const char*, int, unsigned, const char*, int)
{
  //printf("[new:%lu] %s %d %d from %s:%d\n", size, pName, flags, debugFlags, file, line);
  return malloc(size);
}
//void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName, int flags, unsigned debugFlags, const char* file, int line)
void* operator new[](size_t size, size_t, size_t, const char*, int, unsigned, const char*, int)
{
  //printf("[new:%lu] %s %d %d from %s:%d\n", size, pName, flags, debugFlags, file, line);
  return malloc(size);
}

void* operator new (size_t size)
{
  return malloc(size);
}
void* operator new[] (size_t size)
{
  return malloc(size);
}

// placement new/delete
void* operator new  (size_t, void* p)  { return p; }
void* operator new[](size_t, void* p)  { return p; }

extern "C" void __assert_func(int){};

DNS_server myDnsServer;

int main(){
  std::cout << "*** Service is up - with OS Included! ***" << std::endl;
  std::cout << "Starting DNS prototype\n";

  /// www.google.com ///
  std::vector<net::IP4::addr> mapping1;
  mapping1.push_back( { 213, 155, 151, 187 } );
  mapping1.push_back( { 213, 155, 151, 185 } );
  mapping1.push_back( { 213, 155, 151, 180 } );
  mapping1.push_back( { 213, 155, 151, 183 } );
  mapping1.push_back( { 213, 155, 151, 186 } );
  mapping1.push_back( { 213, 155, 151, 184 } );
  mapping1.push_back( { 213, 155, 151, 181 } );
  mapping1.push_back( { 213, 155, 151, 182 } );

  myDnsServer.addMapping("www.google.com.", mapping1);
  ///               ///

  //class Inet{} inet*;
  net::Inet* inet;
  myDnsServer.start(inet);
  std::cout << "<DNS SERVER> Listening on UDP port 53" << std::endl;

  std::cout << "Service out!" << std::endl;
}
<commit_msg>Linux DNS version<commit_after>
// Locals
#include "dns_server.hpp"
#include <stdlib.h>

// EASTL new/delete
//void* operator new[](size_t size, const char* pName, int flags, unsigned debugFlags, const char* file, int line)
void* operator new[](size_t size, const char*, int, unsigned, const char*, int)
{
  //printf("[new:%lu] %s %d %d from %s:%d\n", size, pName, flags, debugFlags, file, line);
  return malloc(size);
}
//void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName, int flags, unsigned debugFlags, const char* file, int line)
void* operator new[](size_t size, size_t, size_t, const char*, int, unsigned, const char*, int)
{
  //printf("[new:%lu] %s %d %d from %s:%d\n", size, pName, flags, debugFlags, file, line);
  return malloc(size);
}

void* operator new (size_t size)
{
  return malloc(size);
}
void* operator new[] (size_t size)
{
  return malloc(size);
}

// placement new/delete
void* operator new  (size_t, void* p)  { return p; }
void* operator new[](size_t, void* p)  { return p; }

extern "C" void __assert_func(int){};

//DNS_server myDnsServer;

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace net;

int main()
{
  std::cout << "*** Service is up - with OS Included! ***" << std::endl;
  std::cout << "Starting DNS prototype\n";

  /// www.google.com ///
  std::vector<IP4::addr> mapping1;
  mapping1.push_back( { 213, 155, 151, 187 } );
  mapping1.push_back( { 213, 155, 151, 185 } );
  mapping1.push_back( { 213, 155, 151, 180 } );
  mapping1.push_back( { 213, 155, 151, 183 } );
  mapping1.push_back( { 213, 155, 151, 186 } );
  mapping1.push_back( { 213, 155, 151, 184 } );
  mapping1.push_back( { 213, 155, 151, 181 } );
  mapping1.push_back( { 213, 155, 151, 182 } );

  eastl::map<eastl::string, eastl::vector<IP4::addr>> lookup;
  lookup["www.google.com."] = mapping1;
  ///               ///

  int fd = socket(AF_INET, SOCK_DGRAM, 0);
  if (fd < 0)
  {
	perror("socket() failed");
	return -1;
  }

  in_addr lan_addr;
  inet_pton(AF_INET, "128.39.74.243", &lan_addr);

  struct sockaddr_in myaddr;
  myaddr.sin_family = AF_INET;
  myaddr.sin_addr.s_addr = lan_addr.s_addr;
  myaddr.sin_port = htons(DNS::DNS_SERVICE_PORT);

  if (bind(fd, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0)
  {
	perror("bind failed");
	return -1;
  }
  std::cout << "<DNS SERVER> Listening on UDP port 53" << std::endl;

  static const int BUFSIZE = 1500;
  char* buffer = new char[BUFSIZE];

  struct sockaddr_in remote;
  socklen_t addrlen = sizeof(remote);

  //int recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict src_addr, socklen_t *restrict *src_len)
  int bytes = recvfrom(fd, buffer, BUFSIZE, 0, (sockaddr*) &remote, &addrlen);

  if (bytes > 0)
  {
	printf("Received %d boats.\n", bytes);

	int packetlen = DNS::createResponse(*(DNS::header*) buffer,

		[&lookup] (const std::string& name) ->
		std::vector<net::IP4::addr>*
		{
			auto it = lookup.find(name);
			if (it == lookup.end()) return nullptr;
			return &lookup[name];
		});

	int sent = sendto(fd, buffer, packetlen, 0,
               (sockaddr*) &remote, addrlen);

	printf("Wrote %d boats.\n", sent);
  }

  std::cout << "Service out!" << std::endl;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *                                                                         *
 *   Copyright 2012 Marco Martin <mart@kde.org>                            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
 ***************************************************************************/

#include "bodegastore.h"
#include "kdeclarativeview.h"

#include <QtDeclarative/qdeclarative.h>
#include <QDeclarativeContext>
#include <QDeclarativeEngine>
#include <QScriptEngine>
#include <QScriptValueIterator>

#include <KConfig>
#include <KConfigGroup>
#include <KDebug>
#include <KGlobal>
#include <kwallet.h>

//Bodega libs
#include <bodega/assetoperations.h>
#include <bodega/bodegamodel.h>
#include <bodega/channelsjob.h>
#include <bodega/historymodel.h>
#include <bodega/networkjob.h>
#include <bodega/participantinfojob.h>
#include <bodega/registerjob.h>
#include <bodega/session.h>
#include <bodega/signonjob.h>
#include <bodega/installjob.h>
#include <bodega/uninstalljob.h>

using namespace Bodega;

QScriptValue qScriptValueFromError(QScriptEngine *engine, const Bodega::Error &error)
{
    QScriptValue obj = engine->newObject();

    obj.setProperty("type", error.type());
    obj.setProperty("errorId", error.errorId());
    obj.setProperty("title", error.title());
    obj.setProperty("description", error.description());

    return obj;
}

void errorFromQScriptValue(const QScriptValue &scriptValue, Bodega::Error &error)
{
    Error::Type type = Error::Network;
    QString errorId;
    QString title;
    QString description;

    QScriptValueIterator it(scriptValue);

    while (it.hasNext()) {
        it.next();
        //kDebug() << it.name() << "is" << it.value().toString();
        if (it.name() == "type") {
            type = (Error::Type)it.value().toInteger();
        } else if (it.name() == "errorId") {
            errorId = it.value().toString();
        } else if (it.name() == "title") {
            title = it.value().toString();
        } else if (it.name() == "description") {
            description = it.value().toString();
        }
    }

    error = Error(type, errorId, title, description);
}

QScriptValue qScriptValueFromChannelInfo(QScriptEngine *engine, const Bodega::ChannelInfo &info)
{
    QScriptValue obj = engine->newObject();

    obj.setProperty("id", info.id);
    obj.setProperty("name", info.name);
    obj.setProperty("description", info.description);
    obj.setProperty("assetCount", info.assetCount);
    //obj.setProperty("images", images);

    return obj;
}

void channelInfoFromQScriptValue(const QScriptValue &scriptValue, Bodega::ChannelInfo &info)
{
    QScriptValueIterator it(scriptValue);

    while (it.hasNext()) {
        it.next();
        //kDebug() << it.name() << "is" << it.value().toString();
        if (it.name() == "id") {
            info.id = it.value().toString();
        } else if (it.name() == "name") {
            info.name = it.value().toString();
        } else if (it.name() == "description") {
            info.description = it.value().toString();
        } else if (it.name() == "assetCount") {
            info.assetCount = it.value().toInteger();
        }
    }
}

QScriptValue qScriptValueFromAssetInfo(QScriptEngine *engine, const Bodega::AssetInfo &info)
{
    QScriptValue obj = engine->newObject();

    obj.setProperty("id", info.id);
    obj.setProperty("license", info.license);
    obj.setProperty("partnerId", info.partnerId);
    obj.setProperty("partnerName", info.partnerName);
    obj.setProperty("name", info.name);
    obj.setProperty("version", info.version);
    obj.setProperty("path", info.path.toString());
    //obj.setProperty("images", info.images);
    obj.setProperty("description", info.description);
    obj.setProperty("points", info.points);

    QScriptValue imageObj = engine->newObject();
    imageObj.setProperty("tiny", info.images[ImageTiny].toString());
    imageObj.setProperty("small", info.images[ImageSmall].toString());
    imageObj.setProperty("medium", info.images[ImageMedium].toString());
    imageObj.setProperty("large", info.images[ImageLarge].toString());
    imageObj.setProperty("huge", info.images[ImageHuge].toString());
    imageObj.setProperty("previews", info.images[ImagePreviews].toString());
    obj.setProperty("images", imageObj);

    return obj;
}

void assetInfoFromQScriptValue(const QScriptValue &scriptValue, Bodega::AssetInfo &info)
{
    QScriptValueIterator it(scriptValue);

    while (it.hasNext()) {
        it.next();
        if (it.name() == "id") {
            info.id = it.value().toString();
        } else if (it.name() == "license") {
            info.license = it.value().toString();
        } else if (it.name() == "partnerId") {
            info.partnerId = it.value().toString();
        } else if (it.name() == "partnerName") {
            info.partnerName = it.value().toString();
        } else if (it.name() == "name") {
            info.name = it.value().toString();
        } else if (it.name() == "version") {
            info.version = it.value().toString();
        } else if (it.name() == "path") {
            info.path = it.value().toString();
        } else if (it.name() == "description") {
            info.description = it.value().toString();
        } else if (it.name() == "points") {
            info.points = it.value().toInteger();
        } else if (it.name() == "images") {
            QMap<ImageUrl, QUrl> images;
            QScriptValueIterator imageIt(scriptValue);

            while (imageIt.hasNext()) {
                imageIt.next();
                if (imageIt.name() == "tiny") {
                    images[ImageTiny] = imageIt.value().toString();
                } else if (imageIt.name() == "small") {
                    images[ImageSmall] = imageIt.value().toString();
                } else if (imageIt.name() == "medium") {
                    images[ImageMedium] = imageIt.value().toString();
                } else if (imageIt.name() == "large") {
                    images[ImageLarge] = imageIt.value().toString();
                } else if (imageIt.name() == "huge") {
                    images[ImageHuge] = imageIt.value().toString();
                } else if (imageIt.name() == "previews") {
                    images[ImagePreviews] = imageIt.value().toString();
                }
            }
            info.images = images;
        }
    }
}

QScriptValue qScriptValueFromTags(QScriptEngine *engine, const Bodega::Tags &tags)
{
    QScriptValue obj = engine->newObject();

    foreach (const QString &key, tags.keys()) {
        QScriptValue list = engine->newArray();
        int i = 0;
        foreach (const QString &value, tags.values(key)) {
            list.setProperty(i, value);
            ++i;
        }
        obj.setProperty(key, list);
    }

    return obj;
}

void tagsFromQScriptValue(const QScriptValue &scriptValue, Bodega::Tags &tags)
{
    QScriptValueIterator it(scriptValue);

    while (it.hasNext()) {
        it.next();
        QScriptValueIterator tagIterator(it.value());
        while (tagIterator.hasNext()) {
            tags.insert(it.name(), tagIterator.value().toString());
        }
    }
}

QScriptValue qScriptValueFromParticipantInfo(QScriptEngine *engine, const Bodega::ParticipantInfo &info)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("assetCount", info.assetCount);
    obj.setProperty("channelCount", info.channelCount);
    obj.setProperty("pointsOwed", info.pointsOwed);
    obj.setProperty("organization", info.organization);
    obj.setProperty("firstName", info.firstName);
    obj.setProperty("lastName", info.lastName);
    obj.setProperty("email", info.email);
    return obj;
}

void participantInfoFromQScriptValue(const QScriptValue &scriptValue, Bodega::ParticipantInfo &info)
{
    info.assetCount = scriptValue.property("assetCount").toInt32();
    info.channelCount = scriptValue.property("channelCount").toInt32();
    info.pointsOwed = scriptValue.property("pointsOwed").toInt32();
    info.organization = scriptValue.property("organization").toString();
    info.firstName = scriptValue.property("firstName").toString();
    info.lastName = scriptValue.property("lastName").toString();
    info.email = scriptValue.property("email").toString();
}

BodegaStore::BodegaStore()
    : KDeclarativeMainWindow(),
      m_historyModel(0)
{
    declarativeView()->setPackageName("com.coherenttheory.addonsapp");

    qmlRegisterType<Bodega::ParticipantInfoJob>();
    qmlRegisterType<Bodega::AssetJob>();
    qmlRegisterType<Bodega::AssetOperations>();
    qmlRegisterType<Bodega::ChannelsJob>();
    qmlRegisterType<Bodega::HistoryModel>();
    qmlRegisterType<Bodega::Model>();
    qmlRegisterType<Bodega::NetworkJob>();
    qmlRegisterType<Bodega::RegisterJob>();
    qmlRegisterType<Bodega::Session>();
    qmlRegisterType<Bodega::SignOnJob>();
    qmlRegisterType<Bodega::InstallJob>();
    qmlRegisterType<Bodega::UninstallJob>();

    qScriptRegisterMetaType<Bodega::Error>(declarativeView()->scriptEngine(), qScriptValueFromError, errorFromQScriptValue, QScriptValue());
    qScriptRegisterMetaType<Bodega::ChannelInfo>(declarativeView()->scriptEngine(), qScriptValueFromChannelInfo, channelInfoFromQScriptValue, QScriptValue());
    qScriptRegisterMetaType<Bodega::AssetInfo>(declarativeView()->scriptEngine(), qScriptValueFromAssetInfo, assetInfoFromQScriptValue, QScriptValue());
    qScriptRegisterMetaType<Bodega::Tags>(declarativeView()->scriptEngine(), qScriptValueFromTags, tagsFromQScriptValue, QScriptValue());
    qScriptRegisterMetaType<Bodega::ParticipantInfo>(declarativeView()->scriptEngine(), qScriptValueFromParticipantInfo, participantInfoFromQScriptValue, QScriptValue());

    m_session = new Session(this);
    KConfigGroup config(KGlobal::config(), "AddOns");
    m_session->setBaseUrl(config.readEntry("URL", "http://addons.makeplaylive.com:3000"));
    m_session->setDeviceId(config.readEntry("Device", "VIVALDI-1"));

    m_channelsModel = new Bodega::Model(this);
    m_channelsModel->setSession(m_session);
    m_searchModel = new Bodega::Model(this);
    m_searchModel->setSession(m_session);

    declarativeView()->rootContext()->setContextProperty("bodegaClient", this);
}

BodegaStore::~BodegaStore()
{
}

Session* BodegaStore::session() const
{
    return m_session;
}

Model* BodegaStore::channelsModel() const
{
    return m_channelsModel;
}

Model* BodegaStore::searchModel() const
{
    return m_searchModel;
}

HistoryModel *BodegaStore::historyModel()
{
    if (!m_historyModel) {
        m_historyUsers = 0;
        m_historyModel = new HistoryModel(m_session);
        m_historyModel->setSession(m_session);
    }

    return m_historyModel;
}

void BodegaStore::historyInUse(bool used)
{
    if (used) {
        ++m_historyUsers;
    } else {
        --m_historyUsers;
        if (m_historyUsers < 1) {
            m_historyUsers = 0;
            m_historyModel->deleteLater();
            m_historyModel = 0;
        }
    }
}

void BodegaStore::forgetCredentials() const
{
    m_session->setUserName(QString());
    m_session->setPassword(QString());
    saveCredentials();
}

void BodegaStore::saveCredentials() const
{
    KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(),
                                           winId(), KWallet::Wallet::Synchronous);
    if (wallet->isOpen() &&
        (wallet->hasFolder("MakePlayLive") ||
         wallet->createFolder("MakePlayLive")) &&
         wallet->setFolder("MakePlayLive")) {

        QMap<QString, QString> map;
        map["username"] = m_session->userName();
        map["password"] = m_session->password();

        if (wallet->writeMap("credentials", map) != 0) {
            kWarning() << "Unable to write credentials to wallet";
        }
    } else {
        kWarning() << "Unable to open wallet";
    }
}

QVariantHash BodegaStore::retrieveCredentials() const
{
    KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(),
                                           winId(), KWallet::Wallet::Synchronous);
    if (wallet->isOpen() && wallet->setFolder("MakePlayLive")) {

        QMap<QString, QString> map;

        if (wallet->readMap("credentials", map) == 0) {
            QVariantHash hash;
            hash["username"] = map["username"];
            hash["password"] = map["password"];
            return hash;
        } else {
            kWarning() << "Unable to write credentials to wallet";
        }
    } else {
        kWarning() << "Unable to open wallet";
    }

    return QVariantHash();
}

#include "bodegastore.moc"
<commit_msg>update qml bindings for assetinfo<commit_after>/***************************************************************************
 *                                                                         *
 *   Copyright 2012 Marco Martin <mart@kde.org>                            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
 ***************************************************************************/

#include "bodegastore.h"
#include "kdeclarativeview.h"

#include <QtDeclarative/qdeclarative.h>
#include <QDeclarativeContext>
#include <QDeclarativeEngine>
#include <QScriptEngine>
#include <QScriptValueIterator>

#include <KConfig>
#include <KConfigGroup>
#include <KDebug>
#include <KGlobal>
#include <kwallet.h>

//Bodega libs
#include <bodega/assetoperations.h>
#include <bodega/bodegamodel.h>
#include <bodega/channelsjob.h>
#include <bodega/historymodel.h>
#include <bodega/networkjob.h>
#include <bodega/participantinfojob.h>
#include <bodega/registerjob.h>
#include <bodega/session.h>
#include <bodega/signonjob.h>
#include <bodega/installjob.h>
#include <bodega/uninstalljob.h>

using namespace Bodega;

QScriptValue qScriptValueFromError(QScriptEngine *engine, const Bodega::Error &error)
{
    QScriptValue obj = engine->newObject();

    obj.setProperty("type", error.type());
    obj.setProperty("errorId", error.errorId());
    obj.setProperty("title", error.title());
    obj.setProperty("description", error.description());

    return obj;
}

void errorFromQScriptValue(const QScriptValue &scriptValue, Bodega::Error &error)
{
    Error::Type type = Error::Network;
    QString errorId;
    QString title;
    QString description;

    QScriptValueIterator it(scriptValue);

    while (it.hasNext()) {
        it.next();
        //kDebug() << it.name() << "is" << it.value().toString();
        if (it.name() == "type") {
            type = (Error::Type)it.value().toInteger();
        } else if (it.name() == "errorId") {
            errorId = it.value().toString();
        } else if (it.name() == "title") {
            title = it.value().toString();
        } else if (it.name() == "description") {
            description = it.value().toString();
        }
    }

    error = Error(type, errorId, title, description);
}

QScriptValue qScriptValueFromChannelInfo(QScriptEngine *engine, const Bodega::ChannelInfo &info)
{
    QScriptValue obj = engine->newObject();

    obj.setProperty("id", info.id);
    obj.setProperty("name", info.name);
    obj.setProperty("description", info.description);
    obj.setProperty("assetCount", info.assetCount);
    //obj.setProperty("images", images);

    return obj;
}

void channelInfoFromQScriptValue(const QScriptValue &scriptValue, Bodega::ChannelInfo &info)
{
    QScriptValueIterator it(scriptValue);

    while (it.hasNext()) {
        it.next();
        //kDebug() << it.name() << "is" << it.value().toString();
        if (it.name() == "id") {
            info.id = it.value().toString();
        } else if (it.name() == "name") {
            info.name = it.value().toString();
        } else if (it.name() == "description") {
            info.description = it.value().toString();
        } else if (it.name() == "assetCount") {
            info.assetCount = it.value().toInteger();
        }
    }
}

QScriptValue qScriptValueFromAssetInfo(QScriptEngine *engine, const Bodega::AssetInfo &info)
{
    QScriptValue obj = engine->newObject();

    obj.setProperty("id", info.id);
    obj.setProperty("license", info.license);
    obj.setProperty("partnerId", info.partnerId);
    obj.setProperty("partnerName", info.partnerName);
    obj.setProperty("name", info.name);
    obj.setProperty("version", info.version);
    obj.setProperty("path", info.path.toString());
    //obj.setProperty("images", info.images);
    obj.setProperty("description", info.description);
    obj.setProperty("points", info.points);
    obj.setProperty("canDownload", info.canDownload);

    QScriptValue imageObj = engine->newObject();
    imageObj.setProperty("tiny", info.images[ImageTiny].toString());
    imageObj.setProperty("small", info.images[ImageSmall].toString());
    imageObj.setProperty("medium", info.images[ImageMedium].toString());
    imageObj.setProperty("large", info.images[ImageLarge].toString());
    imageObj.setProperty("huge", info.images[ImageHuge].toString());
    imageObj.setProperty("previews", info.images[ImagePreviews].toString());
    obj.setProperty("images", imageObj);

    return obj;
}

void assetInfoFromQScriptValue(const QScriptValue &scriptValue, Bodega::AssetInfo &info)
{
    QScriptValueIterator it(scriptValue);

    while (it.hasNext()) {
        it.next();
        if (it.name() == "id") {
            info.id = it.value().toString();
        } else if (it.name() == "license") {
            info.license = it.value().toString();
        } else if (it.name() == "partnerId") {
            info.partnerId = it.value().toString();
        } else if (it.name() == "partnerName") {
            info.partnerName = it.value().toString();
        } else if (it.name() == "name") {
            info.name = it.value().toString();
        } else if (it.name() == "version") {
            info.version = it.value().toString();
        } else if (it.name() == "path") {
            info.path = it.value().toString();
        } else if (it.name() == "description") {
            info.description = it.value().toString();
        } else if (it.name() == "points") {
            info.points = it.value().toInteger();
        } else if (it.name() == "canDownload") {
            info.canDownload = it.value().toBool();
        } else if (it.name() == "images") {
            QMap<ImageUrl, QUrl> images;
            QScriptValueIterator imageIt(scriptValue);

            while (imageIt.hasNext()) {
                imageIt.next();
                if (imageIt.name() == "tiny") {
                    images[ImageTiny] = imageIt.value().toString();
                } else if (imageIt.name() == "small") {
                    images[ImageSmall] = imageIt.value().toString();
                } else if (imageIt.name() == "medium") {
                    images[ImageMedium] = imageIt.value().toString();
                } else if (imageIt.name() == "large") {
                    images[ImageLarge] = imageIt.value().toString();
                } else if (imageIt.name() == "huge") {
                    images[ImageHuge] = imageIt.value().toString();
                } else if (imageIt.name() == "previews") {
                    images[ImagePreviews] = imageIt.value().toString();
                }
            }
            info.images = images;
        }
    }
}

QScriptValue qScriptValueFromTags(QScriptEngine *engine, const Bodega::Tags &tags)
{
    QScriptValue obj = engine->newObject();

    foreach (const QString &key, tags.keys()) {
        QScriptValue list = engine->newArray();
        int i = 0;
        foreach (const QString &value, tags.values(key)) {
            list.setProperty(i, value);
            ++i;
        }
        obj.setProperty(key, list);
    }

    return obj;
}

void tagsFromQScriptValue(const QScriptValue &scriptValue, Bodega::Tags &tags)
{
    QScriptValueIterator it(scriptValue);

    while (it.hasNext()) {
        it.next();
        QScriptValueIterator tagIterator(it.value());
        while (tagIterator.hasNext()) {
            tags.insert(it.name(), tagIterator.value().toString());
        }
    }
}

QScriptValue qScriptValueFromParticipantInfo(QScriptEngine *engine, const Bodega::ParticipantInfo &info)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("assetCount", info.assetCount);
    obj.setProperty("channelCount", info.channelCount);
    obj.setProperty("pointsOwed", info.pointsOwed);
    obj.setProperty("organization", info.organization);
    obj.setProperty("firstName", info.firstName);
    obj.setProperty("lastName", info.lastName);
    obj.setProperty("email", info.email);
    return obj;
}

void participantInfoFromQScriptValue(const QScriptValue &scriptValue, Bodega::ParticipantInfo &info)
{
    info.assetCount = scriptValue.property("assetCount").toInt32();
    info.channelCount = scriptValue.property("channelCount").toInt32();
    info.pointsOwed = scriptValue.property("pointsOwed").toInt32();
    info.organization = scriptValue.property("organization").toString();
    info.firstName = scriptValue.property("firstName").toString();
    info.lastName = scriptValue.property("lastName").toString();
    info.email = scriptValue.property("email").toString();
}

BodegaStore::BodegaStore()
    : KDeclarativeMainWindow(),
      m_historyModel(0)
{
    declarativeView()->setPackageName("com.coherenttheory.addonsapp");

    qmlRegisterType<Bodega::ParticipantInfoJob>();
    qmlRegisterType<Bodega::AssetJob>();
    qmlRegisterType<Bodega::AssetOperations>();
    qmlRegisterType<Bodega::ChannelsJob>();
    qmlRegisterType<Bodega::HistoryModel>();
    qmlRegisterType<Bodega::Model>();
    qmlRegisterType<Bodega::NetworkJob>();
    qmlRegisterType<Bodega::RegisterJob>();
    qmlRegisterType<Bodega::Session>();
    qmlRegisterType<Bodega::SignOnJob>();
    qmlRegisterType<Bodega::InstallJob>();
    qmlRegisterType<Bodega::UninstallJob>();

    qScriptRegisterMetaType<Bodega::Error>(declarativeView()->scriptEngine(), qScriptValueFromError, errorFromQScriptValue, QScriptValue());
    qScriptRegisterMetaType<Bodega::ChannelInfo>(declarativeView()->scriptEngine(), qScriptValueFromChannelInfo, channelInfoFromQScriptValue, QScriptValue());
    qScriptRegisterMetaType<Bodega::AssetInfo>(declarativeView()->scriptEngine(), qScriptValueFromAssetInfo, assetInfoFromQScriptValue, QScriptValue());
    qScriptRegisterMetaType<Bodega::Tags>(declarativeView()->scriptEngine(), qScriptValueFromTags, tagsFromQScriptValue, QScriptValue());
    qScriptRegisterMetaType<Bodega::ParticipantInfo>(declarativeView()->scriptEngine(), qScriptValueFromParticipantInfo, participantInfoFromQScriptValue, QScriptValue());

    m_session = new Session(this);
    KConfigGroup config(KGlobal::config(), "AddOns");
    m_session->setBaseUrl(config.readEntry("URL", "http://addons.makeplaylive.com:3000"));
    m_session->setDeviceId(config.readEntry("Device", "VIVALDI-1"));

    m_channelsModel = new Bodega::Model(this);
    m_channelsModel->setSession(m_session);
    m_searchModel = new Bodega::Model(this);
    m_searchModel->setSession(m_session);

    declarativeView()->rootContext()->setContextProperty("bodegaClient", this);
}

BodegaStore::~BodegaStore()
{
}

Session* BodegaStore::session() const
{
    return m_session;
}

Model* BodegaStore::channelsModel() const
{
    return m_channelsModel;
}

Model* BodegaStore::searchModel() const
{
    return m_searchModel;
}

HistoryModel *BodegaStore::historyModel()
{
    if (!m_historyModel) {
        m_historyUsers = 0;
        m_historyModel = new HistoryModel(m_session);
        m_historyModel->setSession(m_session);
    }

    return m_historyModel;
}

void BodegaStore::historyInUse(bool used)
{
    if (used) {
        ++m_historyUsers;
    } else {
        --m_historyUsers;
        if (m_historyUsers < 1) {
            m_historyUsers = 0;
            m_historyModel->deleteLater();
            m_historyModel = 0;
        }
    }
}

void BodegaStore::forgetCredentials() const
{
    m_session->setUserName(QString());
    m_session->setPassword(QString());
    saveCredentials();
}

void BodegaStore::saveCredentials() const
{
    KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(),
                                           winId(), KWallet::Wallet::Synchronous);
    if (wallet->isOpen() &&
        (wallet->hasFolder("MakePlayLive") ||
         wallet->createFolder("MakePlayLive")) &&
         wallet->setFolder("MakePlayLive")) {

        QMap<QString, QString> map;
        map["username"] = m_session->userName();
        map["password"] = m_session->password();

        if (wallet->writeMap("credentials", map) != 0) {
            kWarning() << "Unable to write credentials to wallet";
        }
    } else {
        kWarning() << "Unable to open wallet";
    }
}

QVariantHash BodegaStore::retrieveCredentials() const
{
    KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(),
                                           winId(), KWallet::Wallet::Synchronous);
    if (wallet->isOpen() && wallet->setFolder("MakePlayLive")) {

        QMap<QString, QString> map;

        if (wallet->readMap("credentials", map) == 0) {
            QVariantHash hash;
            hash["username"] = map["username"];
            hash["password"] = map["password"];
            return hash;
        } else {
            kWarning() << "Unable to write credentials to wallet";
        }
    } else {
        kWarning() << "Unable to open wallet";
    }

    return QVariantHash();
}

#include "bodegastore.moc"
<|endoftext|>


<commit_before>/**
 * bucketize_procedure.cc
 * Mich, 2015-10-27
 * Copyright (c) 2015 Datacratic Inc. All rights reserved.
 *
 * This file is part of MLDB. Copyright 2015 Datacratic. All rights reserved.
 **/

#include "bucketize_procedure.h"
#include "mldb/server/mldb_server.h"
#include "mldb/sql/sql_expression.h"
#include "mldb/server/dataset_context.h"
#include "mldb/types/basic_value_descriptions.h"
#include "mldb/jml/utils/worker_task.h"
#include "mldb/server/function_contexts.h"
#include "mldb/server/bound_queries.h"
#include "mldb/sql/table_expression_operations.h"
#include "mldb/sql/join_utils.h"
#include "mldb/sql/execution_pipeline.h"
#include "mldb/arch/backtrace.h"
#include "mldb/types/any_impl.h"
#include "mldb/server/per_thread_accumulator.h"
#include "mldb/types/date.h"
#include "mldb/sql/sql_expression.h"
#include <memory>

using namespace std;

namespace Datacratic {
namespace MLDB {

BucketizeProcedureConfig::
BucketizeProcedureConfig()
{
    outputDataset.withType("sparse.mutable");
}

DEFINE_STRUCTURE_DESCRIPTION(BucketizeProcedureConfig);

BucketizeProcedureConfigDescription::
BucketizeProcedureConfigDescription()
{
    addField("inputData", &BucketizeProcedureConfig::inputData,
             "An SQL statement to select the input data. The select expression is required "
             "but has no effect.  The order by expression is used to rank the rows prior to "
             "bucketization.");
    addField("outputDataset", &BucketizeProcedureConfig::outputDataset,
             "Output dataset configuration. This may refer either to an "
             "existing dataset, or a fully specified but non-existing dataset "
             "which will be created by the procedure.",
             PolyConfigT<Dataset>().withType("sparse.mutable"));
    addField("percentileBuckets", &BucketizeProcedureConfig::percentileBuckets,
             "Key/ranges of the buckets to create. Buckets ranges can share "
             "start and end values but cannot overlap such that a row can "
             "belong to multiple buckets. "
             "E.g. {\"a\":[0, 50], \"b\": [50, 100]} will give two buckets: "
             "\"a\" has rows where 0% < rank/count <= 50% and "
             "\"b\" has rows where 50% < rank/count <= 100%, where the 'rank' "
             "is based on the orderBy parameter.");
    addParent<ProcedureConfig>();

    onPostValidate = [&] (BucketizeProcedureConfig * cfg,
                          JsonParsingContext & context)
    {
        vector<pair<float, float>> ranges;
        for (const auto & range: cfg->percentileBuckets) {
            ranges.push_back(range.second);
        }
        auto sorter = [](pair<float, float> a, pair<float, float> b)
        {
            return a.first < b.first;
        };
        sort(ranges.begin(), ranges.end(), sorter);

        auto last = make_pair(-1.0, -1.0);
        for (const auto & range: ranges) {
            if (range.first < 0) {
                throw ML::Exception(
                    "Invalid percentileBucket [%f, %f]: lower bound must be "
                    "greater or equal to 0", range.first, range.second);
            }
            if (range.second > 100) {
                throw ML::Exception(
                    "Invalid percentileBucket [%f, %f]: higher bound must be "
                    "lower or equal to 1", range.first, range.second);
            }
            if (range.first >= range.second) {
                throw ML::Exception(
                    "Invalid percentileBucket [%f, %f]: higher bound must  "
                    "be greater than lower bound", range.first, range.second);
            }
            if (range.first < last.second) {
                throw ML::Exception(
                    "Invalid percentileBucket: [%f, %f] is overlapping with "
                    "[%f, %f]", last.first, last.second, range.first,
                    range.second);
            }
            last = range;
        }
    };
}

BucketizeProcedure::
BucketizeProcedure(MldbServer * owner,
                 PolyConfig config,
                 const std::function<bool (const Json::Value &)> & onProgress)
    : Procedure(owner)
{
    procedureConfig = config.params.convert<BucketizeProcedureConfig>();
}

RunOutput
BucketizeProcedure::
run(const ProcedureRunConfig & run,
    const std::function<bool (const Json::Value &)> & onProgress) const
{
    SqlExpressionMldbContext context(server);

    auto boundDataset = procedureConfig.inputData.stm->from->bind(context);

    SelectExpression select(SelectExpression::parse("1"));
    vector<shared_ptr<SqlExpression> > calc;

    vector<Id> orderedRowNames;
    auto getSize = [&] (const MatrixNamedRow & row,
                        const vector<ExpressionValue> & calc)
    {
        orderedRowNames.emplace_back(row.rowName);
        return true;
    };

    BoundSelectQuery(select,
                     *boundDataset.dataset,
                     boundDataset.asName,
                     procedureConfig.inputData.stm->when,
                     procedureConfig.inputData.stm->where,
                     procedureConfig.inputData.stm->orderBy,
                     calc)
        .execute(getSize,
                 procedureConfig.inputData.stm->offset,
                 procedureConfig.inputData.stm->limit,
                 onProgress);

    int64_t rowCount = orderedRowNames.size();
    cerr << "Row count: " << rowCount  << endl;

    std::shared_ptr<Dataset> output;
    if (!procedureConfig.outputDataset.type.empty() || !procedureConfig.outputDataset.id.empty()) {
        output = createDataset(server, procedureConfig.outputDataset, nullptr, true /*overwrite*/);
    }

    typedef tuple<ColumnName, CellValue, Date> cell;
    PerThreadAccumulator<vector<pair<RowName, vector<cell>>>> accum;

    for (const auto & mappedRange: procedureConfig.percentileBuckets) {
        string bucketName(mappedRange.first);
        auto applyFct = [&] (int64_t index)
        {
            std::vector<cell> cols;
            cols.emplace_back(ColumnName("bucket"),
                              bucketName,
                              Date::negativeInfinity());

            auto & rows = accum.get();
            rows.reserve(1024);
            rows.emplace_back(orderedRowNames[index], cols);

            if (rows.size() >= 1024) {
                output->recordRows(rows);
                rows.clear();
            }
        };
        auto range = mappedRange.second;

        //Make sure that numerical issues dont let 100 percentile go out of bound
        int64_t lowerBound = range.second == 0 ? 0 : int64_t(range.first / 100 * rowCount);
        int64_t higherBound = range.second == 100 ? rowCount : int64_t(range.second / 100 * rowCount);

        ExcAssert(higherBound <= rowCount);

        cerr << "Bucket " << bucketName << " from " << lowerBound
             << " to " << higherBound << endl;

        ML::run_in_parallel_blocked(lowerBound, higherBound, applyFct);
    }

    // record remainder
    accum.forEach([&] (vector<pair<RowName, vector<cell>>> * rows)
    {
        output->recordRows(*rows);
    });

    output->commit();
    return output->getStatus();
}

Any
BucketizeProcedure::
getStatus() const
{
    return Any();
}

static RegisterProcedureType<BucketizeProcedure, BucketizeProcedureConfig>
regBucketizeProcedure(
    builtinPackage(),
    "bucketize",
    "Assign buckets based on percentile ranges over a sorted dataset",
    "procedures/BucketizeProcedure.md.html");

} // namespace MLDB
} // namespace Datacratic
<commit_msg>Fix no output<commit_after>/**
 * bucketize_procedure.cc
 * Mich, 2015-10-27
 * Copyright (c) 2015 Datacratic Inc. All rights reserved.
 *
 * This file is part of MLDB. Copyright 2015 Datacratic. All rights reserved.
 **/

#include "bucketize_procedure.h"
#include "mldb/server/mldb_server.h"
#include "mldb/sql/sql_expression.h"
#include "mldb/server/dataset_context.h"
#include "mldb/types/basic_value_descriptions.h"
#include "mldb/jml/utils/worker_task.h"
#include "mldb/server/function_contexts.h"
#include "mldb/server/bound_queries.h"
#include "mldb/sql/table_expression_operations.h"
#include "mldb/sql/join_utils.h"
#include "mldb/sql/execution_pipeline.h"
#include "mldb/arch/backtrace.h"
#include "mldb/types/any_impl.h"
#include "mldb/server/per_thread_accumulator.h"
#include "mldb/types/date.h"
#include "mldb/sql/sql_expression.h"
#include <memory>

using namespace std;

namespace Datacratic {
namespace MLDB {

BucketizeProcedureConfig::
BucketizeProcedureConfig()
{
    outputDataset.withType("sparse.mutable");
}

DEFINE_STRUCTURE_DESCRIPTION(BucketizeProcedureConfig);

BucketizeProcedureConfigDescription::
BucketizeProcedureConfigDescription()
{
    addField("inputData", &BucketizeProcedureConfig::inputData,
             "An SQL statement to select the input data. The select expression is required "
             "but has no effect.  The order by expression is used to rank the rows prior to "
             "bucketization.");
    addField("outputDataset", &BucketizeProcedureConfig::outputDataset,
             "Output dataset configuration. This may refer either to an "
             "existing dataset, or a fully specified but non-existing dataset "
             "which will be created by the procedure.",
             PolyConfigT<Dataset>().withType("sparse.mutable"));
    addField("percentileBuckets", &BucketizeProcedureConfig::percentileBuckets,
             "Key/ranges of the buckets to create. Buckets ranges can share "
             "start and end values but cannot overlap such that a row can "
             "belong to multiple buckets. "
             "E.g. {\"a\":[0, 50], \"b\": [50, 100]} will give two buckets: "
             "\"a\" has rows where 0% < rank/count <= 50% and "
             "\"b\" has rows where 50% < rank/count <= 100%, where the 'rank' "
             "is based on the orderBy parameter.");
    addParent<ProcedureConfig>();

    onPostValidate = [&] (BucketizeProcedureConfig * cfg,
                          JsonParsingContext & context)
    {
        vector<pair<float, float>> ranges;
        for (const auto & range: cfg->percentileBuckets) {
            ranges.push_back(range.second);
        }
        auto sorter = [](pair<float, float> a, pair<float, float> b)
        {
            return a.first < b.first;
        };
        sort(ranges.begin(), ranges.end(), sorter);

        auto last = make_pair(-1.0, -1.0);
        for (const auto & range: ranges) {
            if (range.first < 0) {
                throw ML::Exception(
                    "Invalid percentileBucket [%f, %f]: lower bound must be "
                    "greater or equal to 0", range.first, range.second);
            }
            if (range.second > 100) {
                throw ML::Exception(
                    "Invalid percentileBucket [%f, %f]: higher bound must be "
                    "lower or equal to 1", range.first, range.second);
            }
            if (range.first >= range.second) {
                throw ML::Exception(
                    "Invalid percentileBucket [%f, %f]: higher bound must  "
                    "be greater than lower bound", range.first, range.second);
            }
            if (range.first < last.second) {
                throw ML::Exception(
                    "Invalid percentileBucket: [%f, %f] is overlapping with "
                    "[%f, %f]", last.first, last.second, range.first,
                    range.second);
            }
            last = range;
        }
    };
}

BucketizeProcedure::
BucketizeProcedure(MldbServer * owner,
                 PolyConfig config,
                 const std::function<bool (const Json::Value &)> & onProgress)
    : Procedure(owner)
{
    procedureConfig = config.params.convert<BucketizeProcedureConfig>();
}

RunOutput
BucketizeProcedure::
run(const ProcedureRunConfig & run,
    const std::function<bool (const Json::Value &)> & onProgress) const
{
    SqlExpressionMldbContext context(server);

    auto boundDataset = procedureConfig.inputData.stm->from->bind(context);

    SelectExpression select(SelectExpression::parse("1"));
    vector<shared_ptr<SqlExpression> > calc;

    vector<Id> orderedRowNames;
    auto getSize = [&] (const MatrixNamedRow & row,
                        const vector<ExpressionValue> & calc)
    {
        orderedRowNames.emplace_back(row.rowName);
        return true;
    };

    BoundSelectQuery(select,
                     *boundDataset.dataset,
                     boundDataset.asName,
                     procedureConfig.inputData.stm->when,
                     procedureConfig.inputData.stm->where,
                     procedureConfig.inputData.stm->orderBy,
                     calc)
        .execute(getSize,
                 procedureConfig.inputData.stm->offset,
                 procedureConfig.inputData.stm->limit,
                 onProgress);

    int64_t rowCount = orderedRowNames.size();
    cerr << "Row count: " << rowCount  << endl;

    auto output = createDataset(server, procedureConfig.outputDataset,
                                nullptr, true /*overwrite*/);

    typedef tuple<ColumnName, CellValue, Date> cell;
    PerThreadAccumulator<vector<pair<RowName, vector<cell>>>> accum;

    for (const auto & mappedRange: procedureConfig.percentileBuckets) {
        string bucketName(mappedRange.first);
        auto applyFct = [&] (int64_t index)
        {
            std::vector<cell> cols;
            cols.emplace_back(ColumnName("bucket"),
                              bucketName,
                              Date::negativeInfinity());

            auto & rows = accum.get();
            rows.reserve(1024);
            rows.emplace_back(orderedRowNames[index], cols);

            if (rows.size() >= 1024) {
                output->recordRows(rows);
                rows.clear();
            }
        };
        auto range = mappedRange.second;

        //Make sure that numerical issues dont let 100 percentile go out of bound
        int64_t lowerBound = range.second == 0 ? 0 : int64_t(range.first / 100 * rowCount);
        int64_t higherBound = range.second == 100 ? rowCount : int64_t(range.second / 100 * rowCount);

        ExcAssert(higherBound <= rowCount);

        cerr << "Bucket " << bucketName << " from " << lowerBound
             << " to " << higherBound << endl;

        ML::run_in_parallel_blocked(lowerBound, higherBound, applyFct);
    }

    // record remainder
    accum.forEach([&] (vector<pair<RowName, vector<cell>>> * rows)
    {
        output->recordRows(*rows);
    });

    output->commit();
    return output->getStatus();
}

Any
BucketizeProcedure::
getStatus() const
{
    return Any();
}

static RegisterProcedureType<BucketizeProcedure, BucketizeProcedureConfig>
regBucketizeProcedure(
    builtinPackage(),
    "bucketize",
    "Assign buckets based on percentile ranges over a sorted dataset",
    "procedures/BucketizeProcedure.md.html");

} // namespace MLDB
} // namespace Datacratic
<|endoftext|>