text:
#include <scorum/chain/betting/betting_service.hpp>

#include <boost/range/algorithm/set_algorithm.hpp>
#include <boost/range/algorithm/find_if.hpp>

#include <scorum/chain/schema/bet_objects.hpp>
#include <scorum/chain/schema/game_object.hpp>
#include <scorum/chain/schema/bet_objects.hpp>
#include <scorum/chain/schema/betting_property_object.hpp>

#include <scorum/chain/betting/betting_math.hpp>

#include <scorum/chain/services/account.hpp>

#include <scorum/chain/dba/db_accessor_factory.hpp>
#include <scorum/chain/dba/db_accessor.hpp>

#include <scorum/utils/range/unwrap_ref_wrapper_adaptor.hpp>
#include <scorum/utils/algorithm/foreach_mut.hpp>

#include <scorum/utils/collect_range_adaptor.hpp>

namespace scorum {
namespace chain {

betting_service_i::~betting_service_i() = default;

betting_service::betting_service(account_service_i& account_svc,
                                 database_virtual_operations_emmiter_i& virt_op_emitter,
                                 dba::db_accessor<betting_property_object>& betting_property_dba,
                                 dba::db_accessor<matched_bet_object>& matched_bet_dba,
                                 dba::db_accessor<pending_bet_object>& pending_bet_dba,
                                 dba::db_accessor<game_object>& game_dba,
                                 dba::db_accessor<dynamic_global_property_object>& dprop_dba,
                                 dba::db_accessor<bet_uuid_history_object>& uuid_hist_dba)
    : _account_svc(account_svc)
    , _virt_op_emitter(virt_op_emitter)
    , _betting_property_dba(betting_property_dba)
    , _matched_bet_dba(matched_bet_dba)
    , _pending_bet_dba(pending_bet_dba)
    , _game_dba(game_dba)
    , _dprop_dba(dprop_dba)
    , _uuid_hist_dba(uuid_hist_dba)
{
}

bool betting_service::is_betting_moderator(const account_name_type& account_name) const
{
    try
    {
        return _betting_property_dba.get().moderator == account_name;
    }
    FC_CAPTURE_LOG_AND_RETHROW((account_name))
}

const pending_bet_object& betting_service::create_pending_bet(const account_name_type& better,
                                                              const asset& stake,
                                                              odds odds,
                                                              const wincase_type& wincase,
                                                              uuid_type game_uuid,
                                                              uuid_type bet_uuid,
                                                              pending_bet_kind kind)
{
    const auto& better_acc = _account_svc.get_account(better);
    FC_ASSERT(better_acc.balance >= stake, "Insufficient funds");

    _uuid_hist_dba.create([&](bet_uuid_history_object& o) { o.uuid = bet_uuid; });

    const auto& bet = _pending_bet_dba.create([&](pending_bet_object& o) {
        o.game_uuid = game_uuid;
        o.market = create_market(wincase);
        o.data.uuid = bet_uuid;
        o.data.stake = stake;
        o.data.odds = odds;
        o.data.created = _dprop_dba.get().time;
        o.data.better = better;
        o.data.kind = kind;
        o.data.wincase = wincase;
    });

    _dprop_dba.update([&](auto& obj) { obj.betting_stats.pending_bets_volume += stake; });

    _account_svc.decrease_balance(better_acc, stake);

    return bet;
}

void betting_service::cancel_game(uuid_type game_uuid)
{
    auto matched_bets = _matched_bet_dba.get_range_by<by_game_uuid_market>(game_uuid);
    FC_ASSERT(matched_bets.empty(), "Cannot cancel game which has associated bets");

    auto pending_bets = _matched_bet_dba.get_range_by<by_game_uuid_market>(game_uuid);
    FC_ASSERT(pending_bets.empty(), "Cannot cancel game which has associated bets");

    const auto& game = _game_dba.get_by<by_uuid>(game_uuid);
    _game_dba.remove(game);
}

void betting_service::cancel_bets(uuid_type game_uuid)
{
    cancel_pending_bets(game_uuid);
    cancel_matched_bets(game_uuid);
}

void betting_service::cancel_bets(uuid_type game_uuid, fc::time_point_sec created_after)
{
    using namespace dba;

    auto lower = std::make_tuple(game_uuid, created_after);
    auto upper = game_uuid;
    auto matched_bets = _matched_bet_dba.get_range_by<by_game_uuid_created>(lower <= _x, _x <= upper);
    auto pending_bets = _pending_bet_dba.get_range_by<by_game_uuid_created>(lower <= _x, _x <= upper);

    cancel_pending_bets(pending_bets);

    for (const matched_bet_object& matched_bet : matched_bets)
    {
        if (matched_bet.bet1_data.created >= created_after)
            return_bet(matched_bet.bet1_data, game_uuid);
        else
            restore_pending_bet(matched_bet.bet1_data, game_uuid);

        if (matched_bet.bet2_data.created >= created_after)
            return_bet(matched_bet.bet2_data, game_uuid);
        else
            restore_pending_bet(matched_bet.bet2_data, game_uuid);
    }

    _matched_bet_dba.remove_all(matched_bets);
}

void betting_service::cancel_bets(uuid_type game_uuid, const fc::flat_set<market_type>& cancelled_markets)
{
    // clang-format off
    struct less
    {
        bool operator()(const pending_bet_object& b, const market_type& m) const { return b.market < m; }
        bool operator()(const market_type& m, const pending_bet_object& b) const { return m < b.market; }
        bool operator()(const matched_bet_object& b, const market_type& m) const { return b.market < m; }
        bool operator()(const market_type& m, const matched_bet_object& b) const { return m < b.market; }
    };
    // clang-format on

    auto pending_bets = _pending_bet_dba.get_range_by<by_game_uuid_market>(game_uuid);

    std::vector<std::reference_wrapper<const pending_bet_object>> filtered_pending_bets;
    boost::set_intersection(pending_bets, cancelled_markets, std::back_inserter(filtered_pending_bets), less{});

    cancel_pending_bets(utils::unwrap_ref_wrapper(filtered_pending_bets));

    auto matched_bets = _matched_bet_dba.get_range_by<by_game_uuid_market>(game_uuid);

    std::vector<std::reference_wrapper<const matched_bet_object>> filtered_matched_bets;
    boost::set_intersection(matched_bets, cancelled_markets, std::back_inserter(filtered_matched_bets), less{});

    cancel_matched_bets(utils::unwrap_ref_wrapper(filtered_matched_bets), game_uuid);
}

void betting_service::cancel_pending_bet(pending_bet_id_type id)
{
    const auto& pending_bet = _pending_bet_dba.get_by<by_id>(id);

    cancel_pending_bet(pending_bet, pending_bet.game_uuid);
}

void betting_service::cancel_pending_bets(uuid_type game_uuid)
{
    auto pending_bets = _pending_bet_dba.get_range_by<by_game_uuid_market>(game_uuid);

    cancel_pending_bets(pending_bets);
}

void betting_service::cancel_pending_bets(uuid_type game_uuid, pending_bet_kind kind)
{
    auto pending_bets = _pending_bet_dba.get_range_by<by_game_uuid_kind>(std::make_tuple(game_uuid, kind));

    cancel_pending_bets(pending_bets);
}

void betting_service::cancel_pending_bets(utils::bidir_range<const pending_bet_object> bets)
{
    utils::foreach_mut(bets, [&](const pending_bet_object& bet) { //
        cancel_pending_bet(bet, bet.game_uuid);
    });
}

void betting_service::cancel_matched_bets(uuid_type game_uuid)
{
    auto matched_bets = _matched_bet_dba.get_range_by<by_game_uuid_market>(game_uuid);

    cancel_matched_bets(matched_bets, game_uuid);
}

void betting_service::cancel_matched_bets(utils::bidir_range<const matched_bet_object> bets, uuid_type game_uuid)
{
    utils::foreach_mut(bets, [&](const matched_bet_object& bet) { //
        cancel_matched_bet(bet, game_uuid);
    });
}

void betting_service::cancel_pending_bet(const pending_bet_object& bet, uuid_type game_uuid)
{
    _account_svc.increase_balance(bet.data.better, bet.data.stake);

    push_pending_bet_cancelled_op(bet.data, game_uuid);

    _dprop_dba.update([&](auto& o) { o.betting_stats.pending_bets_volume -= bet.data.stake; });

    _pending_bet_dba.remove(bet);
}

void betting_service::cancel_matched_bet(const matched_bet_object& bet, uuid_type game_uuid)
{
    return_bet(bet.bet1_data, game_uuid);
    return_bet(bet.bet2_data, game_uuid);

    _matched_bet_dba.remove(bet);
}

void betting_service::return_bet(const bet_data& bet, uuid_type game_uuid)
{
    _account_svc.increase_balance(bet.better, bet.stake);

    push_matched_bet_cancelled_op(bet, game_uuid);

    _dprop_dba.update([&](auto& o) { o.betting_stats.matched_bets_volume -= bet.stake; });
}

void betting_service::restore_pending_bet(const bet_data& bet, uuid_type game_uuid)
{
    auto is_exists = _pending_bet_dba.is_exists_by<by_uuid>(bet.uuid);
    if (is_exists)
    {
        const auto& pending_bet = _pending_bet_dba.get_by<by_uuid>(bet.uuid);
        auto old_stake = pending_bet.data.stake;

        _pending_bet_dba.update(pending_bet, [&](pending_bet_object& o) { o.data.stake += bet.stake; });

        _virt_op_emitter.push_virtual_operation(
            bet_updated_operation{ game_uuid, bet.better, bet.uuid, old_stake, pending_bet.data.stake });
    }
    else
    {
        _pending_bet_dba.create([&](pending_bet_object& o) {
            o.game_uuid = game_uuid;
            o.market = create_market(bet.wincase);
            o.data = bet;
        });

        _virt_op_emitter.push_virtual_operation(bet_restored_operation{ game_uuid, bet.better, bet.uuid, bet.stake });
    }

    _dprop_dba.update([&](auto& o) {
        o.betting_stats.pending_bets_volume += bet.stake;
        o.betting_stats.matched_bets_volume -= bet.stake;
    });
}

void betting_service::push_matched_bet_cancelled_op(const bet_data& bet, uuid_type game_uuid)
{
    _virt_op_emitter.push_virtual_operation(
        bet_cancelled_operation{ game_uuid, bet.better, bet.uuid, bet.stake, bet_kind::matched });
}

void betting_service::push_pending_bet_cancelled_op(const bet_data& bet, uuid_type game_uuid)
{
    _virt_op_emitter.push_virtual_operation(
        bet_cancelled_operation{ game_uuid, bet.better, bet.uuid, bet.stake, bet_kind::pending });
}
}
}

max_stars_repo_name: scorum/scorum

max_issues_repo_name: Scorum/Scorum

max_forks_repo_name: Scorum/Scorum


text:
// Copyright (C) 2018 Thejaka Amila Kanewala, Marcin Zalewski, Andrew Lumsdaine.

// Boost Software License - Version 1.0 - August 17th, 2003

// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:

// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//  Authors: Thejaka Kanewala
//           Andrew Lumsdaine
#ifndef DRIVER_SYNTHETIC_GEN
#define DRIVER_SYNTHETIC_GEN

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>
#include <inttypes.h>
#include <cstdlib>
#include <math.h>

#define AMPLUSPLUS_PRINT_HIT_RATES
#define BFS_SV_CC_HACK
#define DISABLE_BFS_BITMAP
#ifdef __bgp__
#define BGP_REPORT_MEMORY 1 // if >1 all ranks will report memory usage
#endif
#define BARRIER_TRANS
#define CALCULATE_GTEPS 1
#include <am++/am++.hpp>
#include <am++/mpi_transport.hpp>
#include <am++/counter_coalesced_message_type.hpp>

#include <boost/graph/distributed/time_calc.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/graph/use_mpi.hpp>
#include <boost/property_map/parallel/distributed_property_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/distributed/compressed_sparse_row_graph.hpp>
#include <boost/graph/distributed/selector.hpp>
#include <boost/graph/recursive_rmat_generator.hpp>
#include <boost/graph/erdos_renyi_generator.hpp>
#include <boost/graph/graph500_generator.hpp>
#include <boost/graph/permute_graph.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/parallel/algorithm.hpp> // for all_reduce
#include <boost/graph/relax.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_map/parallel/global_index_map.hpp>
#include <boost/accumulators/accumulators.hpp>

#include <cds/init.h>       // for cds::Initialize and cds::Terminate
#include <cds/gc/hp.h>      // for cds::HP (Hazard Pointer) SMR

#include <parallel/algorithm>
#include <algorithm> // for std::min, std::max
#include <functional>
#include <boost/graph/util/utils.hpp>

// Params class -- try to keep this simple
class graph_gen_params {
public:
  graph_gen_params(): scale(20),
		      n((unsigned long long)(1) << scale),
		      gen_weights(true),
		      max_weight(255),
		      distribution_type(block),
		      block_size(10),
		      num_threads(16),
		      rmata(INITIATOR_A_NUMERATOR),
		      rmatbc(INITIATOR_BC_NUMERATOR),
		      preprocess(false)

  {}

  int scale;
  unsigned long long n; // number of vertices

  // edges weights
  bool gen_weights;
  weight_type max_weight;

  distribution_t distribution_type;
  size_t block_size;
  size_t distribution_coalescing_size = 1 << 17;

  double edge_factor = 16;
  double edge_list_reserve_factor = 1.15;

  int num_threads;

  uint64_t seed64 = 12345;

  std::vector<routing_type> routing = {rt_none};

  // RMAT parameters -- These values will be divided by 10000
  int32_t rmata;
  int32_t rmatbc;

  // Preprocessing
  bool preprocess;

  void print() {
    assert(_RANK != -1);
    if (_RANK == 0) {
      std::cout << "============= Printing Graph Generation Parameters =============" << std::endl;
      std::cout << "Scale = " << scale << std::endl;
      std::cout << "n = " << n << std::endl;
      std::cout << "Generate Weights = " << gen_weights << std::endl;
      std::cout << "Max weight = " << max_weight << std::endl;
      std::cout << "Distribution type = " << distribution_type << std::endl;
      std::cout << "Block size = " << block_size << std::endl;
      std::cout << "Distribution Coalescing = " << distribution_coalescing_size << std::endl;
      std::cout << "Edge factor = " << edge_factor << std::endl;
      std::cout << "Edge list reserve factor = " << edge_list_reserve_factor << std::endl;
      std::cout << "Threads = " << num_threads << std::endl;
      std::cout << "Seed = " << seed64 << std::endl;
      assert(routing.size() >= 1);
      std::cout << "Routing = " << routing[0] << std::endl;
      std::cout << "RMAT A = " << rmata << std::endl;
      std::cout << "RMAT B = C = " << rmatbc << std::endl;
      std::cout << "Preprocess : " << preprocess << std::endl;
      std::cout << "================================================================" << std::endl;
    }
  }

  std::string get_graph_type() {
    std::string graph_type = "unknown";
    if ((rmata == 5700) &&
	(rmatbc == 1900))
      graph_type = "RMAT1";

    if ((rmata == 5000) &&
	(rmatbc == 1000))
      graph_type = "RMAT2";

    return graph_type;
  }

  std::string get_generator_specific_input() {
    std::stringstream ss;
    ss << ", RMAT-A :" << rmata
       << ", RMAT-BC :" << rmatbc
       << ", SCALE : " << scale
       << ", DEGREE : " << edge_factor;

    return ss.str();
  }

  bool load_graph_file() {
    return false;
  }

  bool parse(int argc, char* argv[]) {

    bool graph_type_specified = false;

    for (int i = 1; i < argc; ++i) {
      std::string arg = argv[i];
      if (arg == "--scale") {
	scale = boost::lexical_cast<size_t>( argv[i+1] );
	n = (unsigned long long)(1) << scale;
      }

      if (arg == "--no-weight") {
	gen_weights = false;
      }

      if (arg == "--max-weight") {
	max_weight = boost::lexical_cast<weight_type>( argv[i+1] );
      }

      if (arg == "--distribution-type") {
	std::string distt = boost::lexical_cast<std::string>( argv[i+1] );
	if (distt == "block")
	  distribution_type = block;
	else if (distt == "cyclic")
	  distribution_type = cyclic;
	else
	  std::cerr << "Invalid distribution type. Available types are block and cyclic" << std::endl;
      }

      if (arg == "--block-size") {
	block_size = boost::lexical_cast<size_t>( argv[i+1] );
      }

      if (arg == "--distribution-coalescing-size") {
	distribution_coalescing_size = boost::lexical_cast<size_t>( argv[i+1] );
      }

      if (arg == "--preprocess")
	preprocess = true;

      if (arg == "--edge-factor") {
	edge_factor = boost::lexical_cast<double>( argv[i+1] );
      }

      if (arg == "--edge-list-reserve-factor") {
	edge_list_reserve_factor = boost::lexical_cast<double>( argv[i+1] );
      }

      if (arg == "--num-threads") {
	num_threads = boost::lexical_cast<int>( argv[i+1] );
      }

      if (arg == "--seed") {
	seed64 = boost::lexical_cast<uint64_t>( argv[i+1] );
      }

      if (arg == "--routing") {
	std::string rt = boost::lexical_cast<std::string>( argv[i+1] );
	if (rt == "rt_none")
	  routing.push_back(rt_none);
	else if (rt == "rt_rook")
	  routing.push_back(rt_rook);
	else if (rt == "rt_hypercube")
	  routing.push_back(rt_hypercube);
	else
	  std::cerr << "Invalid routing type. Available routing types -- rt_none, rt_rook and rt_hypercube"
		   << std::endl;
      }

      if (arg == "--rmat1") {

	if (graph_type_specified) {
	  std::cerr << "Graph type already specified. Cannot specify again." << std::endl;
	  return false;
	}

	rmata = 5700;
	rmatbc = 1900;
	graph_type_specified = true;
      }

      if (arg == "--rmat2") {
	if (graph_type_specified) {
	  std::cerr << "Graph type already specified. Cannot specify again." << std::endl;
	  return false;
	}

	rmata = 5000;
	rmatbc = 1000;
	graph_type_specified = true;
      }

      if (arg == "--rmata") {
	if (graph_type_specified) {
	  std::cerr << "Graph type already specified. Cannot specify again." << std::endl;
	  return false;
	}

	rmata = boost::lexical_cast<int>( argv[i+1] );
	assert(rmata <= INITIATOR_DENOMINATOR);
      }

      if (arg == "--rmatbc") {
	if (graph_type_specified) {
	  std::cerr << "Graph type already specified. Cannot specify again." << std::endl;
	  return false;
	}

	rmatbc = boost::lexical_cast<int>( argv[i+1] );
	assert(rmatbc <= INITIATOR_DENOMINATOR);
      }

      assert((rmata + rmatbc*2) < INITIATOR_DENOMINATOR);
    }

    return true;
  }
};

//
// Edge weight generator iterator
//
template<typename F, typename RandomGenerator>
class generator_iterator
{
public:
  typedef std::input_iterator_tag iterator_category;
  typedef typename F::result_type value_type;
  typedef const value_type&       reference;
  typedef const value_type*       pointer;
  typedef void                    difference_type;

  explicit
  generator_iterator(RandomGenerator& gen, const F& f = F())
    : f(f), gen(&gen)
  {
    value = this->f(gen);
  }

  reference operator*() const  { return value; }
  pointer   operator->() const { return &value; }

  generator_iterator& operator++()
  {
    value = f(*gen);
    return *this;
  }

  generator_iterator operator++(int)
  {
    generator_iterator temp(*this);
    ++(*this);
    return temp;
  }

  bool operator==(const generator_iterator& other) const
  { return f == other.f; }

  bool operator!=(const generator_iterator& other) const
  { return !(*this == other); }

private:
  F f;
  RandomGenerator* gen;
  value_type value;
};

template<typename F, typename RandomGenerator>
inline generator_iterator<F, RandomGenerator>
make_generator_iterator( RandomGenerator& gen, const F& f)
{ return generator_iterator<F, RandomGenerator>(gen, f); }

// For distribution
template<typename MessageType>
class threaded_distributor {
public:
  threaded_distributor(MessageType& mtype) : msg_type(mtype) {}
  void operator()() {
  }
  template <typename InIter, typename Flip, typename SelfLoopDetector>
  void operator()(int tid, InIter begin, InIter end, const Flip& flip,
		  const SelfLoopDetector sloopdet,
                  amplusplus::transport& trans) {
    AMPLUSPLUS_WITH_THREAD_ID(tid) {
      if (0 == tid) {
        int nthreads = trans.get_nthreads();
        t_bar.reset(new amplusplus::detail::barrier(nthreads));
      }

      // for thread barrier to initialize
      { amplusplus::scoped_epoch epoch(trans); }

      //      debug("starting concurrent distribute", tid);
      concurrent_distribute(begin, end, flip, sloopdet, trans, msg_type);

      t_bar->wait();
    }
  }

private:
  MessageType& msg_type;
  boost::shared_ptr<amplusplus::detail::barrier> t_bar;
};

template <typename Edges>
class threaded_merger {
public:
  threaded_merger(Edges& all) : all_edges(all) {}
  void operator()() {
  }
  template <typename EdgesIter>
  void operator()(EdgesIter pos, EdgesIter begin, EdgesIter end) {
    std::copy(begin, end, pos);
  }

private:
  Edges& all_edges;

};

// For distribution -- to generate an undirected graph with weights
struct flip_pair_w_weight {
  template <typename T>
  T operator()(const T& x) const {
    // flipping edges by keeping same weight
    return std::make_pair(x.second.first, std::make_pair(x.first, x.second.second));
  }
};

// For distribution -- to generate an undirected graph
struct flip_pair_wo_weight {
  template <typename T>
  T operator()(const T& x) const {
    // flipping edges by keeping same weight
    return std::make_pair(x.second, x.first);
  }
};

// Exclude self loops for weighted edges
struct a_self_looop_w_weight {
  template <typename T>
  bool operator()(const T& x) const {
    // flipping edges by keeping same weight
    return (x.first == x.second.first);
  }
};

// Exclude self-loops for unweighted edges
struct a_self_loops_wo_weight {
  template <typename T>
  bool operator()(const T& x) const {
    // flipping edges by keeping same weight
    return (x.first == x.second);
  }
};

// functions to separate edge weight and edge
// separating edge
template<typename t1, typename t2>
struct select_edge : std::unary_function< std::pair<t1, std::pair<t1, t2> >, std::pair<t1, t1> > {
public:
  select_edge() {}

  std::pair<t1, t1> operator()(std::pair<t1, std::pair<t1, t2> >& ew) const {
    return std::make_pair(ew.first, ew.second.first);
  }
};

// separating edge weight
template<typename t1, typename t2>
struct select_edge_weight : std::unary_function< std::pair<t1, std::pair<t1, t2> >, t2 > {
public:
  select_edge_weight() {}

  t2 operator()(std::pair<t1, std::pair<t1, t2> >& ew) const {
    return ew.second.second;
  }
};

class synthetic_generator {
  typedef boost::compressed_sparse_row_graph<boost::directedS, boost::no_property, WeightedEdge,
					     boost::no_property, boost::distributedS<unsigned long long> > Digraph;
  typedef boost::graph_traits<Digraph>::vertex_descriptor Vertex;
  typedef boost::graph_traits<Digraph>::edges_size_type edges_size_type;
  typedef boost::graph_traits<Digraph>::vertices_size_type vertices_size_type;
  typedef boost::property_map<Digraph, boost::vertex_index_t>::type VertexIndexMap;
  typedef boost::property_map<Digraph, boost::vertex_owner_t>::const_type OwnerMap;

public:
  synthetic_generator(amplusplus::transport& transport):
    trans(transport), g(NULL) {}

 template<typename Graph500Iter,
	  typename Routing,
	  typename Distribution,
	  typename EdgeSize,
	  typename UInt,
	  typename Edges,
	  typename WeightIterator>
 void do_distribute(const graph_gen_params& params,
		    Distribution &distrib,
		    EdgeSize e_start,
		    EdgeSize e_count,
		    UInt a,
		    UInt b,
		    Edges &edges,
		    WeightIterator weight_iter) {

    typedef amplusplus::routing_generator<amplusplus::counter_coalesced_message_type_gen, Routing> MessageGenerator;
    MessageGenerator msg_gen(amplusplus::counter_coalesced_message_type_gen(params.distribution_coalescing_size
#ifdef NO_COALESCING
									    , true)
#else
									    )
#endif
      , Routing(trans.rank(), trans.size()));

    time_type start = get_time();

    // Multithreaded distribution
    trans.set_nthreads(params.num_threads);

#ifdef PRINT_DEBUG
    std::cout << "Thread start : " << e_start << "Total edge count : " << e_count
	      << " for rank :" << trans.rank()
	      << std::endl;
#endif

    Edges* thread_edges = new Edges[params.num_threads];
    EdgeSize std_count_per_thread = (e_count + params.num_threads - 1) / params.num_threads;
    //   EdgeSize remainder = e_count % num_threads;

#ifdef PRINT_DEBUG
    std::cout << "std_count_per_thread : " << std_count_per_thread << std::endl;
#endif

    EdgeSize thread_start = e_start;
    EdgeSize count_per_thread = std_count_per_thread;

    // create message type
    typedef typename std::iterator_traits<Graph500Iter>::value_type value_type;
    typedef boost::detail::vector_write_handler<Edges> vec_write_handler;

    // not sure we need this here
    amplusplus::register_mpi_datatype<value_type>();

    typedef typename MessageGenerator::template call_result<value_type, vec_write_handler,
							    boost::detail::distrib_to_pair_owner_map_t<Distribution>,
							    amplusplus::no_reduction_t>::type
      write_msg_type;

    write_msg_type write_msg(msg_gen, trans, boost::detail::distrib_to_pair_owner_map<Distribution>(distrib),
			     amplusplus::no_reduction);

    // set the handler (must be in main thread)
    write_msg.set_handler(vec_write_handler(thread_edges));
    threaded_distributor<write_msg_type> td(write_msg);

    boost::scoped_array<boost::thread> threads(new boost::thread[params.num_threads - 1]);
    for (int i = 0; i < params.num_threads - 1; ++i) {
#ifdef PRINT_DEBUG
      if (_RANK == 0) {
	std::cout << "Thread : " << i+1 << " start : " << thread_start
		  << " thread end : " << (thread_start + count_per_thread)
		  << std::endl;
      }
#endif
      boost::thread thr(boost::ref(td), i+1, Graph500Iter(params.scale, thread_start, a, b, weight_iter, params.rmata, params.rmatbc),
			Graph500Iter(params.scale, thread_start + count_per_thread, a, b, weight_iter, params.rmata, params.rmatbc),
			flip_pair_w_weight(), a_self_looop_w_weight(), trans);
      thread_start = thread_start + count_per_thread;
      threads[i].swap(thr);
    }

    // Allocate remainder to main thread
    count_per_thread = std::min(std_count_per_thread, (e_count-thread_start));

#ifdef PRINT_DEBUG
    std::cout << "Thread : " << 0 << " start : " << thread_start
		<< " thread end : " << (thread_start + count_per_thread)
		<< std::endl;
#endif

    td(0, Graph500Iter(params.scale, thread_start, a, b, weight_iter),
       Graph500Iter(params.scale, thread_start + count_per_thread, a, b, weight_iter),
       flip_pair_w_weight(), a_self_looop_w_weight(), trans);

    // Wait till all threads finish
    for (int i = 0; i < params.num_threads - 1; ++i)
      threads[i].join();

    // Merge all edges - in threads
    //    time_type m_start = get_time();

    typename Edges::size_type total_sz = 0;
    std::vector<typename Edges::size_type> positions(params.num_threads);
    for (int i = 0; i < params.num_threads; ++i) {
      positions[i] = total_sz;
      total_sz += thread_edges[i].size();
    }

    edges.resize(total_sz);
    threaded_merger<Edges> tm(edges);

    boost::scoped_array<boost::thread> m_threads(new boost::thread[params.num_threads - 1]);
    for (int i = 0; i < params.num_threads - 1; ++i) {
      typename Edges::iterator pos_ite = edges.begin();
      std::advance(pos_ite, positions[i+1]);
      boost::thread thr(boost::ref(tm), pos_ite,
			thread_edges[i+1].begin(), thread_edges[i+1].end());
      m_threads[i].swap(thr);
    }

    tm(edges.begin(), thread_edges[0].begin(), thread_edges[0].end());

    // Wait till all threads finish
    for (int i = 0; i < params.num_threads - 1; ++i)
      m_threads[i].join();

    //time_type m_end = get_time();

    trans.set_nthreads(1);
    delete[] thread_edges;
    { amplusplus::scoped_epoch epoch(trans); }
    time_type end = get_time();
    if (_RANK==0)
      std::cout << "[INFO] Graph distribution permutation took " << (end-start)
		<< " time" << std::endl;

    // sort edges in parallel
    //__gnu_parallel::sort(edges.begin(), edges.end());
  }

  // distribution without weights -- need to find a better way to do this without duplicating code
 template<typename Graph500Iter,
	  typename Routing,
	  typename Distribution,
	  typename EdgeSize,
	  typename UInt,
	  typename Edges>
 void do_distribute(const graph_gen_params& params,
		    Distribution &distrib,
		    EdgeSize e_start,
		    EdgeSize e_count,
		    UInt a,
		    UInt b,
		    Edges &edges) {

    typedef amplusplus::routing_generator<amplusplus::counter_coalesced_message_type_gen, Routing> MessageGenerator;
    MessageGenerator msg_gen(amplusplus::counter_coalesced_message_type_gen(params.distribution_coalescing_size
#ifdef NO_COALESCING
									    , true)
#else
									    )
#endif
      , Routing(trans.rank(), trans.size()));

    time_type start = get_time();

    // Multithreaded distribution
    trans.set_nthreads(params.num_threads);

#ifdef PRINT_DEBUG
    std::cout << "Thread start : " << e_start << "Total edge count : " << e_count
	      << " for rank :" << trans.rank()
	      << std::endl;
#endif

    Edges* thread_edges = new Edges[params.num_threads];
    EdgeSize std_count_per_thread = (e_count + params.num_threads - 1) / params.num_threads;
    //   EdgeSize remainder = e_count % num_threads;

#ifdef PRINT_DEBUG
    std::cout << "std_count_per_thread : " << std_count_per_thread << std::endl;
#endif

    EdgeSize thread_start = e_start;
    EdgeSize count_per_thread = std_count_per_thread;

    // create message type
    typedef typename std::iterator_traits<Graph500Iter>::value_type value_type;
    typedef boost::detail::vector_write_handler<Edges> vec_write_handler;

    // not sure we need this here
    amplusplus::register_mpi_datatype<value_type>();

    typedef typename MessageGenerator::template call_result<value_type, vec_write_handler,
							    boost::detail::distrib_to_pair_owner_map_t<Distribution>,
							    amplusplus::no_reduction_t>::type
      write_msg_type;

    write_msg_type write_msg(msg_gen, trans, boost::detail::distrib_to_pair_owner_map<Distribution>(distrib),
			     amplusplus::no_reduction);

    // set the handler (must be in main thread)
    write_msg.set_handler(vec_write_handler(thread_edges));
    threaded_distributor<write_msg_type> td(write_msg);

    boost::scoped_array<boost::thread> threads(new boost::thread[params.num_threads - 1]);
    for (int i = 0; i < params.num_threads - 1; ++i) {
#ifdef PRINT_DEBUG
      if (_RANK == 0) {
	std::cout << "Thread : " << i+1 << " start : " << thread_start
		  << " thread end : " << (thread_start + count_per_thread)
		  << std::endl;
      }
#endif
      boost::thread thr(boost::ref(td), i+1, Graph500Iter(params.scale, thread_start, a, b, params.rmata, params.rmatbc),
			Graph500Iter(params.scale, thread_start + count_per_thread, a, b, params.rmata, params.rmatbc),
			flip_pair_wo_weight(), a_self_loops_wo_weight(), trans);
      thread_start = thread_start + count_per_thread;
      threads[i].swap(thr);
    }

    // Allocate remainder to main thread
    count_per_thread = std::min(std_count_per_thread, (e_count-thread_start));

#ifdef PRINT_DEBUG
    std::cout << "Thread : " << 0 << " start : " << thread_start
		<< " thread end : " << (thread_start + count_per_thread)
		<< std::endl;
#endif

    td(0, Graph500Iter(params.scale, thread_start, a, b),
       Graph500Iter(params.scale, thread_start + count_per_thread, a, b),
       flip_pair_wo_weight(), a_self_loops_wo_weight(), trans);

    // Wait till all threads finish
    for (int i = 0; i < params.num_threads - 1; ++i)
      threads[i].join();

    // Merge all edges - in threads
    //    time_type m_start = get_time();

    typename Edges::size_type total_sz = 0;
    std::vector<typename Edges::size_type> positions(params.num_threads);
    for (int i = 0; i < params.num_threads; ++i) {
      positions[i] = total_sz;
      total_sz += thread_edges[i].size();
    }

    edges.resize(total_sz);
    threaded_merger<Edges> tm(edges);

    boost::scoped_array<boost::thread> m_threads(new boost::thread[params.num_threads - 1]);
    for (int i = 0; i < params.num_threads - 1; ++i) {
      typename Edges::iterator pos_ite = edges.begin();
      std::advance(pos_ite, positions[i+1]);
      boost::thread thr(boost::ref(tm), pos_ite,
			thread_edges[i+1].begin(), thread_edges[i+1].end());
      m_threads[i].swap(thr);
    }

    tm(edges.begin(), thread_edges[0].begin(), thread_edges[0].end());

    // Wait till all threads finish
    for (int i = 0; i < params.num_threads - 1; ++i)
      m_threads[i].join();

    //time_type m_end = get_time();

    trans.set_nthreads(1);
    delete[] thread_edges;
    { amplusplus::scoped_epoch epoch(trans); }
    time_type end = get_time();
    if (_RANK == 0)
      std::cout << "[INFO] Graph distribution permutation took " << (end-start)
		<< " time" << std::endl;

    // sort edges in parallel
    //__gnu_parallel::sort(edges.begin(), edges.end());
  }

  struct vertex_comparator {
    template<typename Edge>
    bool operator()(const Edge& e1, const Edge& e2) {
      if (e1.first < e2.first)
	return true;
      else if (e1.first == e2.first) {
	return e1.second < e2.second;
      } else
	return false;
    }
  };

  // Preprocess the graph
  // 1. Remove self loops
  // 2. Remove parallel edges
  template<typename edge_t>
  void preprocess(std::vector<edge_t>& edges) {
    std::sort(edges.begin(), edges.end(), vertex_comparator());
    edges.erase(std::unique(edges.begin(), edges.end(),
			    [](edge_t e1, edge_t e2) {
			      return ((e1.first == e2.first) && (e1.second == e2.second));
			    }), edges.end());

#ifdef PRINT_DEBUG
    for (auto i=0; i < edges.size(); ++i) {
      std::cout << "(" << edges[i].first << ", " << edges[i].second << ")" << std::endl;
    }
#endif
  }

  void generate_graph_w_weights(const graph_gen_params& params) {

    if (_RANK == 0)
      std::cout << "[INFO] Generating graph with edges" << std::endl;

    // Seed general-purpose RNG
    boost::rand48 gen, synch_gen;
    gen.seed(params.seed64);
    synch_gen.seed(params.seed64);

    typedef generator_iterator<boost::uniform_int<weight_type>, boost::rand48> weight_iterator_t;
    weight_iterator_t gi
      = make_generator_iterator(gen, boost::uniform_int<weight_type>(1, params.max_weight));

    typedef std::vector<std::pair<edges_size_type, std::pair<edges_size_type, weight_type> > > edge_with_weight_t;
    edge_with_weight_t edges;
    boost::parallel::variant_distribution<vertices_size_type> distrib;

    edges_size_type m = static_cast<edges_size_type>(floor(params.n * params.edge_factor));
    edges.reserve(static_cast<edges_size_type>(floor(params.edge_list_reserve_factor * 2 * m / trans.size())));

    if (params.distribution_type == cyclic) {
      distrib = boost::parallel::oned_block_cyclic<vertices_size_type>(trans, params.block_size);
    } else //(distribution_type == block)
      distrib = boost::parallel::block<vertices_size_type>(trans, params.n);

    boost::uniform_int<uint64_t> rand_64(0, std::numeric_limits<uint64_t>::max());

    edges_size_type e_start = trans.rank() * (m + trans.size() - 1) / trans.size();
    edges_size_type e_count = (std::min)((m + trans.size() - 1) / trans.size(), m - e_start);

    // Permute and redistribute copy constructs the input iterator
    uint64_t a = rand_64(gen);
    uint64_t b = rand_64(gen);

    // Build a graph to test with
    typedef boost::graph500_iterator<Digraph,
				     generator_iterator<boost::uniform_int<weight_type>,
							boost::rand48>, weight_type > Graph500Iter;
    assert(!params.routing.empty());

    // As for now, we assume that only the first routing from the list is used to generate the graph.
    // It seems that it does not really matter which routing we use here since generation of the graph is not a part of the performance test.
    if (params.routing[0] == rt_none) {
      do_distribute<Graph500Iter, amplusplus::no_routing>(params, distrib, e_start, e_count, a, b, edges, gi);
    } else if (params.routing[0] == rt_hypercube) {
      do_distribute<Graph500Iter, amplusplus::hypercube_routing>(params, distrib, e_start, e_count, a, b, edges, gi);
    } else if (params.routing[0] == rt_rook) {
      do_distribute<Graph500Iter, amplusplus::rook_routing>(params, distrib, e_start, e_count, a, b, edges, gi);
    }

    typedef select_edge<edges_size_type, weight_type> EdgeSelectFunction;
    typedef boost::transform_iterator<EdgeSelectFunction, edge_with_weight_t::iterator> edge_only_iterator;

    typedef select_edge_weight<edges_size_type, weight_type> WeightSelectFunction;
    typedef boost::transform_iterator<WeightSelectFunction, edge_with_weight_t::iterator> weight_only_iterator;

    edge_only_iterator edge_begin(edges.begin(), EdgeSelectFunction()),
      edge_end(edges.end(), EdgeSelectFunction());

    weight_only_iterator weight_begin(edges.begin(), WeightSelectFunction());

    time_type gt1 = get_time();
    g = new Digraph(boost::edges_are_unsorted_multi_pass, edge_begin, edge_end,
		    weight_begin, params.n, trans, distrib);
    time_type gt2 = get_time();

    if (_RANK == 0)
      std::cout << "[INFO] Local graph creation time : " << (gt2-gt1)
		<< std::endl;
    // Clear edge array above
    edges.clear();

  }

  void generate_graph_wo_weights(const graph_gen_params& params) {

    if (_RANK == 0)
      std::cout << "[INFO] Generating graph with out edges" << std::endl;

    // Seed general-purpose RNG
    boost::rand48 gen, synch_gen;
    gen.seed(params.seed64);
    synch_gen.seed(params.seed64);

    typedef std::pair<edges_size_type, edges_size_type> edge_t;
    typedef std::vector<edge_t> edges_t;
    edges_t edges;
    boost::parallel::variant_distribution<vertices_size_type> distrib;

    edges_size_type m = static_cast<edges_size_type>(floor(params.n * params.edge_factor));
    edges.reserve(static_cast<edges_size_type>(floor(params.edge_list_reserve_factor * 2 * m / trans.size())));

    if (params.distribution_type == cyclic) {
      distrib = boost::parallel::oned_block_cyclic<vertices_size_type>(trans, params.block_size);
    } else //(distribution_type == block)
      distrib = boost::parallel::block<vertices_size_type>(trans, params.n);

    boost::uniform_int<uint64_t> rand_64(0, std::numeric_limits<uint64_t>::max());

    edges_size_type e_start = trans.rank() * (m + trans.size() - 1) / trans.size();
    edges_size_type e_count = (std::min)((m + trans.size() - 1) / trans.size(), m - e_start);

    // Permute and redistribute copy constructs the input iterator
    uint64_t a = rand_64(gen);
    uint64_t b = rand_64(gen);

    // Build a graph to test with
    typedef boost::graph500_iterator<Digraph> Graph500Iter;
    assert(!params.routing.empty());

    // As for now, we assume that only the first routing from the list is used to generate the graph.
    // It seems that it does not really matter which routing we use here since generation of the graph is not a part of the performance test.
    if (params.routing[0] == rt_none) {
      do_distribute<Graph500Iter, amplusplus::no_routing>(params, distrib, e_start, e_count, a, b, edges);
    } else if (params.routing[0] == rt_hypercube) {
      do_distribute<Graph500Iter, amplusplus::hypercube_routing>(params, distrib, e_start, e_count, a, b, edges);
    } else if (params.routing[0] == rt_rook) {
      do_distribute<Graph500Iter, amplusplus::rook_routing>(params, distrib, e_start, e_count, a, b, edges);
    }

    if (params.preprocess) {
      if (_RANK == 0)
	std::cout << "[INFO] Preprocessing the graph -- removing parallel edges" << std::endl;

      time_type pt1 = get_time();
      preprocess<edge_t>(edges);
      time_type pt2 = get_time();

      if (_RANK == 0)
	std::cout << "[INFO] The preprocessing time : " << pt2-pt1 << std::endl;
    }

    time_type gt1 = get_time();
    g = new Digraph(boost::edges_are_unsorted_multi_pass, edges.begin(), edges.end(),
	      params.n, trans, distrib);
    time_type gt2 = get_time();

    if (_RANK == 0)
      std::cout << "[INFO] Local graph creation time : " << (gt2-gt1)
	      << std::endl;
    // Clear edge array above
    edges.clear();
  }

  void generate_graph(const graph_gen_params& params) {
    time_type start = get_time();

    if (params.gen_weights)
      generate_graph_w_weights(params);
    else
      generate_graph_wo_weights(params);

    time_type end = get_time();
    if (_RANK == 0)
      std::cout << "[INFO] Graph generation took " << end - start
	      << "(sec) time." << std::endl;
  }

  Digraph* graph() {
    return g;
  }

  // MUST call finalize release memory associated with the graph
  void finalize() {
    delete g;
  }

private:
  amplusplus::transport& trans;
  Digraph* g;

};

#endif

ext: hpp

max_stars_repo_name: thejkane/AGM

max_issues_repo_name: thejkane/AGM

max_forks_repo_name: thejkane/AGM


text:
//==============================================================================
//         Copyright 2003 - 2012 LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2013 LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_SIMD_SWAR_FUNCTIONS_SIMD_COMMON_REPEAT_LOWER_HALF_HPP_INCLUDED
#define BOOST_SIMD_SWAR_FUNCTIONS_SIMD_COMMON_REPEAT_LOWER_HALF_HPP_INCLUDED

#include <boost/simd/swar/functions/repeat_lower_half.hpp>
#include <boost/simd/include/functions/simd/extract.hpp>
#include <boost/simd/include/functions/simd/make.hpp>
#include <boost/simd/include/functions/simd/bitwise_cast.hpp>
#include <boost/simd/sdk/meta/is_bitwise_logical.hpp>
#include <boost/simd/sdk/meta/as_arithmetic.hpp>
#include <boost/simd/sdk/meta/cardinal_of.hpp>
#include <boost/simd/preprocessor/make.hpp>

namespace boost { namespace simd { namespace ext
{
  BOOST_DISPATCH_IMPLEMENT          ( repeat_lower_half_
                                    , tag::cpu_
                                    , (A0)(X)
                                    , ((simd_< unspecified_<A0>, X>))
                                    )
  {
    typedef A0                                    result_type;
    typedef simd::meta::cardinal_of<result_type>  card_t;

    BOOST_FORCEINLINE result_type operator()(A0 const& a0) const
    {
      return eval(a0,typename card_t::type());
    }

    #define M0(z, n, t) extract<n %(card_t::value/2)>(a0)

    BOOST_SIMD_PP_IMPLEMENT_WITH_MAKE(1, M0)

    #undef M0
  };

  BOOST_DISPATCH_IMPLEMENT_IF         ( repeat_lower_half_, tag::cpu_
                                      , (A0)(X)
                                      , ( boost::simd::meta::is_bitwise_logical<A0> )
                                      , ((simd_< logical_<A0>, X>))
                                      )
  {
    typedef A0 result_type;

    BOOST_FORCEINLINE BOOST_SIMD_FUNCTOR_CALL(1)
    {
      typedef typename meta::as_arithmetic<A0>::type type;
      return bitwise_cast<result_type>(
        repeat_lower_half( bitwise_cast<type>(a0) )
      );
    }
  };
} } }

#endif


text:
// Copyright (c) 2015, Galaxy Authors. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: zhoushiyong@baidu.com

#include <fstream>
#include <sstream>
#include <time.h>
#include <vector>
#include <sys/stat.h>
#include <errno.h>
#include <boost/bind.hpp>
#include "common/asm_atomic.h"
#include "common/logging.h"
#include "common/util.h"
#include "monitor_impl.h"

namespace galaxy {
MonitorImpl::MonitorImpl() {
    running_ = false;
    msg_forbit_time_ = 60;
    thread_pool_.AddTask(boost::bind(&MonitorImpl::Reporting, this));
}
MonitorImpl::~MonitorImpl() {
    std::map<std::string, Watch*>::iterator watch_it;
    for (watch_it == watch_map_.begin(); watch_it != watch_map_.end(); watch_it++) {
        delete watch_it->second;
    }

    std::map<std::string, Trigger*>::iterator trigger_it;
    for (trigger_it == trigger_map_.begin(); trigger_it != trigger_map_.end();
            trigger_it++) {
        delete trigger_it->second;
    }

    std::map<std::string, Action*>::iterator action_it;
    for (action_it == action_map_.begin(); action_it != action_map_.end();
            action_it++) {
        delete action_it->second;
    }

    std::vector<Rule*>::iterator rule_it;
    for (rule_it == rule_list_.begin(); rule_it != rule_list_.end();
            rule_it++) {
        delete *rule_it;
    }
    return;
}

void MonitorImpl::Split(std::string& src, std::string& delim, std::vector<std::string>* ret) {
    size_t last = 0;
    size_t index=src.find_first_of(delim, last);
    while (index!=std::string::npos) {
        ret->push_back(src.substr(last,index-last));
        last=index+1;
        index=src.find_first_of(delim,last);
    }
    if (index-last>0) {
        ret->push_back(src.substr(last,index-last));
    }
    return;
}
bool MonitorImpl::ParseConfig(const std::string conf_path) {
    std::ifstream fin(conf_path.c_str());
    if (!fin) {
        LOG(WARNING, "open conf_path err %s", conf_path.c_str());
        return false;
    }
    std::string line;
    char value[1024];
    while (getline(fin, line)) {
        if (line.size() == 0) {
            continue;
        }
        if (sscanf(line.c_str(), "<input>:%s", value)) {
            log_path.assign(value);
        } else if (sscanf(line.c_str(), "<watch>:%s", value)) {
            std::vector<std::string> args;
            std::string input(value);
            std::string delim("|");
            Split(input, delim, &args);
            Watch *watch_ptr = new Watch();
            watch_ptr->item_name.assign(args[1]);
            watch_ptr->regex.assign(args[2]);
            watch_ptr->reg.assign(args[2]);
            watch_ptr->count = 0;
            watch_map_[args[0]] = watch_ptr;
        } else if (sscanf(line.c_str(), "<trigger>:%s", value)) {
            std::vector<std::string> args;
            std::string input(value);
            std::string delim("|");
            Split(input, delim, &args);
            Trigger* trigger_ptr = new Trigger();
            trigger_ptr->item_name.assign(args[0]);
            trigger_ptr->threadhold = atoi(args[2].c_str());
            trigger_ptr->relate.assign(args[1]);
            trigger_ptr->range = atoi(args[3].c_str());
            trigger_ptr->timestamp = time(NULL);
            trigger_map_[args[0]] = trigger_ptr;
        } else if (sscanf(line.c_str(), "<action>:%s", value)) {
            std::vector<std::string> args;
            std::string input(value);
            std::string delim("|");
            Split(input, delim, &args);
            Action* action_ptr = new Action();
            action_ptr->title.assign(args[2]);
            action_ptr->content.assign(args[3]);
            action_ptr->timestamp = 0;
            delim.assign(":");
            Split(args[1], delim, &(action_ptr->to_list));
            action_map_[args[0]] = action_ptr;
        } else if (sscanf(line.c_str(), "<rule>:%s", value)) {
            std::vector<std::string> args;
            std::string input(value);
            std::string delim("|");
            Split(input, delim, &args);
            Rule* rule_ptr = new Rule();
            rule_ptr->watch = watch_map_.find(args[0])->second;
            rule_ptr->trigger = trigger_map_.find(args[1])->second;
            rule_ptr->action = action_map_.find(args[2])->second;
            rule_list_.push_back(rule_ptr);
        }
    }
    return true;
}

void MonitorImpl::Run() {
    size_t seek = 0;
    struct stat* st_mark = new struct stat;
    while (0 != stat(log_path.c_str(), st_mark)) {
        LOG(WARNING, "stat log file err %s [%d:%s]", log_path.c_str(),
                errno, strerror(errno));
        sleep(1);
        continue;
    }
    std::ifstream fin(log_path.c_str());
    fin.seekg(0, std::ios::end);
    seek = fin.tellg();
    fin.seekg(seek, std::ios::beg);
    std::string line;
    running_ = true;

    while (running_) {
        if (fin.peek() == EOF) {
            struct stat* st_tmp = new struct stat;
            if (0 != stat(log_path.c_str(), st_tmp)) {
                LOG(WARNING, "stat log file err %s [%d:%s]", log_path.c_str(),
                     errno, strerror(errno));
                delete st_tmp;
                sleep(1);
                continue;
            } else if (st_tmp->st_ino != st_mark->st_ino) {
                fin.close();
                fin.clear();
                fin.open(log_path.c_str());
                delete st_mark;
                st_mark = st_tmp;
                continue;
            } else if (seek != 0) {
                delete st_tmp;
                fin.clear();
                fin.seekg(seek, std::ios::beg);
                sleep(1);
                continue;
            } else {
                delete st_tmp;
                sleep(1);
                continue;
            }
        }
        getline(fin, line);
        seek = fin.tellg();
        ExecRule(std::string(line));
    }
    delete st_mark;
    fin.close();
    return;
}

bool MonitorImpl::ExecRule(std::string src) {
    for (std::vector<Rule*>::iterator it = rule_list_.begin();
            it != rule_list_.end(); it++) {
        if (Matching(src, (*it)->watch)) {
            LOG(INFO, "Matching hit %s", src.c_str());
        }
    }
    return true;
}

bool MonitorImpl::Matching(std::string src, Watch* watch) {
    assert(watch != NULL);
    boost::cmatch mat;
    if (boost::regex_search(src.c_str(), mat, watch->reg)) {
        common::atomic_inc(&watch->count);
        return true;
    }
    return false;
}

bool MonitorImpl::Judging( int* cnt, Trigger* trigger) {
    assert(trigger != NULL);
    bool ret = false;
    if (trigger->relate == "<") {
        ret = (*cnt < trigger->threadhold);
    } else if (trigger->relate == std::string("=")) {
        ret = (*cnt == trigger->threadhold);
    } else if (trigger->relate == std::string(">")) {
        ret = (*cnt > trigger->threadhold);
    } else {
        LOG(WARNING, "unsupported relate %s", trigger->relate.c_str());
    }

    if (time(NULL) - trigger->timestamp >= trigger->range) {
        common::atomic_swap(cnt, 0);
        trigger->timestamp = time(NULL);
        return ret;
    }
    return false;
}

bool MonitorImpl::Treating(Action* act) {
    assert(act != NULL);
    if (act->timestamp == 0) {
        act->timestamp = time(NULL);
    } else if ((time(NULL) - act->timestamp) < msg_forbit_time_) {
        return true;
    }
    for (std::vector<std::string>::iterator it = act->to_list.begin();
            it != act->to_list.end(); it++) {
        std::string cmd = std::string("/home/galaxy/tools/gsmsend ")
            + std::string("-s emp01.baidu.com:15001 -semp02.baidu.com:15001 ")
            + *it + "@" + "\"from:" + common::util::GetLocalHostName()
            + "\n" + act->title + ":" + act->content + "\"";
        if (0 != system(cmd.c_str())) {
            LOG(WARNING, "gsmsend msg err %s", cmd.c_str());
        }
        act->timestamp = time(NULL);
    }
    return true;
}

void MonitorImpl::Reporting() {
    for (std::vector<Rule*>::iterator it = rule_list_.begin();
            it != rule_list_.end(); it++) {
        if (!Judging(&((*it)->watch->count), (*it)->trigger)) {
            continue;
        }
        if (!Treating((*it)->action)) {
            continue;
        }
    }
    thread_pool_.DelayTask(3000, boost::bind(&MonitorImpl::Reporting, this));
    return;
}
}

/* vim: set ts=4 sw=4 sts=4 tw=100 */

ext: cc

max_stars_repo_name: fxsjy/galaxy

max_issues_repo_name: fxsjy/galaxy

max_forks_repo_name: fxsjy/galaxy


text:
#include <jni.h>

#include <Eigen/Geometry>

#include <opencv/cv.h>
#include <highgui.h>

#include <android/log.h>

#define  LOG_TAG	"CameraPoseUtils"
#define  LOGI(...)	__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define  LOGE(...)	__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

using namespace std;
using namespace cv;
using namespace Eigen;

extern "C"
{
	JNIEXPORT jboolean JNICALL Java_it_unibo_slam_utils_CameraPoseUtils_estimateLocalObjectPoseNative(JNIEnv *env, jobject obj,
			jlong rgbImage, jint chessboardWidth, jint chessboardHeight, jdoubleArray translationVector, jdoubleArray rotationVector);

	JNIEXPORT void JNICALL Java_it_unibo_slam_utils_CameraPoseUtils_estimateWorldCameraPoseNative(JNIEnv *env, jobject obj,
			jdoubleArray worldTranslationVector, jdoubleArray worldRotationMatrix, jdoubleArray initialTranslationVector,
			jdoubleArray initialRotationMatrix, jdoubleArray finalTranslationVector, jdoubleArray finalRotationMatrix);
}

namespace
{
	bool initializedPoseVariables = false;

	Mat rgbIntrinsics;
	Mat rgbDistortion;
	Mat irIntrinsics;
	Mat irDistortion;
	Mat translationVectorRgbIr;
	Mat rotationMatrixRgbIr;
	Mat translationVectorIrRgb;
	Mat rotationMatrixIrRgb;
}

void calculateChessboardCorners(Size boardSize, float squareSize, vector<Point3f>& corners)
{
	corners.resize(0);

    for(int i = 0; i < boardSize.height; i++)
        for(int j = 0; j < boardSize.width; j++)
            corners.push_back(Point3f(float(j * squareSize), float(i * squareSize), 0));
}

JNIEXPORT jboolean JNICALL Java_it_unibo_slam_utils_CameraPoseUtils_estimateLocalObjectPoseNative(JNIEnv *env, jobject obj,
		jlong rgbImage, jint chessboardWidth, jint chessboardHeight, jdoubleArray translationVector, jdoubleArray rotationMatrix)
{
	if (!initializedPoseVariables)
	{
		FileStorage storage("/sdcard/CalibrationResults.xml", FileStorage::READ);

		storage["CameraMat1"] >> rgbIntrinsics;
		storage["DistorsionMat1"] >> rgbDistortion;
		storage["CameraMat2"] >> irIntrinsics;
		storage["DistorsionMat2"] >> irDistortion;
		storage["TranslationVec"] >> translationVectorRgbIr;
		storage["RotationMat"] >> rotationMatrixRgbIr;

		storage.release();

		initializedPoseVariables = true;
	}

	vector<Point2f> chessboardCorners;
	Mat rgbMat = *((Mat*)rgbImage);
	Mat grayscaleMat(rgbMat.rows, rgbMat.cols, CV_8U);
	cvtColor(rgbMat, grayscaleMat, CV_RGB2GRAY);

	bool patternFound = findChessboardCorners(grayscaleMat, Size(chessboardWidth, chessboardHeight), chessboardCorners);

	if (patternFound)
	{
		jdouble *translationVectorTemp = env->GetDoubleArrayElements(translationVector, NULL);
		jdouble *rotationMatrixTemp = env->GetDoubleArrayElements(rotationMatrix, NULL);

		cornerSubPix(grayscaleMat, chessboardCorners, Size(5, 5), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40, 0.001));

		vector<Point3f> objectPoints;
		float sizeSquareSide = 0.026F;
		//float sizeSquareSide = 0.050F;
		calculateChessboardCorners(Size(chessboardWidth, chessboardHeight), sizeSquareSide, objectPoints);

		Mat translationPnP = Mat::zeros(3, 1, CV_64F);
		Mat rotationPnP = Mat::zeros(3, 1, CV_64F);
		solvePnP(objectPoints, chessboardCorners, rgbIntrinsics, rgbDistortion, rotationPnP, translationPnP);

		translationVectorTemp[0] = translationPnP.at<double>(0, 0);
		translationVectorTemp[1] = translationPnP.at<double>(1, 0);
		translationVectorTemp[2] = translationPnP.at<double>(2, 0);

		Vector3d rotationVector;
		rotationVector.x() = rotationPnP.at<double>(0, 0);
		rotationVector.y() = rotationPnP.at<double>(1, 0);
		rotationVector.z() = rotationPnP.at<double>(2, 0);
		double rotationVectorNorm = rotationVector.norm();

		AngleAxisd angleAxisRotation = AngleAxisd(rotationVectorNorm, (rotationVectorNorm == 0) ? Vector3d(1, 0, 0) :
				(rotationVector / rotationVectorNorm).eval());

		Matrix3d rotationMatrixEigen;
		rotationMatrixEigen = angleAxisRotation;

		for (int i = 0; i < 9; i++)
			rotationMatrixTemp[i] = rotationMatrixEigen.data()[i];

		env->ReleaseDoubleArrayElements(translationVector, translationVectorTemp, 0);
		env->ReleaseDoubleArrayElements(rotationMatrix, rotationMatrixTemp, 0);
	}

	return patternFound;
}

JNIEXPORT void JNICALL Java_it_unibo_slam_utils_CameraPoseUtils_estimateWorldCameraPoseNative(JNIEnv *env, jobject obj,
		jdoubleArray worldTranslationVector, jdoubleArray worldRotationMatrix, jdoubleArray initialTranslationVector,
		jdoubleArray initialRotationMatrix, jdoubleArray finalTranslationVector, jdoubleArray finalRotationMatrix)
{
	jdouble worldTranslationVectorTemp[3];
	jdouble worldRotationMatrixTemp[9];
	jdouble initialTranslationVectorTemp[3];
	jdouble initialRotationMatrixTemp[9];

	env->GetDoubleArrayRegion(worldTranslationVector, 0, 3, worldTranslationVectorTemp);
	env->GetDoubleArrayRegion(worldRotationMatrix, 0, 9, worldRotationMatrixTemp);
	env->GetDoubleArrayRegion(initialTranslationVector, 0, 3, initialTranslationVectorTemp);
	env->GetDoubleArrayRegion(initialRotationMatrix, 0, 9, initialRotationMatrixTemp);

	jdouble *finalTranslationVectorTemp = env->GetDoubleArrayElements(finalTranslationVector, NULL);
	jdouble *finalRotationMatrixTemp = env->GetDoubleArrayElements(finalRotationMatrix, NULL);

	Vector3d worldTranslationVectorEigen(worldTranslationVectorTemp[0], worldTranslationVectorTemp[1], worldTranslationVectorTemp[2]);
	Matrix3d worldRotationMatrixEigen;
	worldRotationMatrixEigen << worldRotationMatrixTemp[0], worldRotationMatrixTemp[3], worldRotationMatrixTemp[6],
								worldRotationMatrixTemp[1], worldRotationMatrixTemp[4], worldRotationMatrixTemp[7],
								worldRotationMatrixTemp[2], worldRotationMatrixTemp[5], worldRotationMatrixTemp[8];
	Vector3d initialTranslationVectorEigen(initialTranslationVectorTemp[0], initialTranslationVectorTemp[1], initialTranslationVectorTemp[2]);
	Matrix3d initialRotationMatrixEigen;
	initialRotationMatrixEigen << 	initialRotationMatrixTemp[0], initialRotationMatrixTemp[3], initialRotationMatrixTemp[6],
									initialRotationMatrixTemp[1], initialRotationMatrixTemp[4], initialRotationMatrixTemp[7],
									initialRotationMatrixTemp[2], initialRotationMatrixTemp[5], initialRotationMatrixTemp[8];

	Matrix3d inverseInitialRotation = initialRotationMatrixEigen.transpose();
	Vector3d inverseInitialTranslation = -inverseInitialRotation * initialTranslationVectorEigen;

	Matrix3d finalRotationMatrixEigen = worldRotationMatrixEigen * inverseInitialRotation;
	Vector3d finalTranslationVectorEigen = worldRotationMatrixEigen * inverseInitialTranslation + worldTranslationVectorEigen;

	for (int i = 0; i < 9; i++)
		finalRotationMatrixTemp[i] = finalRotationMatrixEigen.data()[i];

	finalTranslationVectorTemp[0] = finalTranslationVectorEigen.x();
	finalTranslationVectorTemp[1] = finalTranslationVectorEigen.y();
	finalTranslationVectorTemp[2] = finalTranslationVectorEigen.z();

	env->ReleaseDoubleArrayElements(finalTranslationVector, finalTranslationVectorTemp, 0);
	env->ReleaseDoubleArrayElements(finalRotationMatrix, finalRotationMatrixTemp, 0);
}

ext: cpp

max_stars_repo_name: CVLAB-Unibo/Slam-Dunk-Android

max_issues_repo_name: CVLAB-Unibo/Slam-Dunk-Android

max_forks_repo_name: CVLAB-Unibo/Slam-Dunk-Android


text:
/***********************************************************************
Moses - factored phrase-based language decoder
Copyright (C) 2013- University of Edinburgh

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
***********************************************************************/

#include <boost/lexical_cast.hpp>
#include <boost/unordered_set.hpp>

#include "util/exception.hh"
#include "util/tokenize_piece.hh"
#include "moses/TranslationModel/PhraseDictionaryInterpolated.h"

using namespace std;

namespace Moses
{

PhraseDictionaryInterpolated::PhraseDictionaryInterpolated
(size_t numScoreComponent,size_t numInputScores,const PhraseDictionaryFeature* feature):
  PhraseDictionary(numScoreComponent,feature),
  m_targetPhrases(NULL),
  m_languageModels(NULL) {}

bool PhraseDictionaryInterpolated::Load(
  const std::vector<FactorType> &input
  , const std::vector<FactorType> &output
  , const std::vector<std::string>& config
  , const std::vector<float> &weightT
  , size_t tableLimit
  , const LMList &languageModels
  , float weightWP)
{

  m_languageModels = &languageModels;
  m_weightT = weightT;
  m_tableLimit = tableLimit;
  m_weightWP = weightWP;

  //The config should be as follows:
  //0-3: type factor factor num-components (as usual)
  //4: combination mode (e.g. naive)
  //5-(length-2): List of phrase-table files
  //length-1: Weight string, in the same format as used for tmcombine

  UTIL_THROW_IF(config.size() < 7, util::Exception, "Missing fields from phrase table configuration: expected at least 7");
  UTIL_THROW_IF(config[4] != "naive", util::Exception, "Unsupported combination mode: '" << config[4] << "'");

  // Create the dictionaries
  for (size_t i = 5; i < config.size()-1; ++i) {
    m_dictionaries.push_back(DictionaryHandle(new PhraseDictionaryTreeAdaptor(
                               GetFeature()->GetNumScoreComponents(),
                               GetFeature()->GetNumInputScores(),
                               GetFeature())));
    bool ret = m_dictionaries.back()->Load(
                 input,
                 output,
                 config[i],
                 weightT,
                 0,
                 languageModels,
                 weightWP);
    if (!ret) return ret;
  }

  //Parse the weight strings
  for (util::TokenIter<util::SingleCharacter, false> featureWeights(config.back(), util::SingleCharacter(';')); featureWeights; ++featureWeights) {
    m_weights.push_back(vector<float>());
    float sum = 0;
    for (util::TokenIter<util::SingleCharacter, false> tableWeights(*featureWeights, util::SingleCharacter(',')); tableWeights; ++tableWeights) {
      const float weight = boost::lexical_cast<float>(*tableWeights);
      m_weights.back().push_back(weight);
      sum += weight;
    }
    UTIL_THROW_IF(m_weights.back().size() != m_dictionaries.size(), util::Exception,
                  "Number of weights (" << m_weights.back().size() <<
                  ") does not match number of dictionaries to combine (" << m_dictionaries.size() << ")");
    UTIL_THROW_IF(abs(sum - 1) > 0.01, util::Exception, "Weights not normalised");

  }

  //check number of weight sets. Make sure there is a weight for every score component
  //except for the last - which is assumed to be the phrase penalty.
  UTIL_THROW_IF(m_weights.size() != 1 && m_weights.size() != GetFeature()->GetNumScoreComponents()-1, util::Exception, "Unexpected number of weight sets");
  //if 1 weight set, then repeat
  if (m_weights.size() == 1) {
    while(m_weights.size() < GetFeature()->GetNumScoreComponents()-1) {
      m_weights.push_back(m_weights[0]);
    }
  }

  return true;
}

void PhraseDictionaryInterpolated::InitializeForInput(ttasksptr const& ttask)
{
  for (size_t i = 0; i < m_dictionaries.size(); ++i) {
    m_dictionaries[i]->InitializeForInput(ttask);
  }
}

typedef
boost::unordered_set<TargetPhrase*,PhrasePtrHasher,PhrasePtrComparator> PhraseSet;

TargetPhraseCollection::shared_ptr
PhraseDictionaryInterpolated::GetTargetPhraseCollection(const Phrase& src) const
{

  delete m_targetPhrases;
  m_targetPhrases = new TargetPhraseCollection();
  PhraseSet allPhrases;
  vector<PhraseSet> phrasesByTable(m_dictionaries.size());
  for (size_t i = 0; i < m_dictionaries.size(); ++i) {
    TargetPhraseCollection::shared_ptr  phrases = m_dictionaries[i]->GetTargetPhraseCollection(src);
    if (phrases) {
      for (TargetPhraseCollection::const_iterator j = phrases->begin();
           j != phrases->end(); ++j) {
        allPhrases.insert(*j);
        phrasesByTable[i].insert(*j);
      }
    }
  }
  ScoreComponentCollection sparseVector;
  for (PhraseSet::const_iterator i = allPhrases.begin(); i != allPhrases.end(); ++i) {
    TargetPhrase* combinedPhrase = new TargetPhrase((Phrase)**i);
    //combinedPhrase->ResetScore();
    //cerr << *combinedPhrase << " " << combinedPhrase->GetScoreBreakdown() << endl;
    combinedPhrase->SetSourcePhrase((*i)->GetSourcePhrase());
    combinedPhrase->SetAlignTerm(&((*i)->GetAlignTerm()));
    combinedPhrase->SetAlignNonTerm(&((*i)->GetAlignTerm()));
    Scores combinedScores(GetFeature()->GetNumScoreComponents());
    for (size_t j = 0; j < phrasesByTable.size(); ++j) {
      PhraseSet::const_iterator tablePhrase = phrasesByTable[j].find(combinedPhrase);
      if (tablePhrase != phrasesByTable[j].end()) {
        Scores tableScores = (*tablePhrase)->GetScoreBreakdown()
                             .GetScoresForProducer(GetFeature());
        //cerr << "Scores from " << j << " table: ";
        for (size_t k = 0; k < tableScores.size()-1; ++k) {
          //cerr << tableScores[k] << "(" << exp(tableScores[k]) << ") ";
          combinedScores[k] += m_weights[k][j] * exp(tableScores[k]);
          //cerr << m_weights[k][j] * exp(tableScores[k]) << " ";
        }
        //cerr << endl;
      }
    }
    //map back to log space
    //cerr << "Combined ";
    for (size_t k = 0; k < combinedScores.size()-1; ++k) {
      //cerr << combinedScores[k] << " ";
      combinedScores[k] = log(combinedScores[k]);
      //cerr << combinedScores[k] << " ";
    }
    //cerr << endl;
    combinedScores.back() = 1; //assume last is penalty
    combinedPhrase->SetScore(
      GetFeature(),
      combinedScores,
      sparseVector,
      m_weightT,
      m_weightWP,
      *m_languageModels);
    //cerr << *combinedPhrase << " " << combinedPhrase->GetScoreBreakdown() <<  endl;
    m_targetPhrases->Add(combinedPhrase);
  }

  m_targetPhrases->Prune(true,m_tableLimit);

  return m_targetPhrases;
}

}

max_issues_repo_name: Pangeamt/nectm

max_forks_repo_name: Pangeamt/nectm


text:
/* Copyright 2008 (C) Nicira, Inc.
 *
 * This file is part of NOX.
 *
 * NOX is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * NOX is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with NOX.  If not, see <http://www.gnu.org/licenses/>.
 */
/* Tests for Co_sema. */

#include "threads/cooperative.hh"
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <unistd.h>
#include <cstdio>

using namespace vigil;

static Co_sema sema1, sema2;

static void
thread1()
{
    for (int i = 0; i < 10; ++i) {
        sema1.down();
        printf("down\n");
    }
}

static void
thread2()
{
    for (int i = 0; i < 10; ++i) {
        int wake1, wake2;
        sema1.wait(&wake1);
        sema2.wait(&wake2);
        co_block();
        printf("block wake1=%d wake2=%d\n", wake1, wake2);
    }
}

static void
thread3(int id)
{
    printf("start id=%d\n", id);
    sema1.down();
    printf("wake id=%d\n", id);
    sema2.up();
}

int
main()
{
    co_init();
    co_thread_assimilate();
    co_migrate(&co_group_coop);

    co_thread* thread;
    Co_completion join;

    /* These tests tend to hang if something goes wrong. */
    alarm(3);

    printf("Up without yield\n");
    thread = co_thread_create(&co_group_coop, thread1);
    co_join_completion(thread, &join);
    for (int i = 0; i < 10; ++i) {
        sema1.up();
        printf("up\n");
    }
    join.block();
    join.latch();

    printf("\nUp with yield\n");
    thread = co_thread_create(&co_group_coop, thread1);
    co_join_completion(thread, &join);
    for (int i = 0; i < 10; ++i) {
        sema1.up();
        printf("up\n");
        co_yield();
    }
    join.block();
    join.latch();

    printf("\nAlternating wakers\n");
    thread = co_thread_create(&co_group_coop, thread2);
    co_join_completion(thread, &join);
    for (int i = 0; i < 5; ++i) {
        co_yield();
        sema1.up();
        printf("up sema1\n");

        co_yield();
        sema2.up();
        printf("up sema2\n");
    }
    join.block();
    join.latch();

    printf("\nFIFO queuing\n");
    const int n_threads = 10;
    co_thread* threads[n_threads];
    Co_completion joins[n_threads];
    for (int i = 0; i < 10; ++i) {
        threads[i] = co_thread_create(&co_group_coop, boost::bind(thread3, i));
        co_join_completion(threads[i], &joins[i]);
    }
    co_yield();
    for (int i = 0; i < 10; ++i) {
        printf("up id=%d\n", i);
        sema1.up();
        sema2.down();
    }
    for (int i = 0; i < 10; ++i) {
        joins[i].block();
    }

    return 0;
}

max_stars_repo_name: ayjazz/OESS

max_issues_repo_name: ayjazz/OESS

max_forks_repo_name: ayjazz/OESS


text:
/*
Title: Missing Tracks
Author: Adam Howell

This program is designed to read in a text file containing a directory structure and locate missing files.
My filename format is as follows:
	<Artist> - <Album> - <Track#> - <Title>
When the program encounters track 2, it looks back one line (stored in a variable) for track 1.

Pseudo-code:
	scan currentLine for track2String
	if found
		scan prevLine for the track1String
		if found
			restart the loop
		else
			write currentLine to the output file
	else
		prevLine = currentLine
		restart the loop
*/

#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <boost/filesystem.hpp>

using namespace std;
using namespace boost::filesystem;

int main()
{
	string inFilename = "tracks.txt";		// Input filename.
	string outFilename = "outtracks.txt";	// Output filename.  This file will be overwritten without confirmation!
	string track1String = " - 01 - ";		// The text we suspect may be missing.
	string track2String = " - 02 - ";		// The text we search for to know we have passed track 1.
	string currentLine = "";				// Current line contents.
	string prevLine = "";				// Previous line contents.
	int track1Count = 0;				// Counter for how many times a track 1 was found.
	int track2Count = 0;				// Counter for how many times a track 2 was found.
	int missingTracks = 0;				// Counter for how many tracks are missing.
	clock_t startClock;					// A temporary variable to hold the current clock time.
	clock_t endClock;					// A temporary variable to hold the current clock time.

	boost::filesystem::path new_full_path( boost::filesystem::current_path() );
	cout << "Current path is:\n" << new_full_path << endl;
/*
	// list all files in current directory.
	// You could put any file path in here, e.g. "/home/me/mwah" to list that directory
	path p (".");

	directory_iterator end_itr;

	// cycle through the directory
	for (directory_iterator itr(p); itr != end_itr; ++itr)
	{
		// If it's not a directory, list it. If you want to list directories too, just remove this check.
		if (is_regular_file(itr->path()))
		{
			// assign current file name to current_file and echo it out to the console.
			string current_file = itr->path().string();
			cout << current_file << endl;
		}
	}
*/
	// Pause so we can see the output on the console.
	system( "PAUSE" );

	// Open a file stream based on the output filename.  This file will be overwritten without confirmation!
	ofstream outFile ( outFilename );

	// If the file stream creation failed...
	if ( outFile.fail() )
	{
		// Announce that the file did not open properly.
		cout << "\nUnable to open the output file: " << outFilename << endl;
		// Pause so the user can read the error message on the console.
		system( "PAUSE" );
		// Exit the program with a return value of -1.
		return -1;
	}

	// Open a file stream based on the input filename.
	ifstream trackFile ( inFilename );

	// If the file stream creation failed...
	if ( trackFile.fail() )
	{
		// Announce that the file did not open properly.
		cout << "\nUnable to open the input file: " << inFilename << " \nPlease ensure it is in the same directory as this executable." << endl;
		// Pause so the user can read the error message on the console.
		system( "PAUSE" );
		// Exit the program with a return value of -1.
		return -1;
	}
	else
	{
		cout << "Searching the input file: " << inFilename << endl;
		// Get the starting tick.
		startClock = clock();

		// Loop until the end of the file.
		while ( !trackFile.eof() )
		{
			getline( trackFile, currentLine );
			//trackFile >> currentLine;	// This is how I initially tried loading a line from the input file to currentLine.
			// Scan currentLine for " - 02 - ".
			currentLine.find( track2String );
			// If we find track 2...
			if ( currentLine.find( track2String ) != string::npos )
			{
				track2Count++;
				// Test code.
				//cout << "Found track 2" << endl;
				// Scan prevLine for " - 01 - ", and if missing...
				if ( prevLine.find( track1String ) != string::npos )
				{
					// Increment track1Count to show we located a track 1.
					track1Count++;
				}
				else
				{
					// Load the current line into the output file.
					outFile << currentLine << endl;
					// Increment missingTracks to show we located a missing track 1.
					missingTracks++;
				}
			}
			else
			{
				// Prepare to check the next line by loading currentLine into prevLine.
				prevLine = currentLine;
				// Restart this while loop.
				continue;
			}
		}
	}
	// Get the ending tick.
	endClock = clock();

	// Close the file handles.
	trackFile.close();
	outFile.close();

	// Display the results.
	if ( endClock / CLK_TCK )
	{
		cout << "Scan completed in " << endClock / CLK_TCK << " second (" << endClock << " ticks)." << endl;
	}
	else
	{
		cout << "Scan completed in " << endClock / CLK_TCK << " seconds (" << endClock << " ticks)." << endl;
	}
	cout << "Found " << track1Count << " first tracks" << endl;
	cout << "Found " << track2Count << " second tracks" << endl;
	cout << missingTracks << " possible albums with missing first tracks written to " << outFilename << endl;

	// Pause so we can see the output on the console.
	system( "PAUSE" );

} // End main()


text:
//****************************************************************************
// (c) 2008, 2009 by the openOR Team
//****************************************************************************
// The contents of this file are available under the GPL v2.0 license
// or under the openOR commercial license. see
//   /Doc/openOR_free_license.txt or
//   /Doc/openOR_comercial_license.txt
// for Details.
//****************************************************************************

#ifndef openOR_Plugin_AutoOpenLibrary_hpp
#define openOR_Plugin_AutoOpenLibrary_hpp

#include "../include/openOR/Plugin/Library.hpp"
#include "../include/openOR/coreDefs.hpp"

#include <boost/tr1/memory.hpp>

namespace openOR {
   namespace Plugin {

      // fwd declarations
      struct Config;

      //----------------------------------------------------------------------------
      //! \brief Tries to open the Library according to the Plugin::Config
      //!
      //! \param [in] config The Plugin::Config used to find the library.
      //! \param [in] pluginName The name of the PluginClass.
      //! \param [in] unloadableLib If set to true Library unloding will be
      //!   enabled. \sa Library.
      //! \returns A Library handle.
      //! \exception library_open_failure will be thrown if no matching library
      //!   could be found for the plugin.
      //----------------------------------------------------------------------------
      Library OPENOR_CORE_API auto_open_library(const Config& config,
                                                const std::string& pluginName,
                                                bool unloadableLib = false
                                               );

   }
}

#endif //openOR_Plugin_AutoOpenLibrary_hpp

max_stars_repo_name: avinfinity/UnmanagedCodeSnippets

max_issues_repo_name: avinfinity/UnmanagedCodeSnippets

max_forks_repo_name: avinfinity/UnmanagedCodeSnippets


text:
//  Copyright (c) 2001-2007 Joel de Guzman
//  Copyright (c) 2001-2008 Hartmut Kaiser
//
//  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)

#if !defined(BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0455PM)
#define BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0455PM

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once      // MS compatible compilers support #pragma once
#endif

#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/karma/nonterminal/nonterminal.hpp>
#include <boost/spirit/home/karma/nonterminal/grammar_fwd.hpp>
#include <boost/spirit/home/karma/nonterminal/detail/rule.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/assert.hpp>

#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif

namespace boost { namespace spirit { namespace karma
{
    template <typename OutputIterator, typename T0 = unused_type,
        typename T1 = unused_type, typename T2 = unused_type>
    struct rule
      : make_nonterminal<rule<OutputIterator, T0, T1, T2>, T0, T1, T2>::type
    {
        typedef
            make_nonterminal<rule<OutputIterator, T0, T1, T2>, T0, T1, T2>
        make_nonterminal_;

        typedef typename make_nonterminal_::delimiter_type delimiter_type;
        typedef typename make_nonterminal_::type base_type;
        typedef detail::output_iterator<OutputIterator> iterator_type;
        typedef rule<OutputIterator, T0, T1, T2> self_type;

        typedef
            detail::virtual_component_base<
                iterator_type,
                typename base_type::context_type,
                delimiter_type
            >
        virtual_component;

        typedef intrusive_ptr<virtual_component> pointer_type;

        rule() {}
        ~rule() {}

        rule(rule const& rhs)
          : ptr(rhs.ptr)
        {
        }

        rule& operator=(rule const& rhs)
        {
            ptr = rhs.ptr;
            return *this;
        }

        template <typename Expr>
        rule& operator=(Expr const& xpr)
        {
            typedef
                spirit::traits::is_component<karma::domain, Expr>
            is_component;

            // report invalid expression error as early as possible
//             BOOST_MPL_ASSERT_MSG(
//                 is_component::value,
//                 xpr_is_not_convertible_to_a_generator, ());

            // temp workaround for mpl problem
            BOOST_STATIC_ASSERT(is_component::value);

            define(xpr, mpl::false_());
            return *this;
        }

        template <typename Expr>
        friend rule& operator%=(rule& r, Expr const& xpr)
        {
            typedef
                spirit::traits::is_component<karma::domain, Expr>
            is_component;

            // report invalid expression error as early as possible
//             BOOST_MPL_ASSERT_MSG(
//                 is_component::value,
//                 xpr_is_not_convertible_to_a_generator, ());

            // temp workaround for mpl problem
            BOOST_STATIC_ASSERT(is_component::value);

            r.define(xpr, mpl::true_());
            return r;
        }

        self_type alias() const
        {
            self_type result;
            result.define(*this, mpl::false_());
            return result;
        }

        typename
            make_nonterminal_holder<
                nonterminal_object<self_type>
              , self_type
            >::type
        copy() const
        {
            typename
                make_nonterminal_holder<
                    nonterminal_object<self_type>
                  , self_type
                >::type
            result = {{*this}};
            return result;
        }

        std::string name() const
        {
            return name_;
        }

        void name(std::string const& str)
        {
            name_ = str;
        }

    private:

        template <typename Iterator_, typename T0_, typename T1_, typename T2_>
        friend struct grammar;

        template <typename Expr, typename Auto>
        void define(Expr const& xpr, Auto)
        {
            typedef typename
                result_of::as_component<karma::domain, Expr>::type
            component;
            typedef
                detail::virtual_component<
                    iterator_type,
                    component,
                    typename base_type::context_type,
                    delimiter_type,
                    Auto
                >
            virtual_component;
            ptr = new virtual_component(spirit::as_component(karma::domain(), xpr));
        }

        template <typename OutputIterator_, typename Context, typename Delimiter>
        bool generate(
            OutputIterator_& sink, Context& context, Delimiter const& delim) const
        {
            // If the following line produces a compilation error stating the
            // 3rd parameter is not convertible to the expected type, then you
            // are probably trying to use this rule instance with a delimiter
            // which is not compatible with the delimiter type used while
            // defining the type of this rule instance.
            return ptr->generate(sink, context, delim);
        }

        std::string what() const
        {
            if (name_.empty())
            {
                if (ptr)
                {
                    return "unnamed-rule";
                }
                else
                {
                    return "empty-rule";
                }
            }
            else
            {
                return name_;
            }
        }

        friend struct nonterminal_director;
        pointer_type ptr;
        std::string name_;
    };

}}}

#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif

#endif

max_stars_repo_name: jaredhoberock/gotham

max_issues_repo_name: jaredhoberock/gotham

max_forks_repo_name: jaredhoberock/gotham


text:
/*******************************************************************************
 *         Copyright 2003 & onward LASMEA UMR 6602 CNRS/Univ. Clermont II
 *         Copyright 2009 & onward LRI    UMR 8623 CNRS/Univ Paris Sud XI
 *
 *          Distributed under the Boost Software License, Version 1.0.
 *                 See accompanying file LICENSE.txt or copy at
 *                     http://www.boost.org/LICENSE_1_0.txt
 ******************************************************************************/
#ifndef NT2_SDK_META_DETAILS_ANY_HPP_INCLUDED
#define NT2_SDK_META_DETAILS_ANY_HPP_INCLUDED

////////////////////////////////////////////////////////////////////////////////
// Internals for meta::any_
////////////////////////////////////////////////////////////////////////////////
#include <boost/mpl/end.hpp>
#include <boost/mpl/not.hpp>
#include <nt2/sdk/meta/na.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/type_traits/is_same.hpp>

#if !defined(BOOST_HAS_VARIADIC_TMPL)
#include <nt2/extension/parameters.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#endif

namespace nt2 { namespace details
{
  //////////////////////////////////////////////////////////////////////////////
  // Recursive variadic version
  //////////////////////////////////////////////////////////////////////////////
  #if defined(BOOST_HAS_VARIADIC_TMPL)
  template< class Predicate, class... Args> struct any_impl;

  template< class Pred, class Head, class... Tails>
  struct  any_impl<Pred,Head,Tails...>
        : boost::mpl::or_ < boost::mpl::apply1<Pred,Head>
                          , any_impl<Pred,Tails...>
                          >
  {};

  template< class Pred, class T>
  struct  any_impl<Pred, T>
        : boost::mpl::eval_if_c < boost::mpl::is_sequence<T>::value
                                , boost::mpl::not_<
                                    boost::is_same< typename
                                                    boost::mpl::find_if<T,Pred>::type
                                                  , typename
                                                    boost::mpl::end<T>::type
                                                  >
                                                >
                                , boost::mpl::apply1<Pred,T>
                                >::type
  {};
  #else
  //////////////////////////////////////////////////////////////////////////////
  // Macro based version
  //////////////////////////////////////////////////////////////////////////////
  #define M1(z,n,t)                                           \
  || boost::mpl::apply1<Pred,BOOST_PP_CAT(A,n)>::type::value  \
  /**/

  template< class Pred
          , BOOST_PP_ENUM_BINARY_PARAMS ( NT2_MAX_META_ARITY
                                        , class A
                                        , = meta::na_ BOOST_PP_INTERCEPT
                                        )
          >
  struct  any_impl
        : boost::mpl::bool_<false BOOST_PP_REPEAT(NT2_MAX_META_ARITY,M1,~)>
  {};

  template< class Pred, class T>
  struct  any_impl<Pred, T>
        : boost::mpl::eval_if_c < boost::mpl::is_sequence<T>::value
                                , boost::mpl::not_<
                                    boost::is_same< typename
                                                    boost::mpl::find_if<T,Pred>::type
                                                  , typename
                                                    boost::mpl::end<T>::type
                                                  >
                                                >
                                , boost::mpl::apply1<Pred,T>
                                >::type
  {};

  #define M0(z,n,t)                                         \
  template<class Pred, BOOST_PP_ENUM_PARAMS(n,class A)>     \
  struct  any_impl<Pred,BOOST_PP_ENUM_PARAMS(n,A)>          \
        : boost::mpl::bool_<false BOOST_PP_REPEAT(n,M1,~)>  \
  {};                                                       \
  /**/

  BOOST_PP_REPEAT_FROM_TO(2,NT2_MAX_META_ARITY,M0,~)

  #undef M1
  #undef M0

  #endif

} }

#endif


text:
#include "greet.hpp"
#include <boost/python.hpp>

BOOST_PYTHON_MODULE(greet_ext)
{
  using namespace boost::python;
  def( "greet", greet );
}

max_stars_repo_name: ctriley/boost-python-hello-world

max_issues_repo_name: ctriley/boost-python-hello-world

max_forks_repo_name: ctriley/boost-python-hello-world


text:
//============================================================================
// Name        :
// Author      : Avi
// Revision    : $Revision: #25 $
//
// 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 :
//============================================================================
#include "ServerTestHarness.hpp"

#include "Defs.hpp"
#include "Suite.hpp"
#include "Family.hpp"
#include "Task.hpp"
#include "DurationTimer.hpp"
#include "VerifyAttr.hpp"

#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>

#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;
using namespace ecf;
namespace fs = boost::filesystem;

BOOST_AUTO_TEST_SUITE( TestSuite )

// In the test case we will dynamically create all the test data.
// The data is created dynamically so that we can stress test the server
// This test does not have any time dependencies in the def file.
//
// This test shows the use of repeat and complete. this shows how
// we can repeat a family without waiting for all the children to
// complete. See page 65 of user manual
//
// As protection against user, a family should not complete
// if any of its children are still in ACTIVE or SUBMIITED state.
//
// **************************************************************************
// Note: When we use a complete expression. Node resolution will set complete
//      hierarchically
// **************************************************************************
BOOST_AUTO_TEST_CASE( test_complete )
{
	DurationTimer timer;
	cout << "Test:: ...test_complete " << flush;
   TestClean clean_at_start_and_end;

	// Create the defs file corresponding to the text below
	// ECF_HOME variable is automatically added by the test harness.
	// ECF_INCLUDE variable is automatically added by the test harness.
	// SLEEPTIME variable is automatically added by the test harness.
	// ECF_CLIENT_EXE_PATH variable is automatically added by the test harness.
	//                     This is substituted in sms includes
	//                     Allows test to run without requiring installation

 	//# Note: we have to use relative paths, since these tests are relocatable
	//	suite test_complete
	//	  family family
	//      repeat integer YMD 0 1
	//	   	complete ./family/check:nofiles  # repeat family with waiting for children to complete
	//	   	task check
	//	   		event 1 nofiles
	//	    task t1
	//        trigger check==complete
	//      task t2
	//         trigger t2 == complete   #  never runs
	//	    endfamily
	//	endsuite
 	std::string eventName = "nofiles";
  	Defs theDefs;
 	{
      suite_ptr suite = theDefs.add_suite("test_complete");
      family_ptr fam = suite->add_family("family");
 		fam->addRepeat( RepeatInteger("VAR",0,1,1));  // repeat family 2 times
 		fam->add_complete( "/test_complete/family/check:nofiles" );
		fam->addVerify( VerifyAttr(NState::COMPLETE,2) );       // family should complete 2 times

      task_ptr task_check = fam->add_task("check");
 		task_check->addEvent( Event(1,eventName) );
 		task_check->addVerify( VerifyAttr(NState::COMPLETE,2) );

      task_ptr task_t1 = fam->add_task("t1");
		task_t1->add_trigger( "check == complete");
		task_t1->addVerify( VerifyAttr(NState::COMPLETE,2) );

      task_ptr task_t2 = fam->add_task("t2");
		task_t2->add_trigger( "t2 == complete" );
		task_t2->addVerify( VerifyAttr(NState::COMPLETE,2) );
 	}

 	// The test harness will create corresponding directory structure & default ecf file
   ServerTestHarness serverTestHarness;
 	serverTestHarness.run(theDefs, ServerTestHarness::testDataDefsLocation("test_complete.def") );

	cout << timer.duration() << " update-calendar-count(" << serverTestHarness.serverUpdateCalendarCount() << ")\n";
}

BOOST_AUTO_TEST_CASE( test_complete_does_not_hold )
{
   DurationTimer timer;
   cout << "Test:: ...test_complete_does_not_hold " << flush;

   /// This test shows that a complete expression should not hold a node
   /// A complete should complete a node, and not hold it

   // suite test_complete
   //   family family
   //     complete 1 == 0            # impossible expression that never evaluates
   //     task t1                    # task t1 should still run
   //     task t2
   //         complete 1 == 0        # impossible expression that never evaluates
   //         trigger t1 == complete # task t2 should still run
   //     endfamily
   // endsuite
   Defs theDefs;
   {
      suite_ptr suite = theDefs.add_suite("test_complete_does_not_hold");
      family_ptr fam = suite->add_family("family");
      fam->add_complete( "1 == 0");
      task_ptr t1 = fam->add_task("t1");
      t1->addVerify( VerifyAttr(NState::COMPLETE,1) );
      task_ptr t2 = fam->add_task("t2");
      t2->add_trigger( "t1 == complete");
      t2->add_complete( "1 == 0");
      t2->addVerify( VerifyAttr(NState::COMPLETE,1) );
   }

   ServerTestHarness serverTestHarness;
   serverTestHarness.run(theDefs, ServerTestHarness::testDataDefsLocation("test_complete_does_not_hold.def") );

   cout << timer.duration() << " update-calendar-count(" << serverTestHarness.serverUpdateCalendarCount() << ")\n";
}

BOOST_AUTO_TEST_CASE( test_complete_with_empty_family )
{
   DurationTimer timer;
   cout << "Test:: ...test_complete_with_empty_family " << flush;

   // Test a family with a complete expression and that has no children

   // suite test_complete_with_empty_family
   //   family empty
   //      complete /test_complete_with_empty_family/family/t1 == complete and
   //               /test_complete_with_empty_family/family/t2 == complete
   //   family family
   //       task t1
   //       task t2
   //     endfamily
   // endsuite
   Defs theDefs;
   {
      suite_ptr suite = theDefs.add_suite("test_complete_with_empty_family");
      family_ptr empty = suite->add_family("empty");
      empty->add_complete( "/test_complete_with_empty_family/family/t1 == complete and /test_complete_with_empty_family/family/t2 == complete");
      empty->addVerify( VerifyAttr(NState::COMPLETE,1) );
      family_ptr fam = suite->add_family("family");
      fam->add_task("t1")->addVerify( VerifyAttr(NState::COMPLETE,1) );
      fam->add_task("t2")->addVerify( VerifyAttr(NState::COMPLETE,1) );
   }

   ServerTestHarness serverTestHarness;
   serverTestHarness.run(theDefs, ServerTestHarness::testDataDefsLocation("test_complete_with_empty_family.def") );

   cout << timer.duration() << " update-calendar-count(" << serverTestHarness.serverUpdateCalendarCount() << ")\n";
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: ecmwf/ecflow

max_issues_repo_name: CoollRock/ecflow

max_forks_repo_name: CoollRock/ecflow


text:
#ifndef FEEDING_PERCEPTIONSERVOCLIENT_HPP_
#define FEEDING_PERCEPTIONSERVOCLIENT_HPP_

#include <mutex>

#include <aikido/control/ros/RosTrajectoryExecutor.hpp>
#include <aikido/rviz/InteractiveMarkerViewer.hpp>
#include <aikido/statespace/dart/MetaSkeletonStateSpace.hpp>
#include <aikido/trajectory/Spline.hpp>
#include <boost/optional.hpp>
#include <dart/dynamics/BodyNode.hpp>
#include <ros/ros.h>
#include <sensor_msgs/JointState.h>

#include <libada/Ada.hpp>

#include "feeding/perception/Perception.hpp"

namespace feeding {

class PerceptionServoClient {
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  PerceptionServoClient(
      const ::ros::NodeHandle *node,
      boost::function<Eigen::Isometry3d(void)> getTransform,
      aikido::statespace::dart::ConstMetaSkeletonStateSpacePtr
          metaSkeletonStateSpace,
      std::shared_ptr<ada::Ada> ada,
      ::dart::dynamics::MetaSkeletonPtr metaSkeleton,
      ::dart::dynamics::BodyNodePtr bodyNode,
      std::shared_ptr<aikido::control::TrajectoryExecutor> trajectoryExecutor,
      aikido::constraint::dart::CollisionFreePtr collisionFreeConstraint,
      double perceptionUpdateTime, float goalPrecision, double planningTimeout,
      double endEffectorOffsetPositionTolerance,
      double endEffectorOffsetAngularTolerance, bool servoFood,
      const Eigen::Vector6d &velocityLimits);

  virtual ~PerceptionServoClient();

  void start();

  void stop();

  bool isRunning();

  bool wait(double timelimit);

protected:
  void nonRealtimeCallback(const ros::TimerEvent &event);

  bool updatePerception(Eigen::Isometry3d &goalPose);

  aikido::trajectory::SplinePtr
  planEndEffectorOffset(const Eigen::Isometry3d &goalPose);

  aikido::trajectory::SplinePtr
  planToGoalPose(const Eigen::Isometry3d &goalPose);

  aikido::trajectory::TrajectoryPtr
  planEndEffectorOffset(const Eigen::Vector3d &goalDirection,
                        double threshold = 0.1);

  aikido::trajectory::UniqueSplinePtr
  createPartialTimedTrajectoryFromCurrentConfig(
      const aikido::trajectory::Spline *trajectory);

  ::ros::NodeHandle mNodeHandle;
  boost::function<Eigen::Isometry3d(void)> mGetTransform;
  /// Meta skeleton state space.
  aikido::statespace::dart::ConstMetaSkeletonStateSpacePtr
      mMetaSkeletonStateSpace;

  /// Meta Skeleton
  ::dart::dynamics::MetaSkeletonPtr mMetaSkeleton;

  /// BodyNode
  ::dart::dynamics::BodyNodePtr mBodyNode;

  std::shared_ptr<aikido::control::TrajectoryExecutor> mTrajectoryExecutor;

  double mPerceptionUpdateTime;

  aikido::trajectory::SplinePtr mCurrentTrajectory;

  std::future<void> mExec;

  ros::Timer mNonRealtimeTimer;

  Eigen::VectorXd mMaxVelocity;
  Eigen::VectorXd mMaxAcceleration;

  Eigen::VectorXd mCurrentPosition;

  Eigen::Isometry3d mOriginalPose;
  Eigen::Isometry3d mPreviousGoalPose;
  Eigen::VectorXd mOriginalConfig;

  aikido::constraint::dart::CollisionFreePtr mCollisionFreeConstraint;

  std::vector<dart::dynamics::SimpleFramePtr> mFrames;
  std::vector<aikido::rviz::FrameMarkerPtr> mFrameMarkers;
  bool mExecutionDone;
  bool mIsRunning;
  bool mNotFailed;
  bool mServoFood;

  ros::Subscriber mSub;
  std::mutex mJointStateUpdateMutex;
  std::mutex mTimerMutex;

  std::shared_ptr<ada::Ada> mAda;

  std::chrono::time_point<std::chrono::system_clock> mStartTime;
  std::chrono::time_point<std::chrono::system_clock> mLastSuccess;

  float mGoalPrecision = 0.01;

  double mPlanningTimeout;
  double mEndEffectorOffsetPositionTolerance;
  double mEndEffectorOffsetAngularTolerance;

  bool mRemoveRotation;
  Eigen::VectorXd mVelocityLimits;
};
} // namespace feeding

#endif // FEEDING_PERCEPTIONSERVOCLIENT_HPP_