<commit_before>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

/*!
 * \file processor.hpp
 * \brief This file is made to be included by the dllp generated file only.
 */

#include <string>
#include <vector>
#include <iostream>
#include <iomanip>

#include "dll/rbm/rbm.hpp"
#include "dll/rbm/conv_rbm.hpp"
#include "dll/neural/dense_layer.hpp"
#include "dll/neural/conv_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/text_reader.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

namespace dll {

namespace processor {

struct options {
    bool quiet  = false;
    bool mkl    = false;
    bool cublas = false;
    bool cufft  = false;
    bool cache  = false;
};

template <typename LastLayer, typename Enable = void>
struct sgd_possible {
    static constexpr bool value = false;
};

template <typename LastLayer>
struct sgd_possible<LastLayer, std::enable_if_t<decay_layer_traits<LastLayer>::base_traits::sgd_supported>> {
    static constexpr bool value = true;
};

//These functions are only exposed to be able to unit-test the program
int process_file(const options& opt, const std::vector<std::string>& actions, const std::string& source_file);
std::string process_file_result(const options& opt, const std::vector<std::string>& actions, const std::string& source_file);

constexpr double stupid_default = -666.0;

struct datasource {
    std::string source_file;
    std::string reader;

    bool binarize         = false;
    bool normalize        = false;
    bool scale            = false;
    double scale_d        = 0.0;
    bool shift            = false;
    double shift_d        = 0.0;
    bool normal_noise     = false;
    double normal_noise_d = 0.0;

    long limit = -1;

    datasource() {}
    datasource(std::string source_file, std::string reader)
            : source_file(std::move(source_file)), reader(std::move(reader)) {}

    bool empty() const {
        return source_file.empty();
    }
};

struct datasource_pack {
    datasource samples;
    datasource labels;
};

struct general_desc {
    bool batch_mode       = false;
    size_t big_batch = 1;
};

struct pretraining_desc {
    size_t epochs = 25;
    bool denoising     = false;
};

struct training_desc {
    size_t epochs     = 25;
    double learning_rate   = stupid_default;
    double momentum        = stupid_default;
    size_t batch_size = 0;

    std::string decay     = "none";
    double l1_weight_cost = stupid_default;
    double l2_weight_cost = stupid_default;

    std::string trainer = "none";

    bool verbose = false;
};

struct weights_desc {
    std::string file = "weights.dat";
};

struct task {
    std::vector<std::string> default_actions;

    dll::processor::datasource_pack pretraining;
    dll::processor::datasource_pack pretraining_clean;
    dll::processor::datasource_pack training;
    dll::processor::datasource_pack testing;

    dll::processor::pretraining_desc pt_desc;
    dll::processor::training_desc ft_desc;
    dll::processor::weights_desc w_desc;
    dll::processor::general_desc general_desc;
};

template <bool Three, typename Sample>
bool read_samples(const datasource& ds, std::vector<Sample>& samples) {
    size_t limit = 0;

    if (ds.limit > 0) {
        limit = ds.limit;
    }

    if (ds.reader == "mnist") {
        mnist::read_mnist_image_file<std::vector, Sample>(samples, ds.source_file, limit, [] { return Sample(1 * 28 * 28); });
    } else if(ds.reader == "text"){
        dll::text::read_images_direct<Three, std::vector, Sample>(samples, ds.source_file, limit);
    } else {
        std::cout << "dllp: error: unknown samples reader: " << ds.reader << std::endl;
        return false;
    }

    if (ds.binarize) {
        mnist::binarize_each(samples);
    }

    if (ds.normalize) {
        mnist::normalize_each(samples);
    }

    if (ds.shift) {
        for (auto& vec : samples) {
            for (auto& v : vec) {
                v += ds.shift_d;
            }
        }
    }

    if (ds.scale) {
        for (auto& vec : samples) {
            for (auto& v : vec) {
                v *= ds.scale_d;
            }
        }
    }

    if (ds.normal_noise) {
        mnist::normalize_each(samples);

        std::random_device rd;
        std::default_random_engine rand_engine(rd());
        std::normal_distribution<float> normal_distribution(0.0, ds.normal_noise_d);
        auto noise = std::bind(normal_distribution, rand_engine);

        for (auto& vec : samples) {
            for (auto& noisy_x : vec) {
                noisy_x += noise();
            }
        }

        mnist::normalize_each(samples);
    }

    return !samples.empty();
}

template <typename Label>
bool read_labels(const datasource& ds, std::vector<Label>& labels) {
    size_t limit = 0;

    if (ds.limit > 0) {
        limit = ds.limit;
    }

    if (ds.reader == "mnist") {
        mnist::read_mnist_label_file<std::vector, Label>(labels, ds.source_file, limit);
    } else if (ds.reader == "text") {
        dll::text::read_labels<std::vector, Label>(labels, ds.source_file, limit);
    } else {
        std::cout << "dllp: error: unknown labels reader: " << ds.reader << std::endl;
        return false;
    }

    return !labels.empty();
}

inline void print_title(const std::string& value) {
    std::cout << std::string(25, ' ') << std::endl;
    std::cout << std::string(25, '*') << std::endl;
    std::cout << "* " << value << std::string(25 - value.size() - 3, ' ') << "*" << std::endl;
    std::cout << std::string(25, '*') << std::endl;
    std::cout << std::string(25, ' ') << std::endl;
}

template <typename Container, bool Three, typename DBN>
void execute(DBN& dbn, task& task, const std::vector<std::string>& actions) {
    print_title("Network");
    dbn.display();

    using dbn_t = std::decay_t<DBN>;

    //Execute all the actions sequentially
    for (auto& action : actions) {
        if (action == "pretrain") {
            print_title("Pretraining");

            if (task.pretraining.samples.empty()) {
                std::cout << "dllp: error: pretrain is not possible without a pretraining input" << std::endl;
                return;
            }

            std::vector<Container> pt_samples;

            //Try to read the samples
            if (!read_samples<Three>(task.pretraining.samples, pt_samples)) {
                std::cout << "dllp: error: failed to read the pretraining samples" << std::endl;
                return;
            }

            if (task.pt_desc.denoising) {
                std::vector<Container> clean_samples;

                //Try to read the samples
                if (!read_samples<Three>(task.pretraining_clean.samples, clean_samples)) {
                    std::cout << "dllp: error: failed to read the clean samples" << std::endl;
                    return;
                }

                //Pretrain the network
                if constexpr(dbn_t::pretrain_possible && dbn_t::layers_t::is_denoising) {
                    dbn.pretrain_denoising(pt_samples.begin(), pt_samples.end(), clean_samples.begin(), clean_samples.end(), task.pt_desc.epochs);
                }
            } else {
                if constexpr (dbn_t::pretrain_possible) {
                    //Pretrain the network
                    dbn.pretrain(pt_samples.begin(), pt_samples.end(), task.pt_desc.epochs);
                }
            }
        } else if (action == "train") {
            print_title("Training");

            if (task.training.samples.empty() || task.training.labels.empty()) {
                std::cout << "dllp: error: train is not possible without samples and labels" << std::endl;
                return;
            }

            std::vector<Container> ft_samples;
            std::vector<size_t> ft_labels;

            //Try to read the samples
            if (!read_samples<Three>(task.training.samples, ft_samples)) {
                std::cout << "dllp: error: failed to read the training samples" << std::endl;
                return;
            }

            //Try to read the labels
            if (!read_labels(task.training.labels, ft_labels)) {
                std::cout << "dllp: error: failed to read the training labels" << std::endl;
                return;
            }

            using last_layer = typename dbn_t::template layer_type<dbn_t::layers - 1>;

            if(!sgd_possible<last_layer>::value){
                std::cout << "dllp: error: The network is not trainable by SGD" << std::endl;
                return;
            }

            //Train the network
            if constexpr(sgd_possible<last_layer>::value) {
                auto ft_error = dbn.fine_tune(ft_samples, ft_labels, task.ft_desc.epochs);
                std::cout << "Train Classification Error:" << ft_error << std::endl;
            }
        } else if (action == "test") {
            print_title("Testing");

            if (task.testing.samples.empty() || task.testing.labels.empty()) {
                std::cout << "dllp: error: test is not possible without samples and labels" << std::endl;
                return;
            }

            std::vector<Container> test_samples;
            std::vector<size_t> test_labels;

            //Try to read the samples
            if (!read_samples<Three>(task.testing.samples, test_samples)) {
                std::cout << "dllp: error: failed to read the test samples" << std::endl;
                return;
            }

            //Try to read the labels
            if (!read_labels(task.testing.labels, test_labels)) {
                std::cout << "dllp: error: failed to read the test labels" << std::endl;
                return;
            }

            auto classes = dbn.output_size();

            etl::dyn_matrix<size_t, 2> conf(classes, classes, 0.0);

            size_t n  = test_samples.size();
            size_t tp = 0;

            for (size_t i = 0; i < test_samples.size(); ++i) {
                auto sample = test_samples[i];
                auto label  = test_labels[i];

                auto predicted = dbn.predict(sample);

                if (predicted == label) {
                    ++tp;
                }

                ++conf(label, predicted);
            }

            double test_error = (n - tp) / double(n);

            std::cout << "Error rate: " << test_error << std::endl;
            std::cout << "Accuracy: " << (1.0 - test_error) << std::endl
                      << std::endl;

            std::cout << "Results per class" << std::endl;

            double overall = 0.0;

            std::cout << "   | Accuracy | Error rate |" << std::endl;

            for (size_t l = 0; l < classes; ++l) {
                size_t total = etl::sum(conf(l));
                double acc = (total - conf(l, l)) / double(total);
                std::cout << std::setw(3) << l;
                std::cout << "|" << std::setw(10) << (1.0 - acc) << "|" << std::setw(12) << acc << "|" << std::endl;
                overall += acc;
            }

            std::cout << std::endl;

            std::cout << "Overall Error rate: " << overall / classes << std::endl;
            std::cout << "Overall Accuracy: " << 1.0 - (overall / classes) << std::endl
                      << std::endl;

            std::cout << "Confusion Matrix (%)" << std::endl
                      << std::endl;

            std::cout << "    ";
            for (size_t l = 0; l < classes; ++l) {
                std::cout << std::setw(5) << l << " ";
            }
            std::cout << std::endl;

            for (size_t l = 0; l < classes; ++l) {
                size_t total = etl::sum(conf(l));
                std::cout << std::setw(3) << l << "|";
                for (size_t p = 0; p < classes; ++p) {
                    std::cout << std::setw(5) << std::setprecision(2) << 100.0 * (conf(l, p) / double(total)) << "|";
                }
                std::cout << std::endl;
            }
            std::cout << std::endl;
        } else if (action == "save") {
            print_title("Save Weights");

            dbn.store(task.w_desc.file);
            std::cout << "Weights saved" << std::endl;
        } else if (action == "load") {
            print_title("Load Weights");

            dbn.load(task.w_desc.file);
            std::cout << "Weights loaded" << std::endl;
        } else {
            std::cout << "dllp: error: Invalid action: " << action << std::endl;
        }
    }

    //TODO
}

} //end of namespace processor

} //end of namespace dll
<commit_msg>Update processor<commit_after>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

/*!
 * \file processor.hpp
 * \brief This file is made to be included by the dllp generated file only.
 */

#include <string>
#include <vector>
#include <iostream>
#include <iomanip>

#include "dll/rbm/rbm.hpp"
#include "dll/rbm/conv_rbm.hpp"
#include "dll/neural/dense_layer.hpp"
#include "dll/neural/conv_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/text_reader.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

namespace dll {

namespace processor {

struct options {
    bool quiet  = false;
    bool mkl    = false;
    bool cublas = false;
    bool cufft  = false;
    bool cache  = false;
};

template <typename LastLayer, typename Enable = void>
struct sgd_possible {
    static constexpr bool value = false;
};

template <typename LastLayer>
struct sgd_possible<LastLayer, std::enable_if_t<decay_layer_traits<LastLayer>::base_traits::sgd_supported>> {
    static constexpr bool value = true;
};

//These functions are only exposed to be able to unit-test the program
int process_file(const options& opt, const std::vector<std::string>& actions, const std::string& source_file);
std::string process_file_result(const options& opt, const std::vector<std::string>& actions, const std::string& source_file);

constexpr double stupid_default = -666.0;

struct datasource {
    std::string source_file;
    std::string reader;

    bool binarize         = false;
    bool normalize        = false;
    bool scale            = false;
    double scale_d        = 0.0;
    bool shift            = false;
    double shift_d        = 0.0;
    bool normal_noise     = false;
    double normal_noise_d = 0.0;

    long limit = -1;

    datasource() {}
    datasource(std::string source_file, std::string reader)
            : source_file(std::move(source_file)), reader(std::move(reader)) {}

    bool empty() const {
        return source_file.empty();
    }
};

struct datasource_pack {
    datasource samples;
    datasource labels;
};

struct general_desc {
    bool batch_mode       = false;
    size_t big_batch = 1;
};

struct pretraining_desc {
    size_t epochs = 25;
    bool denoising     = false;
};

struct training_desc {
    size_t epochs     = 25;
    double learning_rate   = stupid_default;
    double momentum        = stupid_default;
    size_t batch_size = 0;

    std::string decay     = "none";
    double l1_weight_cost = stupid_default;
    double l2_weight_cost = stupid_default;

    std::string trainer = "none";

    bool verbose = false;
};

struct weights_desc {
    std::string file = "weights.dat";
};

struct task {
    std::vector<std::string> default_actions;

    dll::processor::datasource_pack pretraining;
    dll::processor::datasource_pack pretraining_clean;
    dll::processor::datasource_pack training;
    dll::processor::datasource_pack testing;

    dll::processor::pretraining_desc pt_desc;
    dll::processor::training_desc ft_desc;
    dll::processor::weights_desc w_desc;
    dll::processor::general_desc general_desc;
};

template <bool Three, typename Sample>
bool read_samples(const datasource& ds, std::vector<Sample>& samples) {
    size_t limit = 0;

    if (ds.limit > 0) {
        limit = ds.limit;
    }

    if (ds.reader == "mnist") {
        mnist::read_mnist_image_file<std::vector, Sample>(samples, ds.source_file, limit, [] { return Sample(1 * 28 * 28); });
    } else if(ds.reader == "text"){
        dll::text::read_images_direct<Three>(samples, ds.source_file, limit);
    } else {
        std::cout << "dllp: error: unknown samples reader: " << ds.reader << std::endl;
        return false;
    }

    if (ds.binarize) {
        mnist::binarize_each(samples);
    }

    if (ds.normalize) {
        mnist::normalize_each(samples);
    }

    if (ds.shift) {
        for (auto& vec : samples) {
            for (auto& v : vec) {
                v += ds.shift_d;
            }
        }
    }

    if (ds.scale) {
        for (auto& vec : samples) {
            for (auto& v : vec) {
                v *= ds.scale_d;
            }
        }
    }

    if (ds.normal_noise) {
        mnist::normalize_each(samples);

        std::random_device rd;
        std::default_random_engine rand_engine(rd());
        std::normal_distribution<float> normal_distribution(0.0, ds.normal_noise_d);
        auto noise = std::bind(normal_distribution, rand_engine);

        for (auto& vec : samples) {
            for (auto& noisy_x : vec) {
                noisy_x += noise();
            }
        }

        mnist::normalize_each(samples);
    }

    return !samples.empty();
}

template <typename Label>
bool read_labels(const datasource& ds, std::vector<Label>& labels) {
    size_t limit = 0;

    if (ds.limit > 0) {
        limit = ds.limit;
    }

    if (ds.reader == "mnist") {
        mnist::read_mnist_label_file<std::vector, Label>(labels, ds.source_file, limit);
    } else if (ds.reader == "text") {
        dll::text::read_labels<std::vector, Label>(labels, ds.source_file, limit);
    } else {
        std::cout << "dllp: error: unknown labels reader: " << ds.reader << std::endl;
        return false;
    }

    return !labels.empty();
}

inline void print_title(const std::string& value) {
    std::cout << std::string(25, ' ') << std::endl;
    std::cout << std::string(25, '*') << std::endl;
    std::cout << "* " << value << std::string(25 - value.size() - 3, ' ') << "*" << std::endl;
    std::cout << std::string(25, '*') << std::endl;
    std::cout << std::string(25, ' ') << std::endl;
}

template <typename Container, bool Three, typename DBN>
void execute(DBN& dbn, task& task, const std::vector<std::string>& actions) {
    print_title("Network");
    dbn.display();

    using dbn_t = std::decay_t<DBN>;

    //Execute all the actions sequentially
    for (auto& action : actions) {
        if (action == "pretrain") {
            print_title("Pretraining");

            if (task.pretraining.samples.empty()) {
                std::cout << "dllp: error: pretrain is not possible without a pretraining input" << std::endl;
                return;
            }

            std::vector<Container> pt_samples;

            //Try to read the samples
            if (!read_samples<Three>(task.pretraining.samples, pt_samples)) {
                std::cout << "dllp: error: failed to read the pretraining samples" << std::endl;
                return;
            }

            if (task.pt_desc.denoising) {
                std::vector<Container> clean_samples;

                //Try to read the samples
                if (!read_samples<Three>(task.pretraining_clean.samples, clean_samples)) {
                    std::cout << "dllp: error: failed to read the clean samples" << std::endl;
                    return;
                }

                //Pretrain the network
                if constexpr(dbn_t::pretrain_possible && dbn_t::layers_t::is_denoising) {
                    dbn.pretrain_denoising(pt_samples.begin(), pt_samples.end(), clean_samples.begin(), clean_samples.end(), task.pt_desc.epochs);
                }
            } else {
                if constexpr (dbn_t::pretrain_possible) {
                    //Pretrain the network
                    dbn.pretrain(pt_samples.begin(), pt_samples.end(), task.pt_desc.epochs);
                }
            }
        } else if (action == "train") {
            print_title("Training");

            if (task.training.samples.empty() || task.training.labels.empty()) {
                std::cout << "dllp: error: train is not possible without samples and labels" << std::endl;
                return;
            }

            std::vector<Container> ft_samples;
            std::vector<size_t> ft_labels;

            //Try to read the samples
            if (!read_samples<Three>(task.training.samples, ft_samples)) {
                std::cout << "dllp: error: failed to read the training samples" << std::endl;
                return;
            }

            //Try to read the labels
            if (!read_labels(task.training.labels, ft_labels)) {
                std::cout << "dllp: error: failed to read the training labels" << std::endl;
                return;
            }

            using last_layer = typename dbn_t::template layer_type<dbn_t::layers - 1>;

            if(!sgd_possible<last_layer>::value){
                std::cout << "dllp: error: The network is not trainable by SGD" << std::endl;
                return;
            }

            //Train the network
            if constexpr(sgd_possible<last_layer>::value) {
                auto ft_error = dbn.fine_tune(ft_samples, ft_labels, task.ft_desc.epochs);
                std::cout << "Train Classification Error:" << ft_error << std::endl;
            }
        } else if (action == "test") {
            print_title("Testing");

            if (task.testing.samples.empty() || task.testing.labels.empty()) {
                std::cout << "dllp: error: test is not possible without samples and labels" << std::endl;
                return;
            }

            std::vector<Container> test_samples;
            std::vector<size_t> test_labels;

            //Try to read the samples
            if (!read_samples<Three>(task.testing.samples, test_samples)) {
                std::cout << "dllp: error: failed to read the test samples" << std::endl;
                return;
            }

            //Try to read the labels
            if (!read_labels(task.testing.labels, test_labels)) {
                std::cout << "dllp: error: failed to read the test labels" << std::endl;
                return;
            }

            auto classes = dbn.output_size();

            etl::dyn_matrix<size_t, 2> conf(classes, classes, 0.0);

            size_t n  = test_samples.size();
            size_t tp = 0;

            for (size_t i = 0; i < test_samples.size(); ++i) {
                auto sample = test_samples[i];
                auto label  = test_labels[i];

                auto predicted = dbn.predict(sample);

                if (predicted == label) {
                    ++tp;
                }

                ++conf(label, predicted);
            }

            double test_error = (n - tp) / double(n);

            std::cout << "Error rate: " << test_error << std::endl;
            std::cout << "Accuracy: " << (1.0 - test_error) << std::endl
                      << std::endl;

            std::cout << "Results per class" << std::endl;

            double overall = 0.0;

            std::cout << "   | Accuracy | Error rate |" << std::endl;

            for (size_t l = 0; l < classes; ++l) {
                size_t total = etl::sum(conf(l));
                double acc = (total - conf(l, l)) / double(total);
                std::cout << std::setw(3) << l;
                std::cout << "|" << std::setw(10) << (1.0 - acc) << "|" << std::setw(12) << acc << "|" << std::endl;
                overall += acc;
            }

            std::cout << std::endl;

            std::cout << "Overall Error rate: " << overall / classes << std::endl;
            std::cout << "Overall Accuracy: " << 1.0 - (overall / classes) << std::endl
                      << std::endl;

            std::cout << "Confusion Matrix (%)" << std::endl
                      << std::endl;

            std::cout << "    ";
            for (size_t l = 0; l < classes; ++l) {
                std::cout << std::setw(5) << l << " ";
            }
            std::cout << std::endl;

            for (size_t l = 0; l < classes; ++l) {
                size_t total = etl::sum(conf(l));
                std::cout << std::setw(3) << l << "|";
                for (size_t p = 0; p < classes; ++p) {
                    std::cout << std::setw(5) << std::setprecision(2) << 100.0 * (conf(l, p) / double(total)) << "|";
                }
                std::cout << std::endl;
            }
            std::cout << std::endl;
        } else if (action == "save") {
            print_title("Save Weights");

            dbn.store(task.w_desc.file);
            std::cout << "Weights saved" << std::endl;
        } else if (action == "load") {
            print_title("Load Weights");

            dbn.load(task.w_desc.file);
            std::cout << "Weights loaded" << std::endl;
        } else {
            std::cout << "dllp: error: Invalid action: " << action << std::endl;
        }
    }

    //TODO
}

} //end of namespace processor

} //end of namespace dll
<|endoftext|>


<commit_before>#ifndef EE_X_COCOS_FWD_HPP
#define EE_X_COCOS_FWD_HPP

#include <cstddef>
#include <string>
#include <unordered_map>

#include <platform/CCPlatformDefine.h> // For CC_DLL

#include <ee/CoreFwd.hpp>

#include "ee/cocos/EEMacro.hpp"

enum class ResolutionPolicy;

namespace cocos2d {
class Node;
class DrawNode;
class Font;
class FontAtlas;
class Label;
class LabelAtlas;
class Layer;
class LayerColor;
class Scene;
class Transition;
class ProgressTimer;
class Menu;
class MenuItem;
class MenuItemImage;
class ClippingRectangleNode;
class ClippingNode;
class ParticleSystem;
class ParticleSystemQuad;
class Animation;
class Sprite;
class SpriteFrame;
class SpriteBatchNode;
class Image;
class Texture2D;
class RenderTexture;

struct _ttfConfig;
using TTFConfig = _ttfConfig;

class Action;
class ActionInstant;
class Show;
class Hide;
class RemoveSelf;
class FlipX;
class FlipY;
class Place;
class CallFunc;

class ActionInterval;
class FiniteTimeAction;
class Speed;
class Follow;
class Repeat;
class RepeatForever;
class Spawn;
class RotateTo;
class RotateBy;
class MoveTo;
class MoveBy;
class SkewTo;
class SkewBy;
class ScaleBy;
class ScaleTo;
class Blink;
class FadeTo;
class FadeIn;
class FadeOut;
class DelayTime;
class ActionFloat;
class ActionEase;
class Sequence;

class Event;
class EventCustom;
class EventListener;
class EventListenerCustom;
class EventListenerKeyboard;
class EventListenerTouchOneByOne;
class EventListenerTouchAllAtOnce;
class EventTouch;

class Touch;

class Ref;

template <class T>
class RefPtr;

template <class T>
class Vector;

class Value;
using ValueMap = std::unordered_map<std::string, Value>;

class __Array;
using Array = __Array;

class __Bool;
using Bool = __Bool;

class __Dictionary;
using Dictionary = __Dictionary;

class __Double;
using Double = __Double;

class __Float;
using Float = __Float;

class __Integer;
using Integer = __Integer;

class __Set;
using Set = __Set;

class __String;
using String = __String;

class Vec2;
using Point = Vec2;

class Vec3;
class Mat3;
class Mat4;

class Size;
class Rect;
struct Color3B;
struct Color4F;
struct BlendFunc;

class GLProgram;
class GLProgramState;

struct Uniform;

namespace extension {
class ControlButton;
class ScrollView;
} // namespace extension
} // namespace cocos2d

namespace cocos2d {
namespace ui {
class ListView;
class LoadingBar;
class PageView;
class RichText;
class ScrollView;
class Slider;
class Text;
class TextAtlas;
class Button;
class CheckBox;
class RadioButton;
class ImageView;
class Scale9Sprite;
class Widget;
class EditBox;
class EditBoxDelegate;
class TextField;
class Layout;
} // namespace ui
} // namespace cocos2d

namespace cocos2d {
namespace network {
class HttpClient;
class HttpResponse;
} // namespace network
} // namespace cocos2d

namespace cocosbuilder {
struct BlockData;
struct BlockControlData;

class CCBReader;
class NodeLoaderLibrary;
class NodeLoader;
class SpriteLoader;
class Scale9SpriteLoader;
class ControlLoader;
class LabelBMFontLoader;
class LabelTTFLoader;
class LayerLoader;
class LayerColorLoader;
class LayerGradientLoader;
class ScrollViewLoader;
class ParticleSystemQuadLoader;
class CCBMemberVariableAssigner;
class CCBSelectorResolver;
} // namespace cocosbuilder

namespace spine {
class SkeletonAnimation;
} // namespace spine

namespace ee {
template <class Np, class Lp, class... Ts>
class GenericLoader;

template <class T>
class Pool;
template <class T>
class LazyPtr;

class Action;
class ContinuousAction;

class Sequence;
class Spawn;
class RelativeMoveBy;
class RelativeMoveTo;

namespace detail {
class ButtonEx;
} // namespace detail

using Button = detail::ButtonEx;

class CheckBox;

class BackButtonComponent;

class Console;

template <class T>
class BackButtonListener;

class NodeV3Loader;
class UiWidgetLoader;
class UiButtonLoader;
class UiTextLoader;
class UiLayoutLoader;
class ClippingRectangleNodeLoader;

class ButtonLoader;

class SpriteWithHsv;
class SpriteWithHsvLoader;

class Scale9SpriteWithHsv;

class BlurBackground;
class BlurBackgroundLoader;

namespace language {
class Language;
class ISwitcher;
class Switcher;
class Delegate;
class Formatter;
class MultilingualDelegate;
} // namespace language

using Language = language::Language;
using ILanguageSwitcher = language::ISwitcher;
using LanguageSwitcher = language::Switcher;
using LanguageDelegate = language::Delegate;
using LanguageFormatter = language::Formatter;

namespace ui {
class Widget;
class WidgetLoader;
} // namespace ui

using ui::Widget;
using ui::WidgetLoader;

class ImageBuilder;
class ManagedScene;
class SceneSwitcher;

class Shader;

class SkeletonAnimationLoader;
class SkeletonBone;
class SkeletonBoneLoader;

template <std::size_t Id, class... Args>
class EventInfo;
class EventDispatcher;

template <class T, class = void>
struct DataTraits;

template <class... Keys>
struct DataFormat;

template <std::size_t Id, class Value, class... Args>
struct DataInfo;

class DataHandler;
} // namespace ee

namespace ee {
namespace cocos {
enum class DialogCommandType;

struct DialogCommand;
struct DialogGuard;

class Dialog;
class DialogComponent;
class DialogManager;
class IDialogManager;

class Metrics;

struct Delay;
struct SwitchToCocosThread;
} // namespace cocos

using cocos::Dialog;
using cocos::DialogComponent;
using cocos::Metrics;

using cocos::Delay;
using cocos::SwitchToCocosThread;
} // namespace ee

#endif // EE_X_COCOS_FWD_HPP
<commit_msg>Forward cocos class.<commit_after>#ifndef EE_X_COCOS_FWD_HPP
#define EE_X_COCOS_FWD_HPP

#include <cstddef>
#include <string>
#include <unordered_map>

#include <platform/CCPlatformDefine.h> // For CC_DLL

#include <ee/CoreFwd.hpp>

#include "ee/cocos/EEMacro.hpp"

enum class ResolutionPolicy;

namespace cocos2d {
class Node;
class DrawNode;
class Font;
class FontAtlas;
class Label;
class LabelAtlas;
class Layer;
class LayerColor;
class Scene;
class Transition;
class ProgressTimer;
class Menu;
class MenuItem;
class MenuItemImage;
class MenuItemToggle;
class ClippingRectangleNode;
class ClippingNode;
class ParticleSystem;
class ParticleSystemQuad;
class Animation;
class Sprite;
class SpriteFrame;
class SpriteBatchNode;
class Image;
class Texture2D;
class RenderTexture;

struct _ttfConfig;
using TTFConfig = _ttfConfig;

class Action;
class ActionInstant;
class Show;
class Hide;
class RemoveSelf;
class FlipX;
class FlipY;
class Place;
class CallFunc;

class ActionInterval;
class FiniteTimeAction;
class Speed;
class Follow;
class Repeat;
class RepeatForever;
class Spawn;
class RotateTo;
class RotateBy;
class MoveTo;
class MoveBy;
class SkewTo;
class SkewBy;
class ScaleBy;
class ScaleTo;
class Blink;
class FadeTo;
class FadeIn;
class FadeOut;
class DelayTime;
class ActionFloat;
class ActionEase;
class Sequence;

class Event;
class EventCustom;
class EventListener;
class EventListenerCustom;
class EventListenerKeyboard;
class EventListenerTouchOneByOne;
class EventListenerTouchAllAtOnce;
class EventTouch;

class Touch;

class Ref;

template <class T>
class RefPtr;

template <class T>
class Vector;

class Value;
using ValueMap = std::unordered_map<std::string, Value>;

class __Array;
using Array = __Array;

class __Bool;
using Bool = __Bool;

class __Dictionary;
using Dictionary = __Dictionary;

class __Double;
using Double = __Double;

class __Float;
using Float = __Float;

class __Integer;
using Integer = __Integer;

class __Set;
using Set = __Set;

class __String;
using String = __String;

class Vec2;
using Point = Vec2;

class Vec3;
class Mat3;
class Mat4;

class Size;
class Rect;
struct Color3B;
struct Color4F;
struct BlendFunc;

class GLProgram;
class GLProgramState;

struct Uniform;

namespace extension {
class ControlButton;
class ScrollView;
} // namespace extension
} // namespace cocos2d

namespace cocos2d {
namespace ui {
class ListView;
class LoadingBar;
class PageView;
class RichText;
class ScrollView;
class Slider;
class Text;
class TextAtlas;
class Button;
class CheckBox;
class RadioButton;
class ImageView;
class Scale9Sprite;
class Widget;
class EditBox;
class EditBoxDelegate;
class TextField;
class Layout;
} // namespace ui
} // namespace cocos2d

namespace cocos2d {
namespace network {
class HttpClient;
class HttpResponse;
} // namespace network
} // namespace cocos2d

namespace cocosbuilder {
struct BlockData;
struct BlockControlData;

class CCBReader;
class NodeLoaderLibrary;
class NodeLoader;
class SpriteLoader;
class Scale9SpriteLoader;
class ControlLoader;
class LabelBMFontLoader;
class LabelTTFLoader;
class LayerLoader;
class LayerColorLoader;
class LayerGradientLoader;
class ScrollViewLoader;
class ParticleSystemQuadLoader;
class CCBMemberVariableAssigner;
class CCBSelectorResolver;
} // namespace cocosbuilder

namespace spine {
class SkeletonAnimation;
} // namespace spine

namespace ee {
template <class Np, class Lp, class... Ts>
class GenericLoader;

template <class T>
class Pool;
template <class T>
class LazyPtr;

class Action;
class ContinuousAction;

class Sequence;
class Spawn;
class RelativeMoveBy;
class RelativeMoveTo;

namespace detail {
class ButtonEx;
} // namespace detail

using Button = detail::ButtonEx;

class CheckBox;

class BackButtonComponent;

class Console;

template <class T>
class BackButtonListener;

class NodeV3Loader;
class UiWidgetLoader;
class UiButtonLoader;
class UiTextLoader;
class UiLayoutLoader;
class ClippingRectangleNodeLoader;

class ButtonLoader;

class SpriteWithHsv;
class SpriteWithHsvLoader;

class Scale9SpriteWithHsv;

class BlurBackground;
class BlurBackgroundLoader;

namespace language {
class Language;
class ISwitcher;
class Switcher;
class Delegate;
class Formatter;
class MultilingualDelegate;
} // namespace language

using Language = language::Language;
using ILanguageSwitcher = language::ISwitcher;
using LanguageSwitcher = language::Switcher;
using LanguageDelegate = language::Delegate;
using LanguageFormatter = language::Formatter;

namespace ui {
class Widget;
class WidgetLoader;
} // namespace ui

using ui::Widget;
using ui::WidgetLoader;

class ImageBuilder;
class ManagedScene;
class SceneSwitcher;

class Shader;

class SkeletonAnimationLoader;
class SkeletonBone;
class SkeletonBoneLoader;

template <std::size_t Id, class... Args>
class EventInfo;
class EventDispatcher;

template <class T, class = void>
struct DataTraits;

template <class... Keys>
struct DataFormat;

template <std::size_t Id, class Value, class... Args>
struct DataInfo;

class DataHandler;
} // namespace ee

namespace ee {
namespace cocos {
enum class DialogCommandType;

struct DialogCommand;
struct DialogGuard;

class Dialog;
class DialogComponent;
class DialogManager;
class IDialogManager;

class Metrics;

struct Delay;
struct SwitchToCocosThread;
} // namespace cocos

using cocos::Dialog;
using cocos::DialogComponent;
using cocos::Metrics;

using cocos::Delay;
using cocos::SwitchToCocosThread;
} // namespace ee

#endif // EE_X_COCOS_FWD_HPP
<|endoftext|>


<commit_before>/*
 * dynSSSPGTest.cpp
 *
 *  Created on: 21.07.2014
 *      Author: ebergamini
 */

#include "dynSSSPGTest.h"
#include "../dynBFS.h"
#include "../BFS.h"
#include "../dynDijkstra.h"
#include "../Dijkstra.h"
#include "../../io/METISGraphReader.h"
#include "../../auxiliary/Log.h"

namespace NetworKit {

TEST_F(DynSSSPGTest, testDynamicBFS_1edge) {
/* Graph:
    0    3   6
     \  / \ /
      2    5
     /  \ / \
    1    4   7
 */
	count n = 8;
	Graph G(n);

	G.addEdge(0, 2);
	G.addEdge(1, 2);
	G.addEdge(2, 3);
	G.addEdge(2, 4);
	G.addEdge(3, 5);
	G.addEdge(4, 5);
	G.addEdge(5, 6);
	G.addEdge(5, 7);

  BFS bfs(G, 0);
  bfs.run();
  DynBFS dbfs(G, 0);
	dbfs.init();
	std::vector<GraphEvent> batch(1);
	batch[0].type = GraphEvent::EDGE_ADDITION;
	batch[0].u = 0;
	batch[0].v = 6;
	batch[0].w = 1.0;
	for (GraphEvent edge : batch) {
		G.addEdge(edge.u, edge.v, edge.w);
	}
	dbfs.update(batch);
	bfs.run();
	G.forNodes([&] (node i) {
		EXPECT_EQ(bfs.distance(i), dbfs.distance(i));
		EXPECT_EQ(bfs.numberOfPaths(i), dbfs.numberOfPaths(i));
	});
}

TEST_F(DynSSSPGTest, testDynamicBFS_batch) {
/* Graph:
		0    3   6
		\  / \ /
			2    5
		/  \ / \
		1    4   7
*/
	count n = 8;
	Graph G(n);

	G.addEdge(0, 2);
	G.addEdge(1, 2);
	G.addEdge(2, 3);
	G.addEdge(2, 4);
	G.addEdge(3, 5);
	G.addEdge(4, 5);
	G.addEdge(5, 6);
	G.addEdge(5, 7);

	BFS bfs(G, 0);
	bfs.run();
	DynBFS dbfs(G, 0);
	dbfs.init();
	std::vector<GraphEvent> batch(3);
	batch[0].type = GraphEvent::EDGE_ADDITION;
	batch[0].u = 3;
	batch[0].v = 7;
	batch[0].w = 1.0;
	batch[1].type = GraphEvent::EDGE_ADDITION;
	batch[1].u = 0;
	batch[1].v = 5;
	batch[1].w = 1.0;
	batch[2].type = GraphEvent::EDGE_ADDITION;
	batch[2].u = 2;
	batch[2].v = 7;
	batch[2].w = 1.0;
	for (GraphEvent edge : batch) {
		G.addEdge(edge.u, edge.v, edge.w);
	}
	dbfs.update(batch);
	bfs.run();
	G.forNodes([&] (node i) {
		EXPECT_EQ(bfs.distance(i), dbfs.distance(i));
		EXPECT_EQ(bfs.numberOfPaths(i), dbfs.numberOfPaths(i));
	});

}

TEST_F(DynSSSPGTest, testDynamicDijkstra) {
 /* Graph:
    0    3   6
     \  / \ /
      2 -- 5
     /  \ / \
    1    4   7

    Edges in the upper row have weight 3,
    the edge in the middle row has weight 1.5,
    edges in the lower row have weight 2.
 */
	count n = 8;
	Graph G(n, true);

	G.addEdge(0, 2, 3);
	G.addEdge(1, 2, 2);
	G.addEdge(2, 3, 3);
	G.addEdge(2, 4, 2);
	G.addEdge(2, 5, 1.5);
	G.addEdge(3, 5, 3);
	G.addEdge(4, 5, 2);
	G.addEdge(5, 6, 3);
	G.addEdge(5, 7, 2);

	Dijkstra dij(G, 0);
	dij.run();
	DynDijkstra ddij(G, 0);
	ddij.run();
	std::vector<GraphEvent> batch(3);
	batch[0].type = GraphEvent::EDGE_ADDITION;
	batch[0].u = 0;
	batch[0].v = 4;
	batch[0].w = 1.0;
	batch[1].type = GraphEvent::EDGE_ADDITION;
	batch[1].u = 1;
	batch[1].v = 4;
	batch[1].w = 1.0;
	batch[2].type = GraphEvent::EDGE_ADDITION;
	batch[2].u = 6;
	batch[2].v = 7;
	batch[2].w = 3.0;
	for (GraphEvent edge : batch) {
		G.addEdge(edge.u, edge.v, edge.w);
	}
	ddij.update(batch);
	dij.run();
	G.forNodes([&] (node i) {
		EXPECT_EQ(dij.distance(i), ddij.distance(i));
		EXPECT_EQ(dij.numberOfPaths(i), ddij.numberOfPaths(i));
	});

}

} /* namespace NetworKit */
<commit_msg>Fix includes in DynSSSPGTest<commit_after>/*
 * dynSSSPGTest.cpp
 *
 *  Created on: 21.07.2014
 *      Author: ebergamini
 */

#include "DynSSSPGTest.h"
#include "../DynBFS.h"
#include "../BFS.h"
#include "../DynDijkstra.h"
#include "../Dijkstra.h"
#include "../../io/METISGraphReader.h"
#include "../../auxiliary/Log.h"

namespace NetworKit {

TEST_F(DynSSSPGTest, testDynamicBFS_1edge) {
/* Graph:
    0    3   6
     \  / \ /
      2    5
     /  \ / \
    1    4   7
 */
	count n = 8;
	Graph G(n);

	G.addEdge(0, 2);
	G.addEdge(1, 2);
	G.addEdge(2, 3);
	G.addEdge(2, 4);
	G.addEdge(3, 5);
	G.addEdge(4, 5);
	G.addEdge(5, 6);
	G.addEdge(5, 7);

  BFS bfs(G, 0);
  bfs.run();
  DynBFS dbfs(G, 0);
	dbfs.init();
	std::vector<GraphEvent> batch(1);
	batch[0].type = GraphEvent::EDGE_ADDITION;
	batch[0].u = 0;
	batch[0].v = 6;
	batch[0].w = 1.0;
	for (GraphEvent edge : batch) {
		G.addEdge(edge.u, edge.v, edge.w);
	}
	dbfs.update(batch);
	bfs.run();
	G.forNodes([&] (node i) {
		EXPECT_EQ(bfs.distance(i), dbfs.distance(i));
		EXPECT_EQ(bfs.numberOfPaths(i), dbfs.numberOfPaths(i));
	});
}

TEST_F(DynSSSPGTest, testDynamicBFS_batch) {
/* Graph:
		0    3   6
		\  / \ /
			2    5
		/  \ / \
		1    4   7
*/
	count n = 8;
	Graph G(n);

	G.addEdge(0, 2);
	G.addEdge(1, 2);
	G.addEdge(2, 3);
	G.addEdge(2, 4);
	G.addEdge(3, 5);
	G.addEdge(4, 5);
	G.addEdge(5, 6);
	G.addEdge(5, 7);

	BFS bfs(G, 0);
	bfs.run();
	DynBFS dbfs(G, 0);
	dbfs.init();
	std::vector<GraphEvent> batch(3);
	batch[0].type = GraphEvent::EDGE_ADDITION;
	batch[0].u = 3;
	batch[0].v = 7;
	batch[0].w = 1.0;
	batch[1].type = GraphEvent::EDGE_ADDITION;
	batch[1].u = 0;
	batch[1].v = 5;
	batch[1].w = 1.0;
	batch[2].type = GraphEvent::EDGE_ADDITION;
	batch[2].u = 2;
	batch[2].v = 7;
	batch[2].w = 1.0;
	for (GraphEvent edge : batch) {
		G.addEdge(edge.u, edge.v, edge.w);
	}
	dbfs.update(batch);
	bfs.run();
	G.forNodes([&] (node i) {
		EXPECT_EQ(bfs.distance(i), dbfs.distance(i));
		EXPECT_EQ(bfs.numberOfPaths(i), dbfs.numberOfPaths(i));
	});

}

TEST_F(DynSSSPGTest, testDynamicDijkstra) {
 /* Graph:
    0    3   6
     \  / \ /
      2 -- 5
     /  \ / \
    1    4   7

    Edges in the upper row have weight 3,
    the edge in the middle row has weight 1.5,
    edges in the lower row have weight 2.
 */
	count n = 8;
	Graph G(n, true);

	G.addEdge(0, 2, 3);
	G.addEdge(1, 2, 2);
	G.addEdge(2, 3, 3);
	G.addEdge(2, 4, 2);
	G.addEdge(2, 5, 1.5);
	G.addEdge(3, 5, 3);
	G.addEdge(4, 5, 2);
	G.addEdge(5, 6, 3);
	G.addEdge(5, 7, 2);

	Dijkstra dij(G, 0);
	dij.run();
	DynDijkstra ddij(G, 0);
	ddij.run();
	std::vector<GraphEvent> batch(3);
	batch[0].type = GraphEvent::EDGE_ADDITION;
	batch[0].u = 0;
	batch[0].v = 4;
	batch[0].w = 1.0;
	batch[1].type = GraphEvent::EDGE_ADDITION;
	batch[1].u = 1;
	batch[1].v = 4;
	batch[1].w = 1.0;
	batch[2].type = GraphEvent::EDGE_ADDITION;
	batch[2].u = 6;
	batch[2].v = 7;
	batch[2].w = 3.0;
	for (GraphEvent edge : batch) {
		G.addEdge(edge.u, edge.v, edge.w);
	}
	ddij.update(batch);
	dij.run();
	G.forNodes([&] (node i) {
		EXPECT_EQ(dij.distance(i), ddij.distance(i));
		EXPECT_EQ(dij.numberOfPaths(i), ddij.numberOfPaths(i));
	});

}

} /* namespace NetworKit */
<|endoftext|>


<commit_before>//
//  Queue.cpp
//  Queue
//
//  Created by Sunil on 2/23/17.
//  Copyright © 2017 Sunil. All rights reserved.
//

#ifndef Queue_cpp
#define Queue_cpp

#include "Queue.hpp"

#include <iostream>

using namespace std;

template<typename T>
Queue<T>::Queue() {
    reset();
}

template<typename T>
Queue<T>::~Queue() {
    head = 0;
    tail = 0;
    filled = 0;
    container = nullptr;
}

template<typename T>
Queue<T>::Queue(Queue<T>& queue) : Queue() {
    auto elements = queue.container.get();

    int index = 0;
    while(index < queue.filled) {
        Enqueue(elements[index++]);
    }
}

template<typename T>
Queue<T>::Queue(Queue<T>&& queue) {
    container = std::move(queue.container);
    filled = queue.filled;
    head = queue.head;
    tail = queue.tail;
    queue.reset();
}

template<typename T>
typename Queue<T>::ElementType Queue<T>::Dequeue() {
    if(isEmpty()) {
        throw "Queue is empty";
    }

    auto value = container.get()[head];
    head = (head+1)%capacity;
    filled--;
    return value;
}

template<typename T>
void Queue<T>::Enqueue(ElementType value) {
    if (isFull()) {
        throw "Queue is full";
    }

    container.get()[tail] = value;
    tail = (tail+1)%capacity;
    filled++;
}

template<typename T>
bool Queue<T>::isEmpty() {
    return filled == 0;
}

template<typename T>
bool Queue<T>::isFull() {
    return filled == capacity;
}

template<typename T>
void Queue<T>::reset() {
    head = 0;
    tail = 0;
    filled = 0;

    container =
    std::unique_ptr<ElementType, std::function<void(ElementPtr)>>(new ElementType[capacity], [](ElementPtr ptr) {
        cout << "deleting array of " << typeid(T).name() << endl;
        delete[] ptr;
    });
}

#endif /* Queue_cpp */
<commit_msg>Update Queue.cpp<commit_after>//
//  Queue.cpp
//  Queue
//
//  Created by Sunil on 2/23/17.
//  Copyright © 2017 Sunil. All rights reserved.
//

#ifndef Queue_cpp
#define Queue_cpp

#include "Queue.hpp"

#include <iostream>

using namespace std;

template<typename T>
Queue<T>::Queue() {
    reset();
}

template<typename T>
Queue<T>::~Queue() {
    head = 0;
    tail = 0;
    filled = 0;
    container = nullptr;
}

template<typename T>
Queue<T>::Queue(Queue<T>& queue) : Queue() {
    auto elements = queue.container.get();

    int index = 0;
    while(index < queue.filled) {
        Enqueue(elements[index++]);
    }
}

template<typename T>
Queue<T>::Queue(Queue<T>&& queue) {
    container = std::move(queue.container);
    filled = queue.filled;
    head = queue.head;
    tail = queue.tail;

    queue.head = 0;
    queue.tail = 0;
    queue.filled = 0;
    queue.container = nullptr;
}

template<typename T>
typename Queue<T>::ElementType Queue<T>::Dequeue() {
    if(isEmpty()) {
        throw "Queue is empty";
    }

    auto value = container.get()[head];
    head = (head+1)%capacity;
    filled--;
    return value;
}

template<typename T>
void Queue<T>::Enqueue(ElementType value) {
    if (isFull()) {
        throw "Queue is full";
    }

    container.get()[tail] = value;
    tail = (tail+1)%capacity;
    filled++;
}

template<typename T>
bool Queue<T>::isEmpty() {
    return filled == 0;
}

template<typename T>
bool Queue<T>::isFull() {
    return filled == capacity;
}

template<typename T>
void Queue<T>::reset() {
    head = 0;
    tail = 0;
    filled = 0;

    container =
    std::unique_ptr<ElementType, std::function<void(ElementPtr)>>(new ElementType[capacity], [](ElementPtr ptr) {
        cout << "deleting array of " << typeid(T).name() << endl;
        delete[] ptr;
    });
}

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


<commit_before>/*
 * fast.hpp
 *
 *  Created on: Oct 6, 2014
 *      Author: Michal Busta
 */
#ifndef CMP_FAST_HPP_
#define CMP_FAST_HPP_

#include "KeyPoints.h"
#include <unordered_map>
#include <vector>
#include <map>

namespace cmp{

inline long ColourDistance(const uchar* e1, const uchar* e2)
{
	int ur1 = e1[2];
	int ur2 = e2[2];
	long rmean = (  ur1 + ur2 ) / 2;
	long r = ur1 - ur2;
	int ug1 = e1[1];
	int ug2 = e2[1];
	long g = ug1 - ug2;
	int ub1 = e1[0];
	int ub2 = e2[0];
	long b = ub1 - ub2;
	return (((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8);
}

inline long ColourDistanceMAX(const uchar* e1, const uchar* e2, uchar& sign)
{
	int d1 = e1[0] - (int) e2[0];
	int ad1 = abs(d1);
	int d2 = e1[0] - (int) e2[0];
	int ad2 = abs(d2);
	int d3 = e1[0] - (int) e2[0];
	int ad3 = abs(d3);
	if(ad1 > ad2)
	{
		if(ad1 > ad3)
		{
			sign = d1 > 0;
			return ad1;
		}
		sign = d3 > 0;
		return ad3;
	}else
	{
		if(ad2 > ad3)
		{
			sign = d2 > 0;
			return ad2;
		}
		sign = d3 > 0;
		return ad3;
	}
}

inline long ColourDistanceVec(const cv::Vec3b& e1, const cv::Vec3b& e2)
{
	int ur1 = e1[2];
	int ur2 = e2[2];
	long rmean = (  ur1 + ur2 ) / 2;
	long r = ur1 - ur2;
	int ug1 = e1[1];
	int ug2 = e2[1];
	long g = ug1 - ug2;
	int ub1 = e1[0];
	int ub2 = e2[0];
	long b = ub1 - ub2;
	return (((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8);
}

inline long ColourDistanceGray(const uchar& e1, const uchar& e2)
{
	return e2 - e1;
}

template<int channel>
inline long ColourDistanceRGB(const cv::Vec3b& e1, const cv::Vec3b& e2)
{
	return e2[channel] - e1[channel];
}

template<int channel>
inline long ColourDistanceRGBP(const uchar& e1, const uchar& e2)
{
	return (&e2)[channel] - (&e1)[channel];
}

template<int channel>
inline long ColourDistanceRGBIP(const uchar& e1, const uchar& e2)
{
	return (&e1)[channel] - (&e2)[channel];
}

inline long ColourDistanceGrayABS(const uchar* e1, const uchar* e2)
{
	return abs(((int) *e2) - *e1);
}

inline long ColourDistanceGrayP(const uchar* e1, const uchar* e2)
{
	return (*e2 - *e1);
}

inline long ColourDistanceGrayI(const uchar& e1, const uchar& e2)
{
	return e1 - e2;
}

template<int channel>
inline long ColourDistanceRGBI(const cv::Vec3b& e1, const cv::Vec3b& e2)
{
	return (e1)[channel] - (e2)[channel];
}

inline long ColourDistanceGrayIP(const uchar* e1, const uchar* e2)
{
	return ( *e1 - *e2);
}

inline long ColourDistanceGrayNorm(const uchar* e1, const uchar* e2)
{
	int ur1 = e1[0];
	int ur2 = e2[0];
	long rmean = (  ur1 + ur2 ) / 2;
	long r = ur1 - ur2;
	return (((512+rmean)*r*r)>>8);
}

inline int getValueCorner12(const uchar * ptr, int* pixel, int* corners, const int& k, const int& ks, const uchar& (*dist)(const uchar&, const uchar&) )
{
	int x = ptr[pixel[k]];

	if( k == 3 && ks != 2 && ks != 3 ){
		x = dist(x, ptr[corners[0]]);
	}else if(k == 5 && ks != 4 && ks != 5){
		x = dist(x, ptr[corners[1]]);
	}else if(k == 8 && ks != 7 && ks != 8){
		x = dist(x, ptr[corners[2]]);
	}else if(k == 11 && ks != 11){
		x = dist(x, ptr[corners[3]]);
	}

	return x;
}

inline void getCrossCorner12(const uchar * ptr, int* corners, int* cornersOut, const int& k, int& k1, int& k2, const uchar& (*dist)(const uchar&, const uchar&) )
{
	switch(k){
	case 0:
	case 1:
	case 11:
		k1 = dist(ptr[cornersOut[1]], ptr[corners[1]]);
		k2 = dist(ptr[cornersOut[2]], ptr[corners[2]]);
		break;
	case 2:
	case 3:
	case 4:
		k1 = dist(ptr[cornersOut[2]], ptr[corners[2]]);
		k2 = dist(ptr[cornersOut[3]], ptr[corners[3]]);
		break;
	case 5:
	case 6:
	case 7:
		k1 = dist(ptr[cornersOut[0]], ptr[corners[0]]);
		k2 = dist(ptr[cornersOut[3]], ptr[corners[3]]);
		break;
	case 8:
	case 9:
	case 10:
		k1 = dist(ptr[cornersOut[0]], ptr[corners[0]]);
		k2 = dist(ptr[cornersOut[1]], ptr[corners[1]]);
		break;
	}
}

class CV_EXPORTS_W FastFeatureDetectorC
{
public:

	enum
	{
		KEY_POINTS_BLACK = 0, KEY_POINTS_WHITE = 1, KEY_POINTS_ALL = 3
	};

    CV_WRAP FastFeatureDetectorC( long threshold = 10, bool nonmaxSuppression=true, int keypointsTypes = KEY_POINTS_ALL, int Kmin = 9, int Kmax = 11);

    virtual ~FastFeatureDetectorC(){

    };

    void detect( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints, const cv::Mat& mask ) const
    {
        keypoints.clear();

        if( image.empty() )
            return;

        CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );
        detectImpl( image, keypoints, mask );
    }

    void segment( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints, std::unordered_multimap<int, std::pair<int, int> >& keypointsPixels, const cv::Mat& mask ) const
    {
    	keypoints.clear();

    	if( image.empty() )
    		return;

    	CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );
    	segmentImpl( image, keypoints, keypointsPixels, mask );
    }

    virtual bool isColorDetector(){
    	return false;
    }

    void setThreshold(long threshold){
    	this->threshold = threshold;
    }

    void setKeypointsTypes(int keypointsTypes){
    	this->keypointsTypes = keypointsTypes;
    }

protected:

    virtual void detectImpl( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const = 0;

    virtual void segmentImpl( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints,  std::unordered_multimap<int, std::pair<int, int> >& keypointsPixels, const cv::Mat& mask=cv::Mat() ) const
    {
    	detectImpl( image, keypoints, mask);
    }

    long threshold;
    bool nonmaxSuppression;
    int Kmin;
    int Kmax;

    int keypointsTypes;

    std::vector<std::vector<float> > fastAngles;
};

/**
 * Gray level Fast Feature detector
 */
class CV_EXPORTS_W FASTextGray : public FastFeatureDetectorC
{
public:

    CV_WRAP FASTextGray( long threshold=10, bool nonmaxSuppression=true, int keypointsTypes = KEY_POINTS_ALL, int Kmin = 9, int Kmax = 11);

    virtual ~FASTextGray(){

    };

protected:

    virtual void detectImpl( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const;
};

}//namespace cmp;

#endif /* FAST_HPP_ */
<commit_msg>Fix warnings in FASTex.hpp<commit_after>/*
 * fast.hpp
 *
 *  Created on: Oct 6, 2014
 *      Author: Michal Busta
 */
#ifndef CMP_FAST_HPP_
#define CMP_FAST_HPP_

#include "KeyPoints.h"
#include <unordered_map>
#include <vector>
#include <map>

namespace cmp{

inline long ColourDistance(const uchar* e1, const uchar* e2)
{
	int ur1 = e1[2];
	int ur2 = e2[2];
	long rmean = (  ur1 + ur2 ) / 2;
	long r = ur1 - ur2;
	int ug1 = e1[1];
	int ug2 = e2[1];
	long g = ug1 - ug2;
	int ub1 = e1[0];
	int ub2 = e2[0];
	long b = ub1 - ub2;
	return (((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8);
}

inline long ColourDistanceMAX(const uchar* e1, const uchar* e2, uchar& sign)
{
	int d1 = e1[0] - (int) e2[0];
	int ad1 = abs(d1);
	int d2 = e1[0] - (int) e2[0];
	int ad2 = abs(d2);
	int d3 = e1[0] - (int) e2[0];
	int ad3 = abs(d3);
	if(ad1 > ad2)
	{
		if(ad1 > ad3)
		{
			sign = d1 > 0;
			return ad1;
		}
		sign = d3 > 0;
		return ad3;
	}else
	{
		if(ad2 > ad3)
		{
			sign = d2 > 0;
			return ad2;
		}
		sign = d3 > 0;
		return ad3;
	}
}

inline long ColourDistanceVec(const cv::Vec3b& e1, const cv::Vec3b& e2)
{
	int ur1 = e1[2];
	int ur2 = e2[2];
	long rmean = (  ur1 + ur2 ) / 2;
	long r = ur1 - ur2;
	int ug1 = e1[1];
	int ug2 = e2[1];
	long g = ug1 - ug2;
	int ub1 = e1[0];
	int ub2 = e2[0];
	long b = ub1 - ub2;
	return (((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8);
}

inline long ColourDistanceGray(const uchar& e1, const uchar& e2)
{
	return e2 - e1;
}

template<int channel>
inline long ColourDistanceRGB(const cv::Vec3b& e1, const cv::Vec3b& e2)
{
	return e2[channel] - e1[channel];
}

template<int channel>
inline long ColourDistanceRGBP(const uchar& e1, const uchar& e2)
{
	return (&e2)[channel] - (&e1)[channel];
}

template<int channel>
inline long ColourDistanceRGBIP(const uchar& e1, const uchar& e2)
{
	return (&e1)[channel] - (&e2)[channel];
}

inline long ColourDistanceGrayABS(const uchar* e1, const uchar* e2)
{
	return abs(((int) *e2) - *e1);
}

inline long ColourDistanceGrayP(const uchar* e1, const uchar* e2)
{
	return (*e2 - *e1);
}

inline long ColourDistanceGrayI(const uchar& e1, const uchar& e2)
{
	return e1 - e2;
}

template<int channel>
inline long ColourDistanceRGBI(const cv::Vec3b& e1, const cv::Vec3b& e2)
{
	return (e1)[channel] - (e2)[channel];
}

inline long ColourDistanceGrayIP(const uchar* e1, const uchar* e2)
{
	return ( *e1 - *e2);
}

inline long ColourDistanceGrayNorm(const uchar* e1, const uchar* e2)
{
	int ur1 = e1[0];
	int ur2 = e2[0];
	long rmean = (  ur1 + ur2 ) / 2;
	long r = ur1 - ur2;
	return (((512+rmean)*r*r)>>8);
}

inline int getValueCorner12(const uchar * ptr, int* pixel, int* corners, const int& k, const int& ks, const uchar& (*dist)(const uchar&, const uchar&) )
{
	uchar x = ptr[pixel[k]];

	if( k == 3 && ks != 2 && ks != 3 ){
		x = dist(x, ptr[corners[0]]);
	}else if(k == 5 && ks != 4 && ks != 5){
		x = dist(x, ptr[corners[1]]);
	}else if(k == 8 && ks != 7 && ks != 8){
		x = dist(x, ptr[corners[2]]);
	}else if(k == 11 && ks != 11){
		x = dist(x, ptr[corners[3]]);
	}

	return x;
}

inline void getCrossCorner12(const uchar * ptr, int* corners, int* cornersOut, const int& k, int& k1, int& k2, const uchar& (*dist)(const uchar&, const uchar&) )
{
	switch(k){
	case 0:
	case 1:
	case 11:
		k1 = dist(ptr[cornersOut[1]], ptr[corners[1]]);
		k2 = dist(ptr[cornersOut[2]], ptr[corners[2]]);
		break;
	case 2:
	case 3:
	case 4:
		k1 = dist(ptr[cornersOut[2]], ptr[corners[2]]);
		k2 = dist(ptr[cornersOut[3]], ptr[corners[3]]);
		break;
	case 5:
	case 6:
	case 7:
		k1 = dist(ptr[cornersOut[0]], ptr[corners[0]]);
		k2 = dist(ptr[cornersOut[3]], ptr[corners[3]]);
		break;
	case 8:
	case 9:
	case 10:
		k1 = dist(ptr[cornersOut[0]], ptr[corners[0]]);
		k2 = dist(ptr[cornersOut[1]], ptr[corners[1]]);
		break;
	}
}

class CV_EXPORTS_W FastFeatureDetectorC
{
public:

	enum
	{
		KEY_POINTS_BLACK = 0, KEY_POINTS_WHITE = 1, KEY_POINTS_ALL = 3
	};

    CV_WRAP FastFeatureDetectorC( long threshold = 10, bool nonmaxSuppression=true, int keypointsTypes = KEY_POINTS_ALL, int Kmin = 9, int Kmax = 11);

    virtual ~FastFeatureDetectorC(){

    };

    void detect( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints, const cv::Mat& mask ) const
    {
        keypoints.clear();

        if( image.empty() )
            return;

        CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );
        detectImpl( image, keypoints, mask );
    }

    void segment( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints, std::unordered_multimap<int, std::pair<int, int> >& keypointsPixels, const cv::Mat& mask ) const
    {
    	keypoints.clear();

    	if( image.empty() )
    		return;

    	CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );
    	segmentImpl( image, keypoints, keypointsPixels, mask );
    }

    virtual bool isColorDetector(){
    	return false;
    }

    void setThreshold(long threshold_){
        this->threshold = threshold_;
    }

    void setKeypointsTypes(int keypointsTypes_){
        this->keypointsTypes = keypointsTypes_;
    }

protected:

    virtual void detectImpl( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const = 0;

    virtual void segmentImpl( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints,  std::unordered_multimap<int, std::pair<int, int> >&, const cv::Mat& mask=cv::Mat() ) const
    {
    	detectImpl( image, keypoints, mask);
    }

    long threshold;
    bool nonmaxSuppression;
    int Kmin;
    int Kmax;

    int keypointsTypes;

    std::vector<std::vector<float> > fastAngles;
};

/**
 * Gray level Fast Feature detector
 */
class CV_EXPORTS_W FASTextGray : public FastFeatureDetectorC
{
public:

    CV_WRAP FASTextGray( long threshold=10, bool nonmaxSuppression=true, int keypointsTypes = KEY_POINTS_ALL, int Kmin = 9, int Kmax = 11);

    virtual ~FASTextGray(){

    };

protected:

    virtual void detectImpl( const cv::Mat& image, std::vector<FastKeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const;
};

}//namespace cmp;

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


<commit_before>#include <boost/scoped_ptr.hpp>

#include "errors.hpp"
#include "btree/backfill.hpp"
#include "btree/delete_all_keys.hpp"
#include "btree/slice.hpp"
#include "btree/node.hpp"
#include "buffer_cache/transactor.hpp"
#include "buffer_cache/buf_lock.hpp"
#include "concurrency/cond_var.hpp"
#include "btree/get.hpp"
#include "btree/rget.hpp"
#include "btree/set.hpp"
#include "btree/incr_decr.hpp"
#include "btree/append_prepend.hpp"
#include "btree/delete.hpp"
#include "btree/get_cas.hpp"
#include "replication/delete_queue.hpp"
#include "replication/master.hpp"

void btree_slice_t::create(translator_serializer_t *serializer,
                           mirrored_cache_static_config_t *static_config) {
    cache_t::create(serializer, static_config);

    /* Construct a cache so we can write the superblock */

    /* The values we pass here are almost totally irrelevant. The cache-size parameter must
    be big enough to hold the patch log so we don't trip an assert, though. */
    mirrored_cache_config_t startup_dynamic_config;
    int size = static_config->n_patch_log_blocks * serializer->get_block_size().ser_value() + MEGABYTE;
    startup_dynamic_config.max_size = size * 2;
    startup_dynamic_config.wait_for_flush = false;
    startup_dynamic_config.flush_timer_ms = NEVER_FLUSH;
    startup_dynamic_config.max_dirty_size = size;
    startup_dynamic_config.flush_dirty_size = size;
    startup_dynamic_config.flush_waiting_threshold = INT_MAX;
    startup_dynamic_config.max_concurrent_flushes = 1;
    startup_dynamic_config.io_priority_reads = 100;
    startup_dynamic_config.io_priority_writes = 100;

    thread_saver_t saver;

    /* Cache is in a scoped pointer because it may be too big to allocate on the coroutine stack */
    boost::scoped_ptr<cache_t> cache(new cache_t(serializer, &startup_dynamic_config));

    /* Initialize the btree superblock and the delete queue */
    boost::shared_ptr<transactor_t> txor(new transactor_t(saver, cache.get(), rwi_write, 1, repli_timestamp_t::distant_past()));

    buf_lock_t superblock(saver, *txor, SUPERBLOCK_ID, rwi_write);

    // Initialize replication time barrier to 0 so that if we are a slave, we will begin by pulling
    // ALL updates from master.
    superblock->touch_recency(repli_timestamp_t::distant_past());

    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    bzero(sb, cache->get_block_size().value());

    sb->magic = btree_superblock_t::expected_magic;
    sb->root_block = NULL_BLOCK_ID;

    // Allocate sb->delete_queue_block like an ordinary block.
    buf_lock_t delete_queue_block;
    delete_queue_block.allocate(saver, *txor);
    replication::delete_queue_block_t *dqb = reinterpret_cast<replication::delete_queue_block_t *>(delete_queue_block->get_data_major_write());
    initialize_empty_delete_queue(txor, dqb, serializer->get_block_size());
    sb->delete_queue_block = delete_queue_block->get_block_id();

    sb->replication_clock = sb->last_sync = repli_timestamp_t::distant_past();
    sb->replication_master_id = sb->replication_slave_id = 0;
}

btree_slice_t::btree_slice_t(translator_serializer_t *serializer,
                             mirrored_cache_config_t *dynamic_config,
                             int64_t delete_queue_limit,
                             const std::string& informal_name)
    : cache_(serializer, dynamic_config), delete_queue_limit_(delete_queue_limit), informal_name_(informal_name) { }

btree_slice_t::~btree_slice_t() {
    // Cache's destructor handles flushing and stuff
}

get_result_t btree_slice_t::get(const store_key_t &key, UNUSED order_token_t token) {
    on_thread_t th(home_thread);
    order_sink_.check_out(token);
    return btree_get(key, this, token);
}

rget_result_t btree_slice_t::rget(rget_bound_mode_t left_mode, const store_key_t &left_key, rget_bound_mode_t right_mode, const store_key_t &right_key, UNUSED order_token_t token) {
    on_thread_t th(home_thread);
    order_sink_.check_out(token);
    return btree_rget_slice(this, left_mode, left_key, right_mode, right_key, token);
}

struct btree_slice_change_visitor_t : public boost::static_visitor<mutation_result_t> {
    mutation_result_t operator()(const get_cas_mutation_t &m) {
        return btree_get_cas(m.key, parent, ct, order_token);
    }
    mutation_result_t operator()(const sarc_mutation_t &m) {
        return btree_set(m.key, parent, m.data, m.flags, m.exptime, m.add_policy, m.replace_policy, m.old_cas, ct, order_token);
    }
    mutation_result_t operator()(const incr_decr_mutation_t &m) {
        return btree_incr_decr(m.key, parent, (m.kind == incr_decr_INCR), m.amount, ct, order_token);
    }
    mutation_result_t operator()(const append_prepend_mutation_t &m) {
        return btree_append_prepend(m.key, parent, m.data, (m.kind == append_prepend_APPEND), ct, order_token);
    }
    mutation_result_t operator()(const delete_mutation_t &m) {
        return btree_delete(m.key, m.dont_put_in_delete_queue, parent, ct.timestamp, order_token);
    }

    btree_slice_t *parent;
    castime_t ct;
    order_token_t order_token;
};

mutation_result_t btree_slice_t::change(const mutation_t &m, castime_t castime, UNUSED order_token_t token) {
    // HEY: Honestly this is weird, we should already be on the home
    // thread in all situations I can think of.
    on_thread_t th(home_thread);

    order_sink_.check_out(token);

    btree_slice_change_visitor_t functor;
    functor.parent = this;
    functor.ct = castime;
    functor.order_token = token;
    return boost::apply_visitor(functor, m.mutation);
}

void btree_slice_t::delete_all_keys_for_backfill() {
    on_thread_t th(home_thread);

    btree_delete_all_keys_for_backfill(this);
}

void btree_slice_t::backfill(repli_timestamp since_when, backfill_callback_t *callback) {
    on_thread_t th(home_thread);
    btree_backfill(this, since_when, callback);
}

/* TODO: Storing replication clocks and last-sync information like this is kind of ugly because
it's an abstraction break, which means it might not fit with clustering.

These functions are intentionally verbose because they shouldn't exist at all. The code
duplication is a protest against how horrible it is to have this data stored here. */

void btree_slice_t::set_replication_clock(repli_timestamp_t t) {
    // Having saver before an on_thread_t means the saver's destructor
    // is a no-op, because the on_thread_t's destructor runs right
    // before it.
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_write, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_write);
    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    sb->replication_clock = t;
}

repli_timestamp btree_slice_t::get_replication_clock() {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_read, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_read);
    const btree_superblock_t *sb = reinterpret_cast<const btree_superblock_t *>(superblock->get_data_read());
    return sb->replication_clock;
}

void btree_slice_t::set_last_sync(repli_timestamp_t t) {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_write, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_write);
    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    sb->last_sync = t;
}

repli_timestamp btree_slice_t::get_last_sync() {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_read, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_read);
    const btree_superblock_t *sb = reinterpret_cast<const btree_superblock_t *>(superblock->get_data_read());
    return sb->last_sync;
}

void btree_slice_t::set_replication_master_id(uint32_t t) {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_write, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_write);
    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    sb->replication_master_id = t;
}

uint32_t btree_slice_t::get_replication_master_id() {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_read, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_read);
    const btree_superblock_t *sb = reinterpret_cast<const btree_superblock_t *>(superblock->get_data_read());
    return sb->replication_master_id;
}

void btree_slice_t::set_replication_slave_id(uint32_t t) {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_write, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_write);
    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    sb->replication_slave_id = t;
}

uint32_t btree_slice_t::get_replication_slave_id() {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_read, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_read);
    const btree_superblock_t *sb = reinterpret_cast<const btree_superblock_t *>(superblock->get_data_read());
    return sb->replication_slave_id;
}

<commit_msg>Changed on_thread_t in btree_slice_t::backfill to assert_thread.<commit_after>#include <boost/scoped_ptr.hpp>

#include "errors.hpp"
#include "btree/backfill.hpp"
#include "btree/delete_all_keys.hpp"
#include "btree/slice.hpp"
#include "btree/node.hpp"
#include "buffer_cache/transactor.hpp"
#include "buffer_cache/buf_lock.hpp"
#include "concurrency/cond_var.hpp"
#include "btree/get.hpp"
#include "btree/rget.hpp"
#include "btree/set.hpp"
#include "btree/incr_decr.hpp"
#include "btree/append_prepend.hpp"
#include "btree/delete.hpp"
#include "btree/get_cas.hpp"
#include "replication/delete_queue.hpp"
#include "replication/master.hpp"

void btree_slice_t::create(translator_serializer_t *serializer,
                           mirrored_cache_static_config_t *static_config) {
    cache_t::create(serializer, static_config);

    /* Construct a cache so we can write the superblock */

    /* The values we pass here are almost totally irrelevant. The cache-size parameter must
    be big enough to hold the patch log so we don't trip an assert, though. */
    mirrored_cache_config_t startup_dynamic_config;
    int size = static_config->n_patch_log_blocks * serializer->get_block_size().ser_value() + MEGABYTE;
    startup_dynamic_config.max_size = size * 2;
    startup_dynamic_config.wait_for_flush = false;
    startup_dynamic_config.flush_timer_ms = NEVER_FLUSH;
    startup_dynamic_config.max_dirty_size = size;
    startup_dynamic_config.flush_dirty_size = size;
    startup_dynamic_config.flush_waiting_threshold = INT_MAX;
    startup_dynamic_config.max_concurrent_flushes = 1;
    startup_dynamic_config.io_priority_reads = 100;
    startup_dynamic_config.io_priority_writes = 100;

    thread_saver_t saver;

    /* Cache is in a scoped pointer because it may be too big to allocate on the coroutine stack */
    boost::scoped_ptr<cache_t> cache(new cache_t(serializer, &startup_dynamic_config));

    /* Initialize the btree superblock and the delete queue */
    boost::shared_ptr<transactor_t> txor(new transactor_t(saver, cache.get(), rwi_write, 1, repli_timestamp_t::distant_past()));

    buf_lock_t superblock(saver, *txor, SUPERBLOCK_ID, rwi_write);

    // Initialize replication time barrier to 0 so that if we are a slave, we will begin by pulling
    // ALL updates from master.
    superblock->touch_recency(repli_timestamp_t::distant_past());

    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    bzero(sb, cache->get_block_size().value());

    sb->magic = btree_superblock_t::expected_magic;
    sb->root_block = NULL_BLOCK_ID;

    // Allocate sb->delete_queue_block like an ordinary block.
    buf_lock_t delete_queue_block;
    delete_queue_block.allocate(saver, *txor);
    replication::delete_queue_block_t *dqb = reinterpret_cast<replication::delete_queue_block_t *>(delete_queue_block->get_data_major_write());
    initialize_empty_delete_queue(txor, dqb, serializer->get_block_size());
    sb->delete_queue_block = delete_queue_block->get_block_id();

    sb->replication_clock = sb->last_sync = repli_timestamp_t::distant_past();
    sb->replication_master_id = sb->replication_slave_id = 0;
}

btree_slice_t::btree_slice_t(translator_serializer_t *serializer,
                             mirrored_cache_config_t *dynamic_config,
                             int64_t delete_queue_limit,
                             const std::string& informal_name)
    : cache_(serializer, dynamic_config), delete_queue_limit_(delete_queue_limit), informal_name_(informal_name) { }

btree_slice_t::~btree_slice_t() {
    // Cache's destructor handles flushing and stuff
}

get_result_t btree_slice_t::get(const store_key_t &key, UNUSED order_token_t token) {
    on_thread_t th(home_thread);
    order_sink_.check_out(token);
    return btree_get(key, this, token);
}

rget_result_t btree_slice_t::rget(rget_bound_mode_t left_mode, const store_key_t &left_key, rget_bound_mode_t right_mode, const store_key_t &right_key, UNUSED order_token_t token) {
    on_thread_t th(home_thread);
    order_sink_.check_out(token);
    return btree_rget_slice(this, left_mode, left_key, right_mode, right_key, token);
}

struct btree_slice_change_visitor_t : public boost::static_visitor<mutation_result_t> {
    mutation_result_t operator()(const get_cas_mutation_t &m) {
        return btree_get_cas(m.key, parent, ct, order_token);
    }
    mutation_result_t operator()(const sarc_mutation_t &m) {
        return btree_set(m.key, parent, m.data, m.flags, m.exptime, m.add_policy, m.replace_policy, m.old_cas, ct, order_token);
    }
    mutation_result_t operator()(const incr_decr_mutation_t &m) {
        return btree_incr_decr(m.key, parent, (m.kind == incr_decr_INCR), m.amount, ct, order_token);
    }
    mutation_result_t operator()(const append_prepend_mutation_t &m) {
        return btree_append_prepend(m.key, parent, m.data, (m.kind == append_prepend_APPEND), ct, order_token);
    }
    mutation_result_t operator()(const delete_mutation_t &m) {
        return btree_delete(m.key, m.dont_put_in_delete_queue, parent, ct.timestamp, order_token);
    }

    btree_slice_t *parent;
    castime_t ct;
    order_token_t order_token;
};

mutation_result_t btree_slice_t::change(const mutation_t &m, castime_t castime, UNUSED order_token_t token) {
    // HEY: Honestly this is weird, we should already be on the home
    // thread in all situations I can think of.
    on_thread_t th(home_thread);

    order_sink_.check_out(token);

    btree_slice_change_visitor_t functor;
    functor.parent = this;
    functor.ct = castime;
    functor.order_token = token;
    return boost::apply_visitor(functor, m.mutation);
}

void btree_slice_t::delete_all_keys_for_backfill() {
    on_thread_t th(home_thread);

    btree_delete_all_keys_for_backfill(this);
}

void btree_slice_t::backfill(repli_timestamp since_when, backfill_callback_t *callback) {
    assert_thread();

    btree_backfill(this, since_when, callback);
}

/* TODO: Storing replication clocks and last-sync information like this is kind of ugly because
it's an abstraction break, which means it might not fit with clustering.

These functions are intentionally verbose because they shouldn't exist at all. The code
duplication is a protest against how horrible it is to have this data stored here. */

void btree_slice_t::set_replication_clock(repli_timestamp_t t) {
    // Having saver before an on_thread_t means the saver's destructor
    // is a no-op, because the on_thread_t's destructor runs right
    // before it.
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_write, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_write);
    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    sb->replication_clock = t;
}

repli_timestamp btree_slice_t::get_replication_clock() {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_read, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_read);
    const btree_superblock_t *sb = reinterpret_cast<const btree_superblock_t *>(superblock->get_data_read());
    return sb->replication_clock;
}

void btree_slice_t::set_last_sync(repli_timestamp_t t) {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_write, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_write);
    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    sb->last_sync = t;
}

repli_timestamp btree_slice_t::get_last_sync() {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_read, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_read);
    const btree_superblock_t *sb = reinterpret_cast<const btree_superblock_t *>(superblock->get_data_read());
    return sb->last_sync;
}

void btree_slice_t::set_replication_master_id(uint32_t t) {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_write, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_write);
    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    sb->replication_master_id = t;
}

uint32_t btree_slice_t::get_replication_master_id() {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_read, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_read);
    const btree_superblock_t *sb = reinterpret_cast<const btree_superblock_t *>(superblock->get_data_read());
    return sb->replication_master_id;
}

void btree_slice_t::set_replication_slave_id(uint32_t t) {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_write, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_write);
    btree_superblock_t *sb = reinterpret_cast<btree_superblock_t *>(superblock->get_data_major_write());
    sb->replication_slave_id = t;
}

uint32_t btree_slice_t::get_replication_slave_id() {
    thread_saver_t saver;
    on_thread_t th(cache()->home_thread);
    transactor_t transactor(saver, cache(), rwi_read, 0, repli_timestamp_t::distant_past());
    buf_lock_t superblock(saver, transactor, SUPERBLOCK_ID, rwi_read);
    const btree_superblock_t *sb = reinterpret_cast<const btree_superblock_t *>(superblock->get_data_read());
    return sb->replication_slave_id;
}

<|endoftext|>