text:
#include "test_registrator.h"

#include <deque>
#include <queue>

#include <ts_queue.h>
#include <time_tracker.h>

#include <boost/thread.hpp>

using namespace system_utilities::common;

namespace system_utilities
{
	namespace tests_
	{
		namespace common
		{
			namespace details
			{
				void ts_queue_constructor_test_helper()
				{
					ts_queue< size_t > mq;
					for (int i = 1 ; i < 10 ; i ++)
						mq.push( new size_t(i) );
					size_t *s = mq.pop();
					BOOST_CHECK_EQUAL( *s, (size_t)1 );
					delete s;
					for (int i = 10 ; i < 14 ; i ++)
						mq.push( new size_t(i) );
					size_t i = 2;
					while (!mq.empty())
					{
						size_t* s = mq.pop();
						BOOST_CHECK_EQUAL( *s, i++ );
						delete s;
					}
					BOOST_CHECK_EQUAL( mq.empty(), true );
				}
				typedef ts_queue< size_t > ts_queue_size_t;
				void ts_queue_different_threads_pop_thread_helper( ts_queue_size_t* mq, const size_t different_threads_test_size )
				{
					boost::this_thread::sleep( boost::posix_time::milliseconds( 20 ) );
					size_t i = 0;
					while ( i < different_threads_test_size )
					{
						size_t* s = mq->wait_pop();
						BOOST_CHECK_EQUAL( i, *s );
						delete s;
						i++;
					}
					BOOST_CHECK_EQUAL( i, different_threads_test_size );
					BOOST_CHECK_EQUAL( mq->empty(), true );
					BOOST_CHECK_EQUAL( mq->size(), (size_t)0 );
				}
				void ts_queue_wait_pop_test_helper( ts_queue_size_t* mq )
				{
					time_tracker< std::chrono::seconds > tt;
					using namespace boost::posix_time;
					size_t *s = mq->wait_pop();
					BOOST_CHECK_EQUAL( *s, (size_t)15 );
					delete s;
					BOOST_CHECK_EQUAL( tt.elapsed() >= 1, true );
					BOOST_CHECK_EQUAL( mq->empty(), true );
					BOOST_CHECK_EQUAL( mq->size(), (size_t)0 );
				}
				struct ts_queue_many_threads_test_helper
				{
					ts_queue_size_t mq_;
					boost::mutex push_protector_;
					size_t push_iterations_;

					boost::mutex pop_protector_;
					size_t pop_iterations_;
					explicit ts_queue_many_threads_test_helper()
						: push_iterations_( 0 )
						, pop_iterations_( 0 )
					{
						const size_t push_threads = 12;
						const size_t pop_threads = 6;
						BOOST_CHECK_EQUAL( mq_.size(), (size_t)0 );
						BOOST_CHECK_EQUAL( mq_.empty(), true );
						boost::thread_group tg_push, tg_pop;
						for (size_t i = 0 ; i < push_threads ; ++i)
							tg_push.create_thread( boost::bind( &ts_queue_many_threads_test_helper::pusher, this ) );
						for (size_t i = 0 ; i < pop_threads ; ++i)
							tg_pop.create_thread( boost::bind( &ts_queue_many_threads_test_helper::poper, this ) );
						for (size_t i = 0 ; i < 12 ; ++i)
						{
							boost::this_thread::sleep( boost::posix_time::milliseconds( 1200 ) );
							boost::mutex::scoped_lock push_lock( push_protector_ );
							boost::mutex::scoped_lock pop_lock( pop_protector_ );
							BOOST_CHECK_EQUAL( push_iterations_ - pop_iterations_ > 0, true );
						}
						mq_.stop_processing();
						tg_pop.join_all();
						tg_push.join_all();
					}
					void pusher()
					{
						while (true)
						{
							size_t * s = new size_t( rand() % 100000 );
							bool res = mq_.push( s );
							if (!res)
							{
								delete s;
								break;
							}
							{
								boost::mutex::scoped_lock lock( push_protector_ );
								push_iterations_ ++;
							}
						}
					}
					void poper()
					{
						while (true)
						{
							size_t* s = mq_.wait_pop();
							if (!s)
								break;
							delete s;
							{
								boost::mutex::scoped_lock lock( pop_protector_ );
								pop_iterations_ ++;
							}
						}
					}
				};
				void ts_queue_wait_test_helper(details::ts_queue_size_t* mq_, size_t* pop_iterations_)
				{
					while (true)
					{
						size_t* s = mq_->wait_pop();
						if (!s)
							break;
						delete s;
						(*pop_iterations_)++;
					}
				}
			}
			void ts_queue_constructor_tests()
			{
				ts_queue< int > queue;
				details::ts_queue_constructor_test_helper();
			}
			void ts_queue_different_threads_tests()
			{
				details::ts_queue_size_t mq;
				const size_t different_threads_test_size = 1000000;
				boost::thread pop = boost::thread( boost::bind( &details::ts_queue_different_threads_pop_thread_helper, &mq, different_threads_test_size ) );
				using namespace boost::posix_time;
				for (size_t i = 0 ; i < different_threads_test_size ; i++)
				{
					mq.push( new size_t(i) );
				}
				pop.join();
				BOOST_CHECK_EQUAL( mq.empty(), true );
			}
			void ts_queue_wait_pop_tests()
			{
				details::ts_queue_size_t mq;
				BOOST_CHECK_EQUAL( mq.empty(), true );
				BOOST_CHECK_EQUAL( mq.size(), (size_t)0 );
				boost::thread pop = boost::thread( boost::bind( &details::ts_queue_wait_pop_test_helper, &mq ) );
				boost::this_thread::sleep( boost::posix_time::milliseconds( 1200 ) );
				mq.push( new size_t(15) );
				pop.join();
				BOOST_CHECK_EQUAL( mq.empty(), true );
				BOOST_CHECK_EQUAL( mq.size(), (size_t)0 );
			}
			void ts_queue_many_threads_tests()
			{
				details::ts_queue_many_threads_test_helper helper;
			}
			void ts_queue_wait_tests()
			{
				details::ts_queue_size_t mq;
				mq.restart();
				BOOST_CHECK_EQUAL( mq.size(), (size_t)0 );
				BOOST_CHECK_EQUAL( mq.empty(), true );
				const size_t size = 1000000;
				for(size_t i = 0 ; i < size ; ++i )
				{
					size_t* s = new size_t(i);
					mq.push( s );
				}
				BOOST_CHECK_EQUAL( mq.size(), (size_t)size );
				size_t pop_iterations_ = 0;
				boost::thread poper( boost::bind( &details::ts_queue_wait_test_helper, &mq, &pop_iterations_ ) );
				mq.wait();
				mq.stop();
				poper.join();
				BOOST_CHECK_EQUAL(pop_iterations_, size);
			}

			void ts_queue_another_container_tests()
			{
				ts_queue< int, std::deque > deque_ts;
				deque_ts.push( new int(5) );
				int* a = deque_ts.pop();
				BOOST_CHECK_EQUAL( *a, 5 );
				delete a;
			}
		}
	}
}


text:
#include <boost/test/unit_test.hpp>
#include <boost/format.hpp>

#include <iostream>
#include <vector>
#include <madym/t1_methods/mdm_T1FitterVFA.h>
#include <madym/t1_methods/mdm_T1FitterIR.h>
#include <madym/tests/mdm_test_utils.h>

BOOST_AUTO_TEST_SUITE(test_mdm)

BOOST_AUTO_TEST_CASE(test_T1_VFA) {
  BOOST_TEST_MESSAGE("======= Testing T1 VFA mapping =======");

  //Read in T1 calibration file
  int nFAs;
  double T1;
  double M0;
  double TR;
  std::string T1FileName(mdm_test_utils::calibration_dir() + "T1.dat");
  std::ifstream T1FileStream(T1FileName, std::ios::in | std::ios::binary);
  T1FileStream.read(reinterpret_cast<char*>(&nFAs), sizeof(int));

  std::vector<double> FAs(nFAs);
  std::vector<double> signalsCalibration(nFAs);
  for (double &fa : FAs)
    T1FileStream.read(reinterpret_cast<char*>(&fa), sizeof(double));
  for (double &s : signalsCalibration)
    T1FileStream.read(reinterpret_cast<char*>(&s), sizeof(double));

  T1FileStream.read(reinterpret_cast<char*>(&T1), sizeof(double));
  T1FileStream.read(reinterpret_cast<char*>(&M0), sizeof(double));
  T1FileStream.read(reinterpret_cast<char*>(&TR), sizeof(double));

  T1FileStream.close();

  BOOST_TEST_MESSAGE(boost::format(
    "Read T1 calibration file, T1 = %1% , M0 =%2%, TR = %3%")
    % T1 % M0 % TR);

  //Now compute signals
  std::vector<double> signals(nFAs);
  BOOST_TEST_MESSAGE("Testing signals from VFA (calibration, computed): ");
  for (int i = 0; i < nFAs; i++)
  {
    signals[i] = mdm_T1FitterVFA::T1toSignal(T1, M0, FAs[i], TR);
    BOOST_TEST_MESSAGE(boost::format("(%1%, %2%)")
      % signalsCalibration[i] % signals[i]);
  }
  BOOST_CHECK_VECTORS(signals, signalsCalibration);

  //Next fit the signals to recover M0 and T1
  double T1fit, M0fit;
  mdm_T1FitterVFA T1CalculatorVFA(FAs, TR, false);
  T1CalculatorVFA.setInputs(signalsCalibration);
  auto errCode = T1CalculatorVFA.fitT1(T1fit, M0fit);
  BOOST_CHECK_MESSAGE(!errCode, "T1 fit returned error " << errCode);

  BOOST_TEST_MESSAGE("Testing fitted T1 match using VFA");
  BOOST_CHECK_CLOSE(T1fit, T1, 0.01);
  BOOST_TEST_MESSAGE("Testing fitted M0 match using VFA");
  BOOST_CHECK_CLOSE(M0fit, M0, 0.01);

  //Repeat the test using VFA B1 correction
  auto signalsCalibrationB1 = signalsCalibration;
  auto FAsB1 = FAs;
  double B1 = 0.9;
  for (auto &fa : FAsB1)
    fa /= B1;
  signalsCalibrationB1.push_back(B1);

  mdm_T1FitterVFA T1CalculatorB1(FAsB1, TR, true);
  T1CalculatorB1.setInputs(signalsCalibrationB1);
  errCode = T1CalculatorB1.fitT1(T1fit, M0fit);
  BOOST_CHECK_MESSAGE(!errCode, "T1 fit returned error " << errCode);

  BOOST_TEST_MESSAGE("Testing fitted T1 match using VFA B1 correction");
  BOOST_CHECK_CLOSE(T1fit, T1, 0.01);
  BOOST_TEST_MESSAGE("Testing fitted M0 match using VFA B1 correction");
  BOOST_CHECK_CLOSE(M0fit, M0, 0.01);
}

BOOST_AUTO_TEST_CASE(test_T1_IR) {
  BOOST_TEST_MESSAGE("======= Testing T1 inversion recovery mapping =======");
  //Test inversion recovery method

  //Read in T1 calibration file
  int nTIs;
  double T1;
  double M0;
  double TR;
  std::string T1FileName(mdm_test_utils::calibration_dir() + "T1_IR.dat");
  std::ifstream T1FileStream(T1FileName, std::ios::in | std::ios::binary);
  T1FileStream.read(reinterpret_cast<char*>(&nTIs), sizeof(int));

  std::vector<double> TIs(nTIs);
  std::vector<double> signalsCalibration(nTIs);
  for (double &ti : TIs)
    T1FileStream.read(reinterpret_cast<char*>(&ti), sizeof(double));
  for (double &s : signalsCalibration)
    T1FileStream.read(reinterpret_cast<char*>(&s), sizeof(double));

  T1FileStream.read(reinterpret_cast<char*>(&T1), sizeof(double));
  T1FileStream.read(reinterpret_cast<char*>(&M0), sizeof(double));
  T1FileStream.read(reinterpret_cast<char*>(&TR), sizeof(double));

  T1FileStream.close();

  BOOST_TEST_MESSAGE(boost::format(
    "Read T1 calibration file, T1 = %1% , M0 =%2%, TR = %3%")
    % T1 % M0 % TR);

  std::vector<double> signals(nTIs);
  BOOST_TEST_MESSAGE("Testing signals from IR (calibration, computed): ");
  for (int i = 0; i < nTIs; i++)
  {
    signals[i] = mdm_T1FitterIR::T1toSignal(T1, M0, TIs[i], TR);
    BOOST_TEST_MESSAGE(boost::format("(%1%, %2%)")
      % signalsCalibration[i] % signals[i]);
  }

  mdm_T1FitterIR T1CalculatorIR(TIs, TR);
  T1CalculatorIR.setInputs(signalsCalibration);

  double T1fit, M0fit;
  auto errCode = T1CalculatorIR.fitT1(T1fit, M0fit);
  BOOST_CHECK_MESSAGE(!errCode, "T1 fit returned error " << errCode);

  BOOST_TEST_MESSAGE("Testing fitted T1 match using inversion recovery");
  BOOST_CHECK_CLOSE(T1fit, T1, 0.01);
  BOOST_TEST_MESSAGE("Testing fitted M0 match using inversion recovery");
  BOOST_CHECK_CLOSE(M0fit, M0, 0.01);

}

BOOST_AUTO_TEST_SUITE_END() //

ext: cxx


text: #include <boost/numeric/odeint/integrate/integrate_times.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <boost/algorithm/string.hpp>
#include <boost/unordered_map.hpp>
#include <chrono>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <malloc.h>

class Bee {
public:
    double x, y, z;
    Bee* previous = nullptr;
    Bee* following = nullptr;

    Bee(double x1, double y1, double z1)
    {
        x = x1 * 111111;
        y = y1 * 111111;
        z = z1;
    };

    Bee(const Bee& b)
    {
        x = b.x;
        y = b.y;
        z = b.z;
    };
};

class BeeList {
public:
    Bee* first = nullptr;
    Bee* last = nullptr;
    int size = 0;

    void add_bee(Bee* b)
    {
        b->previous = nullptr;
        b->following = this->first;
        if (this->first != nullptr) {
            this->first->previous = b;
            this->last = this->first;
        }
        this->first = b;
        this->size++;
    }

    void add_first_bee(Bee* b)
    {
        b->following = nullptr;
        b->previous = nullptr;
        this->first = b;
        this->last = b;
        this->size++;
    }

    void concatenate_beelist_end(BeeList* bl)
    {
        if (this->size == 0) {
            this->first = bl->first;
            this->last = bl->last;
            this->size = bl->size;
        } else {
            bl->first->previous = this->last;
            last->following = bl->first;
            this->last = bl->last;
            this->size += bl->size;
        }
    }
};

typedef std::pair<BeeList, bool> Pair;
BeeList resultant_blist;

class Cube {
public:
    int x, y, z;
    Cube(int x, int y, int z)
    {
        this->x = x * 111111;
        this->y = y * 111111;
        this->z = z;
    }
};

std::string find_cube_key(double x, double y, double z)
{
    // round each coordinate, concatenate them into a string and convert this string to an integer
    return ((((std::to_string((int)std::round(x / 57.735026919)) += " ") += std::to_string((int)std::round(y / 57.735026919))) += " ") += std::to_string((int)std::round(z / 57.735026919)));
}

inline void parse_file(std::string input_file, std::vector<std::string>& v, boost::unordered_map<std::string, Pair>& um)
{
    std::ifstream inpp(input_file);
    std::string line;
    std::getline(inpp, line);
    if (inpp.is_open()) {
        Pair* p;
        while (std::getline(inpp, line)) {
            std::vector<std::string> string_coordinates;

            //The data from the file is split and stored in the previously declared vector.
            boost::split(string_coordinates, line, boost::is_any_of(","));

            //A new bee is created using the extracted coordinates.
            Bee* c = new Bee(std::stod(string_coordinates[0]), std::stod(string_coordinates[1]), std::stod(string_coordinates[2]));

            //The coordinates assigned to the generated bee are used to generate a key in order to store said bee in the unordered map.
            std::string key = find_cube_key(c->x, c->y, c->z);
            p = &um[key];
            if ((p->first.size) == 0) {
                p->first.add_first_bee(c);
                p->second = false;
                v.push_back(key);
            } else {
                p->first.add_bee(c);
                p->second = true;
            }
        }
    }
    inpp.close();
}

inline bool compare_adjacent(std::string adj_key, std::string unique_bee_key, boost::unordered_map<std::string, Pair>& cubes, double x, double y, double z)
{

    Bee* current_bee;
    Pair* p;
    BeeList* blist;
    for (int i = 0; i < 26; ++i) {
        p = &cubes[adj_key];
        blist = &p->first;
        if (blist->first != nullptr) {
            current_bee = blist->first;
            double x_distance, y_distance, z_distance;
            while (current_bee != nullptr) {
                x_distance = x - current_bee->x;
                if (x_distance >= -100 && x_distance <= 100) {
                    y_distance = y - current_bee->y;
                    if (y_distance >= -100 && y_distance <= 100) {
                        z_distance = z - current_bee->z;
                        if (z_distance >= -100 && z_distance <= 100) {
                            if (p->second == true) {
                                cubes[unique_bee_key].second = true;
                                resultant_blist.concatenate_beelist_end(&cubes[unique_bee_key].first);
                                return true;
                            } else {
                                p->second = true;
                                cubes[unique_bee_key].second = true;
                                //resultant_blist.concatenate_beelist_end(blist);
                                resultant_blist.concatenate_beelist_end(&cubes[unique_bee_key].first);
                                return true;
                            }
                        }
                    }
                }
                current_bee = current_bee->following;
            }
        }
    }
    return false;
}

void find_for_unique_bee(std::string unique_bee_key, boost::unordered_map<std::string, Pair>& cubes)
{
    Bee* unique_bee = cubes[unique_bee_key].first.first;
    double x = unique_bee->x, y = unique_bee->y, z = unique_bee->z;
    std::vector<std::string> xyz_from_key;
    boost::split(xyz_from_key, unique_bee_key, boost::is_any_of(" "));
    int x_idx = stoi(xyz_from_key[0]), y_idx = stoi(xyz_from_key[1]), z_idx = stoi(xyz_from_key[2]);
    std::vector<std::string> keys;
    keys.reserve(32);
    keys.assign(32, "");

    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    };
    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx + 1) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx + 1)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx + 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx - 1) += " ") += std::to_string(y_idx - 1)) += " ") += std::to_string(z_idx - 1)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx + 2)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx - 2)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx + 2)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx) += " ") += std::to_string(y_idx - 2)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }

    if (compare_adjacent(((((std::to_string(x_idx + 2) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
    if (compare_adjacent(((((std::to_string(x_idx - 2) += " ") += std::to_string(y_idx)) += " ") += std::to_string(z_idx)), unique_bee_key, cubes, x, y, z)) {
        return;
    }
}

BeeList* tony;
double x, y, z;

int main()
{

    std::vector<std::string> files = { "1500beesSet.csv", "150000beesSet.csv   ", "100000beesSet.csv   ", "1000000beesSet.csv  " };
    // string storing name of file that will be parsed
    for (std::string inFileName : files) {
	inFileName = "../datasets/" + inFileName;

        // map trepresent cubes
        boost::unordered_map<std::string, Pair> cubes;

        // vector to store keys and int representing how many bees are in each cube
        std::vector<std::string> keys;
        keys.reserve(500000);

        auto duration_mean = std::chrono::system_clock::duration::zero().count();
        auto duration_max = std::chrono::system_clock::duration::min().count();
        auto duration_min = std::chrono::system_clock::duration::max().count();
        for (int i = 0; i < 100; ++i) {
            auto st = std::chrono::high_resolution_clock::now();
            parse_file(inFileName, keys, cubes);

            auto stop1 = std::chrono::high_resolution_clock::now();
            auto dif = std::chrono::duration_cast<std::chrono::microseconds>(stop1 - st).count();
            if (dif > duration_max) {
                duration_max = dif;
            } else if (dif < duration_min) {
                duration_min = dif;
            }
            duration_mean += dif;
        }
        std::cout << "PARSE_FILE - " << inFileName << " "
                  << "mean: " << duration_mean / 100 << " microseconds" << std::endl;
        std::cout << "PARSE_FILE - " << inFileName << " "
                  << "max: " << duration_max << " microseconds" << std::endl;
        std::cout << "PARSE_FILE - " << inFileName << " "
                  << "min: " << duration_min << " microseconds" << std::endl;

        duration_mean = std::chrono::system_clock::duration::zero().count();
        duration_max = std::chrono::system_clock::duration::min().count();
        duration_min = std::chrono::system_clock::duration::max().count();
        for (int i = 0; i < 100; ++i) {
            auto st = std::chrono::high_resolution_clock::now();
            std::string key;
            Pair* p;
            for (int i = 0; i < keys.size(); i++) {
                key = keys[i];
                p = &cubes[key];
                tony = &p->first;
                if (p->second == true) {
                    resultant_blist.concatenate_beelist_end(tony);
                } else {
                    find_for_unique_bee(key, cubes);
                }
            }
            auto stop1 = std::chrono::high_resolution_clock::now();
            auto dif = std::chrono::duration_cast<std::chrono::microseconds>(stop1 - st).count();
            if (dif > duration_max) {
                duration_max = dif;
            } else if (dif < duration_min) {
                duration_min = dif;
            }
            duration_mean += dif;
        }
        std::cout << "FIND_COLLISIONS - " << inFileName << " "
                  << "mean: " << duration_mean / 100 << " microseconds" << std::endl;
        std::cout << "FIND_COLLISIONS - " << inFileName << " "
                  << "max: " << duration_max << " microseconds" << std::endl;
        std::cout << "FIND_COLLISIONS - " << inFileName << " "
                  << "min: " << duration_min << " microseconds" << std::endl;
    }
}

ext: cpp

max_stars_repo_name: jandrovins/BeeHash

max_issues_repo_name: jandrovins/BeeHash

max_forks_repo_name: jandrovins/BeeHash


text:
//
// Boost.Pointer Container
//
//  Copyright Thorsten Ottosen 2009. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/ptr_container/
//

#include <boost/ptr_container/ptr_container.hpp>

// force instantiation of all members

template class boost::ptr_array<const int, 42>;
template class boost::ptr_array<boost::nullable<const int>, 42>;

template class boost::ptr_deque<const int>;
template class boost::ptr_deque< boost::nullable<const int> >;

template class boost::ptr_list<const int>;
template class boost::ptr_list< boost::nullable<const int> >;

template class boost::ptr_map<int, const int>;
template class boost::ptr_map<int, boost::nullable<const int> >;

template class boost::ptr_vector<const int>;
template class boost::ptr_vector< boost::nullable<const int> >;

//@todo problem with constructor forwarding
//
//template class boost::ptr_unordered_map<int,T>;

// @todo: there seems to be some problems with
//        argument passing in circular_buffer
//
//boost::ptr_circular_buffer<T> buffer(32);
//buffer.push_back( new int(42)  );

template class boost::ptr_set<const int>;

// @todo: problem with constructor forwarding
//
//template class boost::ptr_unordered_set<T>;


text:
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED

#include <boost/property_tree/ptree.hpp>

#include <boost/serialization/nvp.hpp>
#include <boost/serialization/collections_save_imp.hpp>
#include <boost/serialization/collections_load_imp.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/utility.hpp>

namespace boost { namespace property_tree
{

    ///////////////////////////////////////////////////////////////////////////
    // boost::serialization support

    template<class Archive, class C, class K, class P, class D, class X>
    inline void save(Archive &ar,
                     const basic_ptree<C, K, P, D, X> &t,
                     const unsigned int file_version)
    {
        serialization::stl::save_collection<Archive, basic_ptree<C, K, P, D, X> >(ar, t);
        ar << serialization::make_nvp("data", t.data());
    }

    template<class Archive, class C, class K, class P, class D, class X>
    inline void load(Archive &ar,
                     basic_ptree<C, K, P, D, X> &t,
                     const unsigned int file_version)
    {

        // Load children
        boost::serialization::stl::load_collection
        <
            Archive,
            basic_ptree<C, K, P, D, X>,
            boost::serialization::stl::archive_input_seq<Archive, basic_ptree<C, K, P, D, X> >,
            boost::serialization::stl::no_reserve_imp<basic_ptree<C, K, P, D, X> >
        >(ar, t);

        // Load data (must be after load_collection, as it calls clear())
        ar >> serialization::make_nvp("data", t.data());

    }

    template<class Archive, class C, class K, class P, class D, class X>
    inline void serialize(Archive &ar,
                          basic_ptree<C, K, P, D, X> &t,
                          const unsigned int file_version)
    {
        boost::serialization::split_free(ar, t, file_version);
    }

} }

#endif

max_stars_repo_name: gbucknell/fsc-sdk

max_issues_repo_name: gbucknell/fsc-sdk

max_forks_repo_name: gbucknell/fsc-sdk


text:
//============================================================================
// Name        :
// Author      : Avi
// Revision    : $Revision: #10 $
//
// Copyright 2009-2020 ECMWF.
// This software is licensed under the terms of the Apache Licence version 2.0
// which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
// In applying this licence, ECMWF does not waive the privileges and immunities
// granted to it by virtue of its status as an intergovernmental organisation
// nor does it submit to any jurisdiction.
//
// Description : Parser for white list file
//============================================================================

#include <unistd.h>  // for crypt
#include <iostream>

#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/trim.hpp>

#include "PasswdFile.hpp"
#include "File.hpp"
#include "Str.hpp"
#include "User.hpp"

using namespace ecf;
using namespace std;
using namespace boost;

PasswdFile::PasswdFile() = default;
PasswdFile::~PasswdFile() = default;

//#define DEBUG_ME 1

// Parse the file if any errors found return false and errorMsg
// The parser expects version number  4.5.0
bool PasswdFile::load(const std::string& file, bool debug,  std::string& errorMsg)
{
#ifdef DEBUG_ME
   debug = true;
#endif
   vec_.clear();
   passwd_file_ = file;
   if (debug)  std::cout << __func__ << "  " <<  passwd_file_ << " opening...\n";

   std::vector<std::string> lines;
   if (!File::splitFileIntoLines(passwd_file_,lines,true /* ignore empty lines */)) {
      errorMsg += "Could not open file specified by ECF_PASSWD/ECF_CUSTOM_PASSWD ";
      errorMsg += passwd_file_;
      errorMsg += " (";
      errorMsg += strerror(errno);
      errorMsg += ")";
      if (debug)  std::cout << dump() << "\n";
      return false;
   }

   bool foundVersionNumber = false; // can read from version 4.4.0 onwards
   size_t lines_size = lines.size();
   for(size_t i = 0; i < lines_size; ++i) {

      if (lines[i].empty())   continue;

      // ignore/remove all comments
      if (lines[i][0] == '#') continue;
      std::string theLine = lines[i];
      string::size_type comment_pos = theLine.find("#");
      if (comment_pos != std::string::npos ) {
         theLine.erase(comment_pos);
      }

      boost::algorithm::trim(theLine);  // remove leading and trailing spaces
      std::vector< std::string > lineTokens;
      Str::split( theLine, lineTokens );
      if ( lineTokens.empty() ) continue;

      // version should be at the start
      if (!foundVersionNumber) {

         if (!validateVersionNumber(lineTokens[0], errorMsg )) {
            std::stringstream ss;
            ss << " " << i + 1 << ": " << lines[i] << "\n";
            ss << "for ECF_PASSWD/ECF_CUSTOM_PASSWD file " << passwd_file_ << "\n";
            errorMsg += ss.str();
            return false;
         }
         foundVersionNumber = true;
         continue;
      }
      else  {
         if (!add_user(lineTokens,errorMsg)) {
            errorMsg += theLine;
            return false;
         }
      }
   }

   if (debug)  std::cout << dump();

   // Now check the user is unique for a given host/port:
   //   fred host 3141 xxxx
   //   fred host 3141 yyyy  this is illegal.
   size_t vec_size = vec_.size();
   for (size_t i = 0; i < vec_size; i++) {
      for (size_t k = 0; k < vec_size; k++) {
         if (i == k) continue;
         if (vec_[i].user() == vec_[k].user() && vec_[i].host() == vec_[k].host() && vec_[i].port() == vec_[k].port()) {
            std::stringstream ss;
            ss << "user " << vec_[i].user() << " can only appear once for given host/port\n";
            errorMsg += ss.str();
            return false;
         }
      }
   }
   return true;
}

bool PasswdFile::check_at_least_one_user_with_host_and_port(const std::string& host, const std::string& port)
{
   size_t vec_size = vec_.size();
   for (size_t i = 0; i < vec_size; i++) {
      if (vec_[i].host() == host && vec_[i].port() == port) {
         return true;
      }
   }
   return false;
}

std::string PasswdFile::get_passwd(const std::string& user, const std::string& host, const std::string& port)
{
#ifdef DEBUG_ME
   cout << "PasswdFile::get_passwd user(" << user << ") host(" << host << ") port(" << port << ")\n";
#endif
   size_t vec_size = vec_.size();
   for (size_t i = 0; i < vec_size; i++) {
      if (vec_[i].user() == user && vec_[i].host() == host && vec_[i].port() == port) {
         return vec_[i].passwd();
      }
   }
   return string();
}

bool PasswdFile::authenticate(const std::string& user, const std::string& passwd) const
{
#ifdef DEBUG_ME
   cout << "   PasswdFile::authenticate user:" << user << " passwd:" << passwd << " file:" <<  passwd_file_ << " vec_.size(): " << vec_.size() << "\n";
   cout << dump() << "\n";
#endif

   if (user.empty()) {
#ifdef DEBUG_ME
      cout << "      PasswdFile::authenticate: user empty:  FAIL\n";
#endif
      return false;
   }

   // no password specified, and password file is empty
   if (passwd.empty() && vec_.empty()) {
#ifdef DEBUG_ME
      cout << "      PasswdFile::authenticate no password and password file empty: PASS\n";
#endif
      return true;
   }

   // Only fail if user exists in the passwd file
   size_t vec_size = vec_.size();
   for (size_t i = 0; i < vec_size; i++) {
      if (vec_[i].user() == user) {
         if (vec_[i].passwd() == passwd) {
#ifdef DEBUG_ME
            cout << "      PasswdFile::authenticate user and password match: PASS\n";
#endif
            return true;
         }
         else {
#ifdef DEBUG_ME
            cout << "      PasswdFile::authenticate: user found but passwd did not match: FAIL\n";
#endif
            return false;
         }
      }
   }

   // Will ONLY reach here if user not found

   // User not found, but if passwd is not empty, then fail.
   if (!passwd.empty()) {
#ifdef DEBUG_ME
     cout << "      PasswdFile::authenticate: user NOT found, passwd is NOT EMPTY: FAIL\n";
#endif
      return false;
   }

   // Server has a password file, but user not found and passwd is empty.
   if (vec_.empty()) {
#ifdef DEBUG_ME
    cout << "      PasswdFile::authenticate: true, user NOT found, and passwd EMPTY, and password file EMPTY\n";
#endif
      return true;
   }

#ifdef DEBUG_ME
  cout << "      PasswdFile::authenticate false, user NOT found, and passwd EMPTY\n";
#endif
   return false;
}

bool PasswdFile::validateVersionNumber(const std::string& line, std::string& errorMsg) const
{
   // Expect 4.5.0
   // If first character is NUMERIC and we have dots
   bool firstCharIsNumeric = Str::NUMERIC().find( line[0], 0 ) != string::npos;
   if ( firstCharIsNumeric && line.find( "." ) != string::npos) {

      std::vector< std::string > versionNumberTokens;
      Str::split( line, versionNumberTokens, "." );
      if ( versionNumberTokens.size() != 3 ) {
         std::stringstream ss;
         ss << "Expected version of the form <int>.<int>.<int> i.e 4.4.0. but found invalid version number\n";
         errorMsg += ss.str();
         return false;
      }

      try {
         auto major = boost::lexical_cast< int >( versionNumberTokens[0] );
         auto minor = boost::lexical_cast< int >( versionNumberTokens[1] );
         auto part = boost::lexical_cast< int >( versionNumberTokens[2] );
         if ( major < 4  ) {
            errorMsg += "Only passwd files with a version >= 4.5.0 is supported\n";
            return false;
         }
         if ( major == 4 && minor < 5 ) {
            errorMsg += "Only passwd files with a version >= 4.5.0 is supported\n";
            return false;
         }
         if ( major == 4 && minor == 5  && part > 0) {
            errorMsg += "Only passwd files with a version >= 4.5.0 is supported\n";
            return false;
         }
      }
      catch ( boost::bad_lexical_cast& ) {
         errorMsg += "Invalid version number \n";
         return false;
      }

      return true;
   }

   errorMsg +="The version number not found. The version number must appear before the users.\n";
   return false;
}

bool PasswdFile::add_user(std::vector<std::string>& tokens, std::string& error_msg)
{
   // Expected format is:
   // 4.5.0
   // # comment
   // <user> <host> <port> <passwd> # comment
   // <user> <host> <port> <passwd> # comment

   if (tokens.size() < 4) {
      error_msg =  "expected <user> <host> <port> <passwd> # comment\n";
      return false;
   }

   try { boost::lexical_cast< int >( tokens[2] ); }
   catch ( boost::bad_lexical_cast& ) {
      error_msg += "Port number must be integer's\n";
      return false;
   }

   vec_.emplace_back(tokens[0],tokens[1],tokens[2],crypt(tokens[3].c_str(),tokens[0].c_str()));

   return true;
}

std::string PasswdFile::dump() const
{
   std::stringstream ss;
   int count = 1;
   for (const auto & i : vec_) {
      ss << count << ": " << i.user() << " " << i.host() << " " << i.port() << "\n";
      count++;
   }
   return ss.str();
}

bool PasswdFile::createWithAccess(
      const std::string& pathToFile,
      const std::string& host,
      const std::string& port,
      const std::string& passwd,
      std::string& errorMsg)
{
   std::vector<std::string> lines; lines.reserve( 3 );

   lines.emplace_back("4.5.0");

   string line;
   line += User::login_name();
   line += " ";
   line += host;
   line += " ";
   line += port;
   line += " ";
   line += passwd;
   lines.push_back(line);

   line.clear();
   line += User::login_name();
   line += " ";
   line += Str::LOCALHOST();
   line += " ";
   line += port;
   line += " ";
   line += passwd;
   lines.push_back(line);

   return File::create(pathToFile,lines,errorMsg);
}

bool PasswdFile::clear(
      const std::string& pathToFile,
      std::string& errorMsg)
{
   std::vector<std::string> lines;
   if (File::splitFileIntoLines(pathToFile,lines,true /* ignore empty lines */)) {
      // Just leave the version. i.e the first line.
      if (lines.size() > 1) {
         lines.erase(lines.begin()+1,lines.end());

         // Overwrite the file.
         return File::create(pathToFile,lines,errorMsg);
      }
      return true;
   }
   errorMsg += "PasswdFile::clear: Could not open file ";
   errorMsg += pathToFile;
   errorMsg += " (";
   errorMsg += strerror(errno);
   errorMsg += ")";
   return false;
}

max_stars_repo_name: ecmwf/ecflow

max_issues_repo_name: CoollRock/ecflow

max_forks_repo_name: CoollRock/ecflow


text:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <Eigen/Dense>
#include <float.h>
#include "fcm.h"

FCM::FCM(double m, double epsilon){
    m_epsilon = epsilon;
    m_m = m;
    m_membership = nullptr;
    m_data = nullptr;
    m_cluster_center = nullptr;
    m_num_clusters = 0;
    m_num_dimensions = 0;
}

FCM::~FCM(){
    if(m_data!=nullptr){
        delete m_data;
        m_data = nullptr;
    }

    if(m_membership!=nullptr){
        delete m_membership;
        m_membership = nullptr;
    }

    if(m_cluster_center!=nullptr){
        delete m_cluster_center;
        m_cluster_center = nullptr;
    }
}

double FCM::update_membership(){
    /*
     *
    */
    long k, i;
    double new_uik;
    double max_diff = 0.0, diff;

    if(m_data==nullptr || m_data->rows()==0){
        throw std::logic_error("ERROR: data should not be empty when updating the membership");
    }

    if(m_membership==nullptr || m_membership->rows() == 0 || m_membership->rows() != m_data->rows()){
        //cout << "init the membership";
        this->init_membership();
    }
    if(m_num_clusters==0){
        throw std::logic_error("ERROR: the number of clusters should be set");
    }

//    cout <<"mdata rows: "<< m_data->rows()<<endl;
//    cout << "mdata cols: "<<m_data->cols()<<endl;

    for (i = 0; i < m_num_clusters; i++) {
        for (k = 0; k < m_data->rows(); k++) {
            //cout << "point: " << k << " and cluster" << i <<endl;
            //cout << "\nwill ask for the new new_uik"<< endl;
            new_uik = this->compute_membership_point(i, k);
            //cout << new_uik << endl;
            diff = new_uik - (*m_membership)(k,i); // We need the membership inversed which is more natural for us
            if (diff > max_diff){
                max_diff = diff;
            }
            (*m_membership)(k,i) = new_uik;
        }
    }
    return max_diff;
}

void FCM::compute_centers(){
    long i, j, k;
    double numerator, denominator;
    MatrixXf t;
    t.resize(m_data->rows(), m_num_clusters);
    if(m_data == nullptr || m_data->rows() == 0){
        throw std::logic_error("ERROR: number of rows is zero");
        return;
    }
    for (i = 0; i < m_data->rows(); i++) { // compute (u^m) for each cluster for each point
        for (j = 0; j < m_num_clusters; j++) {
            t(i,j) = pow((*m_membership)(i,j), m_m);
        }
    }
    for (j = 0; j < m_num_clusters; j++) { // loop for each cluster
        for (k = 0; k < m_num_dimensions; k++) { // for each dimension
            numerator = 0.0;
            denominator = 0.0;
            for (i = 0; i < m_data->rows(); i++) {
                numerator += t(i,j) * (*m_data)(i,k);
                denominator += t(i,j);
            }
            (*m_cluster_center)(j,k) = numerator / denominator;
        }
    }
}

double FCM::get_dist(long i, long k){
  /*
   * distance which is denoted in the paper as d
   * k is the data point
   * i is the cluster center point
  */
  //cout<<"get_dist: point: "<<k<<" and cluster "<<i<<endl;
  long j;
  double sqsum = 0.0;
  if(m_num_clusters==0){
      throw std::logic_error("ERROR: number of clusters should not be zero\n");
  }
  if(m_num_dimensions==0){
      throw std::logic_error("ERROR: number of dimensions should not be zero\n");
  }
  for (j = 0; j < m_num_dimensions; j++) {
      sqsum += pow( ((*m_data)(k,j) - (*m_cluster_center)(i,j)) ,2) ;
  }
  return sqrt(sqsum);
}

double FCM::compute_membership_point(long i, long k){
    /*
     * i the cluster
     * k is the data point
    */
    //cout << __func__ <<"  num of cluster: "<<m_num_clusters<<endl;
    long j;
    double t, seg=0.0;
    double exp = 2 / (m_m - 1);
    double dik, djk;
    if(m_num_clusters==0){
        throw std::logic_error("ERROR: number of clusters should not be zero\n");
    }
    for (j = 0; j < m_num_clusters; j++) {
      dik = this->get_dist(i, k);
      djk = this->get_dist(j,k);
      if(djk==0){
          djk = DBL_MIN;
      }
      t = dik / djk;
      t = pow(t, exp);
      //cout << "cluster: " << i << "data: " << k << " - " << "t: "<<t<<endl;
      seg += t;
    }
    //cout << "seg: "<<seg << " u: "<<(1.0/seg)<<endl;
    return 1.0 / seg;
}

void FCM::set_data(MatrixXf *data){
    if(m_data!=nullptr){
        delete m_data;
    }
    if(data->rows()==0){
        throw std::logic_error("ERROR: seting empty data");
    }
    m_data = data;
    m_num_dimensions = m_data->cols();
}

void FCM::set_membership(MatrixXf *membership){
    if(m_data==0){
        throw std::logic_error("ERROR: the data should present before setting up the membership");
    }
    if(m_num_clusters==0){
        if(membership->cols() == 0){
            throw std::logic_error("ERROR: the number of clusters is 0 and the membership matrix is empty");
        }
        else{
            this->set_num_clusters(membership->cols());
        }
    }
    if(m_membership!=nullptr){
        delete m_membership;
    }
    m_membership = membership;
    if(m_membership->rows()==0){
        m_membership->resize(m_data->rows(), m_num_clusters);
    }
}

void FCM::init_membership(){
    long i, j;
    double mem;
    if(m_num_clusters == 0){
        throw std::logic_error("ERROR: the number of clusters is 0");
    }
    if(m_data==nullptr){
        throw std::logic_error("ERROR: the data should present before setting up the membership");
    }
    if(m_membership!=nullptr){
        delete m_membership;
    }
    m_membership = new MatrixXf;
    m_membership->resize(m_data->rows(), m_num_clusters);
    mem = 1.0 / m_num_clusters;
    for(j=0;j<m_num_clusters;j++){
        for(i=0;i<m_data->rows();i++){
            (*m_membership)(i,j) = mem;
        }
    }
}

void FCM::set_num_clusters(long num_clusters){
    m_num_clusters = num_clusters;
    if(m_cluster_center){
        delete m_cluster_center;
    }
    m_cluster_center = new MatrixXf;
    m_cluster_center->resize(m_num_clusters, m_num_dimensions);
}

MatrixXf * FCM::get_data(){
    return m_data;
}

MatrixXf * FCM::get_membership(){
    return m_membership;
}

MatrixXf * FCM::get_cluster_center(){
    return m_cluster_center;
}


text:
// Copyright (c) 2019 The Bigbang developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "peernet.h"

#include <boost/bind.hpp>
#include <openssl/rand.h>
#include <string>

#include "netio/nethost.h"
#include "util.h"

using namespace std;
using boost::asio::ip::tcp;

#define CONNECT_TIMEOUT 10

namespace xengine
{

///////////////////////////////
// CPeerNet

CPeerNet::CPeerNet(const string& ownKeyIn)
  : CIOProc(ownKeyIn), confNetwork{}
{
}

CPeerNet::~CPeerNet()
{
}

void CPeerNet::ConfigNetwork(CPeerNetConfig& config)
{
    confNetwork = config;
}

void CPeerNet::HandlePeerClose(CPeer* pPeer)
{
    RemovePeer(pPeer, CEndpointManager::HOST_CLOSE);
}
void CPeerNet::HandlePeerViolate(CPeer* pPeer)
{
    AddProtocolInvalidPeer(pPeer);
    RemovePeer(pPeer, CEndpointManager::PROTOCOL_INVALID);
}

void CPeerNet::HandlePeerError(CPeer* pPeer)
{
    RemovePeer(pPeer, CEndpointManager::NETWORK_ERROR);
}

void CPeerNet::HandlePeerWriten(CPeer* pPeer)
{
}

void CPeerNet::EnterLoop()
{
    for (const CPeerService& service : confNetwork.vecService)
    {
        if (StartService(service.epListen, service.nMaxInBounds))
        {
            Log("Listen port %s:%u, connections limit = %u\n",
                service.epListen.address().to_string().c_str(),
                service.epListen.port(), service.nMaxInBounds);
        }
        else
        {
            Error("Failed to listen port %s:%u, disable in-bound connection\n",
                  service.epListen.address().to_string().c_str(), service.epListen.port());
        }
    }

    for (const CNetHost& host : confNetwork.vecNode)
    {
        AddNewNode(host);
    }
}

void CPeerNet::LeaveLoop()
{
    vector<CPeer*> vPeer;
    for (map<uint64, CPeer*>::iterator it = mapPeer.begin(); it != mapPeer.end(); ++it)
    {
        vPeer.push_back((*it).second);
    }

    for (CPeer* pPeer : vPeer)
    {
        RemovePeer(pPeer, CEndpointManager::HOST_CLOSE);
    }

    for (const CPeerService& service : confNetwork.vecService)
    {
        StopService(service.epListen);
    }

    epMngr.Clear();
}

void CPeerNet::HeartBeat()
{
    if (GetOutBoundIdleCount() != 0)
    {
        tcp::endpoint ep;
        if (epMngr.FetchOutBound(ep))
        {
            if (!Connect(ep, CONNECT_TIMEOUT))
            {
                epMngr.CloseEndpoint(ep, CEndpointManager::CONNECT_FAILURE);
            }
        }
    }
}

void CPeerNet::Timeout(uint64 nNonce, uint32 nTimerId)
{
    CPeer* pPeer = GetPeer(nNonce);
    if (pPeer != nullptr)
    {
        RemovePeer(pPeer, CEndpointManager::RESPONSE_FAILURE);
    }
}

std::size_t CPeerNet::GetMaxOutBoundCount()
{
    return confNetwork.nMaxOutBounds;
}

bool CPeerNet::ClientAccepted(const tcp::endpoint& epService, CIOClient* pClient)
{
    if (epMngr.AcceptInBound(pClient->GetRemote()))
    {
        CPeer* pPeer = AddNewPeer(pClient, true);
        if (pPeer != nullptr)
        {
            return true;
        }
        epMngr.CloseEndpoint(pClient->GetRemote(), CEndpointManager::HOST_CLOSE);
    }
    return false;
}

bool CPeerNet::ClientConnected(CIOClient* pClient)
{
    CPeer* pPeer = AddNewPeer(pClient, false);
    if (pPeer != nullptr)
    {
        localIP = pClient->GetLocal().address();
        return true;
    }

    epMngr.CloseEndpoint(pClient->GetRemote(), CEndpointManager::HOST_CLOSE);
    return false;
}

void CPeerNet::ClientFailToConnect(const tcp::endpoint& epRemote)
{
    epMngr.CloseEndpoint(epRemote, CEndpointManager::CONNECT_FAILURE);
}

void CPeerNet::HostResolved(const CNetHost& host, const tcp::endpoint& ep)
{
    if (host.strName == "toremove")
    {
        epMngr.RemoveOutBound(ep);
        CPeer* pPeer = GetPeer(ep);
        if (pPeer)
        {
            HandlePeerClose(pPeer);
        }
    }
    else
    {
        epMngr.AddNewOutBound(ep, host.strName, host.data);
    }
}

CPeer* CPeerNet::AddNewPeer(CIOClient* pClient, bool fInBound)
{
    uint64 nNonce;
    RAND_bytes((unsigned char*)&nNonce, sizeof(nNonce));
    while (mapPeer.count(nNonce) || nNonce <= 0xFF)
    {
        RAND_bytes((unsigned char*)&nNonce, sizeof(nNonce));
    }

    CPeer* pPeer = CreatePeer(pClient, nNonce, fInBound);
    if (pPeer != nullptr)
    {
        pPeer->Activate();
        mapPeer.insert(make_pair(nNonce, pPeer));
    }

    Log("Add New Peer : %s %d\n", pPeer->GetRemote().address().to_string().c_str(),
        pPeer->GetRemote().port());

    return pPeer;
}

void CPeerNet::RemovePeer(CPeer* pPeer, const CEndpointManager::CloseReason& reason)
{
    Warn("Remove Peer (%d) : %s\n", reason,
         pPeer->GetRemote().address().to_string().c_str());

    epMngr.CloseEndpoint(pPeer->GetRemote(), reason);

    CancelClientTimers(pPeer->GetNonce());
    mapPeer.erase(pPeer->GetNonce());
    DestroyPeer(pPeer);
}

void CPeerNet::RewardPeer(CPeer* pPeer, const CEndpointManager::Bonus& bonus)
{
    Log("Reward Peer (%d) : %s\n", bonus,
        pPeer->GetRemote().address().to_string().c_str());
    epMngr.RewardEndpoint(pPeer->GetRemote(), bonus);
}

CPeer* CPeerNet::GetPeer(uint64 nNonce)
{
    map<uint64, CPeer*>::iterator it = mapPeer.find(nNonce);
    if (it != mapPeer.end())
    {
        return (*it).second;
    }
    return nullptr;
}

CPeer* CPeerNet::GetPeer(const boost::asio::ip::tcp::endpoint& epNode)
{
    for (const auto& peer : mapPeer)
    {
        CPeer* pPeer = peer.second;
        if (pPeer->GetRemote() == epNode)
        {
            return pPeer;
        }
    }
    return nullptr;
}

void CPeerNet::AddNewNode(const CNetHost& host)
{
    const tcp::endpoint ep = host.ToEndPoint();
    if (ep != tcp::endpoint())
    {
        epMngr.AddNewOutBound(ep, host.strName, host.data);
    }
    else
    {
        ResolveHost(host);
    }
}

void CPeerNet::AddNewNode(const tcp::endpoint& epNode, const string& strName, const boost::any& data)
{
    epMngr.AddNewOutBound(epNode, strName, data);
}

void CPeerNet::RemoveNode(const CNetHost& host)
{
    const tcp::endpoint ep = host.ToEndPoint();
    if (ep != tcp::endpoint())
    {
        epMngr.RemoveOutBound(ep);
        CPeer* pPeer = GetPeer(ep);
        if (pPeer)
        {
            HandlePeerClose(pPeer);
        }
    }
    else
    {
        ResolveHost(CNetHost(host.strHost, host.nPort, "toremove"));
    }
}

void CPeerNet::RemoveNode(const tcp::endpoint& epNode)
{
    epMngr.RemoveOutBound(epNode);
}

void CPeerNet::AddProtocolInvalidPeer(CPeer* pPeer)
{
    setProtocolInvalidIP.insert(pPeer->GetRemote().address());
}

string CPeerNet::GetNodeName(const tcp::endpoint& epNode)
{
    return epMngr.GetOutBoundName(epNode);
}

bool CPeerNet::GetNodeData(const tcp::endpoint& epNode, boost::any& data)
{
    return epMngr.GetOutBoundData(epNode, data);
}

bool CPeerNet::SetNodeData(const tcp::endpoint& epNode, const boost::any& data)
{
    return epMngr.SetOutBoundData(epNode, data);
}

void CPeerNet::RetrieveGoodNode(vector<CNodeAvail>& vGoodNode, int64 nActiveTime, size_t nMaxCount)
{
    return epMngr.RetrieveGoodNode(vGoodNode, nActiveTime, nMaxCount);
}

std::string CPeerNet::GetLocalIP()
{
    if (IsRoutable(localIP))
    {
        return localIP.to_string();
    }
    return "0.0.0.0";
}

CPeer* CPeerNet::CreatePeer(CIOClient* pClient, uint64 nNonce, bool fInBound)
{
    return (new CPeer(this, pClient, nNonce, fInBound));
}

void CPeerNet::DestroyPeer(CPeer* pPeer)
{
    delete pPeer;
}

CPeerInfo* CPeerNet::GetPeerInfo(CPeer* pPeer, CPeerInfo* pInfo)
{
    if (pInfo == nullptr)
    {
        pInfo = new CPeerInfo();
    }

    if (pInfo != nullptr)
    {
        tcp::endpoint ep = pPeer->GetRemote();

        if (ep.address().is_v6())
        {
            pInfo->strAddress = string("[") + ep.address().to_string() + string("]:") + to_string(ep.port());
        }
        else
        {
            pInfo->strAddress = ep.address().to_string() + string(":") + to_string(ep.port());
        }
        pInfo->fInBound = pPeer->IsInBound();
        pInfo->nActive = pPeer->nTimeActive;
        pInfo->nLastRecv = pPeer->nTimeRecv;
        pInfo->nLastSend = pPeer->nTimeSend;

        pInfo->nScore = epMngr.GetEndpointScore(ep);
    }

    return pInfo;
}

bool CPeerNet::HandleEvent(CEventPeerNetGetIP& eventGetIP)
{
    eventGetIP.result = GetLocalIP();
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetGetCount& eventGetCount)
{
    eventGetCount.result = mapPeer.size();
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetGetPeers& eventGetPeers)
{
    eventGetPeers.result.reserve(mapPeer.size());
    for (map<uint64, CPeer*>::iterator it = mapPeer.begin(); it != mapPeer.end(); ++it)
    {
        CPeerInfo* pInfo = GetPeerInfo((*it).second);
        if (pInfo != nullptr)
        {
            eventGetPeers.result.push_back(pInfo);
        }
    }
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetAddNode& eventAddNode)
{
    AddNewNode(eventAddNode.data);
    eventAddNode.result = true;
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetRemoveNode& eventRemoveNode)
{
    RemoveNode(eventRemoveNode.data);
    eventRemoveNode.result = true;
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetGetBanned& eventGetBanned)
{
    epMngr.GetBanned(eventGetBanned.result);
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetSetBan& eventSetBan)
{
    vector<boost::asio::ip::address> vAddrToBan;
    for (const string& strAddress : eventSetBan.data.first)
    {
        boost::system::error_code ec;
        boost::asio::ip::address addr = boost::asio::ip::address::from_string(strAddress, ec);
        if (!ec)
        {
            vAddrToBan.push_back(addr);
        }
    }
    epMngr.SetBan(vAddrToBan, eventSetBan.data.second);
    eventSetBan.result = vAddrToBan.size();
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetClrBanned& eventClrBanned)
{
    vector<boost::asio::ip::address> vAddrToClear;
    for (const string& strAddress : eventClrBanned.data)
    {
        boost::system::error_code ec;
        boost::asio::ip::address addr = boost::asio::ip::address::from_string(strAddress, ec);
        if (!ec)
        {
            vAddrToClear.push_back(addr);
        }
    }
    epMngr.ClearBanned(vAddrToClear);
    eventClrBanned.result = vAddrToClear.size();
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetReward& eventReward)
{
    CPeer* pPeer = GetPeer(eventReward.nNonce);
    if (pPeer == nullptr)
    {
        return false;
    }
    epMngr.RewardEndpoint(pPeer->GetRemote(), eventReward.data);
    return true;
}

bool CPeerNet::HandleEvent(CEventPeerNetClose& eventClose)
{
    CPeer* pPeer = GetPeer(eventClose.nNonce);
    if (pPeer == nullptr)
    {
        return false;
    }
    RemovePeer(pPeer, eventClose.data);
    return true;
}

} // namespace xengine


text:
#include "reader.hpp"
#include "consts.hpp"
#include "tablestore/core/types.hpp"
#include "tablestore/util/security.hpp"
#include "tablestore/util/try.hpp"
#include "tablestore/util/foreach.hpp"
#include <boost/static_assert.hpp>
#include <tr1/type_traits>
#include <cstring>

using namespace std;
using namespace aliyun::tablestore::util;

namespace aliyun {
namespace tablestore {
namespace core {
namespace plainbuffer {

namespace {

Optional<OTSError> issueError(const char* filename, int line)
{
    OTSError e(OTSError::kPredefined_CorruptedResponse);
    e.mutableMessage() = "Fail to parse protobuf in response at ";
    e.mutableMessage().append(filename);
    e.mutableMessage().push_back(':');
    pp::prettyPrint(e.mutableMessage(), line);
    return Optional<OTSError>(util::move(e));
}

} // namespace

#define ISSUE()                                 \
    return issueError(__FILE__, __LINE__)

namespace impl {

template<class T>
Optional<OTSError> readUint(T& out, uint8_t const *& b, uint8_t const * e)
{
    BOOST_STATIC_ASSERT(std::tr1::is_unsigned<T>::value);

    if (b + sizeof(T) > e) {
        ISSUE();
    }

    out = 0;
    for(size_t i = 0; i < sizeof(T); ++i) {
        T x = *b;
        x <<= 8 * i;
        out |= x;
        ++b;
    }

    return Optional<OTSError>();
}

Optional<OTSError> readUint64(uint64_t& out, uint8_t const *& b, uint8_t const * e)
{
    return readUint<uint64_t>(out, b, e);
}

Optional<OTSError> readUint32(uint32_t& out, uint8_t const *& b, uint8_t const * e)
{
    return readUint<uint32_t>(out, b, e);
}

Optional<OTSError> readUint8(uint8_t& out, uint8_t const *& b, uint8_t const * e)
{
    if (b + sizeof(uint8_t) > e) {
        ISSUE();
    }
    out = *b;
    ++b;
    return Optional<OTSError>();
}

Optional<OTSError> readHeader(uint8_t const *& b, uint8_t const * e)
{
    uint32_t header = 0;
    TRY(readUint32(header, b, e));
    if (header != kHeader) {
        ISSUE();
    }
    return Optional<OTSError>();
}

Optional<OTSError> readTag(Tag& out, uint8_t const *& b, uint8_t const * e)
{
    uint8_t res = 0;
    TRY(readUint8(res, b, e));
    out = static_cast<Tag>(res);
    return Optional<OTSError>();
}

bool peekAndCheckTag(const Tag expect, uint8_t const * b, uint8_t const * e)
{
    if (b + sizeof(uint8_t) > e) {
        return false;
    }
    return static_cast<uint8_t>(expect) == *b;
}

Optional<OTSError> readBlob(
    string& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    uint32_t len = 0;
    TRY(readUint32(len, b, e));

    if (b + len > e) {
        ISSUE();
    }

    MemPiece p(b, len);
    out = p.to<string>();
    crc8U32(checksum, len);
    crc8MemPiece(checksum, p);
    b += len;

    return Optional<OTSError>();
}

Optional<OTSError> readName(
    string& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_CellName) {
            ISSUE();
        }
    }
    uint32_t len = 0;
    TRY(readUint32(len, b, e));

    if (b + len > e) {
        ISSUE();
    }

    MemPiece p(b, len);
    out = p.to<string>();
    crc8MemPiece(checksum, p);
    b += len;

    return Optional<OTSError>();
}

Optional<OTSError> readVariantType(
    VariantType& out,
    uint8_t const *& b,
    uint8_t const * e)
{
    deque<VariantType> types;
    types.push_back(kVT_Integer);
    types.push_back(kVT_Double);
    types.push_back(kVT_Boolean);
    types.push_back(kVT_String);
    types.push_back(kVT_Blob);

    uint8_t v = 0;
    TRY(readUint8(v, b, e));

    FOREACH_ITER(i, types) {
        if (static_cast<uint8_t>(*i) == v) {
            out = *i;
            return Optional<OTSError>();
        }
    }
    ISSUE();
}

Optional<OTSError> readPrimaryKeyValue(
    PrimaryKeyValue& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_CellValue) {
            ISSUE();
        }
    }
    {
        uint32_t placeholder = 0;
        TRY(readUint32(placeholder, b, e));
    }

    VariantType vt = kVT_Null;
    TRY(readVariantType(vt, b, e));
    switch(vt) {
    case kVT_Integer: {
        uint64_t v = 0;
        TRY(readUint64(v, b, e));
        out.mutableInteger() = v;
        crc8(checksum, static_cast<uint8_t>(kVT_Integer));
        crc8U64(checksum, v);
        break;
    }
    case kVT_String: {
        crc8(checksum, static_cast<uint8_t>(kVT_String));
        string v;
        TRY(readBlob(v, checksum, b, e));
        out.mutableStr() = v;
        break;
    }
    case kVT_Blob: {
        crc8(checksum, static_cast<uint8_t>(kVT_Blob));
        string v;
        TRY(readBlob(v, checksum, b, e));
        out.mutableBlob() = v;
        break;
    }

    case kVT_Double: case kVT_Boolean: case kVT_Null:
    case kVT_InfMin: case kVT_InfMax: case kVT_AutoIncrement:
        ISSUE();
    }
    return Optional<OTSError>();
}

Optional<OTSError> readPrimaryKeyColumn(
    PrimaryKeyColumn& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_Cell) {
            ISSUE();
        }
    }
    uint8_t colChecksum = 0;
    TRY(readName(out.mutableName(), colChecksum, b, e));
    TRY(readPrimaryKeyValue(out.mutableValue(), colChecksum, b, e));

    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_CellChecksum) {
            ISSUE();
        }
        uint8_t oracle = 0;
        TRY(readUint8(oracle, b, e));
        if (colChecksum != oracle) {
            ISSUE();
        }
    }
    crc8(checksum, colChecksum);

    return Optional<OTSError>();
}

Optional<OTSError> readRowKey(
    PrimaryKey& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_RowKey) {
            ISSUE();
        }
    }
    for(;peekAndCheckTag(kTag_Cell, b, e);) {
        TRY(readPrimaryKeyColumn(out.append(), checksum, b, e));
    }
    return Optional<OTSError>();
}

Optional<OTSError> readAttrValue(
    AttributeValue& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_CellValue) {
            ISSUE();
        }
    }
    {
        uint32_t placeholder = 0;
        TRY(readUint32(placeholder, b, e));
    }

    VariantType vt = kVT_Null;
    TRY(readVariantType(vt, b, e));
    switch(vt) {
    case kVT_Integer: {
        uint64_t v = 0;
        TRY(readUint64(v, b, e));
        out.mutableInteger() = v;
        crc8(checksum, static_cast<uint8_t>(kVT_Integer));
        crc8U64(checksum, v);
        break;
    }
    case kVT_String: {
        crc8(checksum, static_cast<uint8_t>(kVT_String));
        string v;
        TRY(readBlob(v, checksum, b, e));
        out.mutableStr() = v;
        break;
    }
    case kVT_Blob: {
        crc8(checksum, static_cast<uint8_t>(kVT_Blob));
        string v;
        TRY(readBlob(v, checksum, b, e));
        out.mutableBlob() = v;
        break;
    }
    case kVT_Double: {
        uint64_t iv = 0;
        TRY(readUint64(iv, b, e));
        double v = 0;
        memcpy(static_cast<void*>(&v), static_cast<const void*>(&iv), sizeof(double));
        out.mutableFloatPoint() = v;
        crc8(checksum, static_cast<uint8_t>(kVT_Double));
        crc8U64(checksum, iv);
        break;
    }
    case kVT_Boolean: {
        uint8_t v = 0;
        TRY(readUint8(v, b, e));
        out.mutableBoolean() = v ? true : false;
        crc8(checksum, static_cast<uint8_t>(kVT_Boolean));
        crc8(checksum, static_cast<uint8_t>(out.boolean() ? 1 : 0));
        break;
    }

    case kVT_Null: case kVT_InfMin: case kVT_InfMax: case kVT_AutoIncrement:
        ISSUE();
    }
    return Optional<OTSError>();
}

Optional<OTSError> readOptionalCellTimestamp(
    Optional<UtcTime>& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    if (peekAndCheckTag(kTag_CellTimestamp, b, e)) {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        uint64_t v = 0;
        TRY(readUint64(v, b, e));
        out.reset(UtcTime::fromMsec(static_cast<int64_t>(v)));
        crc8U64(checksum, v);
    }
    return Optional<OTSError>();
}

Optional<OTSError> readAttr(
    Attribute& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_Cell) {
            ISSUE();
        }
    }
    uint8_t colChecksum = 0;
    TRY(readName(out.mutableName(), colChecksum, b, e));
    TRY(readAttrValue(out.mutableValue(), colChecksum, b, e));
    TRY(readOptionalCellTimestamp(out.mutableTimestamp(), colChecksum, b, e));

    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_CellChecksum) {
            ISSUE();
        }
        uint8_t oracle = 0;
        TRY(readUint8(oracle, b, e));
        if (colChecksum != oracle) {
            ISSUE();
        }
    }
    crc8(checksum, colChecksum);

    return Optional<OTSError>();
}

Optional<OTSError> readAttrs(
    IVector<Attribute>& out,
    uint8_t& checksum,
    uint8_t const *& b,
    uint8_t const * e)
{
    {
        Tag tag = kTag_None;
        TRY(readTag(tag, b, e));
        if (tag != kTag_RowData) {
            ISSUE();
        }
    }
    for(;peekAndCheckTag(kTag_Cell, b, e);) {
        TRY(readAttr(out.append(), checksum, b, e));
    }
    return Optional<OTSError>();
}

Optional<OTSError> readRow(Row& out, uint8_t const *& b, uint8_t const * e)
{
    uint8_t checksum = 0;

    TRY(readRowKey(out.mutablePrimaryKey(), checksum, b, e));

    if (peekAndCheckTag(kTag_RowData, b, e)) {
        TRY(readAttrs(out.mutableAttributes(), checksum, b, e));
    }

    crc8(checksum, 0); // for row-delete marker

    {
        Tag tag;
        TRY(readTag(tag, b, e));
        if (tag != kTag_RowChecksum) {
            ISSUE();
        }
        uint8_t oracle = 0;
        TRY(readUint8(oracle, b, e));
        if (checksum != oracle) {
            ISSUE();
        }
    }
    return Optional<OTSError>();
}

Optional<OTSError> readRows(IVector<Row>& out, uint8_t const *& b, uint8_t const * e)
{
    for(; b < e;) {
        Row row;
        TRY(impl::readRow(row, b, e));
        moveAssign(out.append(), util::move(row));
    }
    return Optional<OTSError>();
}
} //namespace impl

Optional<OTSError> readRow(Row& out, const MemPiece& p)
{
    const uint8_t* b = p.data();
    const uint8_t* e = b + p.length();
    TRY(impl::readHeader(b, e));
    TRY(impl::readRow(out, b, e));
    if (b != e) {
        ISSUE();
    }
    return Optional<OTSError>();
}

Optional<OTSError> readRows(IVector<Row>& out, const MemPiece& p)
{
    const uint8_t* b = p.data();
    const uint8_t* e = b + p.length();
    TRY(impl::readHeader(b, e));
    TRY(impl::readRows(out, b, e));
    if (b != e) {
        ISSUE();
    }
    return Optional<OTSError>();
}

} // namespace plainbuffer
} // namespace core
} // namespace tablestore
} // namespace aliyun

max_stars_repo_name: TimeExceed/aliyun-tablestore-cpp-sdk

max_issues_repo_name: TimeExceed/aliyun-tablestore-cpp-sdk

max_forks_repo_name: TimeExceed/aliyun-tablestore-cpp-sdk


text:
#ifndef PERSEPHONE_H_
#define PERSEPHONE_H_

#include <boost/optional.hpp>
#include <boost/program_options.hpp>

#include <yaml-cpp/yaml.h>

#include <thread>

#include <psp/logging.hh>
#include <psp/libos/io/lrpc/context.hh>
#include <psp/libos/io/udp_dpdk/context.hh>
#include <psp/libos/Request.hh>

#include <deque>

/*************** Gloval variables **************/
namespace po = boost::program_options;

/* Logging */
const int TRACE = 0;
const int APP_TRACE = 1;

extern std::string log_dir;
extern std::string label;
#define MAX_LOG_FILENAME_LEN 128

#define MAX_FILE_PATH_LEN 128
static inline std::string generate_log_file_path(std::string exp_label, char const *log_label) {
    char pathname[MAX_FILE_PATH_LEN];
    snprintf(
        pathname, MAX_FILE_PATH_LEN, "%s/%s/%s", log_dir.c_str(), exp_label.c_str(), log_label
    );
    std::string str_pathname(pathname);
    return pathname;
}

enum class WorkerType {
    UNKNOWN = 0,
    HTTP,
    STORE,
    NET,
    DISPATCH,
    CLIENT,
    SILO,
    MBK,
    RDB
};

[[gnu::unused]] static const char *wt_str[] {
    "UNKNOWN",
    "HTTP",
    "STORE",
    "NET",
    "DISPATCH",
    "CLIENT",
    "SILO",
    "MBK",
    "ROCKSDB",
};

/************** Workers ************/
#define MAX_WORKERS 32
class Worker {
    private:
        bool started = false, exited = false;
        std::thread worker_thread;
        static void main_loop(void *wrkr);
        // Functions to overload in child classes
        virtual int dequeue(unsigned long *payload) = 0;
        virtual int setup() = 0;
        virtual int work(int status, unsigned long payload) = 0;
        virtual int process_request(unsigned long payload) = 0;
    protected:
        template <typename T> int drain_queue(T &rqueue);
        int app_work(int status, unsigned long payload);
        int app_dequeue(unsigned long *payload);
        uint32_t meter_peer_queue(int peer_id);

        uint64_t n_batchs_rcvd = 0;
        uint64_t n_drops = 0;

        int dpt_id = -1;

        bool terminate = false;

    public:
        UdpContext *udp_ctx;
        LrpcContext lrpc_ctx;

        int register_dpt(Worker &dpt);

        uint64_t n_peers = 0;
        int peer_ids[MAX_PEERS];

        bool notify = true;
        uint32_t cpu_id;
        int worker_id;
        enum WorkerType type;
        bool eal_thread = false;

        int join();
        int launch();
        bool has_exited() { return exited; }
        void stop() { terminate = true; }

        Worker(enum WorkerType type);
        Worker(enum WorkerType type, int worker_id);

        virtual ~Worker() = 0;
};

extern Worker *workers[MAX_WORKERS];
extern uint32_t total_workers;

class Psp {
    /* HW related variables */
    std::vector<uint32_t> cpus;
    public: struct rte_mempool *net_mempool = nullptr; /* << A global network mempool. Maybe unused */

    /* ctor */
    public: Psp(std::string &app_cfg, std::string label = "PspApp");
    /* dtor */
    public: ~Psp() {
        print_dpdk_device_stats(0); //XXX
        if (net_mempool) {
            rte_mempool_free(net_mempool);
            net_mempool = nullptr;
        }
    }
    private:
        template <typename A, typename B, typename C>
        int CreateWorker(int su_idx, B *dpt, C *netw, UdpContext *udp_ctx);

    /* Retrieve all workers of a given type */
    public: uint32_t get_workers(enum WorkerType type, Worker **wrkrs) {
        int j = 0;
        for (unsigned int i = 0; i < total_workers; ++i) {
            if (workers[i]->type == type) {
                wrkrs[j++] = workers[i];
            }
        }
        return j;
    }

    public: static void stop_all(int signo) {
        PSP_INFO("Stopping all workers");
        for (unsigned int i = 0; i < total_workers; ++i) {
            PSP_WARN(
                "Setting worker " << workers[i]->worker_id
                << " (" << wt_str[static_cast<int>(workers[i]->type)] << ") to terminate"
            );
            workers[i]->stop();
        }
    }

    /* Utilities */
    public: std::string role;
};

/**************** Utilities ****************/
//FIXME: those should be somewhere else
static inline void pin_thread(pthread_t thread, u_int16_t cpu) {
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(cpu, &cpuset);

    if (pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset) != 0) {
        PSP_ERROR("could not pin thread: " << strerror(errno));
    }
}

#endif //PERSEPHONE_H_

ext: hh

max_stars_repo_name: maxdml/Pers-phone

max_issues_repo_name: maxdml/psp

max_forks_repo_name: maxdml/psp


text:
//
//  cal_BTDB.hpp
//  hybrid_fem_bie
//
//  Created by Max on 2/6/18.
//
//

#ifndef cal_BTDB_hpp
#define cal_BTDB_hpp

#include <stdio.h>
#include <Eigen/Eigen>
using namespace Eigen;
void cal_BTDB (MatrixXd coord,double E, double nu,MatrixXd &B_T_D_B);

#endif /* cal_BTDB_hpp */


text:
#ifndef UMIGV_ZIP_HPP
#define UMIGV_ZIP_HPP

// defines umigv::zip, which takes a variadic number of iterable ranges and zips them together

#include "umigv_utilities/fold.hpp"
#include "umigv_utilities/traits.hpp"
#include "umigv_utilities/types.hpp"

#include <iterator>
#include <memory>
#include <tuple>
#include <type_traits>

#include <boost/optional.hpp>

namespace umigv {

template <typename IterTuple, usize ...Is>
class ZippedRange;

template <typename Iterators, usize ...Is>
class ZippedRangeIterator {
public:
    friend ZippedRange<Iterators, Is...>;

    using difference_type = isize;
    using value_type = std::tuple<iterator_reference_t<
        std::tuple_element_t<Is, Iterators>
    >...>;
    using pointer = const value_type*;
    using reference = const value_type&;
    using iterator_category = std::input_iterator_tag;

    constexpr reference operator*() const {
        if (any_equal_last()) {
            throw std::out_of_range{ "ZippedRangeIterator::operator*" };
        }

        deref_.emplace(*std::get<Is>(current_)...);

        return deref_.value();
    }

    constexpr pointer operator->() const {
        return std::addressof(**this);
    }

    constexpr ZippedRangeIterator& operator++() {
        if (any_equal_last()) {
            throw std::out_of_range{ "ZippedRangeIterator::operator++" };
        }

        auto increment = [](auto &&x) {
            ++std::forward<decltype(x)>(x);
        };

        unary_fold(std::move(increment), std::get<Is>(current_)...);

        return *this;
    }

    constexpr friend bool operator==(const ZippedRangeIterator lhs,
                                     const ZippedRangeIterator rhs) {
        if (!boolean_and(
            (std::get<Is>(lhs.last_) == std::get<Is>(rhs.last_))...
        )) {
            throw std::out_of_range{
                "operator==(ZippedRangeIterator, ZippedRangeIterator)"
            };
        }

        return boolean_or(
            (std::get<Is>(lhs.current_) == std::get<Is>(rhs.current_))...
        );
    }

    constexpr friend bool operator!=(const ZippedRangeIterator lhs,
                                     const ZippedRangeIterator rhs) {
        if (!boolean_and(
            (std::get<Is>(lhs.last_) == std::get<Is>(rhs.last_))...
        )) {
            throw std::out_of_range{
                "operator!=(ZippedRangeIterator, ZippedRangeIterator)"
            };
        }

        return boolean_and(
            (std::get<Is>(lhs.current_) != std::get<Is>(rhs.current_))...
        );
    }

private:
    constexpr ZippedRangeIterator(Iterators current, Iterators last)
    noexcept(std::is_nothrow_move_constructible<Iterators>::value)
    : current_{ std::move(current) }, last_{ std::move(last) } { }

    constexpr bool any_equal_last() const
    noexcept(conjunction_v<is_nothrow_equality_comparable<
        std::tuple_element_t<Is, value_type>
    >...>) {
        return boolean_or((std::get<Is>(current_) == std::get<Is>(last_))...);
    }

    Iterators current_;
    Iterators last_;
    mutable boost::optional<value_type> deref_;
};

template <typename Iterators, usize ...Is>
class ZippedRange {
    template <typename T>
    using DereferenceT = decltype((*std::declval<T>()));

public:
    using iterator = ZippedRangeIterator<Iterators, Is...>;
    using difference_type = iterator_difference_type<iterator>;

    constexpr ZippedRange(Iterators first, Iterators last)
    noexcept(std::is_nothrow_move_constructible<Iterators>::value)
    : first_{ std::move(first) }, last_{ std::move(last) } { }

    constexpr iterator begin() const {
        return { first_, last_ };
    }

    constexpr iterator end() const {
        return { last_, last_ };
    }

private:
    Iterators first_;
    Iterators last_;
};

template <typename IteratorTuple, usize ...Is>
typename ZippedRange<IteratorTuple, Is...>::Iterator
begin(const ZippedRange<IteratorTuple, Is...> &range)
    noexcept(noexcept(
        std::declval<ZippedRange<IteratorTuple, Is...>>().begin()
    ))
{
    return range.begin();
}

template <typename IteratorTuple, usize ...Is>
typename ZippedRange<IteratorTuple, Is...>::Iterator
end(const ZippedRange<IteratorTuple, Is...> &range)
    noexcept(noexcept(
        std::declval<ZippedRange<IteratorTuple, Is...>>().end()
    ))
{
    return range.end();
}

namespace detail {

template <typename BeginTuple, typename EndTuple,
          typename = std::common_type_t<BeginTuple, EndTuple>, usize ...Is>
auto zip(BeginTuple &&begins, EndTuple &&ends, std::index_sequence<Is...>) {
    using IteratorTupleT = std::common_type_t<BeginTuple, EndTuple>;
    using RangeT = ZippedRange<IteratorTupleT, Is...>;

    return RangeT{ std::forward<BeginTuple>(begins),
                   std::forward<EndTuple>(ends) };
}

} // namespace detail

template <typename ...Rs>
auto zip(Rs &&...ranges) noexcept(conjunction_v<has_nothrow_begin<Rs>...>
                                  && conjunction_v<has_nothrow_end<Rs>...>) {
    return detail::zip(
        std::make_tuple(adl_begin(std::forward<Rs>(ranges))...),
        std::make_tuple(adl_end(std::forward<Rs>(ranges))...),
        std::index_sequence_for<Rs...>{ }
    );
}

} // namespace umigv

#endif

max_stars_repo_name: umigv/goat

max_issues_repo_name: umigv/atlas

max_forks_repo_name: umigv/atlas