text:
/*

Copyright (c) 2005-2022, University of Oxford.
All rights reserved.

University of Oxford means the Chancellor, Masters and Scholars of the
University of Oxford, having an administrative office at Wellington
Square, Oxford OX1 2JD, UK.

This file is part of Chaste.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
 * Neither the name of the University of Oxford nor the names of its
   contributors may be used to endorse or promote products derived from this
   software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TIMESTEPPER_HPP_
#define TIMESTEPPER_HPP_

#include <vector>
#include <climits>
#include <boost/serialization/vector.hpp>

#include "ChasteSerialization.hpp"
#include "Exception.hpp"

/**
 * A helper class that provides a robust way to deal with time loops.
 *
 * An incremented integer counter is used to calculate the current time
 * and ensure that the correct end time.
 */
class TimeStepper
{
    friend class TestTimeStepper;
private:
    /*
     * Private default constructor for archiving
     */
     TimeStepper(){};

public:

    /**
     * Create a new time stepper over some simulation interval.
     * Time units are not specified, but all parameters should have consistent units.
     *
     * @param startTime  the start of the interval
     * @param endTime  the end of the interval
     * @param dt  the time step to use.
     * @param enforceConstantTimeStep If this is true the stepper estimates whether non-constant
     *  timesteps will be used and quits if so.
     * @param additionalTimes If the timestepper needs to stop at certain additional times, they can be passed in in this std::vector.
     *  Defaults to empty. These times must be in ascending order.
     *  DEPRECATION: Note that these additional times are checked in order to ensure that the stepper will
     *  stop at these times anyway.  (For example we want to check that new events such as electrodes switching on will be detected
     *  in a regular time loop.) New additional times are not added but instead throw an exception.
     */
    TimeStepper(double startTime, double endTime, double dt, bool enforceConstantTimeStep=false, std::vector<double> additionalTimes=std::vector<double> ());

    /**
     * Step forward one step in time and update member variables.
     *
     * Note that this should be used in conjuction with (not) IsTimeAtEnd because
     * increment past the end of a simulation will throw an exception
     */
    void AdvanceOneTimeStep();

    /**
     * @return Get the time.
     */
    double GetTime() const;

    /**
     * @return Get the value time will take at the next step.
     */
    double GetNextTime() const;

    /**
     * @return Get the size of the next time step which will be taken.
     *
     * Note that this is often reported as the ideal timestep.
     *
     * The actual time step is mNextTime - mTime which could be evaluated as
     *  GetNextTime() - GetTime() = mNextTime - mTime
     *  ~= mStart + (mTotalTimeStepsTaken  + 1)*mDt - mTime
     *  ~= mStart + (mTotalTimeStepsTaken  + 1)*mDt - (mStart + mTotalTimeStepsTaken*mDt)
     *  ~= mDt
     *  This wouldn't evaluate to mDt in general but to within 2*mEpsilon <= 2*DBL_EPSILON*mEnd*mDt
     *  When mEnd and/or mStart are a long way from zero then the value reported
     *   mNextTime - mTime
     *  will differ from mDt, even when the actual step is mDt
     */
    double GetNextTimeStep();

    /**
     * @return Get the size of the ideal time step (as set in the constructor.
     * Note when a fixed time step is used GetNextTimeStep() ==  GetIdealTimeStep()
     * until the end of the simulation when GetNextTimeStep() == 0.0
     */
    double GetIdealTimeStep();

    /**
     * @return True when GetTime == endTime.
     */
    bool IsTimeAtEnd() const;

    /**
     * @return Estimate number of time steps remaining, which may be an overestimate.
     * Used to reserve memory for writing intermediate solutions.
     */
    unsigned EstimateTimeSteps() const;

    /**
     * @return The number of times AdvanceOneTimeStep() has been called SINCE
     * the last time ResetTimeStep() was called.
     */
    unsigned GetTotalTimeStepsTaken() const;

    /**
     * Set the time step to use for adaptive time integration. Note that
     * this also resets mStart to be the current time and zeroes
     * mTotalTimeStepsTaken.
     *
     * @param dt  is the new time-step
     */
    void ResetTimeStep(double dt);

private:

    /** The start time. */
    double mStart;

    /** The end time. */
    double mEnd;

    /** The size of time step. */
    double mDt;

    /** The total number of time steps taken. */
    unsigned mTotalTimeStepsTaken;

    /** DEPRECATED: The number of times one of the 'additional times' has been passed. */
    unsigned mAdditionalTimesReachedDeprecated;

    /** The current time. */
    double mTime;

    /** What the time will be after the next time step. */
    double mNextTime;

    /** An architecture-dependent scaling factor.  This is so that we can compare
     * relative to the end time when mEnd is large.
     * mEpsilon = DBL_EPSILON when mEnd is small
     *          = mEnd*DBL_EPSILON when mEnd is large
     */
    double mEpsilon;

    /** @return Compute what the time will be at the next time step. */
    double CalculateNextTime();

    /** DEPRECATED Vector to store the additional times the stepper must stop at. */
    std::vector<double> mAdditionalTimesDeprecated;

        /** Needed for serialization. */
    friend class boost::serialization::access;

    /**
     *
     * @param archive the archive
     * @param version the current version of this class
     */
    template<class Archive>
    void serialize(Archive & archive, const unsigned int version)
    {
        archive & mStart;
        archive & mEnd;
        archive & mDt;
        archive & mTotalTimeStepsTaken;
        archive & mTime;
        archive & mNextTime;
        archive & mEpsilon;
        archive & mAdditionalTimesReachedDeprecated;
        archive & mAdditionalTimesDeprecated;
    }
};

#include "SerializationExportWrapper.hpp"
// Declare identifier for the serializer
CHASTE_CLASS_EXPORT(TimeStepper)

#endif /*TIMESTEPPER_HPP_*/

ext: hpp

max_stars_repo_name: stu-l/Chaste

max_issues_repo_name: stu-l/Chaste

max_forks_repo_name: stu-l/Chaste


text:
// Copyright 2010 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. 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)

#include <vector>
#include <iostream>

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/euml/euml.hpp>

using namespace std;
using namespace boost::msm::front::euml;
namespace msm = boost::msm;

// how long the timer will ring when countdown elapsed.
#define RINGING_TIME 5

namespace  // Concrete FSM implementation
{
    // events
    BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_timer)
    BOOST_MSM_EUML_ATTRIBUTES((attributes_ << m_timer ), start_timer_attr)
    BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(start_timer,start_timer_attr)

    BOOST_MSM_EUML_EVENT(stop_timer)

    BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_tick)
    BOOST_MSM_EUML_ATTRIBUTES((attributes_ << m_tick ), tick_attr)
    BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(tick,tick_attr)

    BOOST_MSM_EUML_EVENT(start_ringing)

    // Concrete FSM implementation

    // The list of FSM states
    BOOST_MSM_EUML_ACTION(Stopped_Entry)
    {
        template <class Event,class FSM,class STATE>
        void operator()(Event const&,FSM&,STATE& )
        {
            std::cout << "entering: Stopped" << std::endl;
        }
    };
    BOOST_MSM_EUML_STATE(( Stopped_Entry ),Stopped)

    BOOST_MSM_EUML_ACTION(Started_Entry)
    {
        template <class Event,class FSM,class STATE>
        void operator()(Event const&,FSM&,STATE& )
        {
            std::cout << "entering: Started" << std::endl;
        }
    };

    BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_counter)
    BOOST_MSM_EUML_STATE((  Started_Entry,
                            no_action,
                            attributes_ << m_counter
                  ),
                  Started)

    BOOST_MSM_EUML_ACTION(Ringing_Entry)
    {
        template <class Event,class FSM,class STATE>
        void operator()(Event const&,FSM&,STATE& )
        {
            std::cout << "entering: Ringing" << std::endl;
        }
    };
    BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_ringing_cpt)
    BOOST_MSM_EUML_STATE((  Ringing_Entry,
                            no_action,
                            attributes_ << m_ringing_cpt
                  ),
                  Ringing)

    // external function
    void do_ring(int ringing_time) {std::cout << "ringing " << ringing_time << " s" << std::endl;}
    // create functor and eUML function
    BOOST_MSM_EUML_FUNCTION(Ring_ , do_ring , ring_ , void , void )

    // replaces the old transition table
    BOOST_MSM_EUML_TRANSITION_TABLE((
        //  +------------------------------------------------------------------------------+
          // When we start the countdown, the countdown value is not hardcoded but contained in the start_timer event.
          // We copy this value into Started
          Started     == Stopped + start_timer /(target_(m_counter)= event_(m_timer))         ,
          Stopped     == Started + stop_timer                                                 ,
          // internal transition
          Started + tick
                    // we here use the message queue to move to Started when the countdown is finished
                    // to do this we put start_ringing into the message queue
                    / if_then_( (source_(m_counter) -= event_(m_tick) ) <= Int_<0>(),
                                 process_(start_ringing) )                                        ,
          // when we start ringing, we give to the state its hard-coded ringing time.
          Ringing     == Started + start_ringing
                           / (target_(m_ringing_cpt) = Int_<RINGING_TIME>(),
                              // call the external do_ring function
                              ring_(Int_<RINGING_TIME>()))                                          ,
          // to change a bit, we now do not use the message queue but a transition conflict to solve the same problem.
          // When tick is fired, we have an internal transition Ringing -> Ringing, as long as Counter > 0
          Ringing + tick [ source_(m_ringing_cpt) - event_(m_tick) > Int_<0>() ]
                             /(target_(m_ringing_cpt) -= event_(m_tick) )                           ,
          // And we move to Stopped when the counter is 0
          Stopped     == Ringing + tick[source_(m_ringing_cpt)-event_(m_tick) <= Int_<0>()]   ,
          // we let the user manually stop the ringing by pressing any button
          Stopped     == Ringing + stop_timer                                                 ,
          Stopped     == Ringing + start_timer
          //  +------------------------------------------------------------------------------+
          ),transition_table)

    // create a state machine "on the fly"
    BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
                                        init_ << Stopped // Init State
                                        ),
                                      SimpleTimer_) //fsm name

    // choice of back-end
    typedef msm::back::state_machine<SimpleTimer_> SimpleTimer;

    //
    // Testing utilities.
    //
    static char const* const state_names[] = { "Stopped", "Started","Ringing" };
    void pstate(SimpleTimer const& p)
    {
        std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
    }

    void test()
    {
        SimpleTimer p;
        // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
        p.start();

        p.process_event(start_timer(5));pstate(p); //timer set to 5 ticks
        p.process_event(tick(2));pstate(p);
        p.process_event(tick(1));pstate(p);
        p.process_event(tick(1));pstate(p);
        p.process_event(tick(1));pstate(p);
        // we are now ringing, let it ring a bit
        p.process_event(tick(2));pstate(p);
        p.process_event(tick(1));pstate(p);
        p.process_event(tick(1));pstate(p);
        p.process_event(tick(1));pstate(p);
    }
}

int main()
{
    test();
    return 0;
}

ext: cpp

max_stars_repo_name: zyiacas/boost-doc-zh

max_issues_repo_name: sdfict/boost-doc-zh

max_forks_repo_name: sdfict/boost-doc-zh


text:
/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */
#include "BrokerReplicator.h"
#include "HaBroker.h"
#include "QueueReplicator.h"
#include "qpid/broker/Broker.h"
#include "qpid/broker/amqp_0_10/Connection.h"
#include "qpid/broker/Queue.h"
#include "qpid/broker/QueueSettings.h"
#include "qpid/broker/Link.h"
#include "qpid/broker/amqp_0_10/MessageTransfer.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/framing/FieldValue.h"
#include "qpid/log/Statement.h"
#include "qpid/amqp_0_10/Codecs.h"
#include "qpid/broker/SessionHandler.h"
#include "qpid/framing/reply_exceptions.h"
#include "qpid/framing/MessageTransferBody.h"
#include "qpid/framing/reply_exceptions.h"
#include "qmf/org/apache/qpid/broker/EventBind.h"
#include "qmf/org/apache/qpid/broker/EventUnbind.h"
#include "qmf/org/apache/qpid/broker/EventExchangeDeclare.h"
#include "qmf/org/apache/qpid/broker/EventExchangeDelete.h"
#include "qmf/org/apache/qpid/broker/EventQueueDeclare.h"
#include "qmf/org/apache/qpid/broker/EventQueueDelete.h"
#include "qmf/org/apache/qpid/broker/EventSubscribe.h"
#include "qmf/org/apache/qpid/ha/EventMembersUpdate.h"
#include <boost/bind.hpp>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <assert.h>

namespace qpid {
namespace ha {

using qmf::org::apache::qpid::broker::EventBind;
using qmf::org::apache::qpid::broker::EventUnbind;
using qmf::org::apache::qpid::broker::EventExchangeDeclare;
using qmf::org::apache::qpid::broker::EventExchangeDelete;
using qmf::org::apache::qpid::broker::EventQueueDeclare;
using qmf::org::apache::qpid::broker::EventQueueDelete;
using qmf::org::apache::qpid::broker::EventSubscribe;
using qmf::org::apache::qpid::ha::EventMembersUpdate;
using qpid::broker::amqp_0_10::MessageTransfer;
using namespace framing;
using namespace std;
using std::ostream;
using types::Variant;
using namespace broker;

namespace {

const string QPID_CONFIGURATION_REPLICATOR("qpid.broker-replicator");
const string CLASS_NAME("_class_name");
const string EVENT("_event");
const string OBJECT_NAME("_object_name");
const string PACKAGE_NAME("_package_name");
const string QUERY_RESPONSE("_query_response");
const string VALUES("_values");
const string SCHEMA_ID("_schema_id");
const string WHAT("_what");

const string ALTEX("altEx");
const string ALTEXCHANGE("altExchange");
const string ARGS("args");
const string ARGUMENTS("arguments");
const string AUTODEL("autoDel");
const string AUTODELETE("autoDelete");
const string BIND("bind");
const string BINDING("binding");
const string BINDING_KEY("bindingKey");
const string CREATED("created");
const string DISP("disp");
const string DEST("dest");
const string DURABLE("durable");
const string EXCHANGE("exchange");
const string EXCL("excl");
const string EXCLUSIVE("exclusive");
const string EXNAME("exName");
const string EXTYPE("exType");
const string HA_BROKER("habroker");
const string KEY("key");
const string NAME("name");
const string PARTIAL("partial");
const string QNAME("qName");
const string QUEUE("queue");
const string TYPE("type");
const string UNBIND("unbind");
const string CONSUMER_COUNT("consumerCount");

const string AGENT_EVENT_BROKER("agent.ind.event.org_apache_qpid_broker.#");
const string AGENT_EVENT_HA("agent.ind.event.org_apache_qpid_ha.#");
const string QMF2("qmf2");
const string QMF_CONTENT("qmf.content");
const string QMF_DEFAULT_TOPIC("qmf.default.topic");
const string QMF_OPCODE("qmf.opcode");

const string OBJECT("OBJECT");
const string ORG_APACHE_QPID_BROKER("org.apache.qpid.broker");
const string ORG_APACHE_QPID_HA("org.apache.qpid.ha");
const string QMF_DEFAULT_DIRECT("qmf.default.direct");
const string _QUERY_REQUEST("_query_request");
const string BROKER("broker");
const string MEMBERS("members");
const string AUTO_DELETE_TIMEOUT("qpid.auto_delete_timeout");

const string COLON(":");

void sendQuery(const string& packageName, const string& className, const string& queueName,
               SessionHandler& sessionHandler)
{
    Variant::Map request;
    request[WHAT] = OBJECT;
    Variant::Map schema;
    schema[CLASS_NAME] = className;
    schema[PACKAGE_NAME] = packageName;
    request[SCHEMA_ID] = schema;

    AMQFrame method((MessageTransferBody(ProtocolVersion(), QMF_DEFAULT_DIRECT, 0, 0)));
    method.setBof(true);
    method.setEof(false);
    method.setBos(true);
    method.setEos(true);
    AMQHeaderBody headerBody;
    MessageProperties* props = headerBody.get<MessageProperties>(true);
    props->setReplyTo(qpid::framing::ReplyTo("", queueName));
    props->setAppId(QMF2);
    props->getApplicationHeaders().setString(QMF_OPCODE, _QUERY_REQUEST);
    headerBody.get<qpid::framing::DeliveryProperties>(true)->setRoutingKey(BROKER);
    headerBody.get<qpid::framing::MessageProperties>(true)->setCorrelationId(className);
    AMQFrame header(headerBody);
    header.setBof(false);
    header.setEof(false);
    header.setBos(true);
    header.setEos(true);
    AMQContentBody data;
    qpid::amqp_0_10::MapCodec::encode(request, data.getData());
    AMQFrame content(data);
    content.setBof(false);
    content.setEof(true);
    content.setBos(true);
    content.setEos(true);
    sessionHandler.out->handle(method);
    sessionHandler.out->handle(header);
    sessionHandler.out->handle(content);
}

// Like Variant::asMap but treat void value as an empty map.
Variant::Map asMapVoid(const Variant& value) {
    if (!value.isVoid()) return value.asMap();
    else return Variant::Map();
}
} // namespace

// Report errors on the broker replication session.
class BrokerReplicator::ErrorListener : public broker::SessionHandler::ErrorListener {
  public:
    ErrorListener(const LogPrefix& lp) : logPrefix(lp) {}

    void connectionException(framing::connection::CloseCode code, const std::string& msg) {
        QPID_LOG(error, logPrefix << framing::createConnectionException(code, msg).what());
    }
    void channelException(framing::session::DetachCode code, const std::string& msg) {
        QPID_LOG(error, logPrefix << framing::createChannelException(code, msg).what());
    }
    void executionException(framing::execution::ErrorCode code, const std::string& msg) {
        QPID_LOG(error, logPrefix << framing::createSessionException(code, msg).what());
    }
    void incomingExecutionException(framing::execution::ErrorCode code, const std::string& msg) {
        QPID_LOG(error, logPrefix << "Incoming " << framing::createSessionException(code, msg).what());
    }
    void detach() {}

  private:
    const LogPrefix& logPrefix;
};

/** Keep track of queues or exchanges during the update process to solve 2
 * problems.
 *
 * 1. Once all responses are processed, remove any queues/exchanges
 * that were not mentioned as they no longer exist on the primary.
 *
 * 2. During the update if we see an event for an object we should
 * ignore any subsequent responses for that object as they are out
 * of date.
 */
class BrokerReplicator::UpdateTracker {
  public:
    typedef std::set<std::string> Names;
    typedef boost::function<void (const std::string&)> CleanFn;

    UpdateTracker(const std::string& type_, // "queue" or "exchange"
                  CleanFn f,
                  const LogPrefix& lp)
        : type(type_), cleanFn(f), logPrefix(lp) {}

    /** Clean up remaining initial queues. */
    void done() {
        for_each(initial.begin(), initial.end(),
                 boost::bind(&UpdateTracker::clean, this, _1));
    }

    /** Add an exchange name */
    void addExchange(Exchange::shared_ptr ex)  { initial.insert(ex->getName()); }

    /** Add a queue name. */
    void addQueue(Queue::shared_ptr q) { initial.insert(q->getName()); }

    /** Received an event for name */
    void event(const std::string& name) {
        initial.erase(name); // no longer a candidate for deleting
        events.insert(name); // we have seen an event for this name
    }

    /** Received a response for name.
     *@return true if this response should be processed, false if we have
     *already seen an event for this object.
     */
    bool response(const std::string& name) {
        initial.erase(name); // no longer a candidate for deleting
        return events.find(name) == events.end(); // true if no event seen yet.
    }

  private:
    void clean(const std::string& name) {
        QPID_LOG(debug, logPrefix << "Deleted " << type << " " << name <<
                 ": no longer exists on primary");
        try { cleanFn(name); }
        catch (const framing::NotFoundException&) {}
    }

    std::string type;
    Names initial, events;
    CleanFn cleanFn;
    const LogPrefix& logPrefix;
};

namespace {
template <class EventType> std::string key() {
    pair<string,string> name = EventType::getFullName();
    return name.first + COLON + name.second;
}
}

boost::shared_ptr<BrokerReplicator> BrokerReplicator::create(
    HaBroker& hb, const boost::shared_ptr<broker::Link>& l)
{
    boost::shared_ptr<BrokerReplicator> br(new BrokerReplicator(hb, l));
    br->initialize();
    return br;
}

BrokerReplicator::BrokerReplicator(HaBroker& hb, const boost::shared_ptr<Link>& l)
    : Exchange(QPID_CONFIGURATION_REPLICATOR),
      logPrefix(hb.logPrefix), replicationTest(NONE),
      haBroker(hb), broker(hb.getBroker()),
      exchanges(broker.getExchanges()), queues(broker.getQueues()),
      link(l),
      initialized(false),
      alternates(hb.getBroker().getExchanges()),
      connect(0)
{
    framing::FieldTable args = getArgs();
    args.setString(QPID_REPLICATE, printable(NONE).str());
    setArgs(args);

    dispatch[key<EventQueueDeclare>()] = &BrokerReplicator::doEventQueueDeclare;
    dispatch[key<EventQueueDelete>()] = &BrokerReplicator::doEventQueueDelete;
    dispatch[key<EventExchangeDeclare>()] = &BrokerReplicator::doEventExchangeDeclare;
    dispatch[key<EventExchangeDelete>()] = &BrokerReplicator::doEventExchangeDelete;
    dispatch[key<EventBind>()] = &BrokerReplicator::doEventBind;
    dispatch[key<EventUnbind>()] = &BrokerReplicator::doEventUnbind;
    dispatch[key<EventMembersUpdate>()] = &BrokerReplicator::doEventMembersUpdate;
    dispatch[key<EventSubscribe>()] = &BrokerReplicator::doEventSubscribe;
}

void BrokerReplicator::initialize() {
    // Can't do this in the constructor because we need a shared_ptr to this.
    types::Uuid uuid(true);
    const std::string name(QPID_CONFIGURATION_REPLICATOR + ".bridge." + uuid.str());
    std::pair<Bridge::shared_ptr, bool> result = broker.getLinks().declare(
        name,               // name for bridge
        *link,              // parent
        false,              // durable
        QPID_CONFIGURATION_REPLICATOR, // src
        QPID_CONFIGURATION_REPLICATOR, // dest
        "",                 // key
        false,              // isQueue
        false,              // isLocal
        "",                 // id/tag
        "",                 // excludes
        false,              // dynamic
        0,                  // sync?
        LinkRegistry::INFINITE_CREDIT,
        // shared_ptr keeps this in memory until outstanding connected
        // calls are run.
        boost::bind(&BrokerReplicator::connected, shared_from_this(), _1, _2)
    );
    assert(result.second);
    result.first->setErrorListener(boost::shared_ptr<ErrorListener>(new ErrorListener(logPrefix)));
    broker.getConnectionObservers().add(shared_from_this());
}

BrokerReplicator::~BrokerReplicator() {}

namespace {
struct QueueReplicators : public  std::deque<boost::shared_ptr<QueueReplicator> > {
    QueueReplicators(const ExchangeRegistry& er) { addAll(er); }

    /** Add the exchange if it is a QueueReplicator. */
    void add(const boost::shared_ptr<Exchange>& ex) {
        boost::shared_ptr<QueueReplicator> qr =
            boost::dynamic_pointer_cast<QueueReplicator>(ex);
        if (qr) push_back(qr);
    }
    /** Add all QueueReplicator in the ExchangeRegistry. */
    void addAll(const ExchangeRegistry& er) {
        // Make copy of exchanges so we can work outside the registry lock.
        er.eachExchange(boost::bind(&QueueReplicators::add, this, _1));
    }
};
} // namespace

void BrokerReplicator::shutdown() {
    // NOTE: this is called in a QMF dispatch thread, not the Link's connection
    // thread.  It's OK to be unlocked because it doesn't use any mutable state,
    // it only calls thread safe functions objects belonging to the Broker.

    // Unregister with broker objects:
    broker.getConnectionObservers().remove(shared_from_this());
    broker.getExchanges().destroy(getName());
}

// This is called in the connection IO thread when the bridge is started.
void BrokerReplicator::connected(Bridge& bridge, SessionHandler& sessionHandler) {
    // Use the credentials of the outgoing Link connection for creating queues,
    // exchanges etc. We know link->getConnection() is non-zero because we are
    // being called in the connections thread context.
    //
    connect = link->getConnection();
    assert(connect);
    userId = link->getConnection()->getUserId();
    remoteHost = link->getConnection()->getMgmtId();

    link->getRemoteAddress(primary);
    string queueName = bridge.getQueueName();

    QPID_LOG(info, logPrefix << (initialized ? "Failing over" : "Connecting")
             << " to primary " << primary);
    initialized = true;

    exchangeTracker.reset(
        new UpdateTracker("exchange",
                          boost::bind(&BrokerReplicator::deleteExchange, this, _1),
                          logPrefix));
    exchanges.eachExchange(boost::bind(&BrokerReplicator::existingExchange, this, _1));

    queueTracker.reset(
        new UpdateTracker("queue",
                          boost::bind(&BrokerReplicator::deleteQueue, this, _1, true),
                          logPrefix));
    queues.eachQueue(boost::bind(&BrokerReplicator::existingQueue, this, _1));

    framing::AMQP_ServerProxy peer(sessionHandler.out);
    const qmf::org::apache::qpid::broker::ArgsLinkBridge& args(bridge.getArgs());

    //declare and bind an event queue
    FieldTable declareArgs;
    declareArgs.setString(QPID_REPLICATE, printable(NONE).str());
    peer.getQueue().declare(queueName, "", false, false, true, true, declareArgs);
    peer.getExchange().bind(queueName, QMF_DEFAULT_TOPIC, AGENT_EVENT_BROKER, FieldTable());
    peer.getExchange().bind(queueName, QMF_DEFAULT_TOPIC, AGENT_EVENT_HA, FieldTable());
    //subscribe to the queue
    FieldTable arguments;
    arguments.setInt(QueueReplicator::QPID_SYNC_FREQUENCY, 1); // TODO aconway 2012-05-22: optimize?
    peer.getMessage().subscribe(
        queueName, args.i_dest, 1/*accept-none*/, 0/*pre-acquired*/,
        false/*exclusive*/, "", 0, arguments);
    peer.getMessage().setFlowMode(args.i_dest, 1); // Window
    peer.getMessage().flow(args.i_dest, 0, haBroker.getSettings().getFlowMessages());
    peer.getMessage().flow(args.i_dest, 1, haBroker.getSettings().getFlowBytes());

    // Issue a query request for queues, exchanges, bindings and the habroker
    // using event queue as the reply-to address
    sendQuery(ORG_APACHE_QPID_HA, HA_BROKER, queueName, sessionHandler);
    sendQuery(ORG_APACHE_QPID_BROKER, QUEUE, queueName, sessionHandler);
    sendQuery(ORG_APACHE_QPID_BROKER, EXCHANGE, queueName, sessionHandler);
    sendQuery(ORG_APACHE_QPID_BROKER, BINDING, queueName, sessionHandler);
}

// Called for each queue in existence when the backup connects to a primary.
void BrokerReplicator::existingQueue(const boost::shared_ptr<Queue>& q) {
    if (replicationTest.getLevel(*q)) {
        QPID_LOG(debug, logPrefix << "Existing queue: " << q->getName());
        queueTracker->addQueue(q);
    }
}

void BrokerReplicator::existingExchange(const boost::shared_ptr<Exchange>& ex) {
    if (replicationTest.getLevel(*ex)) {
        QPID_LOG(debug, logPrefix << "Existing exchange: " << ex->getName());
        exchangeTracker->addExchange(ex);
    }
}

void BrokerReplicator::route(Deliverable& msg) {
    // We transition from JOINING->CATCHUP on the first message received from the primary.
    // Until now we couldn't be sure if we had a good connection to the primary.
    if (haBroker.getStatus() == JOINING) {
        haBroker.getMembership().setStatus(CATCHUP);
        QPID_LOG(notice, logPrefix << "Connected to primary " << primary);
    }
    Variant::List list;
    try {
        if (!MessageTransfer::isQMFv2(msg.getMessage()))
            throw Exception("Unexpected message, not QMF2 event or query response.");
        // decode as list
        string content = msg.getMessage().getContent();
        qpid::amqp_0_10::ListCodec::decode(content, list);

        if (msg.getMessage().getPropertyAsString(QMF_CONTENT) == EVENT) {
            for (Variant::List::iterator i = list.begin(); i != list.end(); ++i) {
                Variant::Map& map = i->asMap();
                QPID_LOG(trace, logPrefix << "Broker replicator event: " << map);
                Variant::Map& schema = map[SCHEMA_ID].asMap();
                Variant::Map& values = map[VALUES].asMap();
                std::string key = (schema[PACKAGE_NAME].asString() +
                                   COLON +
                                   schema[CLASS_NAME].asString());
                EventDispatchMap::iterator j = dispatch.find(key);
                if (j != dispatch.end()) (this->*(j->second))(values);
            }
        } else if (msg.getMessage().getPropertyAsString(QMF_OPCODE) == QUERY_RESPONSE) {
            for (Variant::List::iterator i = list.begin(); i != list.end(); ++i) {
                Variant::Map& map = i->asMap();
                QPID_LOG(trace, logPrefix << "Broker replicator response: " << map);
                string type = map[SCHEMA_ID].asMap()[CLASS_NAME].asString();
                Variant::Map& values = map[VALUES].asMap();
                framing::FieldTable args;
                qpid::amqp_0_10::translate(asMapVoid(values[ARGUMENTS]), args);
                if      (type == QUEUE) doResponseQueue(values);
                else if (type == EXCHANGE) doResponseExchange(values);
                else if (type == BINDING) doResponseBind(values);
                else if (type == HA_BROKER) doResponseHaBroker(values);
            }
            if (MessageTransfer::isLastQMFResponse(msg.getMessage(), EXCHANGE)) {
                QPID_LOG(debug, logPrefix << "All exchange responses received.")
                exchangeTracker->done(); // Clean up exchanges that no longer exist in the primary
                exchangeTracker.reset();
                alternates.clear();
            }
            if (MessageTransfer::isLastQMFResponse(msg.getMessage(), QUEUE)) {
                QPID_LOG(debug, logPrefix << "All queue responses received.");
                queueTracker->done(); // Clean up queues that no longer exist in the primary
                queueTracker.reset();
            }
        }
    } catch (const std::exception& e) {
        haBroker.shutdown(
            QPID_MSG(logPrefix << "Configuration replication failed: "
                     << e.what() << ": while handling: " << list));
        throw;
    }
}

void BrokerReplicator::doEventQueueDeclare(Variant::Map& values) {
    Variant::Map argsMap = asMapVoid(values[ARGS]);
    if (values[DISP] == CREATED && replicationTest.getLevel(argsMap)) {
        string name = values[QNAME].asString();
        QueueSettings settings(values[DURABLE].asBool(), values[AUTODEL].asBool());
        QPID_LOG(debug, logPrefix << "Queue declare event: " << name);
        if (queueTracker.get()) queueTracker->event(name);
        framing::FieldTable args;
        qpid::amqp_0_10::translate(argsMap, args);
        // If we already have a queue with this name, replace it.
        // The queue was definitely created on the primary.
        if (queues.find(name)) {
            QPID_LOG(warning, logPrefix << "Declare event, replacing exsiting queue: "
                     << name);
            deleteQueue(name);
        }
        replicateQueue(name, values[DURABLE].asBool(), values[AUTODEL].asBool(), args,
                       values[ALTEX].asString());
    }
}

boost::shared_ptr<QueueReplicator> BrokerReplicator::findQueueReplicator(
    const std::string& qname)
{
    string rname = QueueReplicator::replicatorName(qname);
    boost::shared_ptr<broker::Exchange> ex = exchanges.find(rname);
    return boost::dynamic_pointer_cast<QueueReplicator>(ex);
}

void BrokerReplicator::doEventQueueDelete(Variant::Map& values) {
    // The remote queue has already been deleted so replicator
    // sessions may be closed by a "queue deleted" exception.
    string name = values[QNAME].asString();
    boost::shared_ptr<Queue> queue = queues.find(name);
    if (queue && replicationTest.getLevel(*queue)) {
        QPID_LOG(debug, logPrefix << "Queue delete event: " << name);
        if (queueTracker.get()) queueTracker->event(name);
        deleteQueue(name);
    }
}

void BrokerReplicator::doEventExchangeDeclare(Variant::Map& values) {
    Variant::Map argsMap(asMapVoid(values[ARGS]));
    if (values[DISP] == CREATED && replicationTest.getLevel(argsMap)) {
        string name = values[EXNAME].asString();
        QPID_LOG(debug, logPrefix << "Exchange declare event: " << name);
        if (exchangeTracker.get()) exchangeTracker->event(name);
        framing::FieldTable args;
        qpid::amqp_0_10::translate(argsMap, args);
        // If we already have a exchange with this name, replace it.
        // The exchange was definitely created on the primary.
        if (exchanges.find(name)) {
            deleteExchange(name);
            QPID_LOG(warning, logPrefix << "Declare event, replacing existing exchange: "
                     << name);
        }
        //Note: unlike qieth queues, autodeleted exchanges have no
        //messages, so need no special handling for autodelete in ha
        CreateExchangeResult result = createExchange(
            name, values[EXTYPE].asString(), values[DURABLE].asBool(), values[AUTODEL].asBool(), args,
            values[ALTEX].asString());
        assert(result.second);
    }
}

void BrokerReplicator::doEventExchangeDelete(Variant::Map& values) {
    string name = values[EXNAME].asString();
    boost::shared_ptr<Exchange> exchange = exchanges.find(name);
    if (exchange && replicationTest.getLevel(*exchange)) {
        QPID_LOG(debug, logPrefix << "Exchange delete event:" << name);
        if (exchangeTracker.get()) exchangeTracker->event(name);
        deleteExchange(name);
    }
}

void BrokerReplicator::doEventBind(Variant::Map& values) {
    boost::shared_ptr<Exchange> exchange =
        exchanges.find(values[EXNAME].asString());
    boost::shared_ptr<Queue> queue =
        queues.find(values[QNAME].asString());
    framing::FieldTable args;
    qpid::amqp_0_10::translate(asMapVoid(values[ARGS]), args);
    // We only replicate binds for a replicated queue to replicated exchange
    // that both exist locally. Respect the replication level set in the
    // bind arguments, but replicate by default.
    if (exchange && replicationTest.getLevel(*exchange) &&
        queue && replicationTest.getLevel(*queue) &&
        ReplicationTest(ALL).getLevel(args))
    {
        string key = values[KEY].asString();
        QPID_LOG(debug, logPrefix << "Bind event: exchange=" << exchange->getName()
                 << " queue=" << queue->getName()
                 << " key=" << key
                 << " args=" << args);
        queue->bind(exchange, key, args);
    }
}

void BrokerReplicator::doEventUnbind(Variant::Map& values) {
    boost::shared_ptr<Exchange> exchange =
        exchanges.find(values[EXNAME].asString());
    boost::shared_ptr<Queue> queue =
        queues.find(values[QNAME].asString());
    // We only replicate unbinds for a replicated queue to replicated
    // exchange that both exist locally.
    if (exchange && replicationTest.getLevel(*exchange) &&
        queue && replicationTest.getLevel(*queue))
    {
        string key = values[KEY].asString();
        QPID_LOG(debug, logPrefix << "Unbind event: exchange=" << exchange->getName()
                 << " queue=" << queue->getName()
                 << " key=" << key);
        exchange->unbind(queue, key, 0);
    }
}

void BrokerReplicator::doEventMembersUpdate(Variant::Map& values) {
    Variant::List members = values[MEMBERS].asList();
    setMembership(members);
}

void BrokerReplicator::doEventSubscribe(Variant::Map& values) {
    // Ignore queue replicator subscriptions.
    if (QueueReplicator::isReplicatorName(values[DEST].asString())) return;
    boost::shared_ptr<QueueReplicator> qr = findQueueReplicator(values[QNAME]);
    if (qr) {
        qr->setSubscribed();
        QPID_LOG(debug, logPrefix << "Subscribe event: " << values[QNAME]);
    }
}

namespace {

// Get the alternate exchange from the exchange field of a queue or exchange response.
static const string EXCHANGE_KEY_PREFIX("org.apache.qpid.broker:exchange:");

string getAltExchange(const types::Variant& var) {
    if (!var.isVoid()) {
        management::ObjectId oid(var);
        string key = oid.getV2Key();
        if (key.find(EXCHANGE_KEY_PREFIX) != 0) throw Exception("Invalid exchange reference: "+key);
        return key.substr(EXCHANGE_KEY_PREFIX.size());
    }
    else return string();
}

Variant getHaUuid(const Variant::Map& map) {
    Variant::Map::const_iterator i = map.find(QPID_HA_UUID);
    return i == map.end() ? Variant() : i->second;
}

} // namespace

void BrokerReplicator::doResponseQueue(Variant::Map& values) {
    Variant::Map argsMap(asMapVoid(values[ARGUMENTS]));
    if (!replicationTest.getLevel(argsMap)) return;
    string name(values[NAME].asString());
    if (!queueTracker.get())
        throw Exception(QPID_MSG("Unexpected queue response: " << values));
    if (!queueTracker->response(name)) return; // Response is out-of-date

    QPID_LOG(debug, logPrefix << "Queue response: " << name);
    boost::shared_ptr<Queue> queue = queues.find(name);

    if (queue) { // Already exists
        bool uuidOk = (getHaUuid(queue->getSettings().original) == getHaUuid(argsMap));
        if (!uuidOk) QPID_LOG(debug, logPrefix << "UUID mismatch for queue: " << name);
        if (uuidOk && findQueueReplicator(name)) return; // already replicated, UUID OK.
        QPID_LOG(debug, logPrefix << "Queue response replacing queue:  " << name);
        deleteQueue(name);
    }

    framing::FieldTable args;
    qpid::amqp_0_10::translate(argsMap, args);
    boost::shared_ptr<QueueReplicator> qr = replicateQueue(
        name, values[DURABLE].asBool(), values[AUTODELETE].asBool(), args,
        getAltExchange(values[ALTEXCHANGE]));
    if (qr) {
        Variant::Map::const_iterator i = values.find(CONSUMER_COUNT);
        if (i != values.end() && isIntegerType(i->second.getType())) {
            if (i->second.asInt64()) qr->setSubscribed();
        }
    }
}

void BrokerReplicator::doResponseExchange(Variant::Map& values) {
    Variant::Map argsMap(asMapVoid(values[ARGUMENTS]));
    if (!replicationTest.getLevel(argsMap)) return;
    string name = values[NAME].asString();
    if (!exchangeTracker.get())
        throw Exception(QPID_MSG("Unexpected exchange response: " << values));
    if (!exchangeTracker->response(name)) return; // Response is out of date.
    QPID_LOG(debug, logPrefix << "Exchange response: " << name);
    framing::FieldTable args;
    qpid::amqp_0_10::translate(argsMap, args);
    // If we see an exchange with the same name as one we have, but a different UUID,
    // then replace the one we have.
    boost::shared_ptr<Exchange> exchange = exchanges.find(name);
    if (exchange &&
        exchange->getArgs().getAsString(QPID_HA_UUID) != args.getAsString(QPID_HA_UUID))
    {
        QPID_LOG(warning, logPrefix << "Exchange response replacing (UUID mismatch): " << name);
        deleteExchange(name);
    }
    CreateExchangeResult result = createExchange(
        name, values[TYPE].asString(), values[DURABLE].asBool(), values[AUTODELETE].asBool(), args,
        getAltExchange(values[ALTEXCHANGE]));
}

namespace {
const std::string QUEUE_REF_PREFIX("org.apache.qpid.broker:queue:");
const std::string EXCHANGE_REF_PREFIX("org.apache.qpid.broker:exchange:");

std::string getRefName(const std::string& prefix, const Variant& ref) {
    Variant::Map map(ref.asMap());
    Variant::Map::const_iterator i = map.find(OBJECT_NAME);
    if (i == map.end())
        throw Exception(QPID_MSG("Replicator: invalid object reference: " << ref));
    const std::string name = i->second.asString();
    if (name.compare(0, prefix.size(), prefix) != 0)
        throw Exception(QPID_MSG("Replicator: unexpected reference prefix: " << name));
    std::string ret = name.substr(prefix.size());
    return ret;
}

const std::string EXCHANGE_REF("exchangeRef");
const std::string QUEUE_REF("queueRef");

} // namespace

void BrokerReplicator::doResponseBind(Variant::Map& values) {
    std::string exName = getRefName(EXCHANGE_REF_PREFIX, values[EXCHANGE_REF]);
    std::string qName = getRefName(QUEUE_REF_PREFIX, values[QUEUE_REF]);
    boost::shared_ptr<Exchange> exchange = exchanges.find(exName);
    boost::shared_ptr<Queue> queue = queues.find(qName);

    framing::FieldTable args;
    qpid::amqp_0_10::translate(asMapVoid(values[ARGUMENTS]), args);

    // Automatically replicate binding if queue and exchange exist and are replicated.
    // Respect replicate setting in binding args but default to replicated.
    if (exchange && replicationTest.getLevel(*exchange) &&
        queue && replicationTest.getLevel(*queue) &&
        ReplicationTest(ALL).getLevel(args))
    {
        string key = values[BINDING_KEY].asString();
        QPID_LOG(debug, logPrefix << "Bind response: exchange:" << exName
                 << " queue:" << qName
                 << " key:" << key
                 << " args:" << args);
        queue->bind(exchange, key, args);
    }
}

namespace {
const string REPLICATE_DEFAULT="replicateDefault";
}

// Received the ha-broker configuration object for the primary broker.
void BrokerReplicator::doResponseHaBroker(Variant::Map& values) {
    try {
        QPID_LOG(debug, logPrefix << "HA Broker response: " << values);
        ReplicateLevel mine = haBroker.getSettings().replicateDefault.get();
        ReplicateLevel primary = replicationTest.getLevel(values[REPLICATE_DEFAULT].asString());
        if (mine != primary)
            throw Exception(QPID_MSG("Replicate default on backup (" << mine
                                     << ") does not match primary (" <<  primary << ")"));
        setMembership(values[MEMBERS].asList());
    } catch (const std::exception& e) {
        haBroker.shutdown(
            QPID_MSG(logPrefix << "Invalid HA Broker response: " << e.what()
                     << ": " << values));

        throw;
    }
}

boost::shared_ptr<QueueReplicator> BrokerReplicator::startQueueReplicator(
    const boost::shared_ptr<Queue>& queue)
{
    if (replicationTest.getLevel(*queue) == ALL) {
        return QueueReplicator::create(haBroker, queue, link);
    }
    return boost::shared_ptr<QueueReplicator>();
}

void BrokerReplicator::deleteQueue(const std::string& name, bool purge) {
    Queue::shared_ptr queue = queues.find(name);
    if (queue) {
        // Purge before deleting to ensure that we don't reroute any
        // messages. Any reroutes will be done at the primary and
        // replicated as normal.
        if (purge) queue->purge(0, boost::shared_ptr<Exchange>());
        haBroker.getBroker().deleteQueue(name, userId, remoteHost);
        QPID_LOG(debug, logPrefix << "Queue deleted: " << name);
    }
}

void BrokerReplicator::deleteExchange(const std::string& name) {
    boost::shared_ptr<broker::Exchange> exchange = exchanges.find(name);
    if (!exchange) {
        QPID_LOG(warning, logPrefix << "Cannot delete exchange, not found: " << name);
        return;
    }
    if (exchange->inUseAsAlternate()) {
        QPID_LOG(warning, logPrefix << "Cannot delete exchange, in use as alternate: " << name);
        return;
    }
    broker.deleteExchange(name, userId, remoteHost);
    QPID_LOG(debug, logPrefix << "Exchange deleted: " << name);
}

boost::shared_ptr<QueueReplicator> BrokerReplicator::replicateQueue(
    const std::string& name,
    bool durable,
    bool autodelete,
    const qpid::framing::FieldTable& arguments,
    const std::string& alternateExchange)
{
    QueueSettings settings(durable, autodelete);
    settings.populate(arguments, settings.storeSettings);
    CreateQueueResult result =
        broker.createQueue(
            name,
            settings,
            0,// no owner regardless of exclusivity on primary
            string(), // Set alternate exchange below
            userId,
            remoteHost);
    boost::shared_ptr<QueueReplicator> qr;
    if (!findQueueReplicator(name)) qr = startQueueReplicator(result.first);
    if (result.second && !alternateExchange.empty()) {
        alternates.setAlternate(
            alternateExchange, boost::bind(&Queue::setAlternateExchange, result.first, _1));
    }
    return qr;
}

BrokerReplicator::CreateExchangeResult BrokerReplicator::createExchange(
    const std::string& name,
    const std::string& type,
    bool durable,
    bool autodelete,
    const qpid::framing::FieldTable& args,
    const std::string& alternateExchange)
{
    CreateExchangeResult result =
        broker.createExchange(
            name,
            type,
            durable,
            autodelete,
            string(),  // Set alternate exchange below
            args,
            userId,
            remoteHost);
    alternates.addExchange(result.first);
    if (!alternateExchange.empty()) {
        alternates.setAlternate(
            alternateExchange, boost::bind(&Exchange::setAlternate, result.first, _1));
    }
    return result;
}

bool BrokerReplicator::bind(boost::shared_ptr<Queue>, const string&, const framing::FieldTable*) { return false; }
bool BrokerReplicator::unbind(boost::shared_ptr<Queue>, const string&, const framing::FieldTable*) { return false; }
bool BrokerReplicator::isBound(boost::shared_ptr<Queue>, const string* const, const framing::FieldTable* const) { return false; }
bool BrokerReplicator::hasBindings() { return false; }

// ConnectionObserver methods
void BrokerReplicator::connection(broker::Connection&) {}
void BrokerReplicator::opened(broker::Connection&) {}

void BrokerReplicator::closed(broker::Connection& c) {
    if (link && &c == connect) disconnected();
}

void BrokerReplicator::forced(broker::Connection& c, const std::string& message) {
    if (link && &c == link->getConnection()) {
        haBroker.shutdown(
            QPID_MSG(logPrefix << "Connection forced, cluster may be misconfigured: "
                     << message));
    }
    closed(c);
}

string BrokerReplicator::getType() const { return QPID_CONFIGURATION_REPLICATOR; }

void BrokerReplicator::disconnectedQueueReplicator(
    const boost::shared_ptr<QueueReplicator>& qr)
{
    qr->disconnect();
}

// Called by ConnectionObserver::disconnected, disconnected from the network side.
void BrokerReplicator::disconnected() {
    QPID_LOG(info, logPrefix << "Disconnected from primary " << primary);
    connect = 0;
    QueueReplicators qrs(broker.getExchanges());
    for_each(qrs.begin(), qrs.end(),
             boost::bind(&BrokerReplicator::disconnectedQueueReplicator, this, _1));
}

void BrokerReplicator::setMembership(const Variant::List& brokers) {
    haBroker.getMembership().assign(brokers);
}

}} // namespace broker


text:
/**
 *  Copyright (C) 2021 FISCO BCOS.
 *  SPDX-License-Identifier: Apache-2.0
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 * @brief test for TopicManager
 * @file TopicManagerTest.cpp
 * @author: octopus
 * @date 2021-06-21
 */
#include <bcos-framework/testutils/TestPromptFixture.h>
#include <bcos-gateway/libamop/TopicManager.h>
#include <boost/test/unit_test.hpp>

using namespace bcos;
using namespace bcos::amop;
using namespace bcos::test;

BOOST_FIXTURE_TEST_SUITE(TopicManagerTest, TestPromptFixture)

BOOST_AUTO_TEST_CASE(test_initTopicManager)
{
    auto topicManager = std::make_shared<TopicManager>("", nullptr);
    {
        auto jsonValue = topicManager->queryTopicsSubByClient();

        uint32_t topicSeq;
        TopicItems topicItems;
        auto b = topicManager->parseTopicItemsJson(topicSeq, topicItems, jsonValue);
        BOOST_CHECK(b);
        BOOST_CHECK(topicSeq == 1);
        BOOST_CHECK(topicItems.empty());
    }

    {
        auto seq = topicManager->topicSeq();
        BOOST_CHECK(seq == 1);
        topicManager->incTopicSeq();
        BOOST_CHECK(topicManager->topicSeq() == (seq + 1));
        topicManager->incTopicSeq();
        BOOST_CHECK(topicManager->topicSeq() == (seq + 2));
    }
}

BOOST_AUTO_TEST_CASE(test_parseTopicItemsJson)
{
    auto topicManager = std::make_shared<TopicManager>("", nullptr);
    {
        uint32_t topicSeq;
        TopicItems topicItems;
        std::string json = "";
        auto r = topicManager->parseTopicItemsJson(topicSeq, topicItems, json);
        BOOST_CHECK(!r);
    }
    {
        uint32_t topicSeq;
        TopicItems topicItems;
        std::string json = "{\"topicSeq\":111,\"topicItems\":[]}";
        auto r = topicManager->parseTopicItemsJson(topicSeq, topicItems, json);
        BOOST_CHECK(r);
        BOOST_CHECK(topicSeq == 111);
        BOOST_CHECK(topicItems.size() == 0);
    }
    {
        uint32_t topicSeq;
        TopicItems topicItems;
        std::string json = "{\"topicSeq\":123,\"topicItems\":[\"a\",\"b\",\"c\"]}";
        auto r = topicManager->parseTopicItemsJson(topicSeq, topicItems, json);
        BOOST_CHECK(r);
        BOOST_CHECK(topicSeq == 123);
        BOOST_CHECK(topicItems.size() == 3);
        auto a = std::string("a");
        BOOST_CHECK(std::find_if(topicItems.begin(), topicItems.end(),
                        [a](const TopicItem& _topicItem) { return _topicItem.topicName() == a; }) !=
                    topicItems.end());
        auto b = std::string("b");
        BOOST_CHECK(std::find_if(topicItems.begin(), topicItems.end(),
                        [b](const TopicItem& _topicItem) { return _topicItem.topicName() == b; }) !=
                    topicItems.end());
        auto c = std::string("c");
        BOOST_CHECK(std::find_if(topicItems.begin(), topicItems.end(),
                        [c](const TopicItem& _topicItem) { return _topicItem.topicName() == c; }) !=
                    topicItems.end());
    }
}

BOOST_AUTO_TEST_CASE(test_subTopics)
{
    auto topicManager = std::make_shared<TopicManager>("", nullptr);

    std::string clientID = "client";
    {
        TopicItems topicItems;
        auto r = topicManager->queryTopicItemsByClient(clientID, topicItems);
        BOOST_CHECK(!r);
        BOOST_CHECK(topicItems.empty());
    }

    {
        TopicItems topicItems;
        std::vector<std::string> topics{"topic0", "topic1", "topic2", "topic3"};
        for (const auto& topic : topics)
        {
            topicItems.insert(TopicItem(topic));
        }
        auto seq = topicManager->topicSeq();
        // sub topics
        topicManager->subTopic(clientID, topicItems);
        topicItems.clear();
        auto r = topicManager->queryTopicItemsByClient(clientID, topicItems);
        BOOST_CHECK(r);
        BOOST_CHECK(topicItems.size() == topics.size());
        BOOST_CHECK(topicManager->topicSeq() == (seq + 1));

        auto jsonValue = topicManager->queryTopicsSubByClient();
        BOOST_CHECK(!jsonValue.empty());

        uint32_t topicSeqFromJson;
        TopicItems topicItemsFromJson;
        auto b = topicManager->parseTopicItemsJson(topicSeqFromJson, topicItemsFromJson, jsonValue);
        BOOST_CHECK(b);
        BOOST_CHECK(topicSeqFromJson = topicManager->topicSeq());
        BOOST_CHECK(topicItemsFromJson.size() == topicItems.size());
    }
}

BOOST_AUTO_TEST_SUITE_END()


text:
/**
 * Copyright Soramitsu Co., Ltd. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef IROHA_ABSTRACT_CACHE_HPP
#define IROHA_ABSTRACT_CACHE_HPP

#include <boost/optional.hpp>
#include <list>
#include <shared_mutex>
#include <string>

namespace iroha {
  namespace cache {
    /**
     * Cache for any key-value types.
     * Internally it uses a map to cache ItemTypes and linked list
     * based index of KeyTypes to remove oldest items when getIndexSizeHigh() is
     * reached. Implemented as a CRTP pattern.
     * @tparam KeyType - type of cache keys
     * @tparam ValueType - type of cache values
     * @tparam T - type of implementation
     */
    template <typename KeyType, typename ValueType, typename T>
    class AbstractCache {
     public:
      /**
       * @return high border of cache limit (@see AbstractCache#addItem)
       */
      uint32_t getIndexSizeHigh() const {
        // shared lock
        std::shared_lock<std::shared_timed_mutex> lock(access_mutex_);
        return constUnderlying().getIndexSizeHighImpl();
      }

      /**
       * @return low border of cache limit (@see AbstractCache#addItem)
       */
      uint32_t getIndexSizeLow() const {
        // shared lock
        std::shared_lock<std::shared_timed_mutex> lock(access_mutex_);
        return constUnderlying().getIndexSizeLowImpl();
      }

      /**
       * @return amount of items in cache
       */
      uint32_t getCacheItemCount() const {
        // shared lock
        std::shared_lock<std::shared_timed_mutex> lock(access_mutex_);
        return constUnderlying().getCacheItemCountImpl();
      }

      /**
       * Adds new item to cache. When amount of cache records reaches
       * getIndexSizeHigh() a procedure of clean starts until getIndexSizeLow()
       * records left. Note: cache does not have a remove method, deletion
       * performs automatically.
       * Since every add operation can potentially lead to deletion,
       * it should be protected by mutex.
       * @param key - key to insert
       * @param value - value to insert
       */
      void addItem(const KeyType &key, const ValueType &value) {
        // exclusive lock
        std::lock_guard<std::shared_timed_mutex> lock(access_mutex_);
        underlying().addItemImpl(key, value);
      }

      /**
       * Performs a search for an item with a specific key.
       * @param hash - key to find
       * @return Optional of ValueType
       */
      boost::optional<ValueType> findItem(const KeyType &key) const {
        std::shared_lock<std::shared_timed_mutex> lock(access_mutex_);
        return constUnderlying().findItemImpl(key);
      }

     private:
      const T &constUnderlying() const {
        return static_cast<const T &>(*this);
      }
      T &underlying() {
        return static_cast<T &>(*this);
      }

      mutable std::shared_timed_mutex access_mutex_;
    };
  }  // namespace cache
}  // namespace iroha

#endif  // IROHA_ABSTRACT_CACHE_HPP

max_stars_repo_name: e-ivkov/iroha

max_issues_repo_name: e-ivkov/iroha

max_forks_repo_name: e-ivkov/iroha


text:
#include <iostream>
#include <boost/program_options.hpp>

#include "request.hpp"

namespace po = boost::program_options;

using std::cout;
using std::endl;

void print_help (std::string& binary, po::options_description& desc)
{
	cout << desc << endl;
	cout << "read a file: " << binary << " --operation read --file myfile --size 1024 --server localhost --port 4444" << " - read 1024 bytes from the remote file myfile" << endl;
	cout << "write a file: " << binary << " --operation write --file myfile --size 2 --server localhost --port 4444" << " - write 2 bytes to the remote file myfile from the standard input" << endl;
}

void check_arguments (std::string& binary, po::variables_map& vm, po::options_description& desc)
{

   if (vm.count("help"))
	{
		print_help (binary, desc);
		exit (EXIT_SUCCESS);
	}

   if (
			vm.count("server") == 0 ||
			vm.count("operation") == 0 ||
			vm.count("port") == 0
		)
	{
		print_help (binary, desc);
		exit (EXIT_FAILURE);
	}

	std::string operation = vm["operation"].as<std::string>();

	if (operation == "read")
	{
		if (vm.count("file") == 0)
		{
			print_help (binary, desc);
			exit (EXIT_FAILURE);
		}
	}

}

int main (int ac, char* av[])
{
   po::options_description desc("Available options");

   desc.add_options()
      ("help", "print help message")
      ("operation", po::value<std::string>(), "requested operation: read/write/list")
      ("size", po::value<int>(), "size to read/write")
      ("server", po::value<std::string>(), "server to connect to")
      ("port", po::value<int>(), "remote port")
      ("file", po::value<std::string>(), "file to read/write from/to")
      ;

	std::string binary = av[0];
   po::variables_map vm;
   po::store(po::parse_command_line(ac, av, desc), vm);
   po::notify(vm);

	check_arguments (binary, vm, desc);

	std::string operation = vm["operation"].as<std::string>();
	std::string server = vm["server"].as<std::string>();
	int port = vm["port"].as<int>();

	if (operation == "read")
	{
		std::string file = vm["file"].as<std::string>();
		int size = vm["size"].as<int>();
		ReadRequest request(server, port, file, size);

		srfs_error_t err = request.perform ();

		if (err == no_error)
		{
			exit (EXIT_SUCCESS);
		}

		exit (EXIT_SUCCESS);

	}

	print_help (binary, desc);
	exit (EXIT_FAILURE);
}


text:
//
// atomic_sp_constexpr_test.cpp
//
// Copyright 2017, 2018 Peter Dimov
//
// 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
//

#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config/helper_macros.hpp>

#if defined( BOOST_NO_CXX11_CONSTEXPR )

BOOST_PRAGMA_MESSAGE("Skipping test due to BOOST_NO_CXX11_CONSTEXPR")
int main() {}

#elif BOOST_WORKAROUND( BOOST_MSVC, < 1920 )

// MSVC does not implement static initialization for constexpr
BOOST_PRAGMA_MESSAGE("Skipping test due to BOOST_MSVC < 1920")
int main() {}

#elif defined(__clang__) && defined( BOOST_NO_CXX14_CONSTEXPR )

// Clang only implements static initialization for constexpr in C++14 mode
BOOST_PRAGMA_MESSAGE("Skipping test due to __clang__ and BOOST_NO_CXX14_CONSTEXPR")
int main() {}

#elif defined( _LIBCPP_VERSION ) && ( _LIBCPP_VERSION < 6000 )

// in libc++, atomic_flag has a non-constexpr constructor from bool
BOOST_PRAGMA_MESSAGE("Skipping test due to _LIBCPP_VERSION " BOOST_STRINGIZE(_LIBCPP_VERSION))
int main() {}

#elif defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX )

BOOST_PRAGMA_MESSAGE("Skipping test due to BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX")
int main() {}

#else

#include <boost/smart_ptr/atomic_shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>

struct X
{
};

struct Z
{
    Z();
};

static Z z;

static boost::atomic_shared_ptr<X> p1;

Z::Z()
{
    p1 = boost::shared_ptr<X>( new X );
}

int main()
{
    boost::shared_ptr<X> p2 = p1;

    BOOST_TEST( p2.get() != 0 );
    BOOST_TEST_EQ( p2.use_count(), 2 );

    return boost::report_errors();
}

#endif


text:
/*
 *  World.cpp
 *  Kepler
 *
 *  Created by Robert Hodgin on 2/25/11.
 *  Copyright 2013 Smithsonian Institution. All rights reserved.
 *
 */

#include <boost/foreach.hpp>
#include <deque>
#include "World.h"
#include "NodeArtist.h"
#include "NodeAlbum.h"
#include "NodeTrack.h"
#include "cinder/gl/gl.h"
#include "cinder/Rect.h"
#include "cinder/Text.h"
#include "cinder/Rand.h"
#include "Globals.h"
#include "BloomSphere.h"
#include "Filter.h"

using std::stringstream;
using namespace ci;
using namespace ci::app;
using namespace ci::ipod;
using namespace std;

void World::setup()
{
	if( !mSpheresInitialized ){
		// VERTEX ARRAY SPHERE
		if ( G_IS_IPAD2 ) {
            mHiSphere.setup(32);
            mMdSphere.setup(20);
            mLoSphere.setup(16);
            mTySphere.setup(10);
		} else {
            mHiSphere.setup(32);
            mMdSphere.setup(16);
            mLoSphere.setup(12);
            mTySphere.setup(8);
		}
        mOrbitRing.setup();
        mPlanetRing.setup();
        mSpheresInitialized = true;
	}

	mAge			= 0;
	mEndRepulseAge	= 30;//200
	mIsRepulsing	= true;
	mIsInitialized	= false;
}

void World::initNodes( const vector<PlaylistRef> &artists, const Font &font, const Font &smallFont, const Surface &highResSurfaces, const Surface &lowResSurfaces, const Surface &noAlbumArt )
{
//	float t = App::get()->getElapsedSeconds();

	for( vector<NodeArtist*>::iterator it = mNodes.begin(); it != mNodes.end(); ++it ){
        NodeArtist* node = *it;
        delete node;
    }
	mNodes.clear();
    mNodesById.clear();

	int i=0;
    BOOST_FOREACH(PlaylistRef artistPlaylist, artists) {
		NodeArtist *newNode = new NodeArtist( i++, font, smallFont, highResSurfaces, lowResSurfaces, noAlbumArt );
		newNode->setData( artistPlaylist );
        newNode->setSphereData( &mHiSphere, &mMdSphere, &mLoSphere, &mTySphere );
		mNodes.push_back( newNode );
        mNodesById[newNode->getId()] = newNode;
	}

//	cout << (App::get()->getElapsedSeconds() - t) << " seconds to World::initNodes" << endl;

	mIsInitialized = true;
}

void World::setFilter(FilterRef filterRef)
{
    mFilterRef = filterRef;

    mFilteredNodes.clear();

    BOOST_FOREACH(NodeArtist* nodeArtist, mNodes) {
        if ( mFilterRef->testArtist( nodeArtist->getPlaylist() ) ) {
            nodeArtist->mIsHighlighted = true;
            mFilteredNodes.push_back(nodeArtist);
        }
        else {
            nodeArtist->mIsHighlighted = false;
        }
	}

	if( mFilteredNodes.size() > 1 ){
		if( mAge >= mEndRepulseAge + 150 ){
            mConstellation.setup( mFilteredNodes );
        }
	}
}

void World::updateIsPlaying( uint64_t artistId, uint64_t albumId, uint64_t trackId )
{
	mPlayingTrackNode = NULL;

    BOOST_FOREACH(NodeArtist* artistNode, mNodes) {
        artistNode->mIsPlaying = artistNode->getId() == artistId;
        BOOST_FOREACH(Node* albumNode, artistNode->mChildNodes) {
            albumNode->mIsPlaying = albumNode->getId() == albumId;
            BOOST_FOREACH(Node *trackNode, albumNode->mChildNodes) {
                bool wasPlaying = trackNode->mIsPlaying;
                trackNode->mIsPlaying = trackNode->getId() == trackId;
				if( trackNode->mIsPlaying && !trackNode->isDying() ){
					mPlayingTrackNode = static_cast<NodeTrack*>(trackNode);
                    if (!wasPlaying) {
                        mPlayingTrackNode->setStartAngle();
                    }
				}
            }
        }
    }
}

void World::selectHierarchy( uint64_t artistId, uint64_t albumId, uint64_t trackId )
{
    BOOST_FOREACH(NodeArtist* artistNode, mNodes) {
        if (artistNode->getId() == artistId) {
            artistNode->select();
            BOOST_FOREACH(Node* albumNode, artistNode->mChildNodes) {
                if (albumNode->getId() == albumId) {
                    albumNode->select();
                    BOOST_FOREACH(Node *trackNode, albumNode->mChildNodes) {
                        if (trackNode->getId() == trackId) {
                            trackNode->select();
                        }
                        else {
                            trackNode->deselect();
                        }
                    }
                }
                else {
                    albumNode->deselect();
                }
            }
        }
        else {
            artistNode->deselect();
        }
    }
}

NodeTrack* World::getTrackNodeById( uint64_t artistId, uint64_t albumId, uint64_t trackId )
{
    // NB:- artist and album must be selected, otherwise track node won't exist
    NodeArtist* artistNode = getArtistNodeById(artistId);
    if (artistNode->getId() == artistId) {
        BOOST_FOREACH(Node* albumNode, artistNode->mChildNodes) {
            if (albumNode->getId() == albumId) {
                BOOST_FOREACH(Node *trackNode, albumNode->mChildNodes) {
                    if (trackNode->getId() == trackId) {
                        return static_cast<NodeTrack*>(trackNode);
                    }
                }
                break;
            }
        }
    }
    return NULL;
}

NodeAlbum* World::getAlbumNodeById( uint64_t artistId, uint64_t albumId )
{
    // NB:- artist and album must be selected already
    NodeArtist* artistNode = getArtistNodeById(artistId);
    if (artistNode->getId() == artistId) {
        // TODO: add a map childrenById to Node?
        BOOST_FOREACH(Node* albumNode, artistNode->mChildNodes) {
            if (albumNode->getId() == albumId) {
                return static_cast<NodeAlbum*>(albumNode);
            }
        }
    }
    return NULL;
}

// check albums and artists (that may have been selected since the filter was set) and unhighlight them if needed
void World::updateAgainstCurrentFilter()
{
    if (mFilterRef) {
        BOOST_FOREACH(NodeArtist* artistNode, mFilteredNodes) {
            BOOST_FOREACH(Node* n1, artistNode->mChildNodes) {
                NodeAlbum* albumNode = static_cast<NodeAlbum*>(n1);
                albumNode->mIsHighlighted = mFilterRef->testAlbum(albumNode->getPlaylist());
                BOOST_FOREACH(Node* n2, albumNode->mChildNodes) {
                    NodeTrack *trackNode = static_cast<NodeTrack*>(n2);
                    trackNode->mIsHighlighted = albumNode->mIsHighlighted && mFilterRef->testTrack(trackNode->mTrack);
                }
            }
        }
    }
}

NodeTrack* World::selectPlayingHierarchy( uint64_t artistId, uint64_t albumId, uint64_t trackId )
{
    mPlayingTrackNode = NULL;

    BOOST_FOREACH(NodeArtist* artistNode, mNodes) {
        artistNode->mIsPlaying = artistNode->getId() == artistId;
        if (artistNode->mIsPlaying) {
            artistNode->select();
        }
        else {
            artistNode->deselect();
        }
        BOOST_FOREACH(Node* albumNode, artistNode->mChildNodes) {
            albumNode->mIsPlaying = albumNode->getId() == albumId;
            if (albumNode->mIsPlaying) {
                albumNode->select();
            }
            else {
                albumNode->deselect();
            }
            BOOST_FOREACH(Node* trackNode, albumNode->mChildNodes) {
                bool wasPlaying = trackNode->mIsPlaying;
                trackNode->mIsPlaying = trackNode->getId() == trackId;
                if( trackNode->mIsPlaying && !trackNode->isDying() ){
                    mPlayingTrackNode = static_cast<NodeTrack*>(trackNode);
                    if (!wasPlaying) {
                        mPlayingTrackNode->setStartAngle();
                    }
                }
                if (trackNode->mIsPlaying) {
                    trackNode->select();
                }
                else {
                    trackNode->deselect();
                }
            }
        }
    }

    return mPlayingTrackNode;
}

void World::checkForNameTouch( vector<Node*> &nodes, const Vec2f &pos )
{
    BOOST_FOREACH(NodeArtist* artistNode, mFilteredNodes) {
        artistNode->checkForNameTouch( nodes, pos );
    }
}

void World::updateGraphics( const CameraPersp &cam, const Vec2f &center, const Vec3f &bbRight, const Vec3f &bbUp, const float &zoomAlpha )
{
    const float w = app::getWindowWidth();
    const float h = app::getWindowHeight();

    BOOST_FOREACH(NodeArtist* artistNode, mNodes) {
		artistNode->updateGraphics( cam, center, bbRight, bbUp, w, h );
	}

    if (mIsInitialized) {
        mStars.setup(mNodes, bbRight, bbUp, zoomAlpha * 0.3f);
        mStarGlows.setup(mFilteredNodes, bbRight, bbUp, zoomAlpha);
    }
}

void World::update( float param1, float param2 )
{
	if( mIsInitialized ){
		mAge ++;

		if( mAge == mEndRepulseAge ){
			mIsRepulsing = false;
		}

		if( mAge == mEndRepulseAge + 150 ){
			mConstellation.setup( mFilteredNodes );
		}

		if( mIsRepulsing ){
			repulseNodes();
		}

        // reset mPlayingTrackNode before Node::update() has a chance to delete it
        // in future: this is why we should be using shared pointers :(
        const Node *ptn = mPlayingTrackNode; // temp for shorter next line
        const bool playingTrackNodeWillDieNextUpdate = ptn && (ptn->mDeathCount == ptn->mDeathThresh);
        if (playingTrackNodeWillDieNextUpdate) {
            mPlayingTrackNode = NULL;
        }

        BOOST_FOREACH(NodeArtist* artistNode, mNodes) {
			artistNode->update( param1, param2 );
		}
	}
}

void World::repulseNodes()
{
	for( vector<NodeArtist*>::iterator p1 = mNodes.begin(); p1 != mNodes.end(); ++p1 ){

		vector<NodeArtist*>::iterator p2 = p1;
		for( ++p2; p2 != mNodes.end(); ++p2 ) {
			Vec3f dir = (*p1)->mPosDest - (*p2)->mPosDest;

			float thresh = 20.0f;
			if( dir.x > -thresh && dir.x < thresh && dir.y > -thresh && dir.y < thresh && dir.z > -thresh && dir.z < thresh ){
				float distSqrd = dir.lengthSquared();

				if( distSqrd > 0.0f ){
					float F = constrain( 1.0f/distSqrd, 0.0f, 1.0f );
					dir = F * dir.normalized() * 0.75f;
					dir.y *= 0.5f;

					// acceleration = force / mass
					(*p1)->mAcc += dir;
					(*p2)->mAcc -= dir;
				}
			}
		}
	}
}

void World::drawStarsVertexArray()
{
    mStars.draw();
}

void World::drawStarGlowsVertexArray()
{
    mStarGlows.draw();
}

void World::drawRings( const gl::Texture &tex, float camZPos )
{
    BOOST_FOREACH(NodeArtist* artistNode, mNodes) {
		artistNode->drawRings( tex, mPlanetRing, camZPos );
	}
}

void World::drawNames( const CameraPersp &cam, float pinchAlphaOffset, float angle )
{
    // FIXME: consider splitting Node::drawName into drawNameShadow and drawName and using
    // a single bloom::gl::begin/endBatch to reduce the number of state switches
    // needs to extend bloom::gl batching to support storing the current color as well as texture
    BOOST_FOREACH(NodeArtist* artistNode, mFilteredNodes) {
        artistNode->drawName( cam, pinchAlphaOffset, angle );
	}
}

// assumes texture is already bound
void World::drawOrbitRings( float pinchAlphaOffset, float camAlpha, float fadeInAlphaToArtist, float fadeInArtistToAlbum )
{
    BOOST_FOREACH(NodeArtist* artistNode, mNodes) {
		artistNode->drawOrbitRing( pinchAlphaOffset, camAlpha, mOrbitRing, fadeInAlphaToArtist, fadeInArtistToAlbum );
	}
}

void World::drawTouchHighlights( float zoomAlpha )
{
    BOOST_FOREACH(NodeArtist* artistNode, mNodes) {
		artistNode->drawTouchHighlight( zoomAlpha );
	}
}

void World::drawConstellation()
{
    const float alpha = ( 1.0f - (G_ZOOM-1.0f) ) * 0.4f;
    mConstellation.draw( alpha );
}

void World::drawHitAreas()
{
    // HIT AREA VISUALIZER
    for (int i = 0; i < mNodes.size(); i++) {
        NodeArtist* artistNode = mNodes[i];
        if (artistNode->mIsHighlighted) {
            gl::color(ColorA(0.0f,0.0f,1.0f,0.25f));
            if( artistNode->mDistFromCamZAxisPer > 0.0f ){
                if( G_DRAW_TEXT && artistNode->mIsHighlighted ) gl::drawSolidRect(artistNode->mHitArea);
                gl::drawSolidRect(artistNode->mSphereHitArea);
            }
            for (int j = 0; j < artistNode->mChildNodes.size(); j++) {
                Node* albumNode = artistNode->mChildNodes[j];
                if (albumNode->mIsHighlighted) {
                    gl::color(ColorA(0.0f,1.0f,0.0f,0.25f));
                    if( G_DRAW_TEXT ) gl::drawSolidRect(albumNode->mHitArea);
                    gl::drawSolidRect(albumNode->mSphereHitArea);

                    for (int k = 0; k < albumNode->mChildNodes.size(); k++) {
                        Node *trackNode = albumNode->mChildNodes[k];
                        if (trackNode->mIsHighlighted) {
                            gl::color(ColorA(1.0f,0.0f,0.0f,0.25f));
                            if( G_DRAW_TEXT ) gl::drawSolidRect(trackNode->mHitArea);
                            gl::drawSolidRect(trackNode->mSphereHitArea);
                        }
                    }
                }
            }
        }
    }
}

vector<Node*> World::getUnsortedNodes( int fromGen, int toGen )
{
    vector<Node*> unsortedNodes;

    if (mNodes.size() > 0) {
        std::deque<Node*> queue;

        // initialize queue with all artist nodes
        queue.insert(queue.begin(), mNodes.begin(), mNodes.end());

        while (queue.size() > 0) {
            Node* node = queue.front();
            // remove
            queue.pop_front();
            // collect this node if it's valid
            if (node->mGen >= fromGen && node->mGen <= toGen) {
				unsortedNodes.push_back(node);
            }
            // add all node's children to the queue
            queue.insert(queue.end(), node->mChildNodes.begin(), node->mChildNodes.end());
        }
    }

    return unsortedNodes;
}

vector<Node*> World::sortNodes( vector<Node*> nodes )
{
    if( nodes.size() > 0 ){
        sort(nodes.begin(), nodes.end(), nodeSortFunc);
    }

    return nodes;
}

bool nodeSortFunc(Node* a, Node* b) {
    return a->mDistFromCamZAxis > b->mDistFromCamZAxis;
}

max_stars_repo_name: cooperhewitt/Planetary

max_issues_repo_name: bobwol/Planetary

max_forks_repo_name: bobwol/Planetary


text:
// answer to http://weibo.com/1915548291/z2UtyzuvQ
// see also http://www.cnblogs.com/baiyanhuang/archive/2012/11/11/2764914.html

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

#include <fstream>
#include <iostream>
#include <unordered_map>

#ifdef STD_STRING
#warning "STD STRING"
#include <string>
using std::string;
#else
#include <ext/vstring.h>
typedef __gnu_cxx::__sso_string string;
#endif

typedef boost::function<void(const string& query, int64_t count)> Callback;

const size_t kMaxSize = 10 * 1000 * 1000;

void processOneInput(const char* file, const Callback& cb)
{
  std::unordered_map<string, int64_t> queries;
  std::ifstream in(file);
  string query;
  while (in && !in.eof())
  {
    queries.clear();
    while (getline(in, query))
    {
      queries[query] += 1;
      if (queries.size() > kMaxSize)
      {
        std::cout << "    split\n";
        break;
      }
    }

    for (auto kv : queries)
    {
      cb(kv.first, kv.second);
    }
  }
}

class LocalSink : boost::noncopyable
{
 public:
  explicit LocalSink(int idx, int nbuckets)
  {
    char buf[256];
    snprintf(buf, sizeof buf, "shard-%05d-of-%05d", idx, nbuckets);
    out.open(buf);
  }

  void output(const string& query, int64_t count)
  {
    out << query << '\t' << count << '\n';
  }

 private:
  std::ofstream out;
};

// class RemoteSink;

// template<typename SINK>
class Shuffler : boost::noncopyable
{
 public:
  explicit Shuffler(int nbuckets)
    : buckets_(nbuckets)
  {
    for (int i = 0; i < nbuckets; ++i)
    {
      buckets_.push_back(new LocalSink(i, nbuckets));
    }
    assert(buckets_.size() == static_cast<size_t>(nbuckets));
  }

  void output(const string& query, int64_t count)
  {
    int idx = std::hash<string>()(query) % buckets_.size();
    buckets_[idx].output(query, count);
  }

 protected:
  boost::ptr_vector<LocalSink> buckets_;
};

void shuffle(int nbuckets, int argc, char* argv[])
{
  Shuffler shuffler(nbuckets);
  for (int i = 1; i < argc; ++i)
  {
    std::cout << "  processing " << argv[i] << std::endl;
    processOneInput(argv[i],
                    boost::bind(&Shuffler::output, &shuffler, _1, _2));
  }
  std::cout << "shuffling done" << std::endl;
}

// ======= reduce =======

std::unordered_map<string, int64_t> read_shard(int idx, int nbuckets)
{
  std::unordered_map<string, int64_t> queries;

  char buf[256];
  snprintf(buf, sizeof buf, "shard-%05d-of-%05d", idx, nbuckets);
  std::cout << "  reading " << buf << std::endl;
  {
    std::ifstream in(buf);
    string line;

    while (getline(in, line))
    {
      size_t tab = line.find('\t');
      if (tab != string::npos)
      {
        int64_t count = strtol(line.c_str() + tab, NULL, 10);
        if (count > 0)
        {
          queries[line.substr(0, tab)] += count;
        }
      }
    }
  }

  ::unlink(buf);
  return queries;
}

void reduce(const int nbuckets)
{
  for (int i = 0; i < nbuckets; ++i)
  {
    std::unordered_map<string, int64_t> queries(read_shard(i, nbuckets));

    // std::cout << "  sorting " << std::endl;
    std::vector<std::pair<int64_t, string>> counts;
    for (auto entry : queries)
    {
      counts.push_back(make_pair(entry.second, entry.first));
    }
    std::sort(counts.begin(), counts.end());

    char buf[256];
    snprintf(buf, sizeof buf, "count-%05d-of-%05d", i, nbuckets);
    std::ofstream out(buf);
    std::cout << "  writing " << buf << std::endl;
    for (auto it = counts.rbegin(); it != counts.rend(); ++it)
    {
      out << it->first << '\t' << it->second << '\n';
    }
  }

  std::cout << "reducing done" << std::endl;
}

// ======= merge =======
class Source
{
 public:
  explicit Source(std::ifstream* in)
    : in_(in),
      count_(0),
      query_()
  {
  }

  bool next()
  {
    string line;
    if (getline(*in_, line))
    {
      size_t tab = line.find('\t');
      if (tab != string::npos)
      {
        count_ = strtol(line.c_str(), NULL, 10);
        if (count_ > 0)
        {
          query_ = line.substr(tab+1);
          return true;
        }
      }
    }
    return false;
  }

  bool operator<(const Source& rhs) const
  {
    return count_ < rhs.count_;
  }

  void output(std::ostream& out)
  {
    out << count_ << '\t' << query_ << '\n';
  }

 private:
  std::ifstream* in_;
  int64_t count_;
  string query_;
};

void merge(const int nbuckets)
{
  boost::ptr_vector<std::ifstream> inputs;
  std::vector<Source> keys;

  for (int i = 0; i < nbuckets; ++i)
  {
    char buf[256];
    snprintf(buf, sizeof buf, "count-%05d-of-%05d", i, nbuckets);
    inputs.push_back(new std::ifstream(buf));
    Source rec(&inputs.back());
    if (rec.next())
    {
      keys.push_back(rec);
    }
    ::unlink(buf);
  }

  std::ofstream out("output");
  std::make_heap(keys.begin(), keys.end());
  while (!keys.empty())
  {
    std::pop_heap(keys.begin(), keys.end());
    keys.back().output(out);
    // out.writeRecord(keys.back().data);

    if (keys.back().next())
    {
      std::push_heap(keys.begin(), keys.end());
    }
    else
    {
      keys.pop_back();
    }
  }
  std::cout << "merging done\n";
}

int main(int argc, char* argv[])
{
  int nbuckets = 10;
  shuffle(nbuckets, argc, argv);
  reduce(nbuckets);
  merge(nbuckets);
}

ext: cc


text:
/*
 * Created by Anton Zhigaylo <antoooon@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the MIT License
 */

#pragma once

#include <map>
#include <tuple>
#include <string>
#include <vector>
#include <utility>
#include <iostream>

#include <boost/optional.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>

namespace Parsers
{

class CCsvPrserImpl final
{
    public:
        struct router_item_t
        {
            typedef std::pair <std::uint16_t, std::string> mapp_item_t;

            bool        topic_sub;
            uint32_t    number;
            std::string mqtt_topic;
            std::vector<mapp_item_t> mapping;
        };
        typedef std::pair <std::string, router_item_t> gwt_item_t;

        explicit CCsvPrserImpl(const std::string& csv_prj_path, const std::string& table_path);
        ~CCsvPrserImpl();

        void parseCsvProject();

    private:
        typedef std::pair <std::string, uint32_t> header_item_t;
        typedef std::tuple<std::string, std::string, std::string, std::string> gtw_item_tuple_t;

        CCsvPrserImpl(const CCsvPrserImpl&) = delete;
        CCsvPrserImpl& operator=(const CCsvPrserImpl&) = delete;

        bool createGtwFile(const std::string &gtw_file, const std::vector<gtw_item_tuple_t>& gtw_vector);
        bool createValueNode(const std::string& value_str, boost::property_tree::ptree& value_node);
        bool prepareHeaderMap(const std::string &csv_file, std::map <std::string, uint32_t>& header_map);
        bool prepareGtwVector(const std::string &csv_file, std::vector<gtw_item_tuple_t>& gtw_vector);

        boost::optional<uint32_t> getColumByName(const std::string &header, const std::string &col_name);
        boost::optional<std::string> getColumValueByNum(uint32_t colum_num, const std::string &data_str);
        std::string getDate_str();

        std::string m_table_path;
        std::string m_csv_prj_path;
        std::map <std::string, uint32_t> m_header_map;
        std::vector<gtw_item_tuple_t>    m_gtw_vector;
};

} //namespace Parsers

max_stars_repo_name: azhigaylo/csvparser

max_issues_repo_name: azhigaylo/csvparser

max_forks_repo_name: azhigaylo/csvparser


text:
/**
 *  @file
 *  @copyright defined in eos/LICENSE
 */
#pragma once
#include <appbase/application.hpp>
#include <fc/exception/exception.hpp>

#include <fc/reflect/reflect.hpp>

#include <boost/asio.hpp>

#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/config/asio.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include <websocketpp/logger/stub.hpp>

namespace eosio {
   using namespace appbase;
   using std::unordered_map;

   /**
    * @brief A callback function provided to a URL handler to
    * allow it to specify the HTTP response code and body
    *
    * Arguments: response_code, response_body
    */
   using url_response_callback = std::function<void(int,string)>;

   /**
    * @brief Callback type for a URL handler
    *
    * URL handlers have this type
    *
    * The handler must guarantee that url_response_callback() is called;
    * otherwise, the connection will hang and result in a memory leak.
    *
    * Arguments: url, request_body, response_callback
    **/
   using url_handler = std::function<void(string,string,url_response_callback)>;

   /**
    * @brief An API, containing URLs and handlers
    *
    * An API is composed of several calls, where each call has a URL and
    * a handler. The URL is the path on the web server that triggers the
    * call, and the handler is the function which implements the API call
    */
   using api_description = std::map<string, url_handler>;

   struct http_plugin_defaults {
      //If not empty, this string is prepended on to the various configuration
      // items for setting listen addresses
      string address_config_prefix;
      //If empty, unix socket support will be completely disabled. If not empty,
      // unix socket support is enabled with the given default path (treated relative
      // to the datadir)
      string default_unix_socket_path;
      //If non 0, HTTP will be enabled by default on the given port number. If
      // 0, HTTP will not be enabled by default
      uint16_t default_http_port{0};
   };

   /**
    * @brief Internal websocketpp socket config structure
    */
   namespace http_config {
      namespace asio = boost::asio;

      template<typename SocketType>
      struct asio_with_stub_log : public websocketpp::config::asio {
         typedef asio_with_stub_log type;
         typedef asio base;

         typedef base::concurrency_type concurrency_type;

         typedef base::request_type request_type;
         typedef base::response_type response_type;

         typedef base::message_type message_type;
         typedef base::con_msg_manager_type con_msg_manager_type;
         typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;

         typedef websocketpp::log::stub elog_type;
         typedef websocketpp::log::stub alog_type;

         typedef base::rng_type rng_type;

         struct transport_config : public base::transport_config {
            typedef type::concurrency_type concurrency_type;
            typedef type::alog_type alog_type;
            typedef type::elog_type elog_type;
            typedef type::request_type request_type;
            typedef type::response_type response_type;
            typedef SocketType socket_type;
         };

         typedef websocketpp::transport::asio::endpoint<transport_config> transport_type;
      };
   }

   /**
    * @brief WebSocket connection type (shared pointer)
    */
   template<typename SocketType>
   using ws_connection = typename websocketpp::server<eosio::http_config::asio_with_stub_log<SocketType>>::connection_ptr;

   /**
    * @brief WebSocket message type (shared pointer)
    */
   template<typename SocketType>
   using ws_message = typename websocketpp::server<eosio::http_config::asio_with_stub_log<SocketType>>::message_ptr;

   /**
    * @brief Callback type for a WebSocket message handler
    *
    * Arguments: ws_connection, ws_message
    */
   template<typename SocketType>
   using ws_message_handler = std::function<void(ws_connection<SocketType>, ws_message<SocketType>)>;

   /**
    * @brief Callback type called after websocket connection is terminated
    *
    * Arguments: ws_connection
    */
   template<typename SocketType>
   using ws_connection_termination_handler = std::function<void(ws_connection<SocketType>)>;

   /**
    * @brief Internal websocketpp connection type
    */
   using basic_socket_endpoint = websocketpp::transport::asio::basic_socket::endpoint;

   /**
    * @brief Internal websocketpp connection type for TLS
    */
   using tls_socket_endpoint = websocketpp::transport::asio::tls_socket::endpoint;

   /**
    * @brief Equality function of ws_connection
    */
   template<typename SocketType>
   struct ws_connection_equal {
      bool operator()(const ws_connection<SocketType> &lhs, const ws_connection<SocketType> &rhs) const {
         return lhs.get() == rhs.get();
      }
   };

   /**
    * @brief Hash function of ws_connection
    */
   template<typename SocketType>
   struct ws_connection_hash {
      size_t operator()(const ws_connection<SocketType> &conn) const {
         return reinterpret_cast<size_t>(conn.get());
      }
   };

   /**
    *  This plugin starts an HTTP server and dispatches queries to
    *  registered handles based upon URL. The handler is passed the
    *  URL that was requested and a callback method that should be
    *  called with the response code and body.
    *
    *  The handler will be called from the appbase application io_service
    *  thread.  The callback can be called from any thread and will
    *  automatically propagate the call to the http thread.
    *
    *  The HTTP service will run in its own thread with its own io_service to
    *  make sure that HTTP request processing does not interfere with other
    *  plugins.
    */
   class http_plugin : public appbase::plugin<http_plugin>
   {
      public:
        http_plugin();
        virtual ~http_plugin();

        //must be called before initialize
        static void set_defaults(const http_plugin_defaults config);

        APPBASE_PLUGIN_REQUIRES()
        virtual void set_program_options(options_description&, options_description& cfg) override;

        void plugin_initialize(const variables_map& options);
        void plugin_startup();
        void plugin_shutdown();

        void add_handler(const string& url, const url_handler&);
        void add_api(const api_description& api) {
           for (const auto& call : api)
              add_handler(call.first, call.second);
        }

        // standard exception handling for api handlers
        static void handle_exception( const char *api_name, const char *call_name, const string& body, url_response_callback cb );

        bool is_on_loopback() const;
        bool is_secure() const;

        void add_ws_handler(const string& url, ws_message_handler<basic_socket_endpoint> handler);
        void add_wss_handler(const string& url, ws_message_handler<tls_socket_endpoint> handler);
        void set_ws_connection_termination_handler(ws_connection_termination_handler<basic_socket_endpoint> handler);
        void set_wss_connection_termination_handler(ws_connection_termination_handler<tls_socket_endpoint> handler);

        bool verbose_errors()const;

      private:
        std::unique_ptr<class http_plugin_impl> my;
   };

   /**
    * @brief Structure used to create JSON error responses
    */
   struct error_results {
      uint16_t code;
      string message;

      struct error_info {
         int64_t code;
         string name;
         string what;

         struct error_detail {
            string message;
            string file;
            uint64_t line_number;
            string method;
         };

         vector<error_detail> details;

         static const uint8_t details_limit = 10;

         error_info() {};

         error_info(const fc::exception& exc, bool include_all_log) {
            code = exc.code();
            name = exc.name();
            what = exc.what();
            for (auto itr = exc.get_log().begin(); itr != exc.get_log().end(); ++itr) {
               // Prevent sending trace that are too big
               // Append error
               error_detail detail = {
                     itr->get_message(), itr->get_context().get_file(),
                     itr->get_context().get_line_number(), itr->get_context().get_method()
               };
               details.emplace_back(detail);

               if (!include_all_log) break;
               if (details.size() >= details_limit) break;
           }
         }
      };

      error_info error;
   };
}

FC_REFLECT(eosio::error_results::error_info::error_detail, (message)(file)(line_number)(method))
FC_REFLECT(eosio::error_results::error_info, (code)(name)(what)(details))
FC_REFLECT(eosio::error_results, (code)(message)(error))

max_stars_repo_name: InfraBlockchain/infrablockchain

max_issues_repo_name: InfraBlockchain/infrablockchain


text:
#pragma once

#include <cstdint>
#include <map>
#include <memory>
#include <set>
#include <vector>

#ifdef BOOST_PYTHON_EXTENSIONS
#include <boost/python.hpp>
namespace p = boost::python;
#endif

#include "../Variable.hpp"
#include "it/EntropyCalculator.hpp"

namespace mist {

namespace algorithm {

/** Interface for processing tuples in the TupleSpace
 *
 * A class can specialize the TupleSpaceTraverser to gain access to the stream
 * of tuples generated by TupleSpace::traverse family of functions.
 */
class TupleSpaceTraverser {
public:
  using tuple_t = Variable::indexes;
  using count_t = std::uint64_t;
  virtual void process_tuple(count_t tuple_no, tuple_t const& tuple) = 0;
  virtual void process_tuple_entropy(
      count_t tuple_no, tuple_t const& tuple, it::Entropy const& e) = 0;
};

/** Tuple Space defines the set of tuples over which to run a computation
 * search.
 */
class TupleSpace
{
public:
  using tuple_t = Variable::indexes;
  using index_t = Variable::index_t;
  using count_t = std::uint64_t;
  TupleSpace();
  TupleSpace(int N, int d);
  ~TupleSpace();
  /** Define a named logical group of variables
   * @param name group name
   * @param vars set of variables in the group, duplicates will be ignored
   * @return index of created variable group
   * @throws TupleSpaceException variable already listed in existing variable
   * group
   */
  int addVariableGroup(std::string const& name, tuple_t const& vars);
  /** Add a variable group tuple
   *
   * The cross product of groups in the group tuple generates a set of
   * variable tuples that will be added to the TupleSpace by
   * TupleSpaceTupleProducer.
   *
   * @param groups Array of group names
   * @throws TupleSpaceException group does not exists
   */
  void addVariableGroupTuple(std::vector<std::string> const& groups);
  /** Add a variable group tuple
   *
   * The cross product of groups in the group tuple generates a set of
   * variable tuples that will be added to the TupleSpace by
   * TupleSpaceTupleProducer.
   *
   * @param groups Array of group indexed by order created
   * @throws TupleSpaceException group index out of range
   */
  void addVariableGroupTuple(tuple_t const& groups);
  /** Get variable names
   */
  std::vector<std::string> names() const;
  /** Set variable names
   */
  void set_names(std::vector<std::string> const& names);
  int tupleSize() const;

#if BOOST_PYTHON_EXTENSIONS
  int pyAddVariableGroup(std::string const& name, p::list const& list);
  void pyAddVariableGroupTuple(p::list const& list);
#endif

  /** Calculate the size of the tuple space, i.e. count the generated number of
   * tuples.
   */
  count_t count_tuples() const;
  count_t count_tuples_group_tuple(tuple_t const&) const;
  tuple_t find_tuple(count_t target) const;
  tuple_t const& getVariableGroup(int index) const;
  tuple_t const& getVariableGroup(std::string const& name) const;
  std::vector<std::size_t> const& getVariableGroupSizes() const;
  tuple_t const& getVariableGroupAppearances(int index) const;
  std::vector<tuple_t> const& getVariableGroups() const;
  std::vector<tuple_t> const& getVariableGroupTuples() const;

  /** Walk through all tuples in the tuple space
   * @param traverser Process each tuple with methods defined in specialization
   */
  void traverse(TupleSpaceTraverser& traverser) const;
  /** Walk through as subset of tuples in the tuple space
   *
   * TupleSpace generates an ordered list of tuples, that can begin at any
   * position in the list.
   *
   * @param start Begin the walk at tuple in position start
   * @param stop End the walk at tuple in position stop
   * @param traverser Process each tuple with methods defined in specialization
   */
  void traverse(count_t start, count_t stop, TupleSpaceTraverser& traverser) const;
  /** Walk through all tuples in the tuple space, computing entropy values as
   * you go.
   *
   * Some it::Measure classes compute the entropy values of sub-tuples. It is
   * most efficient to compute these as you walk through the tuple space so
   * intermediary values can be reused many times.
   *
   * @param ecalc it::EntropyCalculator object to perform entropy computations
   * @param traverser Process each tuple with methods defined in specialization
   */
  void traverse_entropy(it::EntropyCalculator &ecalc, TupleSpaceTraverser& traverser) const;
  /** Walk through a subset of tuples in the tuple space, computing entropy values as
   * you go.
   */
  void traverse_entropy(count_t start, count_t stop, it::EntropyCalculator &ecalc, TupleSpaceTraverser& traverser) const;

private:
  // variable names, e.g. from data header
  std::vector<std::string> variableNames;
  // groups of variables that construct a tuple
  std::vector<tuple_t> variableGroups;
  std::vector<std::size_t> variableGroupSizes;
  // names for the variable groups and their identifying index
  std::map<std::string, int> variableGroupNames;
  // list of groups that define variable tuples
  std::vector<tuple_t> variableGroupTuples;
  // keep track of seen variables to detect duplicates
  std::set<int> seen_vars;
  int tuple_size = 0;
};

class TupleSpaceException : public std::exception
{
private:
  std::string msg;

public:
  TupleSpaceException(std::string const& method, std::string const& msg)
    : msg("TupleSpace" + method + " : " + msg)
  {}
  virtual const char* what() const throw() { return msg.c_str(); };
};

} // algorithm
} // mist

max_stars_repo_name: andbanman/mist

max_issues_repo_name: andbanman/mist

max_forks_repo_name: andbanman/mist


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

#include <boost/simd/swar/functions/sort.hpp>
#include <nt2/sdk/meta/size_as.hpp>
#include <nt2/sdk/meta/value_as.hpp>
#include <nt2/core/container/dsl/size.hpp>
#include <nt2/core/container/dsl/value_type.hpp>

namespace nt2 { namespace ext
{
  template<class Domain, int N, class Expr>
  struct  size_of<tag::sort_,Domain,N,Expr>
        : meta::size_as<Expr,0>
  {};

  template<class Domain, int N, class Expr>
  struct  value_type<tag::sort_,Domain,N,Expr>
        : meta::value_as<Expr,0>
  {};
} }

#endif