<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

// MOOSE includes
#include "ResidualBalanceMultiApp.h"
#include "TimeStepper.h"
#include "LayeredSideFluxAverage.h"
#include "AllLocalDofIndicesThread.h"
#include "Output.h"
#include "Console.h"

// libMesh includes
#include "libmesh/mesh_tools.h"

//may not be necessary, but it can't hurt:
//#include "MethodATransient.h"
// I think it is very necessary
#include "ResidualBalanceTransient.h"

template<>
InputParameters validParams<ResidualBalanceMultiApp>()
{
  InputParameters params = validParams<MultiApp>();
  params += validParams<TransientInterface>();

  params.addParam<bool>("sub_cycling", false, "Set to true to allow this MultiApp to take smaller timesteps than the rest of the simulation.  More than one timestep will be performed for each 'master' timestep");

  params.addParam<bool>("interpolate_transfers", false, "Only valid when sub_cycling.  This allows transferred values to be interpolated over the time frame the MultiApp is executing over when sub_cycling");

  params.addParam<bool>("detect_steady_state", false, "If true then while sub_cycling a steady state check will be done.  In this mode output will only be done once the MultiApp reaches the target time or steady state is reached");

  params.addParam<Real>("steady_state_tol", 1e-8, "The relative difference between the new solution and the old solution that will be considered to be at steady state");

  params.addParam<bool>("output_sub_cycles", false, "If true when sub_cycling every sub-cycle will be output.");
  params.addParam<bool>("print_sub_cycles", true, "Toggle the display of sub-cycles on the screen.");

  params.addParam<unsigned int>("max_failures", 0, "Maximum number of solve failures tolerated while sub_cycling.");

  params.addParam<bool>("tolerate_failure", false, "If true this MultiApp won't participate in dt decisions and will always be fast-forwarded to the current time.");

  params.addParam<bool>("catch_up", false, "If true this will allow failed solves to attempt to 'catch up' using smaller timesteps.");

  params.addParam<Real>("max_catch_up_steps", 2, "Maximum number of steps to allow an app to take when trying to catch back up after a failed solve.");

  return params;
}

ResidualBalanceMultiApp::ResidualBalanceMultiApp(const std::string & name, InputParameters parameters):
    MultiApp(name, parameters),
    _sub_cycling(getParam<bool>("sub_cycling")),
    _interpolate_transfers(getParam<bool>("interpolate_transfers")),
    _detect_steady_state(getParam<bool>("detect_steady_state")),
    _steady_state_tol(getParam<Real>("steady_state_tol")),
    _output_sub_cycles(getParam<bool>("output_sub_cycles")),
    _max_failures(getParam<unsigned int>("max_failures")),
    _tolerate_failure(getParam<bool>("tolerate_failure")),
    _failures(0),
    _catch_up(getParam<bool>("catch_up")),
    _max_catch_up_steps(getParam<Real>("max_catch_up_steps")),
    _first(declareRestartableData<bool>("first", true)),
    _auto_advance(false),
    _print_sub_cycles(getParam<bool>("print_sub_cycles"))
    //_re_solved(false)
{
  // Transfer interpolation only makes sense for sub-cycling solves
  if (_interpolate_transfers && !_sub_cycling)
    mooseError("MultiApp " << _name << " is set to interpolate_transfers but is not sub_cycling!  That is not valid!");
}

ResidualBalanceMultiApp::~ResidualBalanceMultiApp()
{
  if (!_has_an_app)
    return;

  MPI_Comm swapped = Moose::swapLibMeshComm(_my_comm);

  for (unsigned int i = 0; i < _my_num_apps; i++)
  {  // this would not be painful if you used inheritance
    ResidualBalanceTransient * ex = _transient_executioners[i];
    // MethodATransient * ex = _transient_executioners[i];

    ex->postExecute();
  }

  // Swap back
  Moose::swapLibMeshComm(swapped);
}

NumericVector<Number> &
ResidualBalanceMultiApp::appTransferVector(unsigned int app, std::string var_name)
{
  if (std::find(_transferred_vars.begin(), _transferred_vars.end(), var_name) == _transferred_vars.end())
    _transferred_vars.push_back(var_name);

  if (_interpolate_transfers)
    return appProblem(app)->getAuxiliarySystem().system().get_vector("transfer");

  return appProblem(app)->getAuxiliarySystem().solution();
}

void
ResidualBalanceMultiApp::initialSetup()  //used to be init()
{
  MultiApp::initialSetup(); //this line gave an error. I don't remember this line

  if (!_has_an_app)
    return;

  MPI_Comm swapped = Moose::swapLibMeshComm(_my_comm);

  if (_has_an_app)
  {
    _transient_executioners.resize(_my_num_apps);
    // Grab Transient Executioners from each app
    for (unsigned int i=0; i<_my_num_apps; i++)
      setupApp(i);
  }

  // Swap back
  Moose::swapLibMeshComm(swapped);
}

void
ResidualBalanceMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
{
  if (_sub_cycling && !auto_advance)
    mooseError("TransientMultiApp with sub_cycling=true is not compatible with auto_advance=false");

  if (_catch_up && !auto_advance)
    mooseError("TransientMultiApp with catch_up=true is not compatible with auto_advance=false");

  if (!_has_an_app)
    return;

  _auto_advance = auto_advance;

  _console << "Solving MultiApp " << _name << std::endl;

// "target_time" must always be in global time
  target_time += _app.getGlobalTimeOffset();

  MPI_Comm swapped = Moose::swapLibMeshComm(_my_comm);

  int rank;
  int ierr;
  ierr = MPI_Comm_rank(_orig_comm, &rank); mooseCheckMPIErr(ierr);

  for (unsigned int i=0; i<_my_num_apps; i++)
  {

    FEProblem * problem = appProblem(_first_local_app + i);

    //MethodATransient * ex = _transient_executioners[i];
    ResidualBalanceTransient * ex = _transient_executioners[i];

    // The App might have a different local time from the rest of the problem
    Real app_time_offset = _apps[i]->getGlobalTimeOffset();

////// This is not necessary, because we are just going to work within the Picard Iteration Framework
//////
    //_re_solved=false;
    if ((ex->getTime() + app_time_offset) + 2e-14 >= target_time) // Maybe this MultiApp was already solved
    { ////dt = 0.0; // This seems to work, but it probably will break transient problems.
      //_re_solved=true;   //alternate method, more reprogramming, dt=0 worked better, or just commenting
      ////app_time_offset -= dt; // does not work: move the multi-app back in time so that it re-solves
      continue;  // This prevents multiapp re-solve
    }

// plan: set a flag instead of "continue." Use that flag to not advance multi-app in time.
//       Or step back before stepping forward.

    if (_sub_cycling)
    {
      Real time_old = ex->getTime() + app_time_offset;

      if (_interpolate_transfers)
      {
        AuxiliarySystem & aux_system = problem->getAuxiliarySystem();
        System & libmesh_aux_system = aux_system.system();

        NumericVector<Number> & solution = *libmesh_aux_system.solution;
        NumericVector<Number> & transfer_old = libmesh_aux_system.get_vector("transfer_old");

        solution.close();

        // Save off the current auxiliary solution
        transfer_old = solution;

        transfer_old.close();

        // Snag all of the local dof indices for all of these variables
        AllLocalDofIndicesThread aldit(libmesh_aux_system, _transferred_vars);
        ConstElemRange & elem_range = *problem->mesh().getActiveLocalElementRange();
        Threads::parallel_reduce(elem_range, aldit);

        _transferred_dofs = aldit._all_dof_indices;
      }

      // Disable/enable output for sub cycling
      problem->allowOutput(_output_sub_cycles); // disables all outputs, including console
      problem->allowOutput<Console>(_print_sub_cycles); // re-enables Console to print, if desired

      ex->setTargetTime(target_time-app_time_offset);

//      unsigned int failures = 0;

      bool at_steady = false;

      // Now do all of the solves we need
      while (true)
      {
        if (_first != true)
        {
          //if(_re_solved == false)            //
            ex->incrementStepOrReject();
          //else
          //  ex->re_incrementStepOrReject(); //
        }
        _first = false;

        if (!(!at_steady && ex->getTime() + app_time_offset + 2e-14 < target_time))
          break;

        ex->computeDT();

        if (_interpolate_transfers)
        {
          // See what time this executioner is going to go to.
          Real future_time = ex->getTime() + app_time_offset + ex->getDT();

          // How far along we are towards the target time:
          Real step_percent = (future_time - time_old) / (target_time - time_old);

          Real one_minus_step_percent = 1.0 - step_percent;

          // Do the interpolation for each variable that was transferred to
          FEProblem * problem = appProblem(_first_local_app + i);
          AuxiliarySystem & aux_system = problem->getAuxiliarySystem();
          System & libmesh_aux_system = aux_system.system();

          NumericVector<Number> & solution = *libmesh_aux_system.solution;
          NumericVector<Number> & transfer = libmesh_aux_system.get_vector("transfer");
          NumericVector<Number> & transfer_old = libmesh_aux_system.get_vector("transfer_old");

          solution.close(); // Just to be sure
          transfer.close();
          transfer_old.close();

          std::set<dof_id_type>::iterator it  = _transferred_dofs.begin();
          std::set<dof_id_type>::iterator end = _transferred_dofs.end();

          for (; it != end; ++it)
          {
            dof_id_type dof = *it;
            solution.set(dof, (transfer_old(dof) * one_minus_step_percent) + (transfer(dof) * step_percent));
//            solution.set(dof, transfer_old(dof));
//            solution.set(dof, transfer(dof));
//            solution.set(dof, 1);
          }

          solution.close();
        }

        ex->takeStep();

        bool converged = ex->lastSolveConverged();

        if (!converged)
        {
          mooseWarning("While sub_cycling "<<_name<<_first_local_app+i<<" failed to converge!"<<std::endl);
          _failures++;

          if (_failures > _max_failures)
            mooseError("While sub_cycling "<<_name<<_first_local_app+i<<" REALLY failed!"<<std::endl);
        }

        Real solution_change_norm = ex->getSolutionChangeNorm();

        if (_detect_steady_state)
          _console << "Solution change norm: " << solution_change_norm << std::endl;

        if (converged && _detect_steady_state && solution_change_norm < _steady_state_tol)
        {
          _console << "Detected Steady State!  Fast-forwarding to " << target_time << std::endl;

          at_steady = true;

          // Indicate that the next output call (occurs in ex->endStep()) should output, regardless of intervals etc...
          problem->forceOutput();

          // Clean up the end
          ex->endStep(target_time-app_time_offset);
        }
        else
          ex->endStep();
      }

      // If we were looking for a steady state, but didn't reach one, we still need to output one more time, regardless of interval
      if (!at_steady)
        problem->outputStep(EXEC_FORCED);

    } // sub_cycling
    else if (_tolerate_failure)
    {
      ex->takeStep(dt);
      ex->endStep(target_time-app_time_offset);
    }
    else
    {
      //if (_re_solved)
      //  _console << "RE-Solving Normal Step!" << std::endl;
      //else
        _console << "Solving Normal Step!" << std::endl;
      if (auto_advance)
      { if (_first != true)
        { //_console << "I shot the sheriff" << std::endl;
          //if(_re_solved)
          //  ex->re_incrementStepOrReject();
          //else
            ex->incrementStepOrReject();
        }
      }
      if (auto_advance)
        problem->allowOutput(true);

      //if (_re_solved)
      //  ex->re_takeStep(dt); //we could do it this way because the executioner can't call our methods
                             // I don't know how to pass a pointer to this object to ex
      else
        ex->takeStep(dt);

      if (auto_advance)
      {
        ex->endStep();

        if (!ex->lastSolveConverged())
        {
          mooseWarning(_name << _first_local_app+i << " failed to converge!" << std::endl);

          if (_catch_up)
          {
            _console << "Starting Catch Up!" << std::endl;

            bool caught_up = false;

            unsigned int catch_up_step = 0;

            Real catch_up_dt = dt/2;

            while (!caught_up && catch_up_step < _max_catch_up_steps)
            {
              Moose::err << "Solving " << _name << "catch up step " << catch_up_step << std::endl;
              ex->incrementStepOrReject();

              ex->computeDT();
              ex->takeStep(catch_up_dt); // Cut the timestep in half to try two half-step solves

              if (ex->lastSolveConverged())
              {
                if (ex->getTime() + app_time_offset + ex->timestepTol()*std::abs(ex->getTime()) >= target_time)
                {
                  problem->outputStep(EXEC_FORCED);
                  caught_up = true;
                }
              }
              else
                catch_up_dt /= 2.0;

              ex->endStep();

              catch_up_step++;
            }

            if (!caught_up)
              mooseError(_name << " Failed to catch up!\n");

          }
        }
      }
    }

    // Re-enable all output (it may of been disabled by sub-cycling)
    problem->allowOutput(true);

    //_re_solved = false;// I think this should go here, at ~163 now
  }

  _first = false;

  // Swap back
  Moose::swapLibMeshComm(swapped);

  _transferred_vars.clear();

  _console << "Finished Solving MultiApp " << _name << std::endl;
}

void
ResidualBalanceMultiApp::advanceStep()
{
  if (!_auto_advance)
  {
    for (unsigned int i=0; i<_my_num_apps; i++)
    {
      /*FEProblem * problem =*/ appProblem(_first_local_app + i);
      // Transient * ex = _transient_executioners[i];
      // MethodATransient * ex = _transient_executioners[i];
      ResidualBalanceTransient * ex = _transient_executioners[i];

      ex->endStep();
      ex->incrementStepOrReject();
      //_console << "Jaron, here's your sign" << std::endl;

      // try this and comment previous line.
      // jk, advanceStep() is not called.
      /*if (_re_solved)
      {
        _console << "RE-increment" << std::endl;
        ex->re_incrementStepOrReject();
      }
      else
      {
        _console << "regular increment Step" << std::endl;
        ex->incrementStepOrReject();
      } */
    }
  }
}

Real
ResidualBalanceMultiApp::computeDT()
{
  if (_sub_cycling) // Bow out of the timestep selection dance
    return std::numeric_limits<Real>::max();

  Real smallest_dt = std::numeric_limits<Real>::max();

  if (_has_an_app)
  {
    MPI_Comm swapped = Moose::swapLibMeshComm(_my_comm);

    for (unsigned int i=0; i<_my_num_apps; i++)
    {
      // MethodATransient * ex = _transient_executioners[i];
      ResidualBalanceTransient * ex = _transient_executioners[i];
      ex->computeDT();
      Real dt = ex->getDT();

      smallest_dt = std::min(dt, smallest_dt);
    }

    // Swap back
    Moose::swapLibMeshComm(swapped);
  }

  if (_tolerate_failure) // Bow out of the timestep selection dance, we do this down here because we need to call computeConstrainedDT at least once for these executioners...
    return std::numeric_limits<Real>::max();

  _communicator.min(smallest_dt);
  return smallest_dt;
}

void
ResidualBalanceMultiApp::resetApp(unsigned int global_app, Real /*time*/)  // FIXME: Note that we are passing in time but also grabbing it below
{
  if (hasLocalApp(global_app))
  {
    unsigned int local_app = globalAppToLocal(global_app);

    // Grab the current time the App is at so we can start the new one at the same place
    Real time = _transient_executioners[local_app]->getTime() + _apps[local_app]->getGlobalTimeOffset();

    // Reset the Multiapp
    MultiApp::resetApp(global_app, time);

    MPI_Comm swapped = Moose::swapLibMeshComm(_my_comm);

    // Setup the app, disable the output so that the initial condition does not output
    // When an app is reset the initial condition was effectively already output before reset
    FEProblem * problem = appProblem(local_app );
    problem->allowOutput(false);
    setupApp(local_app, time);
    problem->allowOutput(true);

    // Swap back
    Moose::swapLibMeshComm(swapped);
  }
}

void
ResidualBalanceMultiApp::setupApp(unsigned int i, Real /*time*/)  // FIXME: Should we be passing time?
{
  MooseApp * app = _apps[i];
  // Is it really this annoying? Is there a better way?
  //MethodATransient * ex = dynamic_cast<MethodATransient *>(app->getExecutioner());
  // if (!ex)
  ResidualBalanceTransient * ex = dynamic_cast<ResidualBalanceTransient *>(app->getExecutioner());
  if (!ex)
    mooseError("MultiApp " << _name << " is not using a Transient Executioner!");

  // Get the FEProblem for the current MultiApp
  FEProblem * problem = appProblem(_first_local_app + i);

  // Update the file numbers for the outputs from the parent application
  app->getOutputWarehouse().setFileNumbers(_app.getOutputFileNumbers());

  // Call initialization method of Executioner (Note, this preforms the output of the initial time step, if desired)
  ex->init();

  if (_interpolate_transfers)
  {
    AuxiliarySystem & aux_system = problem->getAuxiliarySystem();
    System & libmesh_aux_system = aux_system.system();

    // We'll store a copy of the auxiliary system's solution at the old time in here
    libmesh_aux_system.add_vector("transfer_old", false);

    // This will be where we'll transfer the value to for the "target" time
    libmesh_aux_system.add_vector("transfer", false);
  }

  ex->preExecute();
  problem->advanceState();
  _transient_executioners[i] = ex;
}

//bool ResidualBalanceMultiApp::is_re_solved()
//{
//  return _re_solved;
//}
<commit_msg>Delete ResidualBalanceMultiApp.C<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2015 Google Inc.
 *
 * 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.
 */

// Author: jmarantz@google.com (Joshua Marantz)

#include "net/instaweb/http/public/iframe_fetcher.h"

#include "net/instaweb/http/public/async_fetch.h"
#include "pagespeed/kernel/html/html_keywords.h"
#include "pagespeed/kernel/http/http_names.h"

namespace net_instaweb {

IframeFetcher::IframeFetcher() {
}

IframeFetcher::~IframeFetcher() {
}

void IframeFetcher::Fetch(const GoogleString& url,
                          MessageHandler* message_handler,
                          AsyncFetch* fetch) {
  fetch->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  fetch->response_headers()->Add(HttpAttributes::kContentType, "text/html");
  fetch->Write("<!DOCTYPE html>", message_handler);
  fetch->Write("", message_handler);

  // TODO(jmarantz): setting width to 1000x2000 appears to work OK for one
  // site and one screen, but we should probably synthesize this iframe in JS
  // using the actual physical screen size (since we don't know the site size
  // and cannot query it in JS even after onload due to same-origin policy).
  fetch->Write("Write(escaped_url, message_handler);
  fetch->Write("\">", message_handler);
  fetch->Write("", message_handler);
  fetch->Done(true);
}

}  // namespace net_instaweb
<commit_msg>Dynamically size the iframe based on the screen's physical size.<commit_after>/*
 * Copyright 2015 Google Inc.
 *
 * 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.
 */

// Author: jmarantz@google.com (Joshua Marantz)

#include "net/instaweb/http/public/iframe_fetcher.h"

#include "net/instaweb/http/public/async_fetch.h"
#include "pagespeed/kernel/html/html_keywords.h"
#include "pagespeed/kernel/http/http_names.h"

namespace net_instaweb {

IframeFetcher::IframeFetcher() {
}

IframeFetcher::~IframeFetcher() {
}

void IframeFetcher::Fetch(const GoogleString& url,
                          MessageHandler* message_handler,
                          AsyncFetch* fetch) {
  fetch->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  fetch->response_headers()->Add(HttpAttributes::kContentType, "text/html");

  // Avoid quirks-mode by specifying and HTML doctype.  This
  // simplifies the code below that tries to get the screen dimensions
  // via document.documentElement.
  fetch->Write("<!DOCTYPE html>", message_handler);
  fetch->Write("", message_handler);

  // We want to size the iframe to fit the physical screen, so we
  // create the iframe in JS.  The code as I have it here seems to
  // work reasonably well even with orientation changes.  Any attempts
  // I've made to try to adjust the iframe size in response to
  // orientation changes seem to make the behavior bad (e.g. cutting
  // off half the screen).  So I'm inclined to leave it as is for now.
  GoogleString escaped_url;
  HtmlKeywords::Escape(url, &escaped_url);
  GoogleString createIframe = StrCat(
      "");
  fetch->Write(createIframe, message_handler);
  fetch->Write("", message_handler);
  fetch->Done(true);
}

}  // namespace net_instaweb
<|endoftext|>


<commit_before>#ifndef TWISTEDCPP_PROTOCOL_CORE
#define TWISTEDCPP_PROTOCOL_CORE

#include "detail/sockets.hpp"

#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/optional.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <boost/ref.hpp>

#ifndef NDEBUG
#include <iostream>
#endif

namespace twisted {

template <typename ChildProtocol, typename BufferType>
class protocol_core : public std::enable_shared_from_this<ChildProtocol> {
public:
    typedef detail::socket_base socket_type;
    typedef boost::asio::steady_timer timer_type;
    typedef boost::asio::io_service::strand strand_type;
    typedef BufferType buffer_type;
    typedef typename buffer_type::iterator buffer_iterator;
    typedef typename buffer_type::const_iterator const_buffer_iterator;

    protocol_core() = default;
    protocol_core(protocol_core&&) = default;
    protocol_core& operator=(protocol_core&&) = default;

    void set_socket(std::unique_ptr<socket_type> socket) {
        _socket = std::move(socket);
    }

    void run_protocol() {
        auto self = this_protocol().shared_from_this();
        boost::asio::spawn(_socket->get_io_service(),
                           [this, self](boost::asio::yield_context yield) {
            _yield = boost::in_place(yield);

            try {
                _socket->do_handshake(*_yield);

                while (_socket->is_open()) {
                    auto bytes_read =
                        _socket->async_read_some(asio_buffer(), yield);
                    this_protocol().on_message(
                        buffer_begin(), std::next(buffer_begin(), bytes_read));
                }
            }
            catch (boost::system::system_error& connection_error) {
                handle_network_error(connection_error);
            }
            catch (...) {
                handle_user_error(std::current_exception());
            }
        });
    }

    template <typename Callable, typename... Args>
    void call_from_thread(Callable&& callable, Args&&... args) {
        _socket->get_io_service().post(std::bind(
            std::forward<Callable>(callable), std::forward<Args>(args)...));
    }

    template <typename Duration>
    void wait_for(const Duration& duration) const {
        boost::asio::high_resolution_timer timer(_socket->get_io_service(),
                                                 duration);
        timer.async_wait(*_yield);
    }

    template <typename Iter>
    void send_message(Iter begin, Iter end) {
        _socket->async_write(
            boost::asio::buffer(&*begin, std::distance(begin, end)), *_yield);
    }

    void send_buffers(const std::array<boost::asio::const_buffer, 2>& buffers) {
        _socket->async_write(buffers, *_yield);
    }

    /*
     * @brief default on_disconnect implementation; does nothing
     */
    void on_disconnect() {}

    /*
     * @brief default on_error implementation; swallows everything
     */
    void on_error(std::exception_ptr eptr) {
        try {
            std::rethrow_exception(eptr);
        }
        catch (const std::exception& excep) {
            print_exception_what(excep);
        }
    }

    void lose_connection() { _socket->close(); }

    /*
     * @brief CRTP wrapper for derived class access
     */
    ChildProtocol& this_protocol() {
        return *static_cast<ChildProtocol*>(this);
    }

    /*
     * @brief CRTP wrapper for derived class access
     */
    const ChildProtocol& this_protocol() const {
        return *static_cast<ChildProtocol*>(this);
    }

private:
#ifdef NDEBUG
    void handle_network_error(boost::system::system_error&) {
#else
    void handle_network_error(boost::system::system_error& connection_error) {
        print_connection_error(connection_error);
#endif
        this_protocol().on_disconnect();
    }

    void handle_user_error(const std::exception_ptr& excep) {
        this_protocol().on_error(excep);
    }

    void print_connection_error(
        const boost::system::system_error& connection_error) const {
        std::cerr << "Client disconnected with code " << connection_error.what()
                  << std::endl;
    }

    void print_exception_what(const std::exception& excep) {
        std::cerr << "Killing connection, exception in client handler: "
                  << excep.what() << std::endl;
    }

    buffer_iterator buffer_begin() {
        return this_protocol().read_buffer().begin();
    }

    buffer_iterator buffer_begin() const {
        return this_protocol().read_buffer().begin();
    }

    buffer_iterator buffer_end() { return this_protocol().read_buffer().end(); }

    buffer_iterator buffer_end() const {
        return this_protocol().read_buffer().end();
    }

    boost::asio::mutable_buffers_1 asio_buffer() {
        return boost::asio::buffer(&*buffer_begin(),
                                   std::distance(buffer_begin(), buffer_end()));
    }

private:
    boost::optional<boost::asio::yield_context> _yield;
    std::unique_ptr<socket_type> _socket;
};

} // namespace twisted

#endif
<commit_msg>added call_later<commit_after>#ifndef TWISTEDCPP_PROTOCOL_CORE
#define TWISTEDCPP_PROTOCOL_CORE

#include "detail/sockets.hpp"

#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/optional.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <boost/ref.hpp>

#ifndef NDEBUG
#include <iostream>
#endif

namespace twisted {

template <typename ChildProtocol, typename BufferType>
class protocol_core : public std::enable_shared_from_this<ChildProtocol> {
public:
    typedef detail::socket_base socket_type;
    typedef boost::asio::steady_timer timer_type;
    typedef boost::asio::io_service::strand strand_type;
    typedef BufferType buffer_type;
    typedef typename buffer_type::iterator buffer_iterator;
    typedef typename buffer_type::const_iterator const_buffer_iterator;

    protocol_core() = default;
    protocol_core(protocol_core&&) = default;
    protocol_core& operator=(protocol_core&&) = default;

    void set_socket(std::unique_ptr<socket_type> socket) {
        _socket = std::move(socket);
    }

    void run_protocol() {
        auto self = this_protocol().shared_from_this();
        boost::asio::spawn(_socket->get_io_service(),
                           [this, self](boost::asio::yield_context yield) {
            _yield = boost::in_place(yield);

            try {
                _socket->do_handshake(*_yield);

                while (_socket->is_open()) {
                    auto bytes_read =
                        _socket->async_read_some(asio_buffer(), yield);
                    this_protocol().on_message(
                        buffer_begin(), std::next(buffer_begin(), bytes_read));
                }
            }
            catch (boost::system::system_error& connection_error) {
                handle_network_error(connection_error);
            }
            catch (...) {
                handle_user_error(std::current_exception());
            }
        });
    }

    template <typename Duration, typename Callable>
    void call_later(Duration duration, Callable callable) {
        auto self = this_protocol().shared_from_this();
        // we pass our existing yield_context and not the io_service such that
        // both contexts run under the same strand
        boost::asio::spawn(*_yield, [this, duration, callable, self](
                                        boost::asio::yield_context yield) {
            boost::asio::high_resolution_timer timer(_socket->get_io_service(),
                                                     duration);
            timer.async_wait(yield);

            // we need to exchange the yield context so that that the user can
            // use the send_message function in the right context
            boost::optional<boost::asio::yield_context> old_yield(
                boost::in_place(*_yield));
            _yield = boost::in_place(yield);
            callable();
            _yield = boost::in_place(*old_yield);
        });
    }

    template <typename Callable, typename... Args>
    void call_from_thread(Callable&& callable, Args&&... args) {
        _socket->get_io_service().post(std::bind(
            std::forward<Callable>(callable), std::forward<Args>(args)...));
    }

    template <typename Duration>
    void wait_for(const Duration& duration) const {
        boost::asio::high_resolution_timer timer(_socket->get_io_service(),
                                                 duration);
        timer.async_wait(*_yield);
    }

    template <typename Iter>
    void send_message(Iter begin, Iter end) {
        _socket->async_write(
            boost::asio::buffer(&*begin, std::distance(begin, end)), *_yield);
    }

    void send_buffers(const std::array<boost::asio::const_buffer, 2>& buffers) {
        _socket->async_write(buffers, *_yield);
    }

    /*
     * @brief default on_disconnect implementation; does nothing
     */
    void on_disconnect() {}

    /*
     * @brief default on_error implementation; swallows everything
     */
    void on_error(std::exception_ptr eptr) {
        try {
            std::rethrow_exception(eptr);
        }
        catch (const std::exception& excep) {
            print_exception_what(excep);
        }
    }

    void lose_connection() { _socket->close(); }

    /*
     * @brief CRTP wrapper for derived class access
     */
    ChildProtocol& this_protocol() {
        return *static_cast<ChildProtocol*>(this);
    }

    /*
     * @brief CRTP wrapper for derived class access
     */
    const ChildProtocol& this_protocol() const {
        return *static_cast<ChildProtocol*>(this);
    }

private:
#ifdef NDEBUG
    void handle_network_error(boost::system::system_error&) {
#else
    void handle_network_error(boost::system::system_error& connection_error) {
        print_connection_error(connection_error);
#endif
        this_protocol().on_disconnect();
    }

    void handle_user_error(const std::exception_ptr& excep) {
        this_protocol().on_error(excep);
    }

    void print_connection_error(
        const boost::system::system_error& connection_error) const {
        std::cerr << "Client disconnected with code " << connection_error.what()
                  << std::endl;
    }

    void print_exception_what(const std::exception& excep) {
        std::cerr << "Killing connection, exception in client handler: "
                  << excep.what() << std::endl;
    }

    buffer_iterator buffer_begin() {
        return this_protocol().read_buffer().begin();
    }

    buffer_iterator buffer_begin() const {
        return this_protocol().read_buffer().begin();
    }

    buffer_iterator buffer_end() { return this_protocol().read_buffer().end(); }

    buffer_iterator buffer_end() const {
        return this_protocol().read_buffer().end();
    }

    boost::asio::mutable_buffers_1 asio_buffer() {
        return boost::asio::buffer(&*buffer_begin(),
                                   std::distance(buffer_begin(), buffer_end()));
    }

private:
    boost::optional<boost::asio::yield_context> _yield;
    std::unique_ptr<socket_type> _socket;
};

} // namespace twisted

#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Google Inc.
 *
 * 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.
 */

// Author: pulkitg@google.com (Pulkit Goyal)

#include "net/instaweb/util/public/property_store.h"

#include "base/logging.h"
#include "net/instaweb/util/public/abstract_mutex.h"
#include "net/instaweb/util/public/property_cache.h"

namespace net_instaweb {

PropertyStore::PropertyStore() {
}

PropertyStore::~PropertyStore() {
}

PropertyStoreGetCallback::PropertyStoreGetCallback(
    AbstractMutex* mutex,
    PropertyPage* page,
    bool is_cancellable,
    BoolCallback* done)
    : mutex_(mutex),
      page_(page),
      is_cancellable_(is_cancellable),
      done_(done),
      delete_when_done_(false),
      done_called_(false) {
}

PropertyStoreGetCallback::~PropertyStoreGetCallback() {
}

void PropertyStoreGetCallback::FastFinishLookup() {
  if (!is_cancellable_) {
    // Returns early as it is in non-cancelable mode.
    return;
  }

  // Call done callback if it is not yet called.
  BoolCallback* done = NULL;
  {
    ScopedMutex lock(mutex());
    if (done_ == NULL) {
      return;
    }
    // NULL out page_ since we shouldn't be touching it any longer.
    page_ = NULL;
    done = done_;
    done_ = NULL;
  }

  // Don't run callback while holding lock.
  done->Run(false);
}

void PropertyStoreGetCallback::Done(bool success) {
  BoolCallback* done = NULL;
  bool delete_this = false;
  {
    ScopedMutex lock(mutex());
    DCHECK(!done_called_);
    // done_ will be NULL if FastFinishLookup() is called, though Done() is not
    // yet called.
    if (done_ != NULL) {
      page_ = NULL;
      done = done_;
      done_ = NULL;
    }
    delete_this = delete_when_done_;
    done_called_ = true;
  }

  // Call done callback if it is not yet called.
  if (done != NULL) {
    done->Run(success);
  }

  // If DeleteWhenDone() is already called, delete this.
  if (delete_this) {
    delete this;
  }
}

void PropertyStoreGetCallback::DeleteWhenDone() {
  {
    ScopedMutex lock(mutex());
    if (delete_when_done_) {
      LOG(DFATAL) << "PropertyStoreGetCallback::DeleteWhenDone() "
                  << "is called twice.";
    }
    delete_when_done_ = true;
    if (!done_called_) {
      // Returns if Done() is not yet called.
      return;
    }
  }
  delete this;
}

bool PropertyStoreGetCallback::AddPropertyValueProtobufToPropertyPage(
      const PropertyCache::Cohort* cohort,
      const PropertyValueProtobuf& pcache_value,
      int64 min_write_timestamp_ms) {
  ScopedMutex lock(mutex());
  if (page() == NULL || !page()->IsCacheValid(min_write_timestamp_ms)) {
    return false;
  }
  page()->AddValueFromProtobuf(cohort, pcache_value);
  return true;
}

}  // namespace net_instaweb
<commit_msg>Setting enable_get_cancellation_ to false by default.<commit_after>/*
 * Copyright 2013 Google Inc.
 *
 * 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.
 */

// Author: pulkitg@google.com (Pulkit Goyal)

#include "net/instaweb/util/public/property_store.h"

#include "base/logging.h"
#include "net/instaweb/util/public/abstract_mutex.h"
#include "net/instaweb/util/public/property_cache.h"

namespace net_instaweb {

PropertyStore::PropertyStore()
    : enable_get_cancellation_(false) {
}

PropertyStore::~PropertyStore() {
}

PropertyStoreGetCallback::PropertyStoreGetCallback(
    AbstractMutex* mutex,
    PropertyPage* page,
    bool is_cancellable,
    BoolCallback* done)
    : mutex_(mutex),
      page_(page),
      is_cancellable_(is_cancellable),
      done_(done),
      delete_when_done_(false),
      done_called_(false) {
}

PropertyStoreGetCallback::~PropertyStoreGetCallback() {
}

void PropertyStoreGetCallback::FastFinishLookup() {
  if (!is_cancellable_) {
    // Returns early as it is in non-cancelable mode.
    return;
  }

  // Call done callback if it is not yet called.
  BoolCallback* done = NULL;
  {
    ScopedMutex lock(mutex());
    if (done_ == NULL) {
      return;
    }
    // NULL out page_ since we shouldn't be touching it any longer.
    page_ = NULL;
    done = done_;
    done_ = NULL;
  }

  // Don't run callback while holding lock.
  done->Run(false);
}

void PropertyStoreGetCallback::Done(bool success) {
  BoolCallback* done = NULL;
  bool delete_this = false;
  {
    ScopedMutex lock(mutex());
    DCHECK(!done_called_);
    // done_ will be NULL if FastFinishLookup() is called, though Done() is not
    // yet called.
    if (done_ != NULL) {
      page_ = NULL;
      done = done_;
      done_ = NULL;
    }
    delete_this = delete_when_done_;
    done_called_ = true;
  }

  // Call done callback if it is not yet called.
  if (done != NULL) {
    done->Run(success);
  }

  // If DeleteWhenDone() is already called, delete this.
  if (delete_this) {
    delete this;
  }
}

void PropertyStoreGetCallback::DeleteWhenDone() {
  {
    ScopedMutex lock(mutex());
    if (delete_when_done_) {
      LOG(DFATAL) << "PropertyStoreGetCallback::DeleteWhenDone() "
                  << "is called twice.";
    }
    delete_when_done_ = true;
    if (!done_called_) {
      // Returns if Done() is not yet called.
      return;
    }
  }
  delete this;
}

bool PropertyStoreGetCallback::AddPropertyValueProtobufToPropertyPage(
      const PropertyCache::Cohort* cohort,
      const PropertyValueProtobuf& pcache_value,
      int64 min_write_timestamp_ms) {
  ScopedMutex lock(mutex());
  if (page() == NULL || !page()->IsCacheValid(min_write_timestamp_ms)) {
    return false;
  }
  page()->AddValueFromProtobuf(cohort, pcache_value);
  return true;
}

}  // namespace net_instaweb
<|endoftext|>


<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// Boost
#include <boost/make_shared.hpp>
// StdAir
#include <stdair/basic/BasChronometer.hpp>
#include <stdair/bom/BomManager.hpp>
#include <stdair/bom/BomDisplay.hpp>
#include <stdair/service/Logger.hpp>
#include <stdair/STDAIR_Service.hpp>
#include <stdair/bom/TravelSolutionStruct.hpp>
#include <stdair/bom/BookingRequestStruct.hpp>
// Simfqt
#include <simfqt/basic/BasConst_SIMFQT_Service.hpp>
#include <simfqt/factory/FacSimfqtServiceContext.hpp>
#include <simfqt/command/FareParser.hpp>
#include <simfqt/command/FareQuoter.hpp>
#include <simfqt/service/SIMFQT_ServiceContext.hpp>
#include <simfqt/SIMFQT_Service.hpp>

namespace SIMFQT {

  // //////////////////////////////////////////////////////////////////////
  SIMFQT_Service::SIMFQT_Service() : _simfqtServiceContext (NULL) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  SIMFQT_Service::SIMFQT_Service (const SIMFQT_Service& iService) {
    assert (false);
  }

  // ////////////////////////////////////////////////////////////////////
  SIMFQT_Service::SIMFQT_Service (const stdair::BasLogParams& iLogParams)
    : _simfqtServiceContext (NULL) {

    // Initialise the STDAIR service handler
    stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
      initStdAirService (iLogParams);

    // Initialise the service context
    initServiceContext();

    // Add the StdAir service context to the SIMFQT service context
    // \note SIMFQT owns the STDAIR service resources here.
    const bool ownStdairService = true;
    addStdAirService (lSTDAIR_Service_ptr, ownStdairService);

    // Initialise the (remaining of the) context
    initSimfqtService();
  }

  // ////////////////////////////////////////////////////////////////////
  SIMFQT_Service::SIMFQT_Service (const stdair::BasLogParams& iLogParams,
                                  const stdair::BasDBParams& iDBParams)
    : _simfqtServiceContext (NULL) {

    // Initialise the STDAIR service handler
    stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
      initStdAirService (iLogParams, iDBParams);

    // Initialise the service context
    initServiceContext();

    // Add the StdAir service context to the SIMFQT service context
    // \note SIMFQT owns the STDAIR service resources here.
    const bool ownStdairService = true;
    addStdAirService (lSTDAIR_Service_ptr, ownStdairService);

    // Initialise the (remaining of the) context
    initSimfqtService();
  }

  // ////////////////////////////////////////////////////////////////////
  SIMFQT_Service::
  SIMFQT_Service (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr)
    : _simfqtServiceContext (NULL) {

    // Initialise the service context
    initServiceContext();

    // Store the STDAIR service object within the (SIMFQT) service context
    // \note Simfqt does not own the STDAIR service resources here.
    const bool doesNotOwnStdairService = false;
    addStdAirService (ioSTDAIR_Service_ptr, doesNotOwnStdairService);

    // Initialise the context
    initSimfqtService();
  }

  // //////////////////////////////////////////////////////////////////////
  SIMFQT_Service::~SIMFQT_Service() {
    // Delete/Clean all the objects from memory
    finalise();
  }

  // //////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::finalise() {
    assert (_simfqtServiceContext != NULL);
    // Reset the (Boost.)Smart pointer pointing on the STDAIR_Service object.
    _simfqtServiceContext->reset();
  }

  // //////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::initServiceContext() {
    // Initialise the service context
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext =
      FacSimfqtServiceContext::instance().create();
    _simfqtServiceContext = &lSIMFQT_ServiceContext;
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::
  addStdAirService (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr,
                    const bool iOwnStdairService) {

    // Retrieve the SimFQT service context
    assert (_simfqtServiceContext != NULL);
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Store the STDAIR service object within the (SimFQT) service context
    lSIMFQT_ServiceContext.setSTDAIR_Service (ioSTDAIR_Service_ptr,
                                              iOwnStdairService);
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::STDAIR_ServicePtr_T SIMFQT_Service::
  initStdAirService (const stdair::BasLogParams& iLogParams,
                     const stdair::BasDBParams& iDBParams) {

    /**
     * Initialise the STDAIR service handler.
     *
     * \note The track of the object memory is kept thanks to the
     * Boost Smart Pointers component.
     */
    stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
      boost::make_shared<stdair::STDAIR_Service> (iLogParams, iDBParams);
    assert (lSTDAIR_Service_ptr != NULL);

    return lSTDAIR_Service_ptr;
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::STDAIR_ServicePtr_T SIMFQT_Service::
  initStdAirService (const stdair::BasLogParams& iLogParams) {

    /**
     * Initialise the STDAIR service handler.
     *
     * \note The track of the object memory is kept thanks to the
     * Boost Smart Pointers component.
     */
    stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
      boost::make_shared<stdair::STDAIR_Service> (iLogParams);
    assert (lSTDAIR_Service_ptr != NULL);

    return lSTDAIR_Service_ptr;
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::initSimfqtService() {
    // Do nothing at this stage. A sample BOM tree may be built by
    // calling the buildSampleBom() method
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::
  parseAndLoad (const stdair::Filename_T& iInventoryInputFilename) {

    // Retrieve the BOM root object.
    assert (_simfqtServiceContext != NULL);
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();
    stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();

    // Initialise the airline inventories
    FareParser::fareRuleGeneration (iInventoryInputFilename, lBomRoot);
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::buildSampleBom() {

    // Retrieve the SimFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The SimFQT service "
                                                    "has not been initialised");
    }
    assert (_simfqtServiceContext != NULL);
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (SimFQT) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM building to the dedicated service
    lSTDAIR_Service.buildSampleBomForFareQuoter();
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::BookingRequestStruct SIMFQT_Service::buildBookingRequest() {

    // Retrieve the SIMFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The Simfqt service has not "
                                                    "been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (Simfqt) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM building to the dedicated service
    stdair::BookingRequestStruct oBookingRequest =
      lSTDAIR_Service.buildSampleBookingRequest ();

    return oBookingRequest;
  }

  // //////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::
  buildSampleTravelSolutions(stdair::TravelSolutionList_T& ioTravelSolutionList){

    // Retrieve the SIMFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The Simfqt service has not "
                                                    "been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (Simfqt) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM building to the dedicated service
    lSTDAIR_Service.buildSampleTravelSolutionForPricing (ioTravelSolutionList);
  }

  // ////////////////////////////////////////////////////////////////////
  std::string SIMFQT_Service::csvDisplay() const {

    // Retrieve the SIMFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The SimFQT service "
                                                    "has not been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (SimFQT) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Get the root of the BOM tree, on which all of the other BOM objects
    // are attached
    stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();

    // Delegate the BOM display to the dedicated service
    std::ostringstream oCSVStr;
    stdair::BomDisplay::csvSimFQTDisplay (oCSVStr, lBomRoot);
    return oCSVStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string SIMFQT_Service::
  csvDisplay (const stdair::TravelSolutionList_T& ioTravelSolutionList) const {

    // Retrieve the Simfqt service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The Simfqt service has not "
                                                    "been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    // Retrieve the Simfqt service context
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (Simfqt) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM building to the dedicated service
    return lSTDAIR_Service.csvDisplay (ioTravelSolutionList);
  }

  // //////////////////////////////////////////////////////////////////////
  std::string SIMFQT_Service::
  csvDisplay (const stdair::AirportCode_T& iOrigin,
              const stdair::AirportCode_T& iDestination,
              const stdair::Date_T& iDepartureDate) const {

    // Retrieve the SIMFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The Simfqt service "
                                                    "has not been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (SIMFQT) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM display to the dedicated service
    return lSTDAIR_Service.csvDisplay (iOrigin, iDestination,
                                       iDepartureDate);
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::
  quotePrices (const stdair::BookingRequestStruct& iBookingRequest,
               stdair::TravelSolutionList_T& ioTravelSolutionList) {

    // Retrieve the Simfqt service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The SimFQT service "
                                                    "has not been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the StdAir service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Get the root of the BOM tree, on which all of the other BOM objects
    // will be attached
    stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();

    // Delegate the action to the dedicated command
    stdair::BasChronometer lFareQuoteRetrievalChronometer;
    lFareQuoteRetrievalChronometer.start();
    FareQuoter::priceQuote (iBookingRequest, ioTravelSolutionList, lBomRoot);

    // DEBUG
    // const double lFareQuoteRetrievalMeasure =
    //   lFareQuoteRetrievalChronometer.elapsed();
    // STDAIR_LOG_DEBUG ("Fare Quote retrieving: " << lFareQuoteRetrievalMeasure
    //                   << " - " << lSIMFQT_ServiceContext.display());
  }

}
<commit_msg>[SimFQT][Dev] Reverted the removal of debugging information.<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// Boost
#include <boost/make_shared.hpp>
// StdAir
#include <stdair/basic/BasChronometer.hpp>
#include <stdair/bom/BomManager.hpp>
#include <stdair/bom/BomDisplay.hpp>
#include <stdair/service/Logger.hpp>
#include <stdair/STDAIR_Service.hpp>
#include <stdair/bom/TravelSolutionStruct.hpp>
#include <stdair/bom/BookingRequestStruct.hpp>
// Simfqt
#include <simfqt/basic/BasConst_SIMFQT_Service.hpp>
#include <simfqt/factory/FacSimfqtServiceContext.hpp>
#include <simfqt/command/FareParser.hpp>
#include <simfqt/command/FareQuoter.hpp>
#include <simfqt/service/SIMFQT_ServiceContext.hpp>
#include <simfqt/SIMFQT_Service.hpp>

namespace SIMFQT {

  // //////////////////////////////////////////////////////////////////////
  SIMFQT_Service::SIMFQT_Service() : _simfqtServiceContext (NULL) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  SIMFQT_Service::SIMFQT_Service (const SIMFQT_Service& iService) {
    assert (false);
  }

  // ////////////////////////////////////////////////////////////////////
  SIMFQT_Service::SIMFQT_Service (const stdair::BasLogParams& iLogParams)
    : _simfqtServiceContext (NULL) {

    // Initialise the STDAIR service handler
    stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
      initStdAirService (iLogParams);

    // Initialise the service context
    initServiceContext();

    // Add the StdAir service context to the SIMFQT service context
    // \note SIMFQT owns the STDAIR service resources here.
    const bool ownStdairService = true;
    addStdAirService (lSTDAIR_Service_ptr, ownStdairService);

    // Initialise the (remaining of the) context
    initSimfqtService();
  }

  // ////////////////////////////////////////////////////////////////////
  SIMFQT_Service::SIMFQT_Service (const stdair::BasLogParams& iLogParams,
                                  const stdair::BasDBParams& iDBParams)
    : _simfqtServiceContext (NULL) {

    // Initialise the STDAIR service handler
    stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
      initStdAirService (iLogParams, iDBParams);

    // Initialise the service context
    initServiceContext();

    // Add the StdAir service context to the SIMFQT service context
    // \note SIMFQT owns the STDAIR service resources here.
    const bool ownStdairService = true;
    addStdAirService (lSTDAIR_Service_ptr, ownStdairService);

    // Initialise the (remaining of the) context
    initSimfqtService();
  }

  // ////////////////////////////////////////////////////////////////////
  SIMFQT_Service::
  SIMFQT_Service (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr)
    : _simfqtServiceContext (NULL) {

    // Initialise the service context
    initServiceContext();

    // Store the STDAIR service object within the (SIMFQT) service context
    // \note Simfqt does not own the STDAIR service resources here.
    const bool doesNotOwnStdairService = false;
    addStdAirService (ioSTDAIR_Service_ptr, doesNotOwnStdairService);

    // Initialise the context
    initSimfqtService();
  }

  // //////////////////////////////////////////////////////////////////////
  SIMFQT_Service::~SIMFQT_Service() {
    // Delete/Clean all the objects from memory
    finalise();
  }

  // //////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::finalise() {
    assert (_simfqtServiceContext != NULL);
    // Reset the (Boost.)Smart pointer pointing on the STDAIR_Service object.
    _simfqtServiceContext->reset();
  }

  // //////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::initServiceContext() {
    // Initialise the service context
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext =
      FacSimfqtServiceContext::instance().create();
    _simfqtServiceContext = &lSIMFQT_ServiceContext;
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::
  addStdAirService (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr,
                    const bool iOwnStdairService) {

    // Retrieve the SimFQT service context
    assert (_simfqtServiceContext != NULL);
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Store the STDAIR service object within the (SimFQT) service context
    lSIMFQT_ServiceContext.setSTDAIR_Service (ioSTDAIR_Service_ptr,
                                              iOwnStdairService);
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::STDAIR_ServicePtr_T SIMFQT_Service::
  initStdAirService (const stdair::BasLogParams& iLogParams,
                     const stdair::BasDBParams& iDBParams) {

    /**
     * Initialise the STDAIR service handler.
     *
     * \note The track of the object memory is kept thanks to the
     * Boost Smart Pointers component.
     */
    stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
      boost::make_shared<stdair::STDAIR_Service> (iLogParams, iDBParams);
    assert (lSTDAIR_Service_ptr != NULL);

    return lSTDAIR_Service_ptr;
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::STDAIR_ServicePtr_T SIMFQT_Service::
  initStdAirService (const stdair::BasLogParams& iLogParams) {

    /**
     * Initialise the STDAIR service handler.
     *
     * \note The track of the object memory is kept thanks to the
     * Boost Smart Pointers component.
     */
    stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
      boost::make_shared<stdair::STDAIR_Service> (iLogParams);
    assert (lSTDAIR_Service_ptr != NULL);

    return lSTDAIR_Service_ptr;
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::initSimfqtService() {
    // Do nothing at this stage. A sample BOM tree may be built by
    // calling the buildSampleBom() method
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::
  parseAndLoad (const stdair::Filename_T& iInventoryInputFilename) {

    // Retrieve the BOM root object.
    assert (_simfqtServiceContext != NULL);
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();
    stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();

    // Initialise the airline inventories
    FareParser::fareRuleGeneration (iInventoryInputFilename, lBomRoot);
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::buildSampleBom() {

    // Retrieve the SimFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The SimFQT service "
                                                    "has not been initialised");
    }
    assert (_simfqtServiceContext != NULL);
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (SimFQT) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM building to the dedicated service
    lSTDAIR_Service.buildSampleBomForFareQuoter();
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::BookingRequestStruct SIMFQT_Service::buildBookingRequest() {

    // Retrieve the SIMFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The Simfqt service has not "
                                                    "been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (Simfqt) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM building to the dedicated service
    stdair::BookingRequestStruct oBookingRequest =
      lSTDAIR_Service.buildSampleBookingRequest ();

    return oBookingRequest;
  }

  // //////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::
  buildSampleTravelSolutions(stdair::TravelSolutionList_T& ioTravelSolutionList){

    // Retrieve the SIMFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The Simfqt service has not "
                                                    "been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (Simfqt) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM building to the dedicated service
    lSTDAIR_Service.buildSampleTravelSolutionForPricing (ioTravelSolutionList);
  }

  // ////////////////////////////////////////////////////////////////////
  std::string SIMFQT_Service::csvDisplay() const {

    // Retrieve the SIMFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The SimFQT service "
                                                    "has not been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (SimFQT) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Get the root of the BOM tree, on which all of the other BOM objects
    // are attached
    stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();

    // Delegate the BOM display to the dedicated service
    std::ostringstream oCSVStr;
    stdair::BomDisplay::csvSimFQTDisplay (oCSVStr, lBomRoot);
    return oCSVStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string SIMFQT_Service::
  csvDisplay (const stdair::TravelSolutionList_T& ioTravelSolutionList) const {

    // Retrieve the Simfqt service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The Simfqt service has not "
                                                    "been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    // Retrieve the Simfqt service context
    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (Simfqt) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM building to the dedicated service
    return lSTDAIR_Service.csvDisplay (ioTravelSolutionList);
  }

  // //////////////////////////////////////////////////////////////////////
  std::string SIMFQT_Service::
  csvDisplay (const stdair::AirportCode_T& iOrigin,
              const stdair::AirportCode_T& iDestination,
              const stdair::Date_T& iDepartureDate) const {

    // Retrieve the SIMFQT service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The Simfqt service "
                                                    "has not been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the STDAIR service object from the (SIMFQT) service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Delegate the BOM display to the dedicated service
    return lSTDAIR_Service.csvDisplay (iOrigin, iDestination,
                                       iDepartureDate);
  }

  // ////////////////////////////////////////////////////////////////////
  void SIMFQT_Service::
  quotePrices (const stdair::BookingRequestStruct& iBookingRequest,
               stdair::TravelSolutionList_T& ioTravelSolutionList) {

    // Retrieve the Simfqt service context
    if (_simfqtServiceContext == NULL) {
      throw stdair::NonInitialisedServiceException ("The SimFQT service "
                                                    "has not been initialised");
    }
    assert (_simfqtServiceContext != NULL);

    SIMFQT_ServiceContext& lSIMFQT_ServiceContext = *_simfqtServiceContext;

    // Retrieve the StdAir service context
    stdair::STDAIR_Service& lSTDAIR_Service =
      lSIMFQT_ServiceContext.getSTDAIR_Service();

    // Get the root of the BOM tree, on which all of the other BOM objects
    // will be attached
    stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();

    // Delegate the action to the dedicated command
    stdair::BasChronometer lFareQuoteRetrievalChronometer;
    lFareQuoteRetrievalChronometer.start();
    FareQuoter::priceQuote (iBookingRequest, ioTravelSolutionList, lBomRoot);

    // DEBUG
    const double lFareQuoteRetrievalMeasure =
      lFareQuoteRetrievalChronometer.elapsed();
    STDAIR_LOG_DEBUG ("Fare Quote retrieving: " << lFareQuoteRetrievalMeasure
                      << " - " << lSIMFQT_ServiceContext.display());
  }

}
<|endoftext|>


<commit_before>#include <bts/chain/database.hpp>
#include <bts/chain/operations.hpp>
#include <bts/chain/key_object.hpp>
#include <bts/chain/account_object.hpp>

#include <bts/time/time.hpp>

#include <fc/crypto/digest.hpp>

#include <boost/test/auto_unit_test.hpp>

using namespace bts::chain;

BOOST_AUTO_TEST_CASE( operation_sanity_check )
{
   try {
      operation op = account_create_operation();
      op.get<account_create_operation>().active.add_authority(account_id_type(), 123);
      operation tmp = std::move(op);
      wdump((tmp.which()));
   } catch (fc::exception& e) {
      edump((e.to_detail_string()));
      throw;
   }
}

BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench )
{
   try {
      genesis_allocation allocation;

#ifdef NDEBUG
      ilog("Running in release mode.");
      const int account_count = 2000000;
      const int blocks_to_produce = 1000000;
#else
      ilog("Running in debug mode.");
      const int account_count = 30000;
      const int blocks_to_produce = 1000;
#endif

      for( int i = 0; i < account_count; ++i )
         allocation.emplace_back(public_key_type(fc::ecc::private_key::regenerate(fc::digest(i)).get_public_key()),
                                 BTS_INITIAL_SUPPLY / account_count);

      fc::temp_directory data_dir(fc::current_path());

      {
         database db;
         db.open(data_dir.path(), allocation);

         for( int i = 11; i < account_count + 11; ++i)
            BOOST_CHECK(db.get_balance(account_id_type(i), asset_id_type()).amount == BTS_INITIAL_SUPPLY / account_count);

         fc::time_point start_time = fc::time_point::now();
         db.close();
         ilog("Closed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));
      }
      {
         database db;

         fc::time_point start_time = fc::time_point::now();
         db.open(data_dir.path());
         ilog("Opened database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));

         for( int i = 11; i < account_count + 11; ++i)
            BOOST_CHECK(db.get_balance(account_id_type(i), asset_id_type()).amount == BTS_INITIAL_SUPPLY / account_count);

         start_simulated_time( bts::chain::now() );

         int blocks_out = 0;
         auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) );
         auto aw = db.get_global_properties().active_witnesses;
         advance_simulated_time_to( db.get_next_generation_time( aw[blocks_out % aw.size()] ) );
         auto b =  db.generate_block( delegate_priv_key, aw[blocks_out++ % aw.size()], ~0 );

         start_time = fc::time_point::now();
         for( int i = 0; i < blocks_to_produce; ++i )
         {
            signed_transaction trx;
            trx.operations.emplace_back(transfer_operation({asset(1), account_id_type(i + 11), account_id_type(), asset(1), memo_data()}));
            db.push_transaction(trx, ~0);

            aw = db.get_global_properties().active_witnesses;
            advance_simulated_time_to( db.get_next_generation_time( aw[blocks_out % aw.size()] ) );
            b =  db.generate_block( delegate_priv_key, aw[blocks_out++ % aw.size()], ~0 );
         }
         ilog("Pushed ${c} blocks (1 op each, no validation) in ${t} milliseconds.",
              ("c", blocks_out)("t", (fc::time_point::now() - start_time).count() / 1000));

         start_time = fc::time_point::now();
         db.close();
         ilog("Closed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));
      }
      {
         database db;

         auto start_time = fc::time_point::now();
         advance_simulated_time_to( now() + fc::seconds(BTS_MAX_BLOCK_INTERVAL) );
         wlog( "about to start reindex..." );
         db.reindex(data_dir.path(), allocation);
         ilog("Replayed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));

         for( int i = 0; i < blocks_to_produce; ++i )
            BOOST_CHECK(db.get_balance(account_id_type(i + 11), asset_id_type()).amount == BTS_INITIAL_SUPPLY / account_count - 2);
      }

   } catch(fc::exception& e) {
      edump((e.to_detail_string()));
      throw;
   }
}
<commit_msg>genesis_allocation.cpp:  Port chain_bench target to new time API<commit_after>#include <bts/chain/database.hpp>
#include <bts/chain/operations.hpp>
#include <bts/chain/key_object.hpp>
#include <bts/chain/account_object.hpp>

#include <bts/time/time.hpp>

#include <fc/crypto/digest.hpp>

#include <boost/test/auto_unit_test.hpp>

using namespace bts::chain;

BOOST_AUTO_TEST_CASE( operation_sanity_check )
{
   try {
      operation op = account_create_operation();
      op.get<account_create_operation>().active.add_authority(account_id_type(), 123);
      operation tmp = std::move(op);
      wdump((tmp.which()));
   } catch (fc::exception& e) {
      edump((e.to_detail_string()));
      throw;
   }
}

BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench )
{
   try {
      genesis_allocation allocation;
      fc::time_point_sec now( BTS_GENESIS_TIMESTAMP );

#ifdef NDEBUG
      ilog("Running in release mode.");
      const int account_count = 2000000;
      const int blocks_to_produce = 1000000;
#else
      ilog("Running in debug mode.");
      const int account_count = 30000;
      const int blocks_to_produce = 1000;
#endif

      for( int i = 0; i < account_count; ++i )
         allocation.emplace_back(public_key_type(fc::ecc::private_key::regenerate(fc::digest(i)).get_public_key()),
                                 BTS_INITIAL_SUPPLY / account_count);

      fc::temp_directory data_dir(fc::current_path());

      {
         database db;
         db.open(data_dir.path(), allocation);

         for( int i = 11; i < account_count + 11; ++i)
            BOOST_CHECK(db.get_balance(account_id_type(i), asset_id_type()).amount == BTS_INITIAL_SUPPLY / account_count);

         fc::time_point start_time = fc::time_point::now();
         db.close();
         ilog("Closed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));
      }
      {
         database db;

         fc::time_point start_time = fc::time_point::now();
         db.open(data_dir.path());
         ilog("Opened database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));

         for( int i = 11; i < account_count + 11; ++i)
            BOOST_CHECK(db.get_balance(account_id_type(i), asset_id_type()).amount == BTS_INITIAL_SUPPLY / account_count);

         int blocks_out = 0;
         auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) );
         auto aw = db.get_global_properties().active_witnesses;
         now += db.block_interval();
         auto b =  db.generate_block( now, db.get_scheduled_witness( now )->second, delegate_priv_key, ~0 );

         start_time = fc::time_point::now();
         for( int i = 0; i < blocks_to_produce; ++i )
         {
            signed_transaction trx;
            trx.operations.emplace_back(transfer_operation({asset(1), account_id_type(i + 11), account_id_type(), asset(1), memo_data()}));
            db.push_transaction(trx, ~0);

            aw = db.get_global_properties().active_witnesses;
            now += db.block_interval();
            b =  db.generate_block( now, db.get_scheduled_witness( now )->second, delegate_priv_key, ~0 );
         }
         ilog("Pushed ${c} blocks (1 op each, no validation) in ${t} milliseconds.",
              ("c", blocks_out)("t", (fc::time_point::now() - start_time).count() / 1000));

         start_time = fc::time_point::now();
         db.close();
         ilog("Closed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));
      }
      {
         database db;

         auto start_time = fc::time_point::now();
         now += BTS_MAX_BLOCK_INTERVAL;
         wlog( "about to start reindex..." );
         db.reindex(data_dir.path(), allocation);
         ilog("Replayed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));

         for( int i = 0; i < blocks_to_produce; ++i )
            BOOST_CHECK(db.get_balance(account_id_type(i + 11), asset_id_type()).amount == BTS_INITIAL_SUPPLY / account_count - 2);
      }

   } catch(fc::exception& e) {
      edump((e.to_detail_string()));
      throw;
   }
}
<|endoftext|>


<commit_before>// soundmgr.cxx -- Sound effect management class
//
// Sound manager initially written by David Findlay
// <david_j_findlay@yahoo.com.au> 2001
//
// C++-ified by Curtis Olson, started March 2001.
//
// Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$

#include <simgear/compiler.h>

#if defined(__APPLE__)
# include <OpenAL/al.h>
# include <OpenAL/alut.h>
# include <OpenAL/alc.h>
#else
# include <AL/al.h>
# include <AL/alut.h>
# include <AL/alc.h>
#endif

#if defined (__APPLE__)
// any C++ header file undefines isinf and isnan
// so this should be included before <iostream>
inline int (isinf)(double r) { return isinf(r); }
inline int (isnan)(double r) { return isnan(r); }
#endif

#if defined(__MINGW32__)
#define isnan(x) _isnan(x)
#endif

#if defined (__FreeBSD__)
inline int isnan(double r) { return !(r < 0 || r > 0); }
#endif

#include STL_IOSTREAM

#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>

#include "soundmgr_openal.hxx"

//
// Sound Manager
//

// constructor
SGSoundMgr::SGSoundMgr() {

    SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" );

    // initialize OpenAL
    alutInit( 0, NULL );
    atexit(alutExit);

    if ( alGetError() == AL_NO_ERROR) {
        working = true;
    } else {
        working = false;
	SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
    }

    listener_pos[0] = 0.0;
    listener_pos[1] = 0.0;
    listener_pos[2] = 0.0;

    listener_vel[0] = 0.0;
    listener_vel[1] = 0.0;
    listener_vel[2] = 0.0;

    listener_ori[0] = 0.0;
    listener_ori[1] = 0.0;
    listener_ori[2] = -1.0;
    listener_ori[3] = 0.0;
    listener_ori[4] = 1.0;
    listener_ori[5] = 0.0;

    alListenerfv( AL_POSITION, listener_pos );
    alListenerfv( AL_VELOCITY, listener_vel );
    alListenerfv( AL_ORIENTATION, listener_ori );
    alGetError();
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after audio initialization!" );
    }

    // exaggerate the ear candy?
    alDopplerFactor(1.0);
    alDopplerVelocity(340.0);	// speed of sound in meters per second.
}

// destructor

SGSoundMgr::~SGSoundMgr() {

    //
    // Remove the samples from the sample manager.
    //
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
	delete sample;
    }
}

// initialize the sound manager
void SGSoundMgr::init() {
    //
    // Remove the samples from the sample manager.
    //
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
        SGSoundSample *sample = sample_current->second;
        delete sample;
    }
    samples.clear();
}

void SGSoundMgr::bind ()
{
    // no properties
}

void SGSoundMgr::unbind ()
{
    // no properties
}

// run the audio scheduler
void SGSoundMgr::update( double dt ) {
}

void
SGSoundMgr::pause ()
{
    ALCcontext *pCurContext = alcGetCurrentContext();
    alcSuspendContext( pCurContext );
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after soundmgr pause()!" );
    }
}

void
SGSoundMgr::resume ()
{
    ALCcontext *pCurContext = alcGetCurrentContext();
    alcProcessContext( pCurContext );
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after soundmgr resume()!" );
    }
}

// add a sound effect, return true if successful
bool SGSoundMgr::add( SGSoundSample *sound, const string& refname ) {

    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
        // sound already exists
        return false;
    }

    samples[refname] = sound;

    return true;
}

// remove a sound effect, return true if successful
bool SGSoundMgr::remove( const string &refname ) {

    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	// first stop the sound from playing (so we don't bomb the
	// audio scheduler)
	SGSoundSample *sample = sample_it->second;
        delete sample;
        samples.erase( sample_it );

        // cout << "sndmgr: removed -> " << refname << endl;
	return true;
    } else {
        // cout << "sndmgr: failed remove -> " << refname << endl;
        return false;
    }
}

// return true of the specified sound exists in the sound manager system
bool SGSoundMgr::exists( const string &refname ) {
    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	return true;
    } else {
	return false;
    }
}

// return a pointer to the SGSoundSample if the specified sound exists
// in the sound manager system, otherwise return NULL
SGSoundSample *SGSoundMgr::find( const string &refname ) {
    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	return sample_it->second;
    } else {
	return NULL;
    }
}

// tell the scheduler to play the indexed sample in a continuous
// loop
bool SGSoundMgr::play_looped( const string &refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->play( true );
        return true;
    }
}

// tell the scheduler to play the indexed sample once
bool SGSoundMgr::play_once( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->play( false );
        return true;
    }
}

// return true of the specified sound is currently being played
bool SGSoundMgr::is_playing( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        return ( sample->is_playing() );
    }
}

// immediate stop playing the sound
bool SGSoundMgr::stop( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->stop();
        return true;
    }
}

// set source position of all managed sounds
void SGSoundMgr::set_source_pos_all( ALfloat *pos ) {
    if ( isnan(pos[0]) || isnan(pos[1]) || isnan(pos[2]) ) {
        // bail if a bad position is passed in
        return;
    }

    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
        sample->set_source_pos( pos );
    }
}

// set source velocity of all managed sounds
void SGSoundMgr::set_source_vel_all( ALfloat *vel ) {
    if ( isnan(vel[0]) || isnan(vel[1]) || isnan(vel[2]) ) {
        // bail if a bad velocity is passed in
        return;
    }

    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
        sample->set_source_vel( vel );
    }
}
<commit_msg>Fix a dumb bug.<commit_after>// soundmgr.cxx -- Sound effect management class
//
// Sound manager initially written by David Findlay
// <david_j_findlay@yahoo.com.au> 2001
//
// C++-ified by Curtis Olson, started March 2001.
//
// Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$

#include <simgear/compiler.h>

#if defined(__APPLE__)
# include <OpenAL/al.h>
# include <OpenAL/alut.h>
# include <OpenAL/alc.h>
#else
# include <AL/al.h>
# include <AL/alut.h>
# include <AL/alc.h>
#endif

#if defined (__APPLE__)
// any C++ header file undefines isinf and isnan
// so this should be included before <iostream>
inline int (isinf)(double r) { return isinf(r); }
inline int (isnan)(double r) { return isnan(r); }
#endif

#if defined(__MINGW32__)
#define isnan(x) _isnan(x)
#endif

#if defined (__FreeBSD__)
inline int isnan(double r) { return !(r <= 0 || r >= 0); }
#endif

#include STL_IOSTREAM

#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>

#include "soundmgr_openal.hxx"

//
// Sound Manager
//

// constructor
SGSoundMgr::SGSoundMgr() {

    SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" );

    // initialize OpenAL
    alutInit( 0, NULL );
    atexit(alutExit);

    if ( alGetError() == AL_NO_ERROR) {
        working = true;
    } else {
        working = false;
	SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
    }

    listener_pos[0] = 0.0;
    listener_pos[1] = 0.0;
    listener_pos[2] = 0.0;

    listener_vel[0] = 0.0;
    listener_vel[1] = 0.0;
    listener_vel[2] = 0.0;

    listener_ori[0] = 0.0;
    listener_ori[1] = 0.0;
    listener_ori[2] = -1.0;
    listener_ori[3] = 0.0;
    listener_ori[4] = 1.0;
    listener_ori[5] = 0.0;

    alListenerfv( AL_POSITION, listener_pos );
    alListenerfv( AL_VELOCITY, listener_vel );
    alListenerfv( AL_ORIENTATION, listener_ori );
    alGetError();
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after audio initialization!" );
    }

    // exaggerate the ear candy?
    alDopplerFactor(1.0);
    alDopplerVelocity(340.0);	// speed of sound in meters per second.
}

// destructor

SGSoundMgr::~SGSoundMgr() {

    //
    // Remove the samples from the sample manager.
    //
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
	delete sample;
    }
}

// initialize the sound manager
void SGSoundMgr::init() {
    //
    // Remove the samples from the sample manager.
    //
    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
        SGSoundSample *sample = sample_current->second;
        delete sample;
    }
    samples.clear();
}

void SGSoundMgr::bind ()
{
    // no properties
}

void SGSoundMgr::unbind ()
{
    // no properties
}

// run the audio scheduler
void SGSoundMgr::update( double dt ) {
}

void
SGSoundMgr::pause ()
{
    ALCcontext *pCurContext = alcGetCurrentContext();
    alcSuspendContext( pCurContext );
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after soundmgr pause()!" );
    }
}

void
SGSoundMgr::resume ()
{
    ALCcontext *pCurContext = alcGetCurrentContext();
    alcProcessContext( pCurContext );
    if ( alGetError() != AL_NO_ERROR) {
	SG_LOG( SG_GENERAL, SG_ALERT,
                "Oops AL error after soundmgr resume()!" );
    }
}

// add a sound effect, return true if successful
bool SGSoundMgr::add( SGSoundSample *sound, const string& refname ) {

    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
        // sound already exists
        return false;
    }

    samples[refname] = sound;

    return true;
}

// remove a sound effect, return true if successful
bool SGSoundMgr::remove( const string &refname ) {

    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	// first stop the sound from playing (so we don't bomb the
	// audio scheduler)
	SGSoundSample *sample = sample_it->second;
        delete sample;
        samples.erase( sample_it );

        // cout << "sndmgr: removed -> " << refname << endl;
	return true;
    } else {
        // cout << "sndmgr: failed remove -> " << refname << endl;
        return false;
    }
}

// return true of the specified sound exists in the sound manager system
bool SGSoundMgr::exists( const string &refname ) {
    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	return true;
    } else {
	return false;
    }
}

// return a pointer to the SGSoundSample if the specified sound exists
// in the sound manager system, otherwise return NULL
SGSoundSample *SGSoundMgr::find( const string &refname ) {
    sample_map_iterator sample_it = samples.find( refname );
    if ( sample_it != samples.end() ) {
	return sample_it->second;
    } else {
	return NULL;
    }
}

// tell the scheduler to play the indexed sample in a continuous
// loop
bool SGSoundMgr::play_looped( const string &refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->play( true );
        return true;
    }
}

// tell the scheduler to play the indexed sample once
bool SGSoundMgr::play_once( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->play( false );
        return true;
    }
}

// return true of the specified sound is currently being played
bool SGSoundMgr::is_playing( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        return ( sample->is_playing() );
    }
}

// immediate stop playing the sound
bool SGSoundMgr::stop( const string& refname ) {
    SGSoundSample *sample;

    if ( (sample = find( refname )) == NULL ) {
        return false;
    } else {
        sample->stop();
        return true;
    }
}

// set source position of all managed sounds
void SGSoundMgr::set_source_pos_all( ALfloat *pos ) {
    if ( isnan(pos[0]) || isnan(pos[1]) || isnan(pos[2]) ) {
        // bail if a bad position is passed in
        return;
    }

    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
        sample->set_source_pos( pos );
    }
}

// set source velocity of all managed sounds
void SGSoundMgr::set_source_vel_all( ALfloat *vel ) {
    if ( isnan(vel[0]) || isnan(vel[1]) || isnan(vel[2]) ) {
        // bail if a bad velocity is passed in
        return;
    }

    sample_map_iterator sample_current = samples.begin();
    sample_map_iterator sample_end = samples.end();
    for ( ; sample_current != sample_end; ++sample_current ) {
	SGSoundSample *sample = sample_current->second;
        sample->set_source_vel( vel );
    }
}
<|endoftext|>