text:
#pragma once

#include "main.hpp"
#include "session.hpp"

#include <boost/asio/steady_timer.hpp>
#include <chrono>
#include <ipmid/api.hpp>
#include <ipmid/sessiondef.hpp>
#include <map>
#include <memory>
#include <mutex>
#include <string>

namespace session
{

enum class RetrieveOption
{
    BMC_SESSION_ID,
    RC_SESSION_ID,
};

static constexpr size_t maxSessionHandles = multiIntfaceSessionHandleMask;

/**
 * @class Manager
 *
 * Manager class acts a manager for the IPMI sessions and provides interfaces
 * to start a session, stop a session and get reference to the session objects.
 *
 */

class Manager
{
  private:
    struct Private
    {
    };

  public:
    // BMC Session ID is the key for the map
    using SessionMap = std::map<SessionID, std::shared_ptr<Session>>;

    Manager() = delete;
    Manager(std::shared_ptr<boost::asio::io_context>& io, const Private&) :
        io(io), timer(*io){};
    ~Manager() = default;
    Manager(const Manager&) = delete;
    Manager& operator=(const Manager&) = delete;
    Manager(Manager&&) = default;
    Manager& operator=(Manager&&) = default;

    /**
     * @brief Get a reference to the singleton Manager
     *
     * @return Manager reference
     */
    static Manager& get()
    {
        static std::shared_ptr<Manager> ptr = nullptr;
        if (!ptr)
        {
            std::shared_ptr<boost::asio::io_context> io = getIo();
            ptr = std::make_shared<Manager>(io, Private());
            if (!ptr)
            {
                throw std::runtime_error("failed to create session manager");
            }
        }
        return *ptr;
    }

    /**
     * @brief Start an IPMI session
     *
     * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned
     *            in the Open SessionRequest Command
     * @param[in] priv - Privilege level requested
     * @param[in] authAlgo - Authentication Algorithm
     * @param[in] intAlgo - Integrity Algorithm
     * @param[in] cryptAlgo - Confidentiality Algorithm
     *
     * @return session handle on success and nullptr on failure
     *
     */
    std::shared_ptr<Session>
        startSession(SessionID remoteConsoleSessID, Privilege priv,
                     cipher::rakp_auth::Algorithms authAlgo,
                     cipher::integrity::Algorithms intAlgo,
                     cipher::crypt::Algorithms cryptAlgo);

    /**
     * @brief Stop IPMI Session
     *
     * @param[in] bmcSessionID - BMC Session ID
     *
     * @return true on success and failure if session ID is invalid
     *
     */
    bool stopSession(SessionID bmcSessionID);

    /**
     * @brief Get Session Handle
     *
     * @param[in] sessionID - Session ID
     * @param[in] option - Select between BMC Session ID and Remote Console
     *            Session ID, Default option is BMC Session ID
     *
     * @return session handle on success and nullptr on failure
     *
     */
    std::shared_ptr<Session>
        getSession(SessionID sessionID,
                   RetrieveOption option = RetrieveOption::BMC_SESSION_ID);
    uint8_t getActiveSessionCount() const;
    uint8_t getSessionHandle(SessionID bmcSessionID) const;
    uint8_t storeSessionHandle(SessionID bmcSessionID);
    uint32_t getSessionIDbyHandle(uint8_t sessionHandle) const;

    void managerInit(const std::string& channel);

    uint8_t getNetworkInstance(void);

    /**
     * @brief Clean Session Stale Entries
     *
     *  Schedules cleaning the inactive sessions entries from the Session Map
     */
    void scheduleSessionCleaner(const std::chrono::microseconds& grace);

  private:
    /**
     * @brief reclaim system resources by limiting idle sessions
     *
     * Limits on active, authenticated sessions are calculated independently
     * from in-setup sessions, which are not required to be authenticated. This
     * will prevent would-be DoS attacks by calling a bunch of Open Session
     * requests to fill up all available sessions. Too many active sessions will
     * trigger a shorter timeout, but is unaffected by setup session counts.
     *
     * For active sessions, grace time is inversely proportional to (the number
     * of active sessions beyond max sessions per channel)^3
     *
     * For sessions in setup, grace time is inversely proportional to (the
     * number of total sessions beyond max sessions per channel)^3, with a max
     * of 3 seconds
     */
    void cleanStaleEntries();

    std::shared_ptr<boost::asio::io_context> io;
    boost::asio::steady_timer timer;

    std::array<uint32_t, session::maxSessionHandles> sessionHandleMap = {0};

    /**
     * @brief Session Manager keeps the session objects as a sorted
     *        associative container with Session ID as the unique key
     */
    SessionMap sessionsMap;
    std::unique_ptr<sdbusplus::server::manager::manager> objManager = nullptr;
    std::string chName{}; // Channel Name
    uint8_t ipmiNetworkInstance;
    void setNetworkInstance(void);
};

} // namespace session

max_stars_repo_name: openbmc/phosphor-net-ipmid

max_issues_repo_name: openbmc/phosphor-net-ipmid

max_forks_repo_name: openbmc/phosphor-net-ipmid


text:
//
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// 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)
//
// Official repository: https://github.com/vinniefalco/BeastLounge
//

#ifndef LOUNGE_UTILITY_HPP
#define LOUNGE_UTILITY_HPP

#include "config.hpp"
#include <boost/smart_ptr/enable_shared_from_this.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <chrono>
#include <type_traits>

template<class T>
struct is_duration : std::false_type
{
};

template<class Rep, class Period>
struct is_duration<
    std::chrono::duration<Rep, Period>> : std::true_type
{
};

template<
    class To, class Rep, class Period,
    class = typename std::enable_if<
        is_duration<To>::value>::type
>
constexpr
To
ceil(std::chrono::duration<Rep, Period> const& d)
{
    To t = std::chrono::duration_cast<To>(d);
    if (t < d)
        return t + To{1};
    return t;
}
//------------------------------------------------------------------------------

struct enable_shared_from
    : boost::enable_shared_from_this<enable_shared_from>
{
};

template<class T>
boost::shared_ptr<T>
shared_from(T* p)
{
    return boost::shared_ptr<T>(
        p->shared_from_this(), p);
}

template<class T>
boost::weak_ptr<T>
weak_from(T* p)
{
#if 0
    return boost::weak_ptr<T>(
        p->weak_from_this(), p);
#else
    return boost::weak_ptr<T>(
        boost::static_pointer_cast<T>(
            p->weak_from_this().lock()));
#endif
}

//------------------------------------------------------------------------------

namespace detail {

template<class T>
struct shared_handler
{
    boost::shared_ptr<T> self;

    template<class... Args>
    void
    operator()(Args&&... args) const
    {
        (*self)(std::forward<Args>(args)...);
    }
};

template<class T, class MFn>
struct shared_mfn_handler
{
    MFn mfn_;
    boost::shared_ptr<T> self;

    template<class... Args>
    void
    operator()(Args&&... args) const
    {
        ((*self).*mfn_)(std::forward<Args>(args)...);
    }
};

template<class T>
struct handler
{
    T* self;

    template<class... Args>
    void
    operator()(Args&&... args) const
    {
        (*self)(std::forward<Args>(args)...);
    }
};

template<class T, class MFn>
struct mfn_handler
{
    MFn mfn_;
    T* self;

    template<class... Args>
    void
    operator()(Args&&... args) const
    {
        ((*self).*mfn_)(std::forward<Args>(args)...);
    }
};

} // detail

template<class T
    ,class = typename std::enable_if<
        std::is_base_of<enable_shared_from, T>::value>::type
>
detail::shared_handler<T>
bind_front(T* this_)
{
    return {shared_from(this_)};
}

template<class T, class MFn
    ,class = typename std::enable_if<
        std::is_base_of<enable_shared_from, T>::value>::type
>
detail::shared_mfn_handler<T, MFn>
bind_front(T* this_, MFn mfn)
{
    return {mfn, shared_from(this_)};
}

template<class T
    ,class = typename std::enable_if<
        ! std::is_base_of<enable_shared_from, T>::value>::type
>
detail::handler<T>
bind_front(T* this_)
{
    return {this_};
}

template<class T, class MFn
    ,class = typename std::enable_if<
        ! std::is_base_of<enable_shared_from, T>::value>::type
>
detail::mfn_handler<T, MFn>
bind_front(T* this_, MFn mfn)
{
    return {mfn, this_};
}

//------------------------------------------------------------------------------

template<class T, class U>
boost::weak_ptr<T>
weak_ptr_cast(boost::weak_ptr<U> const& wp) noexcept
{
    return boost::static_pointer_cast<T>(wp.lock());
}

#endif

ext: hpp

max_stars_repo_name: djarek/BeastLounge

max_issues_repo_name: djarek/BeastLounge

max_forks_repo_name: djarek/BeastLounge


text:
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2021 YADRO

#include <boost/asio.hpp>
#include <manager.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/asio/connection.hpp>

#include <iostream>

using namespace phosphor::logging;
using namespace sdbusplus::asio;

int main()
{
    boost::asio::io_context io;

    sdbusplus::asio::connection systemConn(io);
    auto sessionManager =
        std::make_shared<obmc::session::SessionManager>(systemConn, io);

    log<level::DEBUG>("io.run()");
    io.run();

    log<level::DEBUG>("Shutdown service 'session-manager'");
    return EXIT_SUCCESS;
}

ext: cpp

max_stars_repo_name: YADRO-KNS/obmc-yadro-session-manager

max_issues_repo_name: YADRO-KNS/obmc-yadro-session-manager

max_forks_repo_name: YADRO-KNS/obmc-yadro-session-manager


text:
#pragma once
#include <Audio/Audio.hpp>
#include <boost/core/noncopyable.hpp>

class AudioLibrary : private boost::noncopyable
{
public:
    Audio::ShortSoundLibrary clips;
    Audio::StreamedSoundLibrary music;
    Audio::Listener listener;

    void init();
    void update(int dt);
};


text:
/** @file GammaDist.cpp
 * @author Mark J. Olah (mjo\@cs.unm DOT edu)
 * @date 2017-2019
 * @brief GammaDist class definition
 *
 */
#include "PriorHessian/GammaDist.h"
#include "PriorHessian/util.h"
#include "PriorHessian/PriorHessianError.h"

#include <cmath>
#include <sstream>
#include <limits>

#include <boost/math/special_functions/gamma.hpp>

namespace prior_hessian {

const StringVecT GammaDist::_param_names = { "scale", "shape" };
const GammaDist::NparamsVecT GammaDist::_param_lbound = {0, 0}; //Lower bound on valid parameter values
const GammaDist::NparamsVecT GammaDist::_param_ubound = {INFINITY, INFINITY}; //Upper bound on valid parameter values

/* Constructors */
GammaDist::GammaDist(double scale, double shape)
    : UnivariateDist(),
      _scale(checked_scale(scale)),
      _shape(checked_shape(shape)),
      llh_const_initialized(false)
{ }

/* Non-static member functions */

void GammaDist::set_scale(double val)
{
    _scale = checked_scale(val);
    llh_const_initialized = false;
}

void GammaDist::set_shape(double val)
{
    _shape = checked_shape(val);
    llh_const_initialized = false;
}

void GammaDist::set_params(double scale, double shape)
{
    _scale = checked_scale(scale);
    _shape = checked_shape(shape);
    llh_const_initialized = false;
}

double GammaDist::cdf(double x) const
{
   return boost::math::gamma_p(_shape, x / _scale);
}

double GammaDist::icdf(double u) const
{
    if(u == 0) return 0;
    if(u == 1) return INFINITY;
    return boost::math::gamma_p_inv(_shape, u) * _scale;
}

double GammaDist::pdf(double x) const
{
    if(x==0) return 0;
    double inv_scale = 1/_scale;
    return boost::math::gamma_p_derivative(_shape, x*inv_scale) * inv_scale;
}

double GammaDist::llh(double x) const
{
    if(!llh_const_initialized) initialize_llh_const();
    return rllh(x) + llh_const;
}

void GammaDist::initialize_llh_const() const
{
    llh_const = compute_llh_const(shape(),scale());
    llh_const_initialized = true;
}

double GammaDist::compute_llh_const(double shape, double scale)
{
    return -shape*log(scale) - std::lgamma(shape);
}

double GammaDist::checked_scale(double val)
{
    if(!std::isfinite(val) || val <= 0) {
        std::ostringstream msg;
        msg<<"GammaDist: got bad scale value:"<<val;
        throw ParameterValueError(msg.str());
    }
    return val;
}

double GammaDist::checked_shape(double val)
{
    if(!std::isfinite(val) || val <= 0) {
        std::ostringstream msg;
        msg<<"GammaDist: got bad shape value:"<<val;
        throw ParameterValueError(msg.str());
    }
    return val;
}

} /* namespace prior_hessian */

max_stars_repo_name: markjolah/PriorHessianLib

max_issues_repo_name: markjolah/PriorHessianLib

max_forks_repo_name: markjolah/PriorHessianLib


text:
//
// execution/context_as.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// 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)
//

#ifndef BOOST_ASIO_EXECUTION_CONTEXT_AS_HPP
#define BOOST_ASIO_EXECUTION_CONTEXT_AS_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/execution/context.hpp>
#include <boost/asio/execution/executor.hpp>
#include <boost/asio/execution/scheduler.hpp>
#include <boost/asio/execution/sender.hpp>
#include <boost/asio/is_applicable_property.hpp>
#include <boost/asio/query.hpp>
#include <boost/asio/traits/query_static_constexpr_member.hpp>
#include <boost/asio/traits/static_query.hpp>

#include <boost/asio/detail/push_options.hpp>

namespace boost {
namespace asio {

#if defined(GENERATING_DOCUMENTATION)

namespace execution {

/// A property that is used to obtain the execution context that is associated
/// with an executor.
template <typename U>
struct context_as_t
{
  /// The context_as_t property applies to executors, senders, and schedulers.
  template <typename T>
  static constexpr bool is_applicable_property_v =
    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;

  /// The context_t property cannot be required.
  static constexpr bool is_requirable = false;

  /// The context_t property cannot be preferred.
  static constexpr bool is_preferable = false;

  /// The type returned by queries against an @c any_executor.
  typedef T polymorphic_query_result_type;
};

/// A special value used for accessing the context_as_t property.
template <typename U>
constexpr context_as_t context_as;

} // namespace execution

#else // defined(GENERATING_DOCUMENTATION)

namespace execution {

template <typename T>
struct context_as_t
{
#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  template <typename U>
  BOOST_ASIO_STATIC_CONSTEXPR(bool,
    is_applicable_property_v = (
      is_executor<U>::value
        || conditional<
            is_executor<U>::value,
            false_type,
            is_sender<U>
          >::type::value
        || conditional<
            is_executor<U>::value,
            false_type,
            is_scheduler<U>
          >::type::value));
#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)

  BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);
  BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);

  typedef T polymorphic_query_result_type;

  BOOST_ASIO_CONSTEXPR context_as_t()
  {
  }

  BOOST_ASIO_CONSTEXPR context_as_t(context_t)
  {
  }

#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  template <typename E>
  static BOOST_ASIO_CONSTEXPR
  typename context_t::query_static_constexpr_member<E>::result_type
  static_query()
    BOOST_ASIO_NOEXCEPT_IF((
      context_t::query_static_constexpr_member<E>::is_noexcept))
  {
    return context_t::query_static_constexpr_member<E>::value();
  }

  template <typename E, typename U = decltype(context_as_t::static_query<E>())>
  static BOOST_ASIO_CONSTEXPR const U static_query_v
    = context_as_t::static_query<E>();
#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
       //   && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)

  template <typename Executor, typename U>
  friend BOOST_ASIO_CONSTEXPR U query(
      const Executor& ex, const context_as_t<U>&,
      typename enable_if<
        is_same<T, U>::value
      >::type* = 0,
      typename enable_if<
        can_query<const Executor&, const context_t&>::value
      >::type* = 0)
#if !defined(__clang__) // Clang crashes if noexcept is used here.
#if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified.
    BOOST_ASIO_NOEXCEPT_IF((
      is_nothrow_query<const Executor&, const context_t&>::value))
#else // defined(BOOST_ASIO_MSVC)
    BOOST_ASIO_NOEXCEPT_IF((
      is_nothrow_query<const Executor&, const context_t&>::value))
#endif // defined(BOOST_ASIO_MSVC)
#endif // !defined(__clang__)
  {
    return boost::asio::query(ex, context);
  }
};

#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
template <typename T> template <typename E, typename U>
const U context_as_t<T>::static_query_v;
#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
       //   && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)

#if (defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) \
    && defined(BOOST_ASIO_HAS_CONSTEXPR)) \
  || defined(GENERATING_DOCUMENTATION)
template <typename T>
constexpr context_as_t<T> context_as{};
#endif // (defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
       //     && defined(BOOST_ASIO_HAS_CONSTEXPR))
       //   || defined(GENERATING_DOCUMENTATION)

} // namespace execution

#if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)

template <typename T, typename U>
struct is_applicable_property<T, execution::context_as_t<U> >
  : integral_constant<bool,
      execution::is_executor<T>::value
        || conditional<
            execution::is_executor<T>::value,
            false_type,
            execution::is_sender<T>
          >::type::value
        || conditional<
            execution::is_executor<T>::value,
            false_type,
            execution::is_scheduler<T>
          >::type::value>
{
};

#endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)

namespace traits {

#if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)

template <typename T, typename U>
struct static_query<T, execution::context_as_t<U>,
  typename enable_if<
    static_query<T, execution::context_t>::is_valid
  >::type> : static_query<T, execution::context_t>
{
};

#endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
       //   || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)

#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)

template <typename T, typename U>
struct query_free<T, execution::context_as_t<U>,
    typename enable_if<
      can_query<const T&, const execution::context_t&>::value
    >::type>
{
  BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
    (is_nothrow_query<const T&, const execution::context_t&>::value));

  typedef U result_type;
};

#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)

} // namespace traits

#endif // defined(GENERATING_DOCUMENTATION)

} // namespace asio
} // namespace boost

#include <boost/asio/detail/pop_options.hpp>

#endif // BOOST_ASIO_EXECUTION_CONTEXT_AS_HPP


text:
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2017-2017. 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)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
#define BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP

#ifndef BOOST_CONFIG_HPP
#  include <boost/config.hpp>
#endif

#if defined(BOOST_HAS_PRAGMA_ONCE)
#  pragma once
#endif

//empty
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME empty
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>

//size
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME size
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>

namespace boost {
namespace container {
namespace dtl {

template <class Container>
struct is_container
{
   static const bool value =
      boost::container::is_container_detail::
         has_member_function_callable_with_size <const Container>::value &&
      boost::container::is_container_detail::
         has_member_function_callable_with_empty<const Container>::value;
};

template <>
struct is_container<void>
{
   static const bool value = false;
};

}  //namespace dtl {
}  //namespace container {
}  //namespace boost {

#endif   //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP

max_stars_repo_name: kindlychung/mediasoup-sfu-cpp

max_issues_repo_name: kindlychung/mediasoup-sfu-cpp

max_forks_repo_name: kindlychung/mediasoup-sfu-cpp


text:
// Copyright 2019 dimakirol <your_email>

#ifndef INCLUDE_HEADER_HPP_
#define INCLUDE_HEADER_HPP_

#include <async++.h>
#include <boost/process.hpp>
#include <boost/process/extend.hpp>
#include <boost/program_options.hpp>
#include <vector>
#include <iostream>
#include <signal.h>
#include <string>
#include <thread>
#include <chrono>

using assio = boost::asio;
using prrocess =  boost::process;
using exxtend = boost::process::extend;
using po = boost::program_options;

namespace
{
    const size_t error_in_command_line = 1;
    const size_t success = 0;
    const size_t error_unhandled_exeption = 2;
}

#endif // INCLUDE_HEADER_HPP_


text:
#include "testsuite.h"
#include <blitz/array.h>

BZ_USING_NAMESPACE(blitz)

int main() {
  Array<int, 2> A(4);
  Array<int, 1> B(4), C(4);

  firstIndex i;
  secondIndex j;

  A = i+j;

  B = max(A,j);

  C = 3, 4, 5, 6;
  BZTEST(count(B == C) == 4);

  return 0;
}

max_stars_repo_name: fraguela/depspawn

max_issues_repo_name: MSV-Project/IBAMR

max_forks_repo_name: MSV-Project/IBAMR


text:
#include <common/net/message/nodes/HeartbeatMsg.h>
#include <common/net/message/nodes/ChangeTargetConsistencyStatesMsg.h>
#include <common/net/message/nodes/ChangeTargetConsistencyStatesRespMsg.h>
#include <common/net/message/nodes/RefreshCapacityPoolsMsg.h>
#include <common/net/message/storage/SetStorageTargetInfoMsg.h>
#include <common/net/message/storage/SetStorageTargetInfoRespMsg.h>
#include <common/net/message/storage/quota/RequestExceededQuotaMsg.h>
#include <common/net/message/storage/quota/RequestExceededQuotaRespMsg.h>
#include <common/toolkit/MessagingTk.h>
#include <common/toolkit/NodesTk.h>
#include <common/toolkit/SessionTk.h>
#include <common/toolkit/Time.h>
#include <common/toolkit/ZipIterator.h>
#include <common/nodes/NodeStore.h>
#include <common/nodes/TargetCapacityPools.h>
#include <app/App.h>
#include <app/config/Config.h>
#include <net/msghelpers/MsgHelperClose.h>
#include <program/Program.h>
#include <toolkit/BuddyCommTk.h>
#include "InternodeSyncer.h"

#include <boost/lexical_cast.hpp>

InternodeSyncer::InternodeSyncer(TargetConsistencyState initialConsistencyState)
   : PThread("XNodeSync"),
     log("XNodeSync"),
     forcePoolsUpdate(true),
     forceTargetStatesUpdate(true),
     forcePublishCapacities(true),
     forceStoragePoolsUpdate(true),
     offlineWait(Program::getApp()->getConfig() ),
     nodeConsistencyState(initialConsistencyState),
     buddyResyncInProgress(false)
{
   MirrorBuddyGroupMapper* mbg = Program::getApp()->getMetaBuddyGroupMapper();
   MirrorBuddyState buddyState = mbg->getBuddyState(Program::getApp()->getLocalNodeNumID().val() );

   if ((buddyState == BuddyState_PRIMARY)
         && (nodeConsistencyState == TargetConsistencyState_NEEDS_RESYNC))
      offlineWait.startTimer();
}

void InternodeSyncer::run()
{
   try
   {
      registerSignalHandler();

      syncLoop();

      log.log(Log_DEBUG, "Component stopped.");
   }
   catch(std::exception& e)
   {
      PThread::getCurrentThreadApp()->handleComponentException(e);
   }
}

void InternodeSyncer::syncLoop()
{
   const App* app = Program::getApp();
   const Config* cfg = app->getConfig();

   const int sleepIntervalMS = 3*1000; // 3sec

   // If (undocumented) sysUpdateTargetStatesSecs is set in config, use that value, otherwise
   // default to 1/6 sysTargetOfflineTimeoutSecs.
   const unsigned updateTargetStatesMS =
      (cfg->getSysUpdateTargetStatesSecs() != 0)
      ? cfg->getSysUpdateTargetStatesSecs() * 1000
      : cfg->getSysTargetOfflineTimeoutSecs() * 166;

   const unsigned updateCapacityPoolsMS = 4 * updateTargetStatesMS;

   const unsigned metaCacheSweepNormalMS = 5*1000; // 5sec
   const unsigned metaCacheSweepStressedMS = 2*1000; // 2sec
   const unsigned idleDisconnectIntervalMS = 70*60*1000; /* 70 minutes (must be less than half the
      streamlis idle disconnect interval to avoid cases where streamlis disconnects first) */
   const unsigned updateIDTimeMS = 60 * 1000; // 1 min
   const unsigned downloadNodesIntervalMS = 300000; // 5 min
   const unsigned updateStoragePoolsMS = downloadNodesIntervalMS;

   Time lastCapacityUpdateT;
   Time lastMetaCacheSweepT;
   Time lastIdleDisconnectT;
   Time lastTimeIDSet;
   Time lastTargetStatesUpdateT;
   Time lastDownloadNodesT;
   Time lastStoragePoolsUpdateT;
   Time lastCapacityPublishedT;

   unsigned currentCacheSweepMS = metaCacheSweepNormalMS; // (adapted inside the loop below)

   while(!waitForSelfTerminateOrder(sleepIntervalMS) )
   {
      const bool capacityPoolsUpdateForced = forcePoolsUpdate.exchange(false);
      const bool doCapacityPoolsUpdate = capacityPoolsUpdateForced
            || (lastCapacityUpdateT.elapsedMS() > updateCapacityPoolsMS);
      const bool doTargetStatesUpdate = forceTargetStatesUpdate.exchange(false)
            || (lastTargetStatesUpdateT.elapsedMS() > updateTargetStatesMS);
      const bool doPublishCapacities = forcePublishCapacities.exchange(false)
            || (lastCapacityPublishedT.elapsedMS() > updateTargetStatesMS);
      const bool doStoragePoolsUpdate = forceStoragePoolsUpdate.exchange(false)
            || (lastStoragePoolsUpdateT.elapsedMS() > updateStoragePoolsMS);

      // download & sync nodes
      if (lastDownloadNodesT.elapsedMS() > downloadNodesIntervalMS)
      {
         downloadAndSyncNodes();
         downloadAndSyncTargetMappings();

         lastDownloadNodesT.setToNow();
      }

      if (doStoragePoolsUpdate)
      {
         downloadAndSyncStoragePools();

         lastStoragePoolsUpdateT.setToNow();
      }

      if(doCapacityPoolsUpdate)
      {
         updateMetaCapacityPools();
         updateMetaBuddyCapacityPools();

         if ( (capacityPoolsUpdateForced) && (!doStoragePoolsUpdate) )
         {  // capacity pools changed, but storage pools were not downloaded (i.e. no update on
            // storage capactity pools was made)
            updateStorageCapacityPools();
            updateTargetBuddyCapacityPools();
         }

         lastCapacityUpdateT.setToNow();
      }

      if(lastMetaCacheSweepT.elapsedMS() > currentCacheSweepMS)
      {
         bool flushTriggered = app->getMetaStore()->cacheSweepAsync();
         currentCacheSweepMS = (flushTriggered ? metaCacheSweepStressedMS : metaCacheSweepNormalMS);

         lastMetaCacheSweepT.setToNow();
      }

      if(lastIdleDisconnectT.elapsedMS() > idleDisconnectIntervalMS)
      {
         dropIdleConns();
         lastIdleDisconnectT.setToNow();
      }

      if(lastTimeIDSet.elapsedMS() > updateIDTimeMS)
      {
         StorageTk::resetIDCounterToNow();
         lastTimeIDSet.setToNow();
      }

      if(doTargetStatesUpdate)
      {
         if (this->offlineWait.hasTimeout() )
         {
            // if we're waiting to be offlined, set our local state to needs-resync and don't report
            // anything to the mgmtd
            setNodeConsistencyState(TargetConsistencyState_NEEDS_RESYNC);
         }
         else
         {
            TargetConsistencyState newConsistencyState;
            if (updateMetaStatesAndBuddyGroups(newConsistencyState, true))
               setNodeConsistencyState(newConsistencyState);
            downloadAndSyncTargetStatesAndBuddyGroups();
         }

         lastTargetStatesUpdateT.setToNow();
      }

      if (doPublishCapacities)
      {
         publishNodeCapacity();
         lastCapacityPublishedT.setToNow();
      }
   }
}

bool InternodeSyncer::updateMetaCapacityPools()
{
   NodeCapacityPools* pools = Program::getApp()->getMetaCapacityPools();

   auto downloadRes = downloadCapacityPools(CapacityPoolQuery_META);

   if(!downloadRes.first)
      return false;

   // poolsMap does only contain one element with INVALID_POOL_ID in this case
   const auto& capacityPoolLists = downloadRes.second[StoragePoolStore::INVALID_POOL_ID];

   pools->syncPoolsFromLists(capacityPoolLists);
   return true;
}

bool InternodeSyncer::updateMetaBuddyCapacityPools()
{
   NodeCapacityPools* pools = Program::getApp()->getMetaBuddyCapacityPools();

   auto downloadRes = downloadCapacityPools(CapacityPoolQuery_METABUDDIES);

   if(!downloadRes.first)
      return false;

   // poolsMap does only contain one element with INVALID_POOL_ID in this case
   const auto& capacityPoolLists = downloadRes.second[StoragePoolStore::INVALID_POOL_ID];

   pools->syncPoolsFromLists(capacityPoolLists);
   return true;
}

bool InternodeSyncer::updateStorageCapacityPools()
{
   const App* app = Program::getApp();
   const Config* cfg = app->getConfig();
   const TargetMapper* targetMapper = app->getTargetMapper();

   const auto downloadRes = downloadCapacityPools(CapacityPoolQuery_STORAGE);

   if(!downloadRes.first)
      return false;

   TargetMap targetMap;

   if(cfg->getSysTargetAttachmentMap() )
      targetMap = *cfg->getSysTargetAttachmentMap(); // user-provided custom assignment map
   else
      targetMap = targetMapper->getMapping();

   const GetNodeCapacityPoolsRespMsg::PoolsMap& poolsMap = downloadRes.second;

   bool failed = false;
   for (auto iter = poolsMap.begin(); iter != poolsMap.end(); iter++)
   {
      StoragePoolPtr storagePool = app->getStoragePoolStore()->getPool(iter->first);
      if (!storagePool)
      {
         LOG(CAPACITY, ERR, "Received capacity pools for unknown storage pool.",
             ("storagePoolId", iter->first));

         failed = true;
         continue;
      }

      storagePool->getTargetCapacityPools()->syncPoolsFromLists(iter->second, targetMap);
   }

   return !failed;
}

bool InternodeSyncer::updateTargetBuddyCapacityPools()
{
   const App* app = Program::getApp();

   auto downloadRes = downloadCapacityPools(CapacityPoolQuery_STORAGEBUDDIES);

   if(!downloadRes.first)
      return false;

   const GetNodeCapacityPoolsRespMsg::PoolsMap& poolsMap = downloadRes.second;

   bool failed = false;
   for (auto iter = poolsMap.begin(); iter != poolsMap.end(); iter++)
   {
      StoragePoolPtr storagePool = app->getStoragePoolStore()->getPool(iter->first);
      if (!storagePool)
      {
         LOG(CAPACITY, ERR, "Received capacity pools for unknown storage pool.",
             ("storagePoolId", iter->first));

         failed = true;
         continue;
      }

      storagePool->getBuddyCapacityPools()->syncPoolsFromLists(iter->second);
   }

   return !failed;
}

/**
 * @return a pair, with first being false on error/true on success and second being the downloaded
 *         map of capacity pools sorted by storage pool
 */
std::pair<bool, GetNodeCapacityPoolsRespMsg::PoolsMap> InternodeSyncer::downloadCapacityPools(
   CapacityPoolQueryType poolType)
{
   LOG(STATES, DEBUG, "Downloading capacity pools.",
       ("Pool type", GetNodeCapacityPoolsMsg::queryTypeToStr(poolType)));

   NodeStore* mgmtNodes = Program::getApp()->getMgmtNodes();

   auto node = mgmtNodes->referenceFirstNode();
   if(!node)
      return std::make_pair(false, GetNodeCapacityPoolsRespMsg::PoolsMap());

   GetNodeCapacityPoolsMsg msg(poolType);
   RequestResponseArgs rrArgs(node.get(), &msg, NETMSGTYPE_GetNodeCapacityPoolsResp);
   GetNodeCapacityPoolsRespMsg* respMsgCast;

#ifndef CONGFS_DEBUG
   rrArgs.logFlags |= REQUESTRESPONSEARGS_LOGFLAG_CONNESTABLISHFAILED
                    | REQUESTRESPONSEARGS_LOGFLAG_RETRY;
#endif // CONGFS_DEBUG

   // connect & communicate
   bool commRes = MessagingTk::requestResponse(&rrArgs);
   if(!commRes)
      return std::make_pair(false, GetNodeCapacityPoolsRespMsg::PoolsMap());

   // handle result
   respMsgCast = (GetNodeCapacityPoolsRespMsg*)rrArgs.outRespMsg.get();

   GetNodeCapacityPoolsRespMsg::PoolsMap poolsMap = respMsgCast->getPoolsMap();

   return std::make_pair(true, poolsMap);
}

/**
 * @return true if an ack was received for the heartbeat, false otherwise
 */
bool InternodeSyncer::registerNode(AbstractDatagramListener* dgramLis)
{
   const char* logContext = "Register node";
   static bool registrationFailureLogged = false; // to avoid log spamming

   App* app = Program::getApp();
   NodeStore* mgmtNodes = app->getMgmtNodes();
   Config* cfg = app->getConfig();

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if(!mgmtNode)
      return false;

   Node& localNode = Program::getApp()->getLocalNode();
   NumNodeID localNodeNumID = localNode.getNumID();
   NumNodeID rootNodeID = app->getMetaRoot().getID();
   bool rootIsBuddyMirrored = app->getMetaRoot().getIsMirrored();
   NicAddressList nicList(localNode.getNicList());

   HeartbeatMsg msg(localNode.getID(), localNodeNumID, NODETYPE_Meta, &nicList);
   msg.setRootNumID(rootNodeID);
   msg.setRootIsBuddyMirrored(rootIsBuddyMirrored);
   msg.setPorts(cfg->getConnMetaPortUDP(), cfg->getConnMetaPortTCP() );

   bool nodeRegistered = dgramLis->sendToNodeUDPwithAck(mgmtNode, &msg);

   if(nodeRegistered)
      LogContext(logContext).log(Log_WARNING, "Node registration successful.");
   else
   if(!registrationFailureLogged)
   {
      LogContext(logContext).log(Log_CRITICAL,
         "Node registration not successful. Management node offline? Will keep on trying...");
      registrationFailureLogged = true;
   }

   return nodeRegistered;
}

/**
 * Download and sync metadata server target states and mirror buddy groups.
 *
 * @param outConsistencyState The new node consistency state.
 */
bool InternodeSyncer::updateMetaStatesAndBuddyGroups(TargetConsistencyState& outConsistencyState,
   bool publish)
{
   LOG(STATES, DEBUG, "Starting state update.");

   App* app = Program::getApp();
   NodeStore* mgmtNodes = app->getMgmtNodes();
   TargetStateStore* metaStateStore = app->getMetaStateStore();
   MirrorBuddyGroupMapper* buddyGroupMapper = app->getMetaBuddyGroupMapper();

   static bool downloadFailedLogged = false; // to avoid log spamming
   static bool publishFailedLogged = false;

   NumNodeID localNodeID = app->getLocalNodeNumID();

   auto node = mgmtNodes->referenceFirstNode();
   if(!node)
   {
      LOG(STATES, ERR, "Management node not defined.");
      return false;
   }

   unsigned numRetries = 10; // If publishing states fails 10 times, give up (-> POFFLINE).

   // Note: Publishing fails if between downloadStatesAndBuddyGroups and
   // publishLocalTargetStateChanges, a state on the mgmtd is changed (e.g. because the primary
   // sets NEEDS_RESYNC for the secondary). In that case, we will retry.

   LOG(STATES, DEBUG, "Beginning target state update...");
   bool publishSuccess = false;

   while (!publishSuccess && (numRetries--) )
   {
      MirrorBuddyGroupMap buddyGroups;
      TargetStateMap states;

      bool downloadRes = NodesTk::downloadStatesAndBuddyGroups(*node, NODETYPE_Meta, buddyGroups,
         states, true);

      if (!downloadRes)
      {
         if (!downloadFailedLogged)
         {
            LOG(STATES, WARNING,
               "Downloading target states from management node failed. "
               "Setting all target states to probably-offline.");
            downloadFailedLogged = true;
         }

         metaStateStore->setAllStates(TargetReachabilityState_POFFLINE);

         break;
      }

      downloadFailedLogged = false;

      // Sync buddy groups here, because decideResync depends on it.
      metaStateStore->syncStatesAndGroups(buddyGroupMapper, states,
         std::move(buddyGroups), localNodeID);

      CombinedTargetState newStateFromMgmtd;
      // Find local state which was sent by mgmtd
      for (const auto& state : states)
      {
         if (state.first == localNodeID.val())
         {
            newStateFromMgmtd = CombinedTargetState(state.second.reachabilityState,
               state.second.consistencyState);
         }
      }

      TargetConsistencyState localChangedState = decideResync(newStateFromMgmtd);
      outConsistencyState = localChangedState;

      if (!publish)
      {
         metaStateStore->setState(localNodeID.val(),
            CombinedTargetState(TargetReachabilityState_ONLINE, localChangedState) );

         return true;
      }

      // Note: In this case "old" means "before we changed it locally".
      TargetConsistencyState oldState = newStateFromMgmtd.consistencyState;

      publishSuccess = publishNodeStateChange(oldState, localChangedState);

      if (publishSuccess)
      {
         metaStateStore->setState(localNodeID.val(),
            CombinedTargetState(TargetReachabilityState_ONLINE, localChangedState) );

         BuddyCommTk::checkBuddyNeedsResync();
      }
   }

   if (!publishSuccess)
   {
      if (!publishFailedLogged)
      {
         LOG(STATES, WARNING, "Pushing local state to management node failed.");
         publishFailedLogged = true;
      }
   }
   else
      publishFailedLogged = false;

   return true;
}

/**
 * Synchronize local client sessions with registered mgmtd clients to release orphaned sessions.
 *
 * @param clientsList must be ordered; contained nodes will be removed and may no longer be
 * accessed after calling this method.
 * @param allowRemoteComm usually true; setting this to false is only useful when called during
 * app shutdown to avoid communication; if false, unlocking of user locks, closing of storage server
 * files and disposal of unlinked files won't be performed
 */
void InternodeSyncer::syncClients(const std::vector<NodeHandle>& clientsList, bool allowRemoteComm)
{
   const char* logContext = "Sync clients";
   App* app = Program::getApp();
   MetaStore* metaStore = Program::getApp()->getMetaStore();
   SessionStore* sessions = app->getSessions();
   SessionStore* mirroredSessions = app->getMirroredSessions();

   SessionList removedSessions;
   NumNodeIDList unremovableSessions;

   sessions->syncSessions(clientsList, removedSessions, unremovableSessions);
   mirroredSessions->syncSessions(clientsList, removedSessions, unremovableSessions);

   // print client session removal results (upfront)
   if(!removedSessions.empty() || !unremovableSessions.empty())
   {
      std::ostringstream logMsgStream;
      logMsgStream << "Removing " << removedSessions.size() << " client sessions.";

      if(unremovableSessions.empty() )
         LogContext(logContext).log(Log_DEBUG, logMsgStream.str() ); // no unremovable sessions
      else
      { // unremovable sessions found => log warning
         logMsgStream << " (" << unremovableSessions.size() << " are unremovable)";
         LogContext(logContext).log(Log_WARNING, logMsgStream.str() );
      }
   }

   // walk over all removed sessions (to cleanup the contained files)

   SessionListIter sessionIter = removedSessions.begin();
   for( ; sessionIter != removedSessions.end(); sessionIter++)
   { // walk over all client sessions: cleanup each session
      Session* session = *sessionIter;
      NumNodeID sessionID = session->getSessionID();
      SessionFileStore* sessionFiles = session->getFiles();

      SessionFileList removedSessionFiles;
      UIntList referencedSessionFiles;

      sessionFiles->removeAllSessions(&removedSessionFiles, &referencedSessionFiles);

      /* note: referencedSessionFiles should always be empty, because otherwise the reference holder
         would also hold a reference to the client session (and we woudn't be here if the client
         session had any references) */

      // print session files results (upfront)

      if (!removedSessionFiles.empty() || !referencedSessionFiles.empty())
      {
         std::ostringstream logMsgStream;
         logMsgStream << "Removing " << removedSessionFiles.size() << " file sessions. ("
            << referencedSessionFiles.size() << " are unremovable). clientNumID: " << sessionID;
         if (referencedSessionFiles.empty())
            LogContext(logContext).log(Log_SPAM, logMsgStream.str() );
         else
            LogContext(logContext).log(Log_NOTICE, logMsgStream.str() );
      }

      // walk over all files in the current session (to clean them up)

      SessionFileListIter fileIter = removedSessionFiles.begin();

      for( ; fileIter != removedSessionFiles.end(); fileIter++)
      { // walk over all files: unlock user locks, close meta, close local, dispose unlinked
         SessionFile* sessionFile = *fileIter;
         unsigned ownerFD = sessionFile->getSessionID();
         unsigned accessFlags = sessionFile->getAccessFlags();
         unsigned numHardlinks;
         unsigned numInodeRefs;

         MetaFileHandle inode = sessionFile->releaseInode();
         std::string fileID = inode->getEntryID();

         std::string fileHandleID = SessionTk::generateFileHandleID(ownerFD, fileID);

         // save nodeIDs for later
         StripePattern* pattern = inode->getStripePattern();
         int maxUsedNodesIndex = pattern->getStripeTargetIDs()->size() - 1;

         // unlock all user locks
         auto appendGranted = inode->flockAppendCancelByClientID(sessionID);
         auto flockGranted = inode->flockEntryCancelByClientID(sessionID);
         auto rangeGranted = inode->flockRangeCancelByClientID(sessionID);

         if(allowRemoteComm)
         {
            LockingNotifier::notifyWaitersEntryLock(LockEntryNotifyType_APPEND,
                  inode->getReferenceParentID(), inode->getEntryID(), inode->getIsBuddyMirrored(),
                  std::move(appendGranted));
            LockingNotifier::notifyWaitersEntryLock(LockEntryNotifyType_FLOCK,
                  inode->getReferenceParentID(), inode->getEntryID(), inode->getIsBuddyMirrored(),
                  std::move(flockGranted));
            LockingNotifier::notifyWaitersRangeLock(inode->getReferenceParentID(),
                  inode->getEntryID(), inode->getIsBuddyMirrored(), std::move(rangeGranted));
         }

         EntryInfo* entryInfo = sessionFile->getEntryInfo();

         FileIDLock lock(sessions->getEntryLockStore(), entryInfo->getEntryID(), true);

         if(allowRemoteComm)
            MsgHelperClose::closeChunkFile(sessionID, fileHandleID.c_str(),
               maxUsedNodesIndex, *inode, entryInfo, NETMSG_DEFAULT_USERID);

         LogContext(logContext).log(Log_NOTICE, "closing file. ParentID: " +
            entryInfo->getParentEntryID() + " FileName: " + entryInfo->getFileName() );

         metaStore->closeFile(entryInfo, std::move(inode), accessFlags, &numHardlinks,
               &numInodeRefs);

         if(allowRemoteComm && !numHardlinks && !numInodeRefs)
            MsgHelperClose::unlinkDisposableFile(fileID, NETMSG_DEFAULT_USERID,
                  entryInfo->getIsBuddyMirrored());

         delete sessionFile;
      } // end of files loop

      delete(session);

   } // end of client sessions loop
}

bool InternodeSyncer::downloadAndSyncNodes()
{
   LOG(STATES, DEBUG, "Starting node list sync.");

   App* app = Program::getApp();
   NodeStore* mgmtNodes = app->getMgmtNodes();

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if(!mgmtNode)
      return false;

   Node& localNode = app->getLocalNode();
   NodeStore* metaNodes = app->getMetaNodes();
   NodeStore* storageNodes = app->getStorageNodes();

   // metadata nodes

   std::vector<NodeHandle> metaNodesList;
   NumNodeIDList addedMetaNodes;
   NumNodeIDList removedMetaNodes;
   NumNodeID rootNodeID;
   bool rootIsBuddyMirrored;

   if(NodesTk::downloadNodes(*mgmtNode, NODETYPE_Meta, metaNodesList, true, &rootNodeID,
      &rootIsBuddyMirrored) )
   {
      metaNodes->syncNodes(metaNodesList, &addedMetaNodes, &removedMetaNodes, &localNode);
      if (app->getMetaRoot().setIfDefault(rootNodeID, rootIsBuddyMirrored))
      {
         LOG(STATES, CRITICAL,
            std::string("Root node ID (from sync results): ") + rootNodeID.str());
         app->getRootDir()->setOwnerNodeID(rootNodeID);
      }

      printSyncResults(NODETYPE_Meta, &addedMetaNodes, &removedMetaNodes);
   }

   // storage nodes

   std::vector<NodeHandle> storageNodesList;
   NumNodeIDList addedStorageNodes;
   NumNodeIDList removedStorageNodes;

   if(NodesTk::downloadNodes(*mgmtNode, NODETYPE_Storage, storageNodesList, true) )
   {
      storageNodes->syncNodes(storageNodesList, &addedStorageNodes, &removedStorageNodes,
         &localNode);
      printSyncResults(NODETYPE_Storage, &addedStorageNodes, &removedStorageNodes);
   }

   return true;
}

void InternodeSyncer::downloadAndSyncClients(bool requeue)
{
   App* app = Program::getApp();
   NodeStore* mgmtNodes = app->getMgmtNodes();
   NodeStoreClients* clientNodes = app->getClientNodes();
   TimerQueue* timerQ = app->getTimerQueue();

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if(!mgmtNode)
      return;

   std::vector<NodeHandle> clientNodesList;
   NumNodeIDList addedClientNodes;
   NumNodeIDList removedClientNodes;

   if(NodesTk::downloadNodes(*mgmtNode, NODETYPE_Client, clientNodesList, true) )
   {
      clientNodes->syncNodes(clientNodesList, &addedClientNodes, &removedClientNodes);
      printSyncResults(NODETYPE_Client, &addedClientNodes, &removedClientNodes);

      syncClients(clientNodesList, true); // sync client sessions
   }

   if (requeue)
      timerQ->enqueue(std::chrono::minutes(5),
            [] { InternodeSyncer::downloadAndSyncClients(true); });
}

bool InternodeSyncer::downloadAndSyncTargetMappings()
{
   LOG(STATES, DEBUG, "Syncing target mappings.");

   App* app = Program::getApp();
   TargetMapper* targetMapper = app->getTargetMapper();
   NodeStore* mgmtNodes = app->getMgmtNodes();

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if(!mgmtNode)
      return false;

   auto mappings = NodesTk::downloadTargetMappings(*mgmtNode, true);
   if (mappings.first)
      targetMapper->syncTargets(std::move(mappings.second));

   return true;
}

bool InternodeSyncer::downloadAndSyncStoragePools()
{
   LOG(STORAGEPOOLS, DEBUG, "Syncing storage pools.");

   const App* app = Program::getApp();
   const NodeStore* mgmtNodes = app->getMgmtNodes();
   StoragePoolStore* storagePoolStore = app->getStoragePoolStore();

   const auto mgmtNode = mgmtNodes->referenceFirstNode();
   if(!mgmtNode)
      return false;

   StoragePoolPtrVec storagePools;

   // note: storage pool download does include capacity pools
   const bool downloadStoragePoolsRes =
         NodesTk::downloadStoragePools(*mgmtNode, storagePools, true);
   if (!downloadStoragePoolsRes)
      return false;

   storagePoolStore->syncFromVector(storagePools);

   return true;
}

/**
 * Download and sync storage target states and mirror buddy groups.
 */
bool InternodeSyncer::downloadAndSyncTargetStatesAndBuddyGroups()
{
   App* app = Program::getApp();
   NodeStore* mgmtNodes = app->getMgmtNodes();
   MirrorBuddyGroupMapper* buddyGroupMapper = app->getStorageBuddyGroupMapper();
   TargetStateStore* targetStates = app->getTargetStateStore();

   LOG(STATES, DEBUG, "Downloading target states and buddy groups");

   static bool downloadFailedLogged = false;

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if(!mgmtNode)
      return false;

   TargetStateMap states;

   MirrorBuddyGroupMap buddyGroups;

   bool downloadRes = NodesTk::downloadStatesAndBuddyGroups(*mgmtNode, NODETYPE_Storage,
      buddyGroups, states, true);

   if ( downloadRes )
   {
      targetStates->syncStatesAndGroups(buddyGroupMapper, states,
         std::move(buddyGroups), app->getLocalNode().getNumID());

      downloadFailedLogged = false;
   }
   else
   { // download failed, so we don't know actual status => carefully set all to poffline

      if(!downloadFailedLogged)
      {
         LOG(STATES, WARNING, "Download from management node failed. "
               "Setting all targets to probably-offline.");
         downloadFailedLogged = true;
      }

      targetStates->setAllStates(TargetReachabilityState_POFFLINE);
   }

   return true;
}

void InternodeSyncer::printSyncResults(NodeType nodeType, NumNodeIDList* addedNodes,
   NumNodeIDList* removedNodes)
{
   Logger* const logger = Logger::getLogger();
   const int logLevel = nodeType == NODETYPE_Client ? Log_DEBUG : Log_WARNING;

   if (!addedNodes->empty())
      logger->log(LogTopic_STATES, logLevel, __func__,
            std::string("Nodes added (sync results): ") +
            StringTk::uintToStr(addedNodes->size() ) +
            " (Type: " + boost::lexical_cast<std::string>(nodeType) + ")");

   if (!removedNodes->empty())
      logger->log(LogTopic_STATES, logLevel, __func__,
            std::string("Nodes removed (sync results): ") +
            StringTk::uintToStr(removedNodes->size() ) +
            " (Type: " + boost::lexical_cast<std::string>(nodeType) + ")");
}

/**
 * Decides new consistency state based on local state, buddy group membership and state fetched
 * from management node.
 *
 * @param newState New state from the management node.
 * @returns The new target consistency state.
 */
TargetConsistencyState InternodeSyncer::decideResync(const CombinedTargetState newState)
{
   App* app = Program::getApp();
   MirrorBuddyGroupMapper* metaBuddyGroupMapper = app->getMetaBuddyGroupMapper();
   InternodeSyncer* internodeSyncer = app->getInternodeSyncer();
   NumNodeID localNodeID = app->getLocalNodeNumID();

   MirrorBuddyState buddyState = metaBuddyGroupMapper->getBuddyState(localNodeID.val());

   if (buddyState == BuddyState_UNMAPPED)
      return TargetConsistencyState_GOOD;

   // If the consistency state is BAD, it stays BAD until admin intervenes.
   if (internodeSyncer && // during early startup, INS is not constructed yet.
       internodeSyncer->getNodeConsistencyState() == TargetConsistencyState_BAD)
      return TargetConsistencyState_BAD;

   const bool isResyncing = newState.consistencyState == TargetConsistencyState_NEEDS_RESYNC;
   const bool isBad = newState.consistencyState == TargetConsistencyState_BAD;

   if (internodeSyncer &&
       internodeSyncer->getNodeConsistencyState() == TargetConsistencyState_NEEDS_RESYNC)
   {
      // If we're already (locally) maked as needs resync, this state can only be left when our
      // (primary) buddy tells us the resync is finished.
      return TargetConsistencyState_NEEDS_RESYNC;
   }
   else if (isResyncing || isBad)
   {
      return TargetConsistencyState_NEEDS_RESYNC;
   }
   else
   {
      // If mgmtd reports the target is (P)OFFLINE, then the meta server knows better and we set our
      // state to GOOD / ONLINE. Otherwise we accept the state reported by the mgmtd.
      if ( (newState.reachabilityState == TargetReachabilityState_OFFLINE)
        || (newState.reachabilityState == TargetReachabilityState_POFFLINE) )
         return TargetConsistencyState_GOOD;
      else
         return newState.consistencyState;
   }
}

bool InternodeSyncer::publishNodeStateChange(const TargetConsistencyState oldState,
   const TargetConsistencyState newState)
{
   const char* logContext = "Publish node state";
   App* app = Program::getApp();
   NodeStore* mgmtNodes = app->getMgmtNodes();
   const NumNodeID localNodeID = app->getLocalNodeNumID();

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if (!mgmtNode)
   {
      LogContext(logContext).logErr("Management node not defined.");
      return false;
   }

   bool res;

   UInt8List oldStateList(1, oldState);
   UInt8List newStateList(1, newState);
   UInt16List nodeIDList(1, localNodeID.val());

   ChangeTargetConsistencyStatesMsg msg(NODETYPE_Meta, &nodeIDList, &oldStateList, &newStateList);
   RequestResponseArgs rrArgs(mgmtNode.get(), &msg, NETMSGTYPE_ChangeTargetConsistencyStatesResp);

#ifndef CONGFS_DEBUG
   rrArgs.logFlags |= REQUESTRESPONSEARGS_LOGFLAG_CONNESTABLISHFAILED
                    | REQUESTRESPONSEARGS_LOGFLAG_RETRY;
#endif // CONGFS_DEBUG

   bool sendRes = MessagingTk::requestResponse(&rrArgs);

   static bool failureLogged = false;

   if (!sendRes)
   {
      if (!failureLogged)
         LogContext(logContext).log(Log_CRITICAL, "Pushing node state to management node failed.");

      res = false;
      failureLogged = true;
   }
   else
   {
      const auto respMsgCast =
            static_cast<const ChangeTargetConsistencyStatesRespMsg*>(rrArgs.outRespMsg.get());

      if ( (FhgfsOpsErr)respMsgCast->getValue() != FhgfsOpsErr_SUCCESS)
      {
         LogContext(logContext).log(Log_CRITICAL, "Management node did not accept node state change.");
         res = false;
      }
      else
      {
         res = true;
      }

      failureLogged = false;
   }

   return res;
}

/**
 * Send local node free space / free inode info to management node.
 */
void InternodeSyncer::publishNodeCapacity()
{
   App* app = Program::getApp();
   NodeStore* mgmtNodes = app->getMgmtNodes();

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if (!mgmtNode)
   {
      log.logErr("Management node not defined.");
      return;
   }

   int64_t sizeTotal = 0;
   int64_t sizeFree = 0;
   int64_t inodesTotal = 0;
   int64_t inodesFree = 0;

   std::string metaPath = app->getMetaPath();
   getStatInfo(&sizeTotal, &sizeFree, &inodesTotal, &inodesFree);

   StorageTargetInfo targetInfo(app->getLocalNodeNumID().val(), metaPath, sizeTotal, sizeFree,
      inodesTotal, inodesFree, getNodeConsistencyState());
   // Note: As long as we don't have meta-HA, consistency state will always be GOOD.

   StorageTargetInfoList targetInfoList(1, targetInfo);

   SetStorageTargetInfoMsg msg(NODETYPE_Meta, &targetInfoList);
   RequestResponseArgs rrArgs(mgmtNode.get(), &msg, NETMSGTYPE_SetStorageTargetInfoResp);

#ifndef CONGFS_DEBUG
   rrArgs.logFlags |= REQUESTRESPONSEARGS_LOGFLAG_CONNESTABLISHFAILED
                    | REQUESTRESPONSEARGS_LOGFLAG_RETRY;
#endif // CONGFS_DEBUG

   bool sendRes = MessagingTk::requestResponse(&rrArgs);

   static bool failureLogged = false;
   if (!sendRes)
   {
      if (!failureLogged)
         log.log(Log_CRITICAL, "Pushing node free space to management node failed.");

      failureLogged = true;
      return;
   }
   else
   {
      const auto respMsgCast = (const SetStorageTargetInfoRespMsg*)rrArgs.outRespMsg.get();
      failureLogged = false;

      if ( (FhgfsOpsErr)respMsgCast->getValue() != FhgfsOpsErr_SUCCESS)
      {
         log.log(Log_CRITICAL, "Management node did not accept free space info message.");
         return;
      }

   }

   // If we were just started and are publishing our capacity for the first time, force a pool
   // refresh on the mgmtd so we're not stuck in the emergency pool until the first regular
   // pool refresh.
   static bool firstTimePubilished = true;
   if (firstTimePubilished)
   {
      forceMgmtdPoolsRefresh();
      firstTimePubilished = false;
   }

}

/**
 * Drop/reset idle conns from all server stores.
 */
void InternodeSyncer::dropIdleConns()
{
   App* app = Program::getApp();

   unsigned numDroppedConns = 0;

   numDroppedConns += dropIdleConnsByStore(app->getMgmtNodes() );
   numDroppedConns += dropIdleConnsByStore(app->getMetaNodes() );
   numDroppedConns += dropIdleConnsByStore(app->getStorageNodes() );

   if(numDroppedConns)
   {
      log.log(Log_DEBUG, "Dropped idle connections: " + StringTk::uintToStr(numDroppedConns) );
   }
}

/**
 * Walk over all nodes in the given store and drop/reset idle connections.
 *
 * @return number of dropped connections
 */
unsigned InternodeSyncer::dropIdleConnsByStore(NodeStoreServers* nodes)
{
   App* app = Program::getApp();

   unsigned numDroppedConns = 0;

   for (const auto& node : nodes->referenceAllNodes())
   {
      /* don't do any idle disconnect stuff with local node
         (the LocalNodeConnPool doesn't support and doesn't need this kind of treatment) */

      if (node.get() != &app->getLocalNode())
      {
         NodeConnPool* connPool = node->getConnPool();

         numDroppedConns += connPool->disconnectAndResetIdleStreams();
      }
   }

   return numDroppedConns;
}

void InternodeSyncer::getStatInfo(int64_t* outSizeTotal, int64_t* outSizeFree,
   int64_t* outInodesTotal, int64_t* outInodesFree)
{
   const char* logContext = "GetStorageTargetInfoMsg (stat path)";

   std::string targetPathStr = Program::getApp()->getMetaPath();

   bool statSuccess = StorageTk::statStoragePath(targetPathStr, outSizeTotal, outSizeFree,
      outInodesTotal, outInodesFree);

   if(unlikely(!statSuccess) )
   { // error
      LogContext(logContext).logErr("Unable to statfs() storage path: " + targetPathStr +
         " (SysErr: " + System::getErrString() );

      *outSizeTotal = -1;
      *outSizeFree = -1;
      *outInodesTotal = -1;
      *outInodesFree = -1;
   }

   // read and use value from manual free space override file (if it exists)
   StorageTk::statStoragePathOverride(targetPathStr, outSizeFree, outInodesFree);
}

/**
 * Tell mgmtd to update its capacity pools.
 */
void InternodeSyncer::forceMgmtdPoolsRefresh()
{
   App* app = Program::getApp();
   DatagramListener* dgramLis = app->getDatagramListener();
   NodeStoreServers* mgmtNodes = app->getMgmtNodes();

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if (!mgmtNode)
   {
      log.log(Log_DEBUG, "Management node not defined.");
      return;
   }

   RefreshCapacityPoolsMsg msg;

   bool ackReceived = dgramLis->sendToNodeUDPwithAck(mgmtNode, &msg);

   if (!ackReceived)
      log.log(Log_DEBUG, "Management node did not accept pools refresh request.");
}

/**
 * @return false on error
 */
bool InternodeSyncer::downloadExceededQuotaList(StoragePoolId storagePoolId, QuotaDataType idType,
   QuotaLimitType exType, UIntList* outIDList, FhgfsOpsErr& error)
{
   App* app = Program::getApp();
   NodeStoreServers* mgmtNodes = app->getMgmtNodes();

   bool retVal = false;

   auto mgmtNode = mgmtNodes->referenceFirstNode();
   if(!mgmtNode)
      return false;

   RequestExceededQuotaMsg msg(idType, exType, storagePoolId);

   RequestExceededQuotaRespMsg* respMsgCast = NULL;

   const auto respMsg = MessagingTk::requestResponse(*mgmtNode, msg,
         NETMSGTYPE_RequestExceededQuotaResp);
   if (!respMsg)
      goto err_exit;

   // handle result
   respMsgCast = (RequestExceededQuotaRespMsg*)respMsg.get();

   respMsgCast->getExceededQuotaIDs()->swap(*outIDList);
   error = respMsgCast->getError();

   retVal = true;

err_exit:
   return retVal;
}

bool InternodeSyncer::downloadAllExceededQuotaLists(const StoragePoolPtrVec& storagePools)
{
   bool retVal = true;

   // note: this is fairly inefficient, but it is done only once on startup
   for (auto iter = storagePools.begin(); iter != storagePools.end(); iter++)
   {
      if (!downloadAllExceededQuotaLists(*iter))
         retVal = false;
   }

   return retVal;
}

/**
 * @return false on error
 */
bool InternodeSyncer::downloadAllExceededQuotaLists(const StoragePoolPtr storagePool)
{
   const char* logContext = "Exceeded quota sync";

   App* app = Program::getApp();
   Config* cfg = app->getConfig();

   UInt16Set targets = storagePool->getTargets();

   bool retVal = true;

   UIntList tmpExceededUIDsSize;
   UIntList tmpExceededGIDsSize;
   UIntList tmpExceededUIDsInode;
   UIntList tmpExceededGIDsInode;

   FhgfsOpsErr error;

   if (downloadExceededQuotaList(storagePool->getId(), QuotaDataType_USER, QuotaLimitType_SIZE,
      &tmpExceededUIDsSize, error) )
   {
      // update exceeded store for every target in the pool
      for (auto iter = targets.begin(); iter != targets.end(); iter++)
      {
         ExceededQuotaStorePtr exceededQuotaStore = app->getExceededQuotaStores()->get(*iter);
         exceededQuotaStore->updateExceededQuota(&tmpExceededUIDsSize, QuotaDataType_USER,
            QuotaLimitType_SIZE);
      }

      // enable or disable quota enforcement
      if (error == FhgfsOpsErr_NOTSUPP)
      {
         if (cfg->getQuotaEnableEnforcement())
         {
            LogContext(logContext).log(Log_DEBUG,
               "Quota enforcement is enabled in the configuration of this metadata server, "
                  "but not on the management daemon. "
                  "The configuration from the management daemon overrides the local setting.");
         }
         else
         {
            LogContext(logContext).log(Log_DEBUG, "Quota enforcement disabled by management daemon.");
         }

         cfg->setQuotaEnableEnforcement(false);
         return true;
      }
      else
      {
         if (!cfg->getQuotaEnableEnforcement())
         {
            LogContext(logContext).log(Log_DEBUG,
               "Quota enforcement is enabled on the management daemon, "
                  "but not in the configuration of this metadata server. "
                  "The configuration from the management daemon overrides the local setting.");
         }
         else
         {
            LogContext(logContext).log(Log_DEBUG, "Quota enforcement enabled by management daemon.");
         }

         cfg->setQuotaEnableEnforcement(true);
      }
   }
   else
   { // error
      LogContext(logContext).logErr("Unable to download exceeded file size quota for users.");
      retVal = false;
   }

   if (downloadExceededQuotaList(storagePool->getId(), QuotaDataType_GROUP, QuotaLimitType_SIZE,
      &tmpExceededGIDsSize, error))
   {
      for (auto iter = targets.begin(); iter != targets.end(); iter++)
      {
         ExceededQuotaStorePtr exceededQuotaStore = app->getExceededQuotaStores()->get(*iter);
         exceededQuotaStore->updateExceededQuota(&tmpExceededGIDsSize, QuotaDataType_GROUP,
            QuotaLimitType_SIZE);
      }
   }
   else
   { // error
      LogContext(logContext).logErr("Unable to download exceeded file size quota for groups.");
      retVal = false;
   }

   if (downloadExceededQuotaList(storagePool->getId(), QuotaDataType_USER, QuotaLimitType_INODE,
      &tmpExceededUIDsInode, error))
   {
      for (auto iter = targets.begin(); iter != targets.end(); iter++)
      {
         ExceededQuotaStorePtr exceededQuotaStore = app->getExceededQuotaStores()->get(*iter);
         exceededQuotaStore->updateExceededQuota(&tmpExceededUIDsInode, QuotaDataType_USER,
            QuotaLimitType_INODE);
      }
   }
   else
   { // error
      LogContext(logContext).logErr("Unable to download exceeded file number quota for users.");
      retVal = false;
   }

   if (downloadExceededQuotaList(storagePool->getId(), QuotaDataType_USER, QuotaLimitType_INODE,
      &tmpExceededGIDsInode, error))
   {
      for (auto iter = targets.begin(); iter != targets.end(); iter++)
      {
         ExceededQuotaStorePtr exceededQuotaStore = app->getExceededQuotaStores()->get(*iter);
         exceededQuotaStore->updateExceededQuota(&tmpExceededGIDsInode, QuotaDataType_GROUP,
            QuotaLimitType_INODE);
      }
   }
   else
   { // error
      LogContext(logContext).logErr("Unable to download exceeded file number quota for groups.");
      retVal = false;
   }

   return retVal;
}

max_stars_repo_name: congweitao/congfs

max_issues_repo_name: congweitao/congfs

max_forks_repo_name: congweitao/congfs


text:
//---------------------------------------------------------------------------//
// Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
// Copyright (c) 2020 Nikita Kaskov <nbering@nil.foundation>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#ifndef CRYPTO3_R1CS_GG_PPZKSNARK_IPP2_VERIFY_HPP
#define CRYPTO3_R1CS_GG_PPZKSNARK_IPP2_VERIFY_HPP

#include <memory>
#include <vector>
#include <tuple>

#include <boost/iterator/zip_iterator.hpp>

#include <nil/crypto3/detail/pack_numeric.hpp>

#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/sha2.hpp>

#include <nil/crypto3/zk/snark/schemes/ppzksnark/r1cs_gg_ppzksnark/verification_key.hpp>
#include <nil/crypto3/zk/snark/schemes/ppzksnark/r1cs_gg_ppzksnark/ipp2/proof.hpp>
#include <nil/crypto3/zk/snark/schemes/ppzksnark/r1cs_gg_ppzksnark/ipp2/srs.hpp>

namespace nil {
    namespace crypto3 {
        namespace zk {
            namespace snark {
                template<typename CurveType>
                struct Op {
                    typedef CurveType curve_type;

                    typedef typename curve_type::pairing::fqk_type::value_type TAB;
                    typedef typename curve_type::pairing::fqk_type::value_type UAB;
                    typedef typename curve_type::pairing::fqk_type::value_type ZAB;
                    typedef typename curve_type::pairing::fqk_type::value_type TC;
                    typedef typename curve_type::pairing::fqk_type::value_type UC;
                    typedef typename curve_type::pairing::g1_type::value_type ZC;
                };

                /// Keeps track of the variables that have been sent by the prover and must
                /// be multiplied together by the verifier. Both MIPP and TIPP are merged
                /// together.
                template<typename CurveType>
                struct gipa_tuz {
                    typedef CurveType curve_type;
                    typedef typename curve_type::scalar_field_type::value_type fr_type;

                    std::pair<typename curve_type::pairing::fqk_type::value_type, fr_type::value_type> tab;
                    std::pair<typename curve_type::pairing::fqk_type::value_type, fr_type::value_type> uab;
                    std::pair<typename curve_type::pairing::fqk_type::value_type, fr_type::value_type> zab;
                    std::pair<typename curve_type::pairing::fqk_type::value_type, fr_type::value_type> tc;
                    std::pair<typename curve_type::pairing::fqk_type::value_type, fr_type::value_type> uc;
                    std::pair<typename curve_type::pairing::g1_type, fr_type> zc;
                };

                /// gipa_verify_tipp_mipp recurse on the proof and statement and produces the final
                /// values to be checked by TIPP and MIPP verifier, namely, for TIPP for example:
                /// * T,U: the final commitment values of A and B
                /// * Z the final product between A and B.
                /// * Challenges are returned in inverse order as well to avoid
                /// repeating the operation multiple times later on.
                /// * There are T,U,Z vectors as well for the MIPP relationship. Both TIPP and
                /// MIPP share the same challenges however, enabling to re-use common operations
                /// between them, such as the KZG proof for commitment keys.
                template<typename CurveType, typename Hash = hashes::sha2<256>>
                std::tuple<gipa_tuz<CurveType>, std::vector<typename CurveType::scalar_field_type::value_type>,
                           std::vector<typename CurveType::scalar_field_type::value_type>>
                    gipa_verify_tipp_mipp(const r1cs_gg_ppzksnark_aggregate_proof<CurveType> &proof) {
                    std::vector<typename CurveType::scalar_field_type::value_type> challenges, challenges_inv;

                    typename CurveType::scalar_field_type::value_type default_transcript =
                        typename CurveType::scalar_field_type::value_type::zero();

                    // We first generate all challenges as this is the only consecutive process
                    // that can not be parallelized then we scale the commitments in a
                    // parallelized way
                    std::for_each(
                        boost::make_zip_iterator(
                            std::make_tuple(proof.tmipp.gipa.comms_ab.begin(), proof.tmipp.gipa.z_ab.begin(),
                                            proof.tmipp.gipa.comms_c.begin(), proof.tmipp.gipa.z_c.begin())),
                        boost::make_zip_iterator(
                            std::make_tuple(proof.tmipp.gipa.comms_ab.end(), proof.tmipp.gipa.z_ab.end(),
                                            proof.tmipp.gipa.comms_c.end(), proof.tmipp.gipa.z_c.end())),
                        [&](const std::tuple<const std::pair<r1cs_gg_ppzksnark_ipp2_commitment_output<CurveType>,
                                                             r1cs_gg_ppzksnark_ipp2_commitment_output<CurveType>> &,
                                             const std::pair<typename CurveType::pairing::fqk_type::value_type,
                                                             typename CurveType::pairing::fqk_type::value_type> &,
                                             const std::pair<r1cs_gg_ppzksnark_ipp2_commitment_output<CurveType>,
                                                             r1cs_gg_ppzksnark_ipp2_commitment_output<CurveType>> &,
                                             const std::pair<typename CurveType::g1_type::value_type,
                                                             typename CurveType::g1_type::value_type> &> &t) {
                            auto tab_l = std::get<0>(std::get<0>(t));
                            auto tab_r = std::get<1>(std::get<0>(t));

                            auto zab_l = std::get<0>(std::get<1>(t));
                            auto zab_r = std::get<1>(std::get<1>(t));

                            auto tc_l = std::get<0>(std::get<2>(t));
                            auto tc_r = std::get<1>(std::get<2>(t));

                            auto zc_l = std::get<0>(std::get<3>(t));
                            auto zc_r = std::get<1>(std::get<3>(t));

                            // Fiat-Shamir challenge
                            auto transcript = challenges.empty() ? *(challenges.end() - 1) : default_transcript;

                            std::size_t counter_nonce = 1;
                            std::array<std::uint8_t, sizeof(std::size_t)> counter_nonce_bytes;
                            crypto3::detail::pack<stream_endian::big_byte_big_bit>({counter_nonce},
                                                                                counter_nonce_bytes);
                            accumulator_set<Hash> acc;

                            hash<Hash>(counter_nonce_bytes, acc);
                            hash<Hash>(transcript, acc);
                            hash<Hash>(std::get<0>(tab_l), acc);
                            hash<Hash>(std::get<1>(tab_l), acc);
                            hash<Hash>(std::get<0>(tab_r), acc);
                            hash<Hash>(std::get<1>(tab_r), acc);
                            hash<Hash>(zab_l, acc);
                            hash<Hash>(zab_r, acc);
                            hash<Hash>(zc_l, acc);
                            hash<Hash>(zc_r, acc);
                            hash<Hash>(std::get<0>(tc_l), acc);
                            hash<Hash>(std::get<1>(tc_l), acc);
                            hash<Hash>(std::get<0>(tc_r), acc);
                            hash<Hash>(std::get<1>(tc_r), acc);

                            typename Hash::digest_type d = accumulators::extract::hash<Hash>(acc);
                            typename CurveType::scalar_field_type::value_type c;
                            multiprecision::import_bits(c.data, d);

                            challenges.emplace_back(c);
                            challenges_inv.emplace_back(c.inversed());
                        });

                    gipa_tuz<CurveType> final_res = {std::get<0>(proof.com_ab), std::get<1>(proof.com_ab), proof.ip_ab,
                                                     std::get<0>(proof.com_c),  std::get<1>(proof.com_c),  proof.agg_c};

                    // we first multiply each entry of the Z U and L vectors by the respective
                    // challenges independently
                    // Since at the end we want to multiple all "t" values together, we do
                    // multiply all of them in parrallel and then merge then back at the end.
                    // same for u and z.
                    std::for_each(
                        boost::make_zip_iterator(
                            std::make_tuple(proof.tmipp.gipa.comms_ab.begin(), proof.tmipp.gipa.z_ab.begin(),
                                            proof.tmipp.gipa.comms_c.begin(), proof.tmipp.gipa.z_c.begin(),
                                            challenges.begin(), challenges_inv.begin())),
                        boost::make_zip_iterator(
                            std::make_tuple(proof.tmipp.gipa.comms_ab.end(), proof.tmipp.gipa.z_ab.end(),
                                            proof.tmipp.gipa.comms_c.end(), proof.tmipp.gipa.z_c.end(),
                                            challenges.end(), challenges_inv.end())),
                        [&](const std::tuple<const std::pair<r1cs_gg_ppzksnark_ipp2_commitment_output<CurveType>,
                                                             r1cs_gg_ppzksnark_ipp2_commitment_output<CurveType>> &,
                                             const std::pair<typename CurveType::pairing::fqk_type::value_type,
                                                             typename CurveType::pairing::fqk_type::value_type> &,
                                             const std::pair<r1cs_gg_ppzksnark_ipp2_commitment_output<CurveType>,
                                                             r1cs_gg_ppzksnark_ipp2_commitment_output<CurveType>> &,
                                             const std::pair<typename CurveType::g1_type::value_type,
                                                             typename CurveType::g1_type::value_type> &,
                                             const typename CurveType::scalar_field_type::value_type &,
                                             const typename CurveType::scalar_field_type::value_type &> &t) {
                            // T and U values for right and left for AB part
                            auto tab_l = std::get<0>(std::get<0>(std::get<0>(t)));
                            auto uab_l = std::get<1>(std::get<0>(std::get<0>(t)));
                            auto tab_r = std::get<0>(std::get<1>(std::get<0>(t)));
                            auto uab_r = std::get<1>(std::get<1>(std::get<0>(t)));

                            auto zab_l = std::get<0>(std::get<1>(t));
                            auto zab_r = std::get<1>(std::get<1>(t));

                            // T and U values for right and left for C part
                            auto tc_l = std::get<0>(std::get<0>(std::get<2>(t)));
                            auto uc_l = std::get<1>(std::get<0>(std::get<2>(t)));
                            auto tc_r = std::get<0>(std::get<1>(std::get<2>(t)));
                            auto uc_r = std::get<1>(std::get<1>(std::get<2>(t)));

                            auto zc_l = std::get<0>(std::get<3>(t));
                            auto zc_r = std::get<1>(std::get<3>(t));

                            // we multiple left side by x and right side by x^-1
                            vec ![
                                Op<CurveType>::TAB(tab_l, std::get<4>(t)),
                                Op<CurveType>::tab(tab_r, c_inv_repr),
                                Op::UAB(uab_l, c_repr),
                                Op::UAB(uab_r, c_inv_repr),
                                Op::ZAB(zab_l, c_repr),
                                Op::ZAB(zab_r, c_inv_repr),
                                Op::TC::<E>(tc_l, c_repr),
                                Op::TC(tc_r, c_inv_repr),
                                Op::UC(uc_l, c_repr),
                                Op::UC(uc_r, c_inv_repr),
                                Op::ZC(zc_l, c_repr),
                                Op::ZC(zc_r, c_inv_repr),
                            ]
                        });
                }

                /// verify_tipp_mipp returns a pairing equation to check the tipp proof.  $r$ is
                /// the randomness used to produce a random linear combination of A and B and
                /// used in the MIPP part with C
                template<typename CurveType>
                PairingCheck<CurveType> verify_tipp_mipp(const r1cs_gg_ppzksnark_verifying_srs<CurveType> &v_srs,
                                                         const r1cs_gg_ppzksnark_aggregate_proof<CurveType> &proof,
                                                         const typename CurveType::scalar_field_type::value_type &r_shift) {
                    // (T,U), Z for TIPP and MIPP  and all challenges
                    std::tuple<gipa_tuz<CurveType>, std::vector<typename CurveType::scalar_field_type::value_type>,
                               std::vector<typename CurveType::scalar_field_type::value_type>>
                        gtmp = gipa_verify_tipp_mipp(proof);
                    auto &final_res = std::get<0>(gtmp);
                    auto &challenges = std::get<1>(gtmp);
                    auto &challenges_inv = std::get<2>(gtmp);

                    // we reverse the order so the KZG polynomial have them in the expected
                    // order to construct them in logn time.
                    std::reverse(challenges.begin(), challenges.end());
                    std::reverse(challenges_inv.begin(), challenges_inv.end());

                    // Verify commitment keys wellformed
                    auto fvkey = proof.tmipp.gipa.final_vkey;
                    auto fwkey = proof.tmipp.gipa.final_wkey;
                }

                template<typename CurveType, typename InputPublicInputsIterator>
                bool verify_aggregate_proof(const r1cs_gg_ppzksnark_verifying_srs<CurveType> &ip_verifier_srs,
                                            const r1cs_gg_ppzksnark_processed_verification_key<CurveType> &pvk,
                                            InputPublicInputsIterator public_inputs_first,
                                            InputPublicInputsIterator public_inputs_last,
                                            const r1cs_gg_ppzksnark_aggregate_proof<CurveType> &proof) {

                    // Random linear combination of proofs
                    std::size_t counter_nonce = 1;
                    std::array<std::uint8_t, sizeof(std::size_t)> counter_nonce_bytes;
                    crypto3::detail::pack<stream_endian::big_byte_big_bit>({counter_nonce}, counter_nonce_bytes);
                    accumulator_set<hashes::sha2<256>> acc;

                    hash<hashes::sha2<256>>(counter_nonce_bytes, acc);
                    hash<hashes::sha2<256>>(std::get<0>(proof.com_ab), acc);
                    hash<hashes::sha2<256>>(std::get<1>(proof.com_ab), acc);
                    hash<hashes::sha2<256>>(std::get<0>(proof.com_c), acc);
                    hash<hashes::sha2<256>>(std::get<1>(proof.com_c), acc);

                    typename hashes::sha2<256>::digest_type d = accumulators::extract::hash<hashes::sha2<256>>(acc);
                    typename CurveType::scalar_field_type::value_type r;
                    crypto3::detail::pack(d, r.data);
                    r = r.inversed();

                    InputPublicInputsIterator vpitr = public_inputs_first;

                    while (vpitr != public_inputs_last) {
                        BOOST_ASSERT_MSG(vpitr->size() + 1 == pvk.ic.size(), "malformed verification key!");
                        ++vpitr;
                    }

                    // 1.Check TIPA proof ab
                    // 2.Check TIPA proof c
                    auto tipa_ab =
                        verify_tipp_mipp<CurveType>(ip_verifier_srs,
                                                    proof,
                                                    r    // we give the extra r as it's not part of the proof itself
                                                         // - it is simply used on top for the groth16 aggregation
                        );
                }

                /// verify_kzg_opening_g2 takes a KZG opening, the final commitment key, SRS and
                /// any shift (in TIPP we shift the v commitment by r^-1) and returns a pairing
                /// tuple to check if the opening is correct or not.
                template<typename CurveType, typename InputScalarIterator>
                PairingCheck<CurveType> verify_kzg_opening_g2(
                    const r1cs_gg_ppzksnark_verifying_srs<CurveType> &v_srs,
                    const r1cs_gg_ppzksnark_ipp2_vkey<CurveType> &final_vkey,
                    const kzg_opening<typename CurveType::g2_type> &vkey_opening,
                    InputScalarIterator challenges_first,
                    InputScalarIterator challenges_last,
                    const typename std::iterator_traits<InputScalarIterator>::value_type &r_shift,
                    const typename std::iterator_traits<InputScalarIterator>::value_type &kzg_challenge) {
                }

                /// Similar to verify_kzg_opening_g2 but for g1.
                template<typename CurveType, typename InputScalarIterator>
                PairingCheck<CurveType> verify_kzg_opening_g1(
                    const r1cs_gg_ppzksnark_verifier_srs<CurveType> &v_srs,
                    const r1cs_gg_ppzksnark_ipp2_wkey<CurveType> &final_wkey,
                    const kzg_opening<typename CurveType::g1_type> &wkey_opening, InputScalarIterator challenges_first,
                    InputScalarIterator challenges_last, ,
                    const typename std::iterator_traits<InputScalarIterator>::value_type &r_shift,
                    const typename std::iterator_traits<InputScalarIterator>::value_type &kzg_challenge) {
                }
            }    // namespace snark
        }        // namespace zk
    }            // namespace crypto3
}    // namespace nil

#endif    // CRYPTO3_R1CS_GG_PPZKSNARK_TYPES_POLICY_HPP


text:
#include "IntrinsicGeometry.h"
#include "MeshConnectivity.h"
#include <Eigen/Dense>

IntrinsicGeometry::IntrinsicGeometry(const MeshConnectivity &mesh, const std::vector<Eigen::Matrix2d> &abars) : abars(abars)
{
    int nedges = mesh.nEdges();
    int nfaces = mesh.nFaces();

    Js.resize(2 * nfaces, 2);
    for (int i = 0; i < nfaces; i++)
    {
        Eigen::Matrix2d Jeuclid;
        Jeuclid << 0, -1,
            1, 0;
        Js.block<2, 2>(2 * i, 0) = std::sqrt(abars[i].determinant()) * abars[i].inverse() * Jeuclid;
    }

    Ts.resize(2 * nedges, 4);
    Ts.setZero();
    for (int i = 0; i < nedges; i++)
    {
        int face1 = mesh.edgeFace(i, 0);
        int face2 = mesh.edgeFace(i, 1);
        if (face1 == -1 || face2 == -1)
            continue;

        int vert1 = mesh.edgeVertex(i, 0);
        int vert2 = mesh.edgeVertex(i, 1);

        // write edge vert1->vert2 in barycentric coordinates on each face
        Eigen::Vector2d barys[3] = { {0,0}, {1,0}, {0,1} };
        Eigen::Vector2d face1e(0, 0);
        Eigen::Vector2d face2e(0, 0);
        for (int j = 0; j < 3; j++)
        {
            if (vert1 == mesh.faceVertex(face1, j))
                face1e -= barys[j];
            else if (vert2 == mesh.faceVertex(face1, j))
                face1e += barys[j];
            if (vert1 == mesh.faceVertex(face2, j))
                face2e -= barys[j];
            else if (vert2 == mesh.faceVertex(face2, j))
                face2e += barys[j];
        }

        Eigen::Vector2d face1eperp = Js.block<2, 2>(2 * face1, 0) * face1e;
        Eigen::Vector2d face2eperp = Js.block<2, 2>(2 * face2, 0) * face2e;
        Eigen::Matrix2d face1basis;
        face1basis.col(0) = face1e;
        face1basis.col(1) = face1eperp;
        Eigen::Matrix2d face2basis;
        face2basis.col(0) = face2e;
        face2basis.col(1) = face2eperp;
        Ts.block<2, 2>(2 * i, 0) = face2basis * face1basis.inverse();
        Ts.block<2, 2>(2 * i, 2) = face1basis * face2basis.inverse();
    }
}

max_stars_repo_name: csyzzkdcz/effective-garbanzo

max_issues_repo_name: csyzzkdcz/effective-garbanzo

max_forks_repo_name: csyzzkdcz/effective-garbanzo


text:
/**
 * \file MFB/include/MFB/api.hpp
 *
 * \author Tristan Vanderbruggen
 *
 */

#ifndef _MFB_API_HPP_
#define _MFB_API_HPP_

#include <set>
#include <boost/filesystem.hpp>

class SgNamespaceSymbol;
class SgFunctionSymbol;
class SgClassSymbol;
class SgEnumSymbol;
class SgVariableSymbol;
class SgMemberFunctionSymbol;
class SgTypedefSymbol;
class SgNonrealSymbol;

namespace MFB {

/*!
 * \addtogroup grp_mfb_sage_api
 * @{
*/

struct api_t {
  std::set<SgNamespaceSymbol *>      namespace_symbols;
  std::set<SgFunctionSymbol *>       function_symbols;
  std::set<SgClassSymbol *>          class_symbols;
  std::set<SgEnumSymbol *>           enum_symbols;
  std::set<SgVariableSymbol *>       variable_symbols;
  std::set<SgMemberFunctionSymbol *> member_function_symbols;
  std::set<SgTypedefSymbol *>        typedef_symbols;
  std::set<SgNonrealSymbol *>        nonreal_symbols;
};

void dump_api(const api_t * api);

void merge_api(api_t * base_api, const api_t * api);

/** @} */

}

#endif /* _MFB_API_HPP_ */

max_stars_repo_name: edmcman/rose

max_issues_repo_name: WildeGeist/rose

max_forks_repo_name: WildeGeist/rose


text:
// Andrew Naplavkov

#ifndef BRIG_GDAL_DETAIL_ROWSET_HPP
#define BRIG_GDAL_DETAIL_ROWSET_HPP

#include <algorithm>
#include <boost/geometry/geometry.hpp>
#include <brig/boost/as_binary.hpp>
#include <brig/boost/envelope.hpp>
#include <brig/boost/geom_from_wkb.hpp>
#include <brig/boost/geometry.hpp>
#include <brig/detail/get_columns.hpp>
#include <brig/gdal/detail/dataset_allocator.hpp>
#include <brig/gdal/detail/lib.hpp>
#include <brig/gdal/detail/transform.hpp>
#include <brig/global.hpp>
#include <brig/rowset.hpp>
#include <brig/string_cast.hpp>
#include <brig/table_def.hpp>
#include <cstdint>
#include <memory>
#include <stdexcept>
#include <vector>

namespace brig { namespace gdal { namespace detail {

class rowset : public brig::rowset {
  dataset m_ds;
  bool m_done;
  std::vector<bool> m_cols;
  transform m_tr;
  int m_width, m_height;
public:
  rowset(dataset_allocator allocator, const table_def& tbl);
  std::vector<std::string> columns() override;
  bool fetch(std::vector<variant>& row) override;
}; // rowset

inline rowset::rowset(dataset_allocator allocator, const table_def& tbl) : m_ds(allocator.allocate()), m_done(false)
{
  using namespace std;
  using namespace brig::boost;

  vector<column_def> col_defs = tbl.query_columns.empty()? tbl.columns: brig::detail::get_columns(tbl.columns, tbl.query_columns);
  for (const auto& col_def: col_defs)
  {
    if (col_def.name.compare(ColumnNamePng) == 0)
      m_cols.push_back(true);
    else if (col_def.name.compare(ColumnNameWkb) == 0)
      m_cols.push_back(false);
    else
      throw runtime_error("GDAL error");
  }
  if (tbl.query_rows == 0)
    m_done = true;

  lib::check(lib::singleton().p_GDALGetGeoTransform(m_ds, m_tr.coef));
  m_width = lib::singleton().p_GDALGetRasterXSize(m_ds);
  m_height = lib::singleton().p_GDALGetRasterYSize(m_ds);

  auto geom_col(tbl[ColumnNameWkb]);
  if ( typeid(blob_t) == geom_col->query_value.type()
    && !::boost::geometry::intersects
      ( box(point(0, 0), point(m_width, m_height))
      , envelope(m_tr.proj_to_pixel(envelope(geom_from_wkb(::boost::get<blob_t>(geom_col->query_value)))))
      )
    )
    m_done = true;
}

inline std::vector<std::string> rowset::columns()
{
  std::vector<std::string> cols;
  for (size_t i(0); i < m_cols.size(); ++i)
  {
    if (m_cols[i]) cols.push_back(ColumnNamePng);
    else cols.push_back(ColumnNameWkb);
  }
  return cols;
}

inline bool rowset::fetch(std::vector<variant>& row)
{
  using namespace std;
  using namespace brig::boost;
  using namespace brig::detail;

  if (m_done) return false;
  m_done = true;

  const size_t count(m_cols.size());
  row.resize(count);
  for (size_t i(0); i < count; ++i)
  {
    if (m_cols[i])
    {
      auto drv(lib::singleton().p_GDALGetDriverByName("PNG"));
      if (!drv) throw runtime_error("GDAL error");
      auto file("/vsimem/" + string_cast<char>(size_t(this)) + ".png");
      {
        auto del = [](void* ptr) { lib::singleton().p_GDALClose(GDALDatasetH(ptr)); };
        unique_ptr<void, decltype(del)> ds(lib::singleton().p_GDALCreateCopy(drv, file.c_str(), m_ds, false, 0, 0, 0), del);
        if (!ds.get()) throw runtime_error("GDAL error");
      }
      {
        vsi_l_offset len(0);
        auto del = [](void* ptr) { lib::singleton().p_VSIFree(ptr); };
        unique_ptr<void, decltype(del)> buf(lib::singleton().p_VSIGetMemFileBuffer(file.c_str(), &len, true), del);
        row[i] = blob_t();
        blob_t& blob = ::boost::get<blob_t>(row[i]);
        const uint8_t* ptr(static_cast<const uint8_t*>(buf.get()));
        blob.assign(ptr, ptr + size_t(len));
      }
    }
    else
      row[i] = as_binary(geometry(m_tr.pixel_to_proj(box(point(0, 0), point(m_width, m_height)))));
  }
  return true;
} // rowset::

} } } // brig::gdal::detail

#endif // BRIG_GDAL_DETAIL_ROWSET_HPP

max_stars_repo_name: isadchenko/brig

max_issues_repo_name: isadchenko/brig

max_forks_repo_name: isadchenko/brig


text:
/* Copyright (C) 2014 InfiniDB, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; version 2 of
   the License.

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

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

/*******************************************************************************
* $Id$
*
*******************************************************************************/

/*
 * Observer.cpp
 *
 *  Created on: Oct 5, 2011
 *      Author: bpaul@calpont.com
 */

#include <boost/thread/mutex.hpp>

#include "we_observer.h"

namespace WriteEngine
{

//-----------------------------------------------------------------------------

//	ctor
Observer::Observer()
{

}

//-----------------------------------------------------------------------------
//dtor
Observer::~Observer()
{
    //
}

//-----------------------------------------------------------------------------
//ctor
Subject::Subject()
{

}
//-----------------------------------------------------------------------------
//dtor
Subject::~Subject()
{

}

//-----------------------------------------------------------------------------

void Subject::attach(Observer* Obs)
{
    boost::mutex::scoped_lock aLstLock;
    fObs.push_back(Obs);
}

//-----------------------------------------------------------------------------

void Subject::detach(Observer* Obs)
{
    boost::mutex::scoped_lock aLstLock;
    Observers::iterator aIt = fObs.begin();

    while (aIt != fObs.end())
    {
        if ((*aIt) == Obs)
        {
            fObs.erase(aIt);
            break;
        }
    }
}

//-----------------------------------------------------------------------------

void Subject::notify()
{
    boost::mutex::scoped_lock aLstLock;
    Observers::iterator aIt = fObs.begin();

    while (aIt != fObs.end())
    {
        (*aIt)->update(this);
    }
}

//-----------------------------------------------------------------------------

}// namespace WriteEngine

max_stars_repo_name: zettadb/zettalib

max_issues_repo_name: zettadb/zettalib

max_forks_repo_name: zettadb/zettalib


text:
#pragma once

#include <string>
#include <functional>
#include <memory>
#include <unordered_map>
#include <thread>
#include <atomic>

#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/asio/strand.hpp>
#include <boost/lockfree/queue.hpp>

#ifdef DELETE
#undef DELETE
#endif

namespace asio = boost::asio;
namespace beast = boost::beast;

class Http
{
public:
	struct Response
	{
		unsigned int status;
		std::string reason;
		std::string body;
		std::string additional_data;
	};
	using ResponseCb_t = std::function<void(Response)>;

public:
	Http(std::string token);
	~Http();

private:
	using Streambuf_t = beast::flat_buffer;
	using SharedStreambuf_t = std::shared_ptr<Streambuf_t>;
	using Response_t = beast::http::response<beast::http::dynamic_body>;
	using SharedResponse_t = std::shared_ptr<Response_t>;
	using Request_t = beast::http::request<beast::http::string_body>;
	using SharedRequest_t = std::shared_ptr<Request_t>;
	using ResponseCallback_t = std::function<void(Streambuf_t&, Response_t&)>;
	using TimePoint_t = std::chrono::steady_clock::time_point;

	struct QueueEntry
	{
		QueueEntry(SharedRequest_t req, ResponseCallback_t &&cb) :
			Request(req),
			Callback(cb)
		{ }
		SharedRequest_t Request;
		ResponseCallback_t Callback;
	};

private:
	asio::io_context m_IoService;
	asio::ssl::context m_SslContext;
	using SslStream_t = beast::ssl_stream<beast::tcp_stream>;
	std::unique_ptr<SslStream_t> m_SslStream;

	std::string m_Token;

	boost::lockfree::queue<
		QueueEntry*,
		boost::lockfree::fixed_sized<true>,
		boost::lockfree::capacity<8192>
	> m_Queue;
	std::atomic<bool> m_NetworkThreadRunning;
	std::thread m_NetworkThread;

private: // functions
	void NetworkThreadFunc();

	bool Connect();
	void Disconnect();
	bool ReconnectRetry();

	SharedRequest_t PrepareRequest(beast::http::verb const method,
		std::string const &url, std::string const &content);
	void SendRequest(beast::http::verb const method, std::string const &url,
		std::string const &content, ResponseCallback_t &&callback);
	ResponseCallback_t CreateResponseCallback(ResponseCb_t &&callback);

public: // functions
	void Get(std::string const &url, ResponseCb_t &&callback);
	void Post(std::string const &url, std::string const &content,
		ResponseCb_t &&callback = nullptr);
	void Delete(std::string const &url);
	void Put(std::string const &url);
	void Patch(std::string const &url, std::string const &content);
};


text:
// A numerically integrated implementation of the circuit described in
// "Rolling Your Own Circuit Simulator with Eigen and Boost.ODEInt"
// Author: Jeff Trull <edaskel@att.net>

/*
Copyright (c) 2014 Jeffrey E. Trull

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include <iostream>
#include <array>
#include <boost/numeric/odeint.hpp>

typedef std::array<double, 2> state_t;   // 0 = V_out, 1 = I_L

struct circuit {
    circuit(double r, double l, double c) : r_(r), l_(l), c_(c) {}

    void operator()(state_t const& x, state_t& dxdt, double t) {
        // calculate state derivatives from current state
        dxdt[0] = ((1 - x[0]) / r_ - x[1]) / c_;  // KCL at V_out node
        dxdt[1] = x[0] / l_;                      // from V_out = L * dI_L/dt
    }
private:
    double r_, l_, c_;
};

int main() {
    using namespace boost::numeric::odeint;
    circuit ckt(100.0, 20e-6, 20e-9);
    state_t x{0.0, 0.0};                    // initial conditions
    integrate( ckt, x, 0.0, 10e-6, 0.1e-6,  // time range and increment
               [](state_t const& x, double t) {
                   std::cout << t << " " << x[0] << std::endl;
               });
}

max_stars_repo_name: jefftrull/CktSimLightningTalk

max_issues_repo_name: jefftrull/CktSimLightningTalk

max_forks_repo_name: jefftrull/CktSimLightningTalk