<commit_before>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
the University of Michigan All rights reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

You may redistribute, use, and create derivate works of HOOMD-blue, in source
and binary forms, provided you abide by the following conditions:

* Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer both in the code and
prominently in any materials provided with the distribution.

* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions, and the following disclaimer in the documentation and/or
other materials provided with the distribution.

* All publications and presentations based on HOOMD-blue, including any reports
or published results obtained, in whole or in part, with HOOMD-blue, will
acknowledge its use according to the terms posted at the time of submission on:
http://codeblue.umich.edu/hoomd-blue/citations.html

* Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
http://codeblue.umich.edu/hoomd-blue/

* Apart from the above required attributions, neither the name of the copyright
holder nor the names of HOOMD-blue's contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// Maintainer: jglaser

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif

#include <boost/python.hpp>
using namespace boost::python;
#include <boost/bind.hpp>
using namespace boost;

#include "TwoStepNVTMTKGPU.h"
#include "TwoStepNVTMTKGPU.cuh"
#include "TwoStepNPTMTKGPU.cuh"

#ifdef ENABLE_MPI
#include "Communicator.h"
#include "HOOMDMPI.h"
#endif

/*! \file TwoStepNVTMTKGPU.h
    \brief Contains code for the TwoStepNVTMTKGPU class
*/

/*! \param sysdef SystemDefinition this method will act on. Must not be NULL.
    \param group The group of particles this integration method is to work on
    \param thermo compute for thermodynamic quantities
    \param tau NVT period
    \param T Temperature set point
    \param suffix Suffix to attach to the end of log quantity names
*/
TwoStepNVTMTKGPU::TwoStepNVTMTKGPU(boost::shared_ptr<SystemDefinition> sysdef,
                             boost::shared_ptr<ParticleGroup> group,
                             boost::shared_ptr<ComputeThermo> thermo,
                             Scalar tau,
                             boost::shared_ptr<Variant> T,
                             const std::string& suffix)
    : TwoStepNVTMTK(sysdef, group, thermo, tau, T, suffix)
    {
    // only one GPU is supported
    if (!exec_conf->isCUDAEnabled())
        {
        m_exec_conf->msg->error() << "Creating a TwoStepNVTMTKPU when CUDA is disabled" << endl;
        throw std::runtime_error("Error initializing TwoStepNVTMTKGPU");
        }

    // initialize autotuner
    std::vector<unsigned int> valid_params;
    for (unsigned int block_size = 32; block_size <= 1024; block_size += 32)
        valid_params.push_back(block_size);

    m_tuner_one.reset(new Autotuner(valid_params, 5, 100000, "nvt_mtk_step_one", this->m_exec_conf));
    m_tuner_two.reset(new Autotuner(valid_params, 5, 100000, "nvt_mtk_step_two", this->m_exec_conf));

    m_reduction_block_size = 512;

    // this breaks memory scaling (calculate memory requirements from global group size)
    // unless we reallocate memory with every change of the maximum particle number
    m_num_blocks = m_group->getNumMembersGlobal() / m_reduction_block_size + 1;
    GPUArray< Scalar > scratch(m_num_blocks, exec_conf);
    m_scratch.swap(scratch);

    GPUArray< Scalar> temperature(1, exec_conf);
    m_temperature.swap(temperature);
    }

/*! \param timestep Current time step
    \post Particle positions are moved forward to timestep+1 and velocities to timestep+1/2 per the Nose-Hoover method
*/
void TwoStepNVTMTKGPU::integrateStepOne(unsigned int timestep)
    {
    unsigned int group_size = m_group->getNumMembers();
    if (group_size == 0)
        return;

    // profile this step
    if (m_prof)
        m_prof->push(exec_conf, "NVT MTK step 1");

    // compute the current thermodynamic properties
    m_thermo->compute(timestep);

    // compute temperature for the next half time step
    m_curr_T = m_thermo->getTemperature();

    // advance thermostat
    advanceThermostat(timestep, false);

    // access all the needed data
    ArrayHandle<Scalar4> d_pos(m_pdata->getPositions(), access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar4> d_vel(m_pdata->getVelocities(), access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar3> d_accel(m_pdata->getAccelerations(), access_location::device, access_mode::read);
    ArrayHandle<int3> d_image(m_pdata->getImages(), access_location::device, access_mode::readwrite);

    BoxDim box = m_pdata->getBox();
    ArrayHandle< unsigned int > d_index_array(m_group->getIndexArray(), access_location::device, access_mode::read);

    // perform the update on the GPU
    m_tuner_one->begin();
    gpu_nvt_mtk_step_one(d_pos.data,
                     d_vel.data,
                     d_accel.data,
                     d_image.data,
                     d_index_array.data,
                     group_size,
                     box,
                     m_tuner_one->getParam(),
                     m_exp_thermo_fac,
                     m_deltaT);

    if (exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();
    m_tuner_one->end();

    // done profiling
    if (m_prof)
        m_prof->pop(exec_conf);
    }

/*! \param timestep Current time step
    \post particle velocities are moved forward to timestep+1 on the GPU
*/
void TwoStepNVTMTKGPU::integrateStepTwo(unsigned int timestep)
    {
    unsigned int group_size = m_group->getNumMembers();

    const GPUArray< Scalar4 >& net_force = m_pdata->getNetForce();

    // profile this step
    if (m_prof)
        m_prof->push(exec_conf, "NVT MTK step 2");

    ArrayHandle<Scalar4> d_vel(m_pdata->getVelocities(), access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar3> d_accel(m_pdata->getAccelerations(), access_location::device, access_mode::readwrite);

    ArrayHandle<Scalar4> d_net_force(net_force, access_location::device, access_mode::read);
    ArrayHandle< unsigned int > d_index_array(m_group->getIndexArray(), access_location::device, access_mode::read);

    // perform the update on the GPU
    m_tuner_two->begin();
    gpu_nvt_mtk_step_two(d_vel.data,
                     d_accel.data,
                     d_index_array.data,
                     group_size,
                     d_net_force.data,
                     m_tuner_two->getParam(),
                     m_deltaT);

    if (exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();

    m_tuner_two->end();

        {
        // recalulate temperature
        ArrayHandle<Scalar> d_temperature(m_temperature, access_location::device, access_mode::overwrite);
        ArrayHandle<Scalar> d_scratch(m_scratch, access_location::device, access_mode::overwrite);

        // update number of blocks to current group size
        m_num_blocks = m_group->getNumMembers() / m_reduction_block_size + 1;

        gpu_npt_mtk_temperature(d_temperature.data,
                                d_vel.data,
                                d_scratch.data,
                                m_num_blocks,
                                m_reduction_block_size,
                                d_index_array.data,
                                group_size,
                                m_thermo->getNDOF());
        if (m_exec_conf->isCUDAErrorCheckingEnabled())
            CHECK_CUDA_ERROR();
        }

    // read back intermediate temperature from GPU
        {
        ArrayHandle<Scalar> h_temperature(m_temperature, access_location::host, access_mode::read);
        m_curr_T= *h_temperature.data;
        }

    #ifdef ENABLE_MPI
    if (m_comm)
        {
        MPI_Allreduce(MPI_IN_PLACE, &m_curr_T, 1, MPI_HOOMD_SCALAR, MPI_SUM, m_exec_conf->getMPICommunicator() );
        }
    #endif

    // get temperature and advance thermostat
    advanceThermostat(timestep+1,true);

    // rescale velocities
    gpu_npt_mtk_thermostat(d_vel.data,
                           d_index_array.data,
                           group_size,
                           m_exp_thermo_fac);

    if (m_exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();

    // done profiling
    if (m_prof)
        m_prof->pop(exec_conf);
    }

void export_TwoStepNVTMTKGPU()
    {
    class_<TwoStepNVTMTKGPU, boost::shared_ptr<TwoStepNVTMTKGPU>, bases<TwoStepNVTMTK>, boost::noncopyable>
        ("TwoStepNVTMTKGPU", init< boost::shared_ptr<SystemDefinition>,
                          boost::shared_ptr<ParticleGroup>,
                          boost::shared_ptr<ComputeThermo>,
                          Scalar,
                          boost::shared_ptr<Variant>,
                          const std::string&
                          >())
        ;
    }

#ifdef WIN32
#pragma warning( pop )
#endif
<commit_msg>Minor strong scaling optimization in NVT MTK<commit_after>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
the University of Michigan All rights reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

You may redistribute, use, and create derivate works of HOOMD-blue, in source
and binary forms, provided you abide by the following conditions:

* Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer both in the code and
prominently in any materials provided with the distribution.

* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions, and the following disclaimer in the documentation and/or
other materials provided with the distribution.

* All publications and presentations based on HOOMD-blue, including any reports
or published results obtained, in whole or in part, with HOOMD-blue, will
acknowledge its use according to the terms posted at the time of submission on:
http://codeblue.umich.edu/hoomd-blue/citations.html

* Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
http://codeblue.umich.edu/hoomd-blue/

* Apart from the above required attributions, neither the name of the copyright
holder nor the names of HOOMD-blue's contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// Maintainer: jglaser

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif

#include <boost/python.hpp>
using namespace boost::python;
#include <boost/bind.hpp>
using namespace boost;

#include "TwoStepNVTMTKGPU.h"
#include "TwoStepNVTMTKGPU.cuh"
#include "TwoStepNPTMTKGPU.cuh"

#ifdef ENABLE_MPI
#include "Communicator.h"
#include "HOOMDMPI.h"
#endif

/*! \file TwoStepNVTMTKGPU.h
    \brief Contains code for the TwoStepNVTMTKGPU class
*/

/*! \param sysdef SystemDefinition this method will act on. Must not be NULL.
    \param group The group of particles this integration method is to work on
    \param thermo compute for thermodynamic quantities
    \param tau NVT period
    \param T Temperature set point
    \param suffix Suffix to attach to the end of log quantity names
*/
TwoStepNVTMTKGPU::TwoStepNVTMTKGPU(boost::shared_ptr<SystemDefinition> sysdef,
                             boost::shared_ptr<ParticleGroup> group,
                             boost::shared_ptr<ComputeThermo> thermo,
                             Scalar tau,
                             boost::shared_ptr<Variant> T,
                             const std::string& suffix)
    : TwoStepNVTMTK(sysdef, group, thermo, tau, T, suffix)
    {
    // only one GPU is supported
    if (!exec_conf->isCUDAEnabled())
        {
        m_exec_conf->msg->error() << "Creating a TwoStepNVTMTKPU when CUDA is disabled" << endl;
        throw std::runtime_error("Error initializing TwoStepNVTMTKGPU");
        }

    // initialize autotuner
    std::vector<unsigned int> valid_params;
    for (unsigned int block_size = 32; block_size <= 1024; block_size += 32)
        valid_params.push_back(block_size);

    m_tuner_one.reset(new Autotuner(valid_params, 5, 100000, "nvt_mtk_step_one", this->m_exec_conf));
    m_tuner_two.reset(new Autotuner(valid_params, 5, 100000, "nvt_mtk_step_two", this->m_exec_conf));

    m_reduction_block_size = 512;

    // this breaks memory scaling (calculate memory requirements from global group size)
    // unless we reallocate memory with every change of the maximum particle number
    m_num_blocks = m_group->getNumMembersGlobal() / m_reduction_block_size + 1;
    GPUArray< Scalar > scratch(m_num_blocks, exec_conf);
    m_scratch.swap(scratch);

    GPUArray< Scalar> temperature(1, exec_conf, true);
    m_temperature.swap(temperature);
    }

/*! \param timestep Current time step
    \post Particle positions are moved forward to timestep+1 and velocities to timestep+1/2 per the Nose-Hoover method
*/
void TwoStepNVTMTKGPU::integrateStepOne(unsigned int timestep)
    {
    unsigned int group_size = m_group->getNumMembers();
    if (group_size == 0)
        return;

    // profile this step
    if (m_prof)
        m_prof->push(exec_conf, "NVT MTK step 1");

    // compute the current thermodynamic properties
    m_thermo->compute(timestep);

    // compute temperature for the next half time step
    m_curr_T = m_thermo->getTemperature();

    // advance thermostat
    advanceThermostat(timestep, false);

    // access all the needed data
    ArrayHandle<Scalar4> d_pos(m_pdata->getPositions(), access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar4> d_vel(m_pdata->getVelocities(), access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar3> d_accel(m_pdata->getAccelerations(), access_location::device, access_mode::read);
    ArrayHandle<int3> d_image(m_pdata->getImages(), access_location::device, access_mode::readwrite);

    BoxDim box = m_pdata->getBox();
    ArrayHandle< unsigned int > d_index_array(m_group->getIndexArray(), access_location::device, access_mode::read);

    // perform the update on the GPU
    m_tuner_one->begin();
    gpu_nvt_mtk_step_one(d_pos.data,
                     d_vel.data,
                     d_accel.data,
                     d_image.data,
                     d_index_array.data,
                     group_size,
                     box,
                     m_tuner_one->getParam(),
                     m_exp_thermo_fac,
                     m_deltaT);

    if (exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();
    m_tuner_one->end();

    // done profiling
    if (m_prof)
        m_prof->pop(exec_conf);
    }

/*! \param timestep Current time step
    \post particle velocities are moved forward to timestep+1 on the GPU
*/
void TwoStepNVTMTKGPU::integrateStepTwo(unsigned int timestep)
    {
    unsigned int group_size = m_group->getNumMembers();

    const GPUArray< Scalar4 >& net_force = m_pdata->getNetForce();

    // profile this step
    if (m_prof)
        m_prof->push(exec_conf, "NVT MTK step 2");

    ArrayHandle<Scalar4> d_vel(m_pdata->getVelocities(), access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar3> d_accel(m_pdata->getAccelerations(), access_location::device, access_mode::readwrite);

    ArrayHandle<Scalar4> d_net_force(net_force, access_location::device, access_mode::read);
    ArrayHandle< unsigned int > d_index_array(m_group->getIndexArray(), access_location::device, access_mode::read);

    // perform the update on the GPU
    m_tuner_two->begin();
    gpu_nvt_mtk_step_two(d_vel.data,
                     d_accel.data,
                     d_index_array.data,
                     group_size,
                     d_net_force.data,
                     m_tuner_two->getParam(),
                     m_deltaT);

    if (exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();

    m_tuner_two->end();

        {
        // recalulate temperature
        ArrayHandle<Scalar> d_temperature(m_temperature, access_location::device, access_mode::overwrite);
        ArrayHandle<Scalar> d_scratch(m_scratch, access_location::device, access_mode::overwrite);

        // update number of blocks to current group size
        m_num_blocks = m_group->getNumMembers() / m_reduction_block_size + 1;

        gpu_npt_mtk_temperature(d_temperature.data,
                                d_vel.data,
                                d_scratch.data,
                                m_num_blocks,
                                m_reduction_block_size,
                                d_index_array.data,
                                group_size,
                                m_thermo->getNDOF());
        if (m_exec_conf->isCUDAErrorCheckingEnabled())
            CHECK_CUDA_ERROR();
        }

    // read back intermediate temperature from GPU
        {
        ArrayHandle<Scalar> h_temperature(m_temperature, access_location::host, access_mode::read);
        m_curr_T= *h_temperature.data;
        }

    #ifdef ENABLE_MPI
    if (m_comm)
        {
        MPI_Allreduce(MPI_IN_PLACE, &m_curr_T, 1, MPI_HOOMD_SCALAR, MPI_SUM, m_exec_conf->getMPICommunicator() );
        }
    #endif

    // get temperature and advance thermostat
    advanceThermostat(timestep+1,true);

    // rescale velocities
    gpu_npt_mtk_thermostat(d_vel.data,
                           d_index_array.data,
                           group_size,
                           m_exp_thermo_fac);

    if (m_exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();

    // done profiling
    if (m_prof)
        m_prof->pop(exec_conf);
    }

void export_TwoStepNVTMTKGPU()
    {
    class_<TwoStepNVTMTKGPU, boost::shared_ptr<TwoStepNVTMTKGPU>, bases<TwoStepNVTMTK>, boost::noncopyable>
        ("TwoStepNVTMTKGPU", init< boost::shared_ptr<SystemDefinition>,
                          boost::shared_ptr<ParticleGroup>,
                          boost::shared_ptr<ComputeThermo>,
                          Scalar,
                          boost::shared_ptr<Variant>,
                          const std::string&
                          >())
        ;
    }

#ifdef WIN32
#pragma warning( pop )
#endif
<|endoftext|>


<commit_before>#include "utility/w5100.h"
#include "utility/socket.h"

extern "C" {
  #include "string.h"
}

#include "Arduino.h"

#include "Ethernet.h"
#include "EthernetClient.h"
#include "EthernetServer.h"
#include "Dns.h"

uint16_t EthernetClient::_srcport = 49152;      //Use IANA recommended ephemeral port range 49152-65535

EthernetClient::EthernetClient() : _sock(MAX_SOCK_NUM) {
}

EthernetClient::EthernetClient(uint8_t sock) : _sock(sock) {
}

int EthernetClient::connect(const char* host, uint16_t port) {
  // Look up the host first
  int ret = 0;
  DNSClient dns;
  IPAddress remote_addr;

  dns.begin(Ethernet.dnsServerIP());
  ret = dns.getHostByName(host, remote_addr);
  if (ret == 1) {
    return connect(remote_addr, port);
  } else {
    return ret;
  }
}

int EthernetClient::connect(IPAddress ip, uint16_t port) {
  if (_sock != MAX_SOCK_NUM)
    return 0;

  for (int i = 0; i < MAX_SOCK_NUM; i++) {
    uint8_t s = socketStatus(i);
    if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
      _sock = i;
      break;
    }
  }

  if (_sock == MAX_SOCK_NUM)
    return 0;

  _srcport++;
  if (_srcport == 0) _srcport = 49152;          //Use IANA recommended ephemeral port range 49152-65535
  socket(_sock, SnMR::TCP, _srcport, 0);

  if (!::connect(_sock, rawIPAddress(ip), port)) {
    _sock = MAX_SOCK_NUM;
    return 0;
  }

  while (status() != SnSR::ESTABLISHED) {
    delay(1);
    if (status() == SnSR::CLOSED) {
      _sock = MAX_SOCK_NUM;
      return 0;
    }
  }

  return 1;
}

size_t EthernetClient::write(uint8_t b) {
  return write(&b, 1);
}

size_t EthernetClient::write(const uint8_t *buf, size_t size) {
  if (_sock == MAX_SOCK_NUM) {
    setWriteError();
    return 0;
  }
  if (!send(_sock, buf, size)) {
    setWriteError();
    return 0;
  }
  return size;
}

int EthernetClient::available() {
  if (_sock != MAX_SOCK_NUM)
    return recvAvailable(_sock);
  return 0;
}

int EthernetClient::read() {
  uint8_t b;
  if ( recv(_sock, &b, 1) > 0 )
  {
    // recv worked
    return b;
  }
  else
  {
    // No data available
    return -1;
  }
}

int EthernetClient::read(uint8_t *buf, size_t size) {
  return recv(_sock, buf, size);
}

int EthernetClient::peek() {
  uint8_t b;
  // Unlike recv, peek doesn't check to see if there's any data available, so we must
  if (!available())
    return -1;
  ::peek(_sock, &b);
  return b;
}

void EthernetClient::flush() {
  ::flush(_sock);
}

void EthernetClient::stop() {
  if (_sock == MAX_SOCK_NUM)
    return;

  // attempt to close the connection gracefully (send a FIN to other side)
  disconnect(_sock);
  unsigned long start = millis();

  // wait up to a second for the connection to close
  uint8_t s;
  do {
    s = status();
    if (s == SnSR::CLOSED)
      break; // exit the loop
    delay(1);
  } while (millis() - start < 1000);

  // if it hasn't closed, close it forcefully
  if (s != SnSR::CLOSED)
    close(_sock);

  EthernetClass::_server_port[_sock] = 0;
  _sock = MAX_SOCK_NUM;
}

uint8_t EthernetClient::connected() {
  if (_sock == MAX_SOCK_NUM) return 0;

  uint8_t s = status();
  return !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||
    (s == SnSR::CLOSE_WAIT && !available()));
}

uint8_t EthernetClient::status() {
  if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED;
  return socketStatus(_sock);
}

// the next function allows us to use the client returned by
// EthernetServer::available() as the condition in an if-statement.

EthernetClient::operator bool() {
  return _sock != MAX_SOCK_NUM;
}

bool EthernetClient::operator==(const EthernetClient& rhs) {
  return _sock == rhs._sock && _sock != MAX_SOCK_NUM && rhs._sock != MAX_SOCK_NUM;
}

+uint8_t EthernetClient::getSocketNumber () {
+	return _sock;
+}
<commit_msg>Removed typos in EthernetClient.cpp<commit_after>#include "utility/w5100.h"
#include "utility/socket.h"

extern "C" {
  #include "string.h"
}

#include "Arduino.h"

#include "Ethernet.h"
#include "EthernetClient.h"
#include "EthernetServer.h"
#include "Dns.h"

uint16_t EthernetClient::_srcport = 49152;      //Use IANA recommended ephemeral port range 49152-65535

EthernetClient::EthernetClient() : _sock(MAX_SOCK_NUM) {
}

EthernetClient::EthernetClient(uint8_t sock) : _sock(sock) {
}

int EthernetClient::connect(const char* host, uint16_t port) {
  // Look up the host first
  int ret = 0;
  DNSClient dns;
  IPAddress remote_addr;

  dns.begin(Ethernet.dnsServerIP());
  ret = dns.getHostByName(host, remote_addr);
  if (ret == 1) {
    return connect(remote_addr, port);
  } else {
    return ret;
  }
}

int EthernetClient::connect(IPAddress ip, uint16_t port) {
  if (_sock != MAX_SOCK_NUM)
    return 0;

  for (int i = 0; i < MAX_SOCK_NUM; i++) {
    uint8_t s = socketStatus(i);
    if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
      _sock = i;
      break;
    }
  }

  if (_sock == MAX_SOCK_NUM)
    return 0;

  _srcport++;
  if (_srcport == 0) _srcport = 49152;          //Use IANA recommended ephemeral port range 49152-65535
  socket(_sock, SnMR::TCP, _srcport, 0);

  if (!::connect(_sock, rawIPAddress(ip), port)) {
    _sock = MAX_SOCK_NUM;
    return 0;
  }

  while (status() != SnSR::ESTABLISHED) {
    delay(1);
    if (status() == SnSR::CLOSED) {
      _sock = MAX_SOCK_NUM;
      return 0;
    }
  }

  return 1;
}

size_t EthernetClient::write(uint8_t b) {
  return write(&b, 1);
}

size_t EthernetClient::write(const uint8_t *buf, size_t size) {
  if (_sock == MAX_SOCK_NUM) {
    setWriteError();
    return 0;
  }
  if (!send(_sock, buf, size)) {
    setWriteError();
    return 0;
  }
  return size;
}

int EthernetClient::available() {
  if (_sock != MAX_SOCK_NUM)
    return recvAvailable(_sock);
  return 0;
}

int EthernetClient::read() {
  uint8_t b;
  if ( recv(_sock, &b, 1) > 0 )
  {
    // recv worked
    return b;
  }
  else
  {
    // No data available
    return -1;
  }
}

int EthernetClient::read(uint8_t *buf, size_t size) {
  return recv(_sock, buf, size);
}

int EthernetClient::peek() {
  uint8_t b;
  // Unlike recv, peek doesn't check to see if there's any data available, so we must
  if (!available())
    return -1;
  ::peek(_sock, &b);
  return b;
}

void EthernetClient::flush() {
  ::flush(_sock);
}

void EthernetClient::stop() {
  if (_sock == MAX_SOCK_NUM)
    return;

  // attempt to close the connection gracefully (send a FIN to other side)
  disconnect(_sock);
  unsigned long start = millis();

  // wait up to a second for the connection to close
  uint8_t s;
  do {
    s = status();
    if (s == SnSR::CLOSED)
      break; // exit the loop
    delay(1);
  } while (millis() - start < 1000);

  // if it hasn't closed, close it forcefully
  if (s != SnSR::CLOSED)
    close(_sock);

  EthernetClass::_server_port[_sock] = 0;
  _sock = MAX_SOCK_NUM;
}

uint8_t EthernetClient::connected() {
  if (_sock == MAX_SOCK_NUM) return 0;

  uint8_t s = status();
  return !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||
    (s == SnSR::CLOSE_WAIT && !available()));
}

uint8_t EthernetClient::status() {
  if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED;
  return socketStatus(_sock);
}

// the next function allows us to use the client returned by
// EthernetServer::available() as the condition in an if-statement.

EthernetClient::operator bool() {
  return _sock != MAX_SOCK_NUM;
}

bool EthernetClient::operator==(const EthernetClient& rhs) {
  return _sock == rhs._sock && _sock != MAX_SOCK_NUM && rhs._sock != MAX_SOCK_NUM;
}

uint8_t EthernetClient::getSocketNumber() {
  return _sock;
}
<|endoftext|>


<commit_before>#include "movearray.hpp"

MoveArray::MoveArray() : count(0), num_attacks(0) {
	//moveArray = new BitMove[100];
	moveArray.resize(100);
}

MoveArray::~MoveArray() {}

void MoveArray::clear() {
	count = 0;
	num_attacks = 0;
}

void MoveArray::addMove(BitMove mv) {
	moveArray[count] = mv;
	++count;
}
<commit_msg>Размер массива в moveArray изменен на 109<commit_after>#include "movearray.hpp"

MoveArray::MoveArray() : count(0), num_attacks(0) {
	//moveArray = new BitMove[100];
	moveArray.resize(109);
}

MoveArray::~MoveArray() {}

void MoveArray::clear() {
	count = 0;
	num_attacks = 0;
}

void MoveArray::addMove(BitMove mv) {
	moveArray[count] = mv;
	++count;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <memory>

#include "block.hpp"
#include "hash.hpp"
#include "slice.hpp"
#include "threadpool.hpp"
#include "transforms.hpp"

int main (int argc, char** argv) {
	time_t start, end;
	time(&start);

	std::unique_ptr<transform_t> delegate;
	size_t memoryAlloc = 200 * 1024 * 1024;
	size_t nThreads = 1;

	// parse command line arguments
	for (auto i = 1; i < argc; ++i) {
		const auto arg = argv[i];
		size_t transformIndex = 0;

		if (sscanf(arg, "-t%lu", &transformIndex) == 1) {
			assert(delegate == nullptr);

			// raw
			if (transformIndex == 0) delegate.reset(new dumpHeaders());
			else if (transformIndex == 1) delegate.reset(new dumpScripts());

			// indexd
			else if (transformIndex == 2) delegate.reset(new dumpScriptIndex());
			else if (transformIndex == 3) delegate.reset(new dumpSpentIndex());
			else if (transformIndex == 4) delegate.reset(new dumpTxIndex());
			else if (transformIndex == 5) delegate.reset(new dumpTxOutIndex());
			else if (transformIndex == 8) delegate.reset(new dumpIndexdLevel());

			// statistics
			else if (transformIndex == 6) delegate.reset(new dumpStatistics());
			else if (transformIndex == 7) delegate.reset(new dumpOutputValuesOverHeight());

			continue;
		}
		if (sscanf(arg, "-j%lu", &nThreads) == 1) continue;
		if (sscanf(arg, "-m%lu", &memoryAlloc) == 1) continue;

		if (delegate && delegate->initialize(arg)) continue;
		assert(false);
	}

	assert(delegate != nullptr);

	// pre-allocate buffers
	const auto halfMemoryAlloc = memoryAlloc / 2;
	HeapSlice iobuffer(halfMemoryAlloc);
	std::cerr << "Allocated IO buffer (" << halfMemoryAlloc << " bytes)" << std::endl;

	HeapSlice buffer(halfMemoryAlloc);
	std::cerr << "Allocated active buffer (" << halfMemoryAlloc << " bytes)" << std::endl;

	ThreadPool<std::function<void(void)>> pool(nThreads);
	std::cerr << "Initialized " << nThreads << " threads in the thread pool" << std::endl;

	size_t count = 0;
	size_t remainder = 0;
	size_t accum = 0;
	size_t invalid = 0;

	while (true) {
		const auto rbuf = iobuffer.drop(remainder);
		const auto read = fread(rbuf.begin(), 1, rbuf.length(), stdin);
		const auto eof = static_cast<size_t>(read) < rbuf.length();
		accum += read;

		// wait for all workers before overwrite
		pool.wait();

		// copy iobuffer to buffer, allows iobuffer to be modified independently after
		memcpy(buffer.begin(), iobuffer.begin(), halfMemoryAlloc);

		auto data = buffer.take(remainder + read);
		if (invalid > 0) {
			std::cerr << std::endl << "--- Skipped " << invalid << " bad bytes" << std::endl;
			invalid = 0;
		}
		std::cerr << "-- Parsed " << count << " blocks (read " << read / 1024 << " KiB, " << accum / 1024 / 1024 << " MiB total)" << (eof ? " EOF" : "") << std::endl;

		while (data.length() >= 88) {
			// skip bad data (e.g bitcoind zero pre-allocations)
			if (data.peek<uint32_t>() != 0xd9b4bef9) {
				data.popFrontN(1);
				continue;
			}

			// skip bad data cont.
			const auto header = data.drop(8).take(80);
			if (!Block(header).verify()) {
				data.popFrontN(1);

				std::cerr << '.';
				++invalid;
				continue;
			}

			if (invalid > 0) {
				std::cerr << std::endl << "--- Skipped " << invalid << " bad bytes" << std::endl;
				invalid = 0;
			}

			// do we have enough data?
			const auto length = data.drop(4).peek<uint32_t>();
			const auto total = 8 + length;
			if (total > data.length()) break;
			data.popFrontN(8);

			// send the block data to the threadpool
			const auto block = Block(header, data.drop(80));

			pool.push([block, &delegate]() {
				delegate->operator()(block);
			});
			count++;

			data.popFrontN(length);
		}

		if (eof) break;

		// assign remainder to front of iobuffer (rbuf is offset to avoid overwrite on rawRead)
		remainder = data.length();
		memcpy(iobuffer.begin(), data.begin(), remainder);
	}

	time(&end);
	std::cerr << "Parsed " << count << " blocks in " << difftime(end, start) << " seconds" << std::endl;

	return 0;
}
<commit_msg>parser: new line before final parsed message<commit_after>#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <memory>

#include "block.hpp"
#include "hash.hpp"
#include "slice.hpp"
#include "threadpool.hpp"
#include "transforms.hpp"

int main (int argc, char** argv) {
	time_t start, end;
	time(&start);

	std::unique_ptr<transform_t> delegate;
	size_t memoryAlloc = 200 * 1024 * 1024;
	size_t nThreads = 1;

	// parse command line arguments
	for (auto i = 1; i < argc; ++i) {
		const auto arg = argv[i];
		size_t transformIndex = 0;

		if (sscanf(arg, "-t%lu", &transformIndex) == 1) {
			assert(delegate == nullptr);

			// raw
			if (transformIndex == 0) delegate.reset(new dumpHeaders());
			else if (transformIndex == 1) delegate.reset(new dumpScripts());

			// indexd
			else if (transformIndex == 2) delegate.reset(new dumpScriptIndex());
			else if (transformIndex == 3) delegate.reset(new dumpSpentIndex());
			else if (transformIndex == 4) delegate.reset(new dumpTxIndex());
			else if (transformIndex == 5) delegate.reset(new dumpTxOutIndex());
			else if (transformIndex == 8) delegate.reset(new dumpIndexdLevel());

			// statistics
			else if (transformIndex == 6) delegate.reset(new dumpStatistics());
			else if (transformIndex == 7) delegate.reset(new dumpOutputValuesOverHeight());

			continue;
		}
		if (sscanf(arg, "-j%lu", &nThreads) == 1) continue;
		if (sscanf(arg, "-m%lu", &memoryAlloc) == 1) continue;

		if (delegate && delegate->initialize(arg)) continue;
		assert(false);
	}

	assert(delegate != nullptr);

	// pre-allocate buffers
	const auto halfMemoryAlloc = memoryAlloc / 2;
	HeapSlice iobuffer(halfMemoryAlloc);
	std::cerr << "Allocated IO buffer (" << halfMemoryAlloc << " bytes)" << std::endl;

	HeapSlice buffer(halfMemoryAlloc);
	std::cerr << "Allocated active buffer (" << halfMemoryAlloc << " bytes)" << std::endl;

	ThreadPool<std::function<void(void)>> pool(nThreads);
	std::cerr << "Initialized " << nThreads << " threads in the thread pool" << std::endl;

	size_t count = 0;
	size_t remainder = 0;
	size_t accum = 0;
	size_t invalid = 0;

	while (true) {
		const auto rbuf = iobuffer.drop(remainder);
		const auto read = fread(rbuf.begin(), 1, rbuf.length(), stdin);
		const auto eof = static_cast<size_t>(read) < rbuf.length();
		accum += read;

		// wait for all workers before overwrite
		pool.wait();

		// copy iobuffer to buffer, allows iobuffer to be modified independently after
		memcpy(buffer.begin(), iobuffer.begin(), halfMemoryAlloc);

		auto data = buffer.take(remainder + read);
		if (invalid > 0) {
			std::cerr << std::endl << "-- Skipped " << invalid << " bad bytes" << std::endl;
			invalid = 0;
		}
		std::cerr << "-- Parsed " << count << " blocks (read " << read / 1024 << " KiB, " << accum / 1024 / 1024 << " MiB total)" << (eof ? " EOF" : "") << std::endl;

		while (data.length() >= 88) {
			// skip bad data (e.g bitcoind zero pre-allocations)
			if (data.peek<uint32_t>() != 0xd9b4bef9) {
				data.popFrontN(1);
				continue;
			}

			// skip bad data cont.
			const auto header = data.drop(8).take(80);
			if (!Block(header).verify()) {
				data.popFrontN(1);

				std::cerr << '.';
				++invalid;
				continue;
			}

			if (invalid > 0) {
				std::cerr << std::endl << "-- Skipped " << invalid << " bad bytes" << std::endl;
				invalid = 0;
			}

			// do we have enough data?
			const auto length = data.drop(4).peek<uint32_t>();
			const auto total = 8 + length;
			if (total > data.length()) break;
			data.popFrontN(8);

			// send the block data to the threadpool
			const auto block = Block(header, data.drop(80));

			pool.push([block, &delegate]() {
				delegate->operator()(block);
			});
			count++;

			data.popFrontN(length);
		}

		if (eof) break;

		// assign remainder to front of iobuffer (rbuf is offset to avoid overwrite on rawRead)
		remainder = data.length();
		memcpy(iobuffer.begin(), data.begin(), remainder);
	}

	if (invalid > 0) {
		std::cerr << std::endl << "-- Skipped " << invalid << " bad bytes" << std::endl;
		invalid = 0;
	}

	time(&end);
	std::cerr << "Parsed " << count << " blocks in " << difftime(end, start) << " seconds" << std::endl;

	return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2007-2015 QReal Research Group, Dmitry Mordvinov
 *
 * 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. */

#include "uiManager.h"

#include <QtCore/QTimer>
#include <QtWidgets/QAction>
#include <QtWidgets/QDialog>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QVBoxLayout>

#include <qrkernel/logging.h>
#include <qrkernel/settingsManager.h>
#include <qrutils/inFile.h>
#include <qrutils/smartDock.h>
#include <qrutils/widgets/consoleDock.h>
#include <kitBase/robotModel/robotModelUtils.h>
#include <kitBase/robotModel/robotParts/shell.h>

#include "src/ui/modeStripe.h"

using namespace interpreterCore;

static const QColor backgrondColor = QPalette().color(QPalette::Background);
static const QColor editModeColor = QPalette().color(QPalette::Background);
static const QColor debugModeColor = qRgb(152, 251, 152);

UiManager::UiManager(QAction &debugModeAction
		, QAction &editModeAction
		, qReal::gui::MainWindowDockInterface &mainWindow
		, qReal::SystemEvents &systemEvents
		, kitBase::EventsForKitPluginInterface &kitPluginEvents
		, kitBase::robotModel::RobotModelManagerInterface &robotModelManager)
	: mDebugModeAction(debugModeAction)
	, mEditModeAction(editModeAction)
	, mMainWindow(mainWindow)
	, mRobotConsole(new qReal::ui::ConsoleDock(tr("Robot console"), mMainWindow.windowWidget()))
{
	mMainWindow.graphicalModelDock()->setWindowTitle(QObject::tr("Blocks"));

	connect(&systemEvents, &qReal::SystemEvents::activeTabChanged, this, &UiManager::onActiveTabChanged);
	connect(&systemEvents, &qReal::SystemEvents::ensureDiagramVisible, this, &UiManager::ensureDiagramVisible);
	connect(&kitPluginEvents, &kitBase::EventsForKitPluginInterface::interpretationStarted
			, this, &UiManager::switchToDebuggerMode);
	connect(&kitPluginEvents, &kitBase::EventsForKitPluginInterface::interpretationStarted
			, mRobotConsole, &qReal::ui::ConsoleDock::clear);
	connect(&kitPluginEvents, &kitBase::EventsForKitPluginInterface::robotModelChanged
			, [=]() { QTimer::singleShot(0, this, SLOT(reloadDocksSavingToolbarsAndErrors())); });
	connect(&robotModelManager, &kitBase::robotModel::RobotModelManagerInterface::robotModelChanged
			, this, &UiManager::onRobotModelChanged);
	connect(&debugModeAction, &QAction::triggered, this, &UiManager::switchToDebuggerMode);
	connect(&editModeAction, &QAction::triggered, this, &UiManager::switchToEditorMode);

	mRobotConsole->hide();
	initTab();
	mMainWindow.addDockWidget(Qt::BottomDockWidgetArea, mRobotConsole);
	mMainWindow.tabifyDockWidget(mRobotConsole, mMainWindow.errorReporterDock());
	mMainWindow.windowWidget()->addAction(mRobotConsole->toggleViewAction());
	mRobotConsole->toggleViewAction()->setShortcut(Qt::ALT + Qt::Key_2);

	mMainWindow.statusBar()->setAutoFillBackground(true);
	mMainWindow.statusBar()->setStyleSheet("QStatusBar::item { border: 0px solid black; padding: 10px; }");
	editModeAction.setProperty("modeName", tr("edit mode"));
	debugModeAction.setProperty("modeName", tr("debug mode"));
	produceModeButton(Mode::Editing, debugModeAction, mMainWindow.statusBar());
	produceModeButton(Mode::Debugging, editModeAction, mMainWindow.statusBar());

	switchToEditorMode();
	onActiveTabChanged(qReal::TabInfo());
}

void UiManager::placeDevicesConfig(QWidget *devicesWidget)
{
	QDockWidget * const devicesDock = produceDockWidget(QObject::tr("Configure devices"), devicesWidget);
	devicesDock->setObjectName("devicesConfigurationDock");
	mMainWindow.addDockWidget(Qt::LeftDockWidgetArea, devicesDock);
}

void UiManager::placeWatchPlugins(QDockWidget *watchWindow, QWidget *graphicsWatch)
{
	mMainWindow.addDockWidget(Qt::LeftDockWidgetArea, watchWindow);
	watchWindow->setObjectName("variablesDebuggerDock");
	watchWindow->setFloating(false);

	QDockWidget * const graphWatchDock = produceDockWidget(QObject::tr("Sensors state"), graphicsWatch);
	graphWatchDock->setObjectName("graphicsWatcherDock");
	mMainWindow.addDockWidget(Qt::LeftDockWidgetArea, graphWatchDock);

	mMainWindow.tabifyDockWidget(watchWindow, graphWatchDock);
	reloadDocks();
}

qReal::ui::ConsoleDock &UiManager::robotConsole()
{
	return *mRobotConsole;
}

void UiManager::onActiveTabChanged(const qReal::TabInfo &tab)
{
	if (tab.type() == mCurrentTab) {
		return;
	}

	saveDocks();
	mCurrentTab = tab.type();
	reloadDocks();
	toggleModeButtons();
}

void UiManager::onRobotModelChanged(kitBase::robotModel::RobotModelInterface &model)
{
	auto subscribeShell = [this, &model]() {
		if (kitBase::robotModel::robotParts::Shell * const shell = kitBase::robotModel::RobotModelUtils::findDevice
				<kitBase::robotModel::robotParts::Shell>(model, "ShellPort"))
		{
			connect(shell, &kitBase::robotModel::robotParts::Shell::textPrinted
					, mRobotConsole, &qReal::ui::ConsoleDock::print, Qt::UniqueConnection);
		}
	};

	// Shell can be already configured or not. However, checking for it now or later, when everything is ready for use.
	subscribeShell();
	connect(&model, &kitBase::robotModel::RobotModelInterface::allDevicesConfigured, subscribeShell);
}

void UiManager::switchToEditorMode()
{
	switchToMode(Mode::Editing);
}

void UiManager::switchToDebuggerMode()
{
	switchToMode(Mode::Debugging);
}

void UiManager::switchToMode(UiManager::Mode mode)
{
	if (mCurrentMode == mode) {
		return;
	}

	saveDocks();
	mCurrentMode = mode;
	reloadDocksSavingToolbarsAndErrors();
	toggleModeButtons();
}

void UiManager::toggleModeButtons()
{
	mTabBar->setVisible(mCurrentTab != qReal::TabInfo::TabType::other);
	mEditModeAction.setVisible(mCurrentTab != qReal::TabInfo::TabType::other);
	mDebugModeAction.setVisible(mCurrentTab != qReal::TabInfo::TabType::other);
	mEditModeAction.setChecked(mCurrentMode == Mode::Editing);
	mDebugModeAction.setChecked(mCurrentMode == Mode::Debugging);

	const QColor color = mCurrentTab == qReal::TabInfo::TabType::other
			? backgrondColor
			: mCurrentMode == Mode::Editing ? editModeColor : debugModeColor;
	QPalette palette;
	palette.setColor(QPalette::Background, color);
	palette.setColor(QPalette::Base, color);
	mMainWindow.statusBar()->setPalette(palette);
}

QDockWidget *UiManager::produceDockWidget(const QString &title, QWidget *content) const
{
	QDockWidget * const dock = new QDockWidget(title);
	dock->setWidget(content);
	return dock;
}

void UiManager::produceModeButton(UiManager::Mode mode, QAction &action, QStatusBar *statusBar) const
{
	QWidget *result = nullptr;
	switch (mode) {
	case Mode::Dummy:
		return;
	case Mode::Editing:
		result = new ui::ModeStripe(action, tr("Edit mode"), statusBar);
		break;
	case Mode::Debugging:
		result = new ui::ModeStripe(action, tr("Debug mode"), statusBar);
		break;
	}

	if (!result) {
		qWarning() << "Forgot to implement producing status bar button for mode" << static_cast<int>(mode);
		return;
	}

	statusBar->addWidget(result, 10);
}

int UiManager::currentMode() const
{
	return static_cast<int>(mCurrentTab) | static_cast<int>(mCurrentMode);
}

QString UiManager::currentSettingsKey() const
{
	return "docksStateInMode" + QString::number(currentMode());
}

void UiManager::saveDocks() const
{
	qReal::SettingsManager::setValue(currentSettingsKey(), mMainWindow.saveState(currentMode()));
}

void UiManager::reloadDocks() const
{
	hack2dModelDock();
	const QByteArray state = qReal::SettingsManager::value(currentSettingsKey()).toByteArray();
	if (!mMainWindow.restoreState(state, currentMode())) {
		QLOG_ERROR() << "Cannot apply docks state for mode" << currentMode() << ":" << state;
	} else {
		resetMainWindowCorners();
		// Same trick as main window does with error reporter.
		if (mRobotConsole->isEmpty()) {
			mRobotConsole->hide();
		}
	}
}

void UiManager::reloadDocksSavingToolbarsAndErrors() const
{
	// To this moment toolbars already updated their visibility. Calling just reloadDocks() here
	// will loose some toolbars visibility and error reporter state, so memorizing it here...
	const bool errorReporterWasVisible = mMainWindow.errorReporterDock()->isVisible();
	const bool robotConsoleWasVisible = mRobotConsole->isVisible();
	QMap<QToolBar *, bool> toolBarsVisiblity;
	for (QToolBar * const toolBar : mMainWindow.toolBars()) {
		toolBarsVisiblity[toolBar] = toolBar->isVisible();
	}

	// Now reloading docks, toolbars are in random visibility after this...
	reloadDocks();

	// And finally restoring old configuration.
	mMainWindow.errorReporterDock()->setVisible(errorReporterWasVisible);
	mRobotConsole->setVisible(robotConsoleWasVisible);
	for (QToolBar * const toolBar : toolBarsVisiblity.keys()) {
		toolBar->setVisible(toolBarsVisiblity[toolBar]);
	}
}

void UiManager::resetMainWindowCorners() const
{
	// Seems like on different platforms the default corner occupation is different, so fixing it here...
	mMainWindow.setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
	mMainWindow.setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
	mMainWindow.setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
	mMainWindow.setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
}

void UiManager::ensureDiagramVisible()
{
	if (mCurrentMode == Mode::Editing) {
		return;
	}

	// 2D model is placed into smart dock that may hide central widget if docked into TopDockWidgetArea.
	// If we met such case then switching to editor mode.
	for (utils::SmartDock * const twoDModel : mMainWindow.windowWidget()->findChildren<utils::SmartDock *>()) {
		if (twoDModel->isCentral()) {
			switchToEditorMode();
			return;
		}
	}
}

void UiManager::initTab()
{
	mTabBar = new QToolBar(mMainWindow.windowWidget());
	mTabBar->setObjectName("largeTabsBar");
	mTabBar->setIconSize(QSize(32, 32));
	mTabBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
	mMainWindow.addToolBar(Qt::LeftToolBarArea, mTabBar);
	mTabBar->addAction(&mEditModeAction);
	mTabBar->addAction(&mDebugModeAction);

	connect(&mEditModeAction, &QAction::triggered, this, &UiManager::switchToEditorMode);
	connect(&mDebugModeAction, &QAction::triggered, this, &UiManager::switchToDebuggerMode);
}

void UiManager::hack2dModelDock() const
{
	// 2D model is placed into smart dock: it may be embedded into instance of QDialog
	// that is not influeced by mMainWindow::restoreState. So we must first switch to a docked form
	// and then restore docks state.
	if (utils::SmartDock * const twoDModel = mMainWindow.windowWidget()->findChild<utils::SmartDock *>()) {
		twoDModel->switchToDocked();
	}
}

void UiManager::enableDocksSnapshotter() const
{
	// This method provides tools only for development.
	// It must not be called in master branch code.
	QWidget * const mainWindow = dynamic_cast<QWidget *>(&mMainWindow);
	QDialog * const dialog = new QDialog(mainWindow);
	QVBoxLayout * const layout = new QVBoxLayout;
	dialog->setLayout(layout);
	QPushButton * const button = new QPushButton("Snapshot docks", mainWindow);
	QLineEdit * const lineEdit = new QLineEdit(mainWindow);
	connect(button, &QPushButton::clicked, [=]() {
		const QString tempSettingsFileName = "tempFileForStoringWindowState";
		QSettings tempSettings(tempSettingsFileName, QSettings::IniFormat);
		tempSettings.setValue(currentSettingsKey(), mMainWindow.saveState(currentMode()));
		tempSettings.sync();
		lineEdit->setText(utils::InFile::readAll(tempSettingsFileName).split("\n", QString::SkipEmptyParts).last());
		QFile::remove(tempSettingsFileName);
	});
	layout->addWidget(button);
	layout->addWidget(lineEdit);
	dialog->show();
}
<commit_msg>Implemented mode tab sight customizing with screen resolution [ci skip]<commit_after>/* Copyright 2007-2015 QReal Research Group, Dmitry Mordvinov
 *
 * 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. */

#include "uiManager.h"

#include <QtCore/QTimer>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QDialog>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QVBoxLayout>

#include <qrkernel/logging.h>
#include <qrkernel/settingsManager.h>
#include <qrutils/inFile.h>
#include <qrutils/smartDock.h>
#include <qrutils/widgets/consoleDock.h>
#include <kitBase/robotModel/robotModelUtils.h>
#include <kitBase/robotModel/robotParts/shell.h>

#include "src/ui/modeStripe.h"

const int lowerMediumResolutionBorder = 1024;
const int upperMediumResolutionBorder = 1280;

using namespace interpreterCore;

static const QColor backgrondColor = QPalette().color(QPalette::Background);
static const QColor editModeColor = QPalette().color(QPalette::Background);
static const QColor debugModeColor = qRgb(152, 251, 152);

UiManager::UiManager(QAction &debugModeAction
		, QAction &editModeAction
		, qReal::gui::MainWindowDockInterface &mainWindow
		, qReal::SystemEvents &systemEvents
		, kitBase::EventsForKitPluginInterface &kitPluginEvents
		, kitBase::robotModel::RobotModelManagerInterface &robotModelManager)
	: mDebugModeAction(debugModeAction)
	, mEditModeAction(editModeAction)
	, mMainWindow(mainWindow)
	, mTabBar(nullptr)
	, mRobotConsole(new qReal::ui::ConsoleDock(tr("Robot console"), mMainWindow.windowWidget()))
{
	mMainWindow.graphicalModelDock()->setWindowTitle(QObject::tr("Blocks"));

	connect(&systemEvents, &qReal::SystemEvents::activeTabChanged, this, &UiManager::onActiveTabChanged);
	connect(&systemEvents, &qReal::SystemEvents::ensureDiagramVisible, this, &UiManager::ensureDiagramVisible);
	connect(&kitPluginEvents, &kitBase::EventsForKitPluginInterface::interpretationStarted
			, this, &UiManager::switchToDebuggerMode);
	connect(&kitPluginEvents, &kitBase::EventsForKitPluginInterface::interpretationStarted
			, mRobotConsole, &qReal::ui::ConsoleDock::clear);
	connect(&kitPluginEvents, &kitBase::EventsForKitPluginInterface::robotModelChanged
			, [=]() { QTimer::singleShot(0, this, SLOT(reloadDocksSavingToolbarsAndErrors())); });
	connect(&robotModelManager, &kitBase::robotModel::RobotModelManagerInterface::robotModelChanged
			, this, &UiManager::onRobotModelChanged);
	connect(&debugModeAction, &QAction::triggered, this, &UiManager::switchToDebuggerMode);
	connect(&editModeAction, &QAction::triggered, this, &UiManager::switchToEditorMode);

	mRobotConsole->hide();
	initTab();
	mMainWindow.addDockWidget(Qt::BottomDockWidgetArea, mRobotConsole);
	mMainWindow.tabifyDockWidget(mRobotConsole, mMainWindow.errorReporterDock());
	mMainWindow.windowWidget()->addAction(mRobotConsole->toggleViewAction());
	mRobotConsole->toggleViewAction()->setShortcut(Qt::ALT + Qt::Key_2);

	mMainWindow.statusBar()->setAutoFillBackground(true);
	mMainWindow.statusBar()->setStyleSheet("QStatusBar::item { border: 0px solid black; padding: 10px; }");
	editModeAction.setProperty("modeName", tr("edit mode"));
	debugModeAction.setProperty("modeName", tr("debug mode"));
	produceModeButton(Mode::Editing, debugModeAction, mMainWindow.statusBar());
	produceModeButton(Mode::Debugging, editModeAction, mMainWindow.statusBar());

	switchToEditorMode();
	onActiveTabChanged(qReal::TabInfo());
}

void UiManager::placeDevicesConfig(QWidget *devicesWidget)
{
	QDockWidget * const devicesDock = produceDockWidget(QObject::tr("Configure devices"), devicesWidget);
	devicesDock->setObjectName("devicesConfigurationDock");
	mMainWindow.addDockWidget(Qt::LeftDockWidgetArea, devicesDock);
}

void UiManager::placeWatchPlugins(QDockWidget *watchWindow, QWidget *graphicsWatch)
{
	mMainWindow.addDockWidget(Qt::LeftDockWidgetArea, watchWindow);
	watchWindow->setObjectName("variablesDebuggerDock");
	watchWindow->setFloating(false);

	QDockWidget * const graphWatchDock = produceDockWidget(QObject::tr("Sensors state"), graphicsWatch);
	graphWatchDock->setObjectName("graphicsWatcherDock");
	mMainWindow.addDockWidget(Qt::LeftDockWidgetArea, graphWatchDock);

	mMainWindow.tabifyDockWidget(watchWindow, graphWatchDock);
	reloadDocks();
}

qReal::ui::ConsoleDock &UiManager::robotConsole()
{
	return *mRobotConsole;
}

void UiManager::onActiveTabChanged(const qReal::TabInfo &tab)
{
	if (tab.type() == mCurrentTab) {
		return;
	}

	saveDocks();
	mCurrentTab = tab.type();
	reloadDocks();
	toggleModeButtons();
}

void UiManager::onRobotModelChanged(kitBase::robotModel::RobotModelInterface &model)
{
	auto subscribeShell = [this, &model]() {
		if (kitBase::robotModel::robotParts::Shell * const shell = kitBase::robotModel::RobotModelUtils::findDevice
				<kitBase::robotModel::robotParts::Shell>(model, "ShellPort"))
		{
			connect(shell, &kitBase::robotModel::robotParts::Shell::textPrinted
					, mRobotConsole, &qReal::ui::ConsoleDock::print, Qt::UniqueConnection);
		}
	};

	// Shell can be already configured or not. However, checking for it now or later, when everything is ready for use.
	subscribeShell();
	connect(&model, &kitBase::robotModel::RobotModelInterface::allDevicesConfigured, subscribeShell);
}

void UiManager::switchToEditorMode()
{
	switchToMode(Mode::Editing);
}

void UiManager::switchToDebuggerMode()
{
	switchToMode(Mode::Debugging);
}

void UiManager::switchToMode(UiManager::Mode mode)
{
	if (mCurrentMode == mode) {
		return;
	}

	saveDocks();
	mCurrentMode = mode;
	reloadDocksSavingToolbarsAndErrors();
	toggleModeButtons();
}

void UiManager::toggleModeButtons()
{
	mEditModeAction.setVisible(mCurrentTab != qReal::TabInfo::TabType::other);
	mDebugModeAction.setVisible(mCurrentTab != qReal::TabInfo::TabType::other);
	mEditModeAction.setChecked(mCurrentMode == Mode::Editing);
	mDebugModeAction.setChecked(mCurrentMode == Mode::Debugging);
	if (mTabBar) {
		mTabBar->setVisible(mCurrentTab != qReal::TabInfo::TabType::other);
	}

	const QColor color = mCurrentTab == qReal::TabInfo::TabType::other
			? backgrondColor
			: mCurrentMode == Mode::Editing ? editModeColor : debugModeColor;
	QPalette palette;
	palette.setColor(QPalette::Background, color);
	palette.setColor(QPalette::Base, color);
	mMainWindow.statusBar()->setPalette(palette);
}

QDockWidget *UiManager::produceDockWidget(const QString &title, QWidget *content) const
{
	QDockWidget * const dock = new QDockWidget(title);
	dock->setWidget(content);
	return dock;
}

void UiManager::produceModeButton(UiManager::Mode mode, QAction &action, QStatusBar *statusBar) const
{
	QWidget *result = nullptr;
	switch (mode) {
	case Mode::Dummy:
		return;
	case Mode::Editing:
		result = new ui::ModeStripe(action, tr("Edit mode"), statusBar);
		break;
	case Mode::Debugging:
		result = new ui::ModeStripe(action, tr("Debug mode"), statusBar);
		break;
	}

	if (!result) {
		qWarning() << "Forgot to implement producing status bar button for mode" << static_cast<int>(mode);
		return;
	}

	statusBar->addWidget(result, 10);
}

int UiManager::currentMode() const
{
	return static_cast<int>(mCurrentTab) | static_cast<int>(mCurrentMode);
}

QString UiManager::currentSettingsKey() const
{
	return "docksStateInMode" + QString::number(currentMode());
}

void UiManager::saveDocks() const
{
	qReal::SettingsManager::setValue(currentSettingsKey(), mMainWindow.saveState(currentMode()));
}

void UiManager::reloadDocks() const
{
	hack2dModelDock();
	const QByteArray state = qReal::SettingsManager::value(currentSettingsKey()).toByteArray();
	if (!mMainWindow.restoreState(state, currentMode())) {
		QLOG_ERROR() << "Cannot apply docks state for mode" << currentMode() << ":" << state;
	} else {
		resetMainWindowCorners();
		// Same trick as main window does with error reporter.
		if (mRobotConsole->isEmpty()) {
			mRobotConsole->hide();
		}
	}
}

void UiManager::reloadDocksSavingToolbarsAndErrors() const
{
	// To this moment toolbars already updated their visibility. Calling just reloadDocks() here
	// will loose some toolbars visibility and error reporter state, so memorizing it here...
	const bool errorReporterWasVisible = mMainWindow.errorReporterDock()->isVisible();
	const bool robotConsoleWasVisible = mRobotConsole->isVisible();
	QMap<QToolBar *, bool> toolBarsVisiblity;
	for (QToolBar * const toolBar : mMainWindow.toolBars()) {
		toolBarsVisiblity[toolBar] = toolBar->isVisible();
	}

	// Now reloading docks, toolbars are in random visibility after this...
	reloadDocks();

	// And finally restoring old configuration.
	mMainWindow.errorReporterDock()->setVisible(errorReporterWasVisible);
	mRobotConsole->setVisible(robotConsoleWasVisible);
	for (QToolBar * const toolBar : toolBarsVisiblity.keys()) {
		toolBar->setVisible(toolBarsVisiblity[toolBar]);
	}
}

void UiManager::resetMainWindowCorners() const
{
	// Seems like on different platforms the default corner occupation is different, so fixing it here...
	mMainWindow.setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
	mMainWindow.setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
	mMainWindow.setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
	mMainWindow.setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
}

void UiManager::ensureDiagramVisible()
{
	if (mCurrentMode == Mode::Editing) {
		return;
	}

	// 2D model is placed into smart dock that may hide central widget if docked into TopDockWidgetArea.
	// If we met such case then switching to editor mode.
	for (utils::SmartDock * const twoDModel : mMainWindow.windowWidget()->findChildren<utils::SmartDock *>()) {
		if (twoDModel->isCentral()) {
			switchToEditorMode();
			return;
		}
	}
}

void UiManager::initTab()
{
	connect(&mEditModeAction, &QAction::triggered, this, &UiManager::switchToEditorMode);
	connect(&mDebugModeAction, &QAction::triggered, this, &UiManager::switchToDebuggerMode);

	const QSize resolution = QApplication::desktop()->screenGeometry().size();
	if (resolution.width() < lowerMediumResolutionBorder) {
		// The screen is super-small, do not show tab bar at all
		mMainWindow.statusBar()->addAction(&mEditModeAction);
		mMainWindow.statusBar()->addAction(&mDebugModeAction);
		return;
	}

	mTabBar = new QToolBar(mMainWindow.windowWidget());
	mTabBar->setObjectName("largeTabsBar");
	mTabBar->setIconSize(QSize(32, 32));
	mTabBar->setToolButtonStyle(resolution.width() < upperMediumResolutionBorder
			? Qt::ToolButtonIconOnly // On small resolutions in some locales text may be too wide.
			: Qt::ToolButtonTextUnderIcon);
	mMainWindow.addToolBar(Qt::LeftToolBarArea, mTabBar);
	mTabBar->addAction(&mEditModeAction);
	mTabBar->addAction(&mDebugModeAction);
}

void UiManager::hack2dModelDock() const
{
	// 2D model is placed into smart dock: it may be embedded into instance of QDialog
	// that is not influeced by mMainWindow::restoreState. So we must first switch to a docked form
	// and then restore docks state.
	if (utils::SmartDock * const twoDModel = mMainWindow.windowWidget()->findChild<utils::SmartDock *>()) {
		twoDModel->switchToDocked();
	}
}

void UiManager::enableDocksSnapshotter() const
{
	// This method provides tools only for development.
	// It must not be called in master branch code.
	QWidget * const mainWindow = dynamic_cast<QWidget *>(&mMainWindow);
	QDialog * const dialog = new QDialog(mainWindow);
	QVBoxLayout * const layout = new QVBoxLayout;
	dialog->setLayout(layout);
	QPushButton * const button = new QPushButton("Snapshot docks", mainWindow);
	QLineEdit * const lineEdit = new QLineEdit(mainWindow);
	connect(button, &QPushButton::clicked, [=]() {
		const QString tempSettingsFileName = "tempFileForStoringWindowState";
		QSettings tempSettings(tempSettingsFileName, QSettings::IniFormat);
		tempSettings.setValue(currentSettingsKey(), mMainWindow.saveState(currentMode()));
		tempSettings.sync();
		lineEdit->setText(utils::InFile::readAll(tempSettingsFileName).split("\n", QString::SkipEmptyParts).last());
		QFile::remove(tempSettingsFileName);
	});
	layout->addWidget(button);
	layout->addWidget(lineEdit);
	dialog->show();
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

// Test for issue 178: a manual compaction causes deleted data to reappear.
#include <iostream>
#include <sstream>
#include <cstdlib>

#include "leveldb/db.h"
#include "leveldb/write_batch.h"
#include "util/testharness.h"

namespace {

const int kNumKeys = 1100000;

std::string Key1(int i) {
  char buf[100];
  snprintf(buf, sizeof(buf), "my_key_%d", i);
  return buf;
}

std::string Key2(int i) {
  return Key1(i) + "_xxx";
}

class Issue178 { };

TEST(Issue178, Test) {
  // Get rid of any state from an old run.
  std::string dbpath = leveldb::test::TmpDir() + "/leveldb_cbug_test";
  DestroyDB(dbpath, leveldb::Options());

  // Open database.  Disable compression since it affects the creation
  // of layers and the code below is trying to test against a very
  // specific scenario.
  leveldb::DB* db;
  leveldb::Options db_options;
  db_options.create_if_missing = true;
  db_options.compression = leveldb::kNoCompression;
  ASSERT_OK(leveldb::DB::Open(db_options, dbpath, &db));

  // create first key range
  leveldb::WriteBatch batch;
  for (size_t i = 0; i < kNumKeys; i++) {
    batch.Put(Key1(i), "value for range 1 key");
  }
  ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));

  // create second key range
  batch.Clear();
  for (size_t i = 0; i < kNumKeys; i++) {
    batch.Put(Key2(i), "value for range 2 key");
  }
  ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));

  // delete second key range
  batch.Clear();
  for (size_t i = 0; i < kNumKeys; i++) {
    batch.Delete(Key2(i));
  }
  ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));

  // compact database
  std::string start_key = Key1(0);
  std::string end_key = Key1(kNumKeys - 1);
  leveldb::Slice least(start_key.data(), start_key.size());
  leveldb::Slice greatest(end_key.data(), end_key.size());

  // commenting out the line below causes the example to work correctly
  db->CompactRange(&least, &greatest);

  // count the keys
  leveldb::Iterator* iter = db->NewIterator(leveldb::ReadOptions());
  size_t num_keys = 0;
  for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
    num_keys++;
  }
  delete iter;
  ASSERT_EQ(kNumKeys, num_keys) << "Bad number of keys";

  // close database
  delete db;
  DestroyDB(dbpath, leveldb::Options());
}

}  // anonymous namespace

int main(int argc, char** argv) {
  return leveldb::test::RunAllTests();
}
<commit_msg>testing<commit_after><|endoftext|>


<commit_before>/*******************************************************************************
 * c7a/api/read_lines.hpp
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Alexander Noe <aleexnoe@gmail.com>
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_API_READ_LINES_HEADER
#define C7A_API_READ_LINES_HEADER

#include <c7a/api/dia.hpp>
#include <c7a/api/dop_node.hpp>
#include <c7a/common/logger.hpp>
#include <c7a/net/buffer_builder.hpp>
// C7A_{/UN}LIKELY
#include <c7a/common/math.hpp>
#include <c7a/common/item_serialization_tools.hpp>

#include <fcntl.h>
#include <fstream>
#include <glob.h>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>

namespace c7a {
namespace api {

//! \addtogroup api Interface
//! \{

/*!
 * A DIANode which performs a line-based Read operation. Read reads a file from
 * the file system and emits it as a DIA.
 */
class ReadLinesNode : public DOpNode<std::string>
{
public:
    using Super = DOpNode<std::string>;
    using Super::context_;
    using Super::result_file_;
	using FileSizePair = std::pair<std::string, size_t>;

    /*!
     * Constructor for a ReadLinesNode. Sets the Context
     * and file path.
     *
     * \param ctx Reference to Context, which holds references to data and
     * network.
     *
     * \param path Path of the input file(s)
     */
    ReadLinesNode(Context& ctx,
                  const std::string& path,
                  StatsNode* stats_node)
        : Super(ctx, { }, "Read", stats_node),
          path_(path)
    {
        glob_t glob_result;
        struct stat filestat;
        glob(path_.c_str(), GLOB_TILDE, nullptr, &glob_result);
        size_t directory_size = 0;

        for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
            const char* filepath = glob_result.gl_pathv[i];

            if (stat(filepath, &filestat)) {
                throw std::runtime_error(
                    "ERROR: Invalid file " + std::string(filepath));
            }
            if (!S_ISREG(filestat.st_mode)) continue;

            directory_size += filestat.st_size;

            filesize_prefix.push_back(std::make_pair(filepath, directory_size));
        }
        globfree(&glob_result);
    }

    void Execute() final { }

    void PushData() final {
        InputLineIterator it = GetInputLineIterator(
            filesize_prefix, context_.my_rank(), context_.num_workers());

        // Hook Read
        while (it.HasNext()) {
            auto item = it.Next();
            for (auto func : Super::callbacks_) {
                func(item);
            }
        }
    }

    void Dispose() final { }

    /*!
     * Produces an 'empty' function stack, which only contains the identity
     * emitter function.
     *
     * \return Empty function stack
     */
    auto ProduceStack() {
        return FunctionStack<std::string>();
    }

    std::string ToString() final {
        return "[ReadLinesNode] Id: " + result_file_.ToString();
    }

private:
    //! Path of the input file.
    std::string path_;

    std::vector<std::pair<std::string, size_t> > filesize_prefix;

    //! InputLineIterator gives you access to lines of a file
    class InputLineIterator
    {
    public:
        const size_t read_size = 2 * 1024 * 1024;

        //! Creates an instance of iterator that reads file line based
        InputLineIterator(
            const std::vector<FileSizePair >& files,
            size_t my_id,
            size_t num_workers)
            : files_(files),
              my_id_(my_id),
              num_workers_(num_workers) {

            input_size_ = files[files.size() - 1].second;

            // Go to start of 'local part'.
			auto my_start_and_end = common::CalculateLocalRange(input_size_, num_workers_, my_id_);

			size_t my_start = std::get<0>(my_start_and_end);
			my_end_ = std::get<1>(my_start_and_end);

            while (files_[current_file_].second <= my_start) {
                current_file_++;
            }

            c_file_ = OpenFile(files_[current_file_].first);

            // find offset in current file:
            // offset = start - sum of previous file sizes
            if (current_file_) {
                offset_ = lseek(c_file_, my_start - files_[current_file_ - 1].second, SEEK_CUR);
                current_size_ = files_[current_file_].second - files_[current_file_ - 1].second;
            }
            else {
                offset_ = lseek(c_file_, my_start, SEEK_CUR);
                current_size_ = files_[0].second;
            }

            if (offset_ != 0) {
                offset_ = lseek(c_file_, -1, SEEK_CUR);
                bb_.Reserve(read_size);
                ssize_t buffer_size = read(c_file_, bb_.data(), read_size);
                bb_.set_size(buffer_size);
                current_ = 1;

				//Move to next newline, if local part does not start at the beginning of a line.
                if (bb_[0] != '\n') {
                    bool found_n = false;

                    // find next newline, discard all previous data as previous worker already covers it
                    while (!found_n) {
                        for (auto it = bb_.begin() + current_; it != bb_.end(); it++) {
                            if (C7A_UNLIKELY(*it == '\n')) {
                                current_ = it - bb_.begin() + 1;
                                found_n = true;
                                break;
                            }
                        }
                        // no newline found: read new data into buffer_builder
                        if (!found_n) {
                            current_ = 0;
                            offset_ += bb_.size();
                            buffer_size = read(c_file_, bb_.data(), read_size);
							//EOF = newline per definition
							if (!buffer_size) {
								found_n = true;
							}
                            bb_.set_size(buffer_size);
                        }
                    }
                    assert(bb_[current_ - 1] == '\n' || !buffer_size);
                }
            }
            else {
                bb_.Reserve(read_size);
                ssize_t buffer_size = read(c_file_, bb_.data(), read_size);
                bb_.set_size(buffer_size);
            }
        }

        //! returns the next element if one exists
        //!
        //! does no checks whether a next element exists!
        std::string Next() {
            while (true) {
                std::string ret;
                for (auto it = bb_.begin() + current_; it != bb_.end(); it++) {
                    if (C7A_UNLIKELY(*it == '\n')) {
                        size_t strlen = it - bb_.begin() - current_;
                        current_ = it - bb_.begin() + 1;
                        return ret.append(bb_.PartialToString(current_ - strlen - 1, strlen));
                    }
                }
                ret.append(bb_.PartialToString(current_, bb_.size() - current_));
                current_ = 0;
                ssize_t buffer_size = read(c_file_, bb_.data(), read_size);
                offset_ += bb_.size();
                if (buffer_size) {
                    bb_.set_size(buffer_size);
                }
                else {
                    close(c_file_);
                    current_file_++;
                    offset_ = 0;

                    // REVIEW(an): you must extract all the open() commands
                    // (this and first) into a function OpenFile() if we are to
                    // add decompressors.

                    c_file_ = OpenFile(files_[current_file_].first);
                    ssize_t buffer_size = read(c_file_, bb_.data(), read_size);
                    bb_.set_size(buffer_size);

                    if (ret.length()) {
                        return ret;
                    }
                }
            }
        }

        //! returns true, if an element is available in local part
        bool HasNext() {
            if (current_file_) {
                return (offset_ + current_ + files_[current_file_ - 1].second < my_end_);
            }
            else {
                return offset_ + current_ < my_end_;
            }
        }

		//! Open file and return file handle
		//! \param path Path to open
		int OpenFile(const std::string& path) {
			return open(path.c_str(), O_RDONLY);
		}

    private:
        //! Input files with inclusive size prefixsum.
        std::vector<FileSizePair > files_;
        //! Index of current file in files_
        size_t current_file_ = 0;
        //! Size of current file in bytes
        size_t current_size_;
		//! File handle to files_[current_file_]
        int c_file_;
		//! Offset of current block in c_file_.
        size_t offset_;
        //! Size of all files combined (in bytes)
        size_t input_size_;
        //! Worker ID
        size_t my_id_;
        //! total number of workers
        size_t num_workers_;
        //! (exclusive) end of local block
        size_t my_end_;
		//! Byte buffer to create line-std::strings
        net::BufferBuilder bb_;
		//! Start of next element in current buffer.
        size_t current_ = 0;
    };

    //! Returns an InputLineIterator with a given input file stream.
    //!
    //! \param file Input file stream
    //! \param my_id Id of this worker
    //! \param num_work Number of workers
    //!
    //! \return An InputLineIterator for a given file stream
    InputLineIterator GetInputLineIterator(
        // REVIEW(an): please make some using typedefs!
        std::vector<FileSizePair> files, size_t my_id, size_t num_work) {
        return InputLineIterator(files, my_id, num_work);
    }
};

DIARef<std::string> ReadLines(Context& ctx, std::string filepath) {

    StatsNode* stats_node = ctx.stats_graph().AddNode("ReadLines", NodeType::DOP);

    auto shared_node =
        std::make_shared<ReadLinesNode>(
            ctx, filepath, stats_node);

    auto read_stack = shared_node->ProduceStack();

    return DIARef<std::string, decltype(read_stack)>(
        shared_node, read_stack, { stats_node });
}

//! \}

} // namespace api
} // namespace c7a

#endif // !C7A_API_READ_LINES_HEADER

/******************************************************************************/
<commit_msg>Move semantics!<commit_after>/*******************************************************************************
 * c7a/api/read_lines.hpp
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Alexander Noe <aleexnoe@gmail.com>
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_API_READ_LINES_HEADER
#define C7A_API_READ_LINES_HEADER

#include <c7a/api/dia.hpp>
#include <c7a/api/dop_node.hpp>
#include <c7a/common/logger.hpp>
#include <c7a/net/buffer_builder.hpp>
// C7A_{/UN}LIKELY
#include <c7a/common/math.hpp>
#include <c7a/common/item_serialization_tools.hpp>

#include <fcntl.h>
#include <fstream>
#include <glob.h>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>

namespace c7a {
namespace api {

//! \addtogroup api Interface
//! \{

/*!
 * A DIANode which performs a line-based Read operation. Read reads a file from
 * the file system and emits it as a DIA.
 */
class ReadLinesNode : public DOpNode<std::string>
{
public:
    using Super = DOpNode<std::string>;
    using Super::context_;
    using Super::result_file_;
	using FileSizePair = std::pair<std::string, size_t>;

    /*!
     * Constructor for a ReadLinesNode. Sets the Context
     * and file path.
     *
     * \param ctx Reference to Context, which holds references to data and
     * network.
     *
     * \param path Path of the input file(s)
     */
    ReadLinesNode(Context& ctx,
                  const std::string& path,
                  StatsNode* stats_node)
        : Super(ctx, { }, "Read", stats_node),
          path_(path)
    {
        glob_t glob_result;
        struct stat filestat;
        glob(path_.c_str(), GLOB_TILDE, nullptr, &glob_result);
        size_t directory_size = 0;

        for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
            const char* filepath = glob_result.gl_pathv[i];

            if (stat(filepath, &filestat)) {
                throw std::runtime_error(
                    "ERROR: Invalid file " + std::string(filepath));
            }
            if (!S_ISREG(filestat.st_mode)) continue;

            directory_size += filestat.st_size;

            filesize_prefix.emplace_back(std::move(filepath), directory_size);
        }
        globfree(&glob_result);
    }

    void Execute() final { }

    void PushData() final {
        InputLineIterator it = GetInputLineIterator(
            filesize_prefix, context_.my_rank(), context_.num_workers());

        // Hook Read
        while (it.HasNext()) {
            auto item = it.Next();
            for (auto func : Super::callbacks_) {
                func(item);
            }
        }
    }

    void Dispose() final { }

    /*!
     * Produces an 'empty' function stack, which only contains the identity
     * emitter function.
     *
     * \return Empty function stack
     */
    auto ProduceStack() {
        return FunctionStack<std::string>();
    }

    std::string ToString() final {
        return "[ReadLinesNode] Id: " + result_file_.ToString();
    }

private:
    //! Path of the input file.
    std::string path_;

    std::vector<std::pair<std::string, size_t> > filesize_prefix;

    //! InputLineIterator gives you access to lines of a file
    class InputLineIterator
    {
    public:
        const size_t read_size = 2 * 1024 * 1024;

        //! Creates an instance of iterator that reads file line based
        InputLineIterator(
            const std::vector<FileSizePair >& files,
            size_t my_id,
            size_t num_workers)
            : files_(files),
              my_id_(my_id),
              num_workers_(num_workers) {

            input_size_ = files[files.size() - 1].second;

            // Go to start of 'local part'.
			auto my_start_and_end = common::CalculateLocalRange(input_size_, num_workers_, my_id_);

			size_t my_start = std::get<0>(my_start_and_end);
			my_end_ = std::get<1>(my_start_and_end);

            while (files_[current_file_].second <= my_start) {
                current_file_++;
            }

            c_file_ = OpenFile(files_[current_file_].first);

            // find offset in current file:
            // offset = start - sum of previous file sizes
            if (current_file_) {
                offset_ = lseek(c_file_, my_start - files_[current_file_ - 1].second, SEEK_CUR);
                current_size_ = files_[current_file_].second - files_[current_file_ - 1].second;
            }
            else {
                offset_ = lseek(c_file_, my_start, SEEK_CUR);
                current_size_ = files_[0].second;
            }

            if (offset_ != 0) {
                offset_ = lseek(c_file_, -1, SEEK_CUR);
                bb_.Reserve(read_size);
                ssize_t buffer_size = read(c_file_, bb_.data(), read_size);
                bb_.set_size(buffer_size);
                current_ = 1;

				//Move to next newline, if local part does not start at the beginning of a line.
                if (bb_[0] != '\n') {
                    bool found_n = false;

                    // find next newline, discard all previous data as previous worker already covers it
                    while (!found_n) {
                        for (auto it = bb_.begin() + current_; it != bb_.end(); it++) {
                            if (C7A_UNLIKELY(*it == '\n')) {
                                current_ = it - bb_.begin() + 1;
                                found_n = true;
                                break;
                            }
                        }
                        // no newline found: read new data into buffer_builder
                        if (!found_n) {
                            current_ = 0;
                            offset_ += bb_.size();
                            buffer_size = read(c_file_, bb_.data(), read_size);
							//EOF = newline per definition
							if (!buffer_size) {
								found_n = true;
							}
                            bb_.set_size(buffer_size);
                        }
                    }
                    assert(bb_[current_ - 1] == '\n' || !buffer_size);
                }
            }
            else {
                bb_.Reserve(read_size);
                ssize_t buffer_size = read(c_file_, bb_.data(), read_size);
                bb_.set_size(buffer_size);
            }
        }

        //! returns the next element if one exists
        //!
        //! does no checks whether a next element exists!
        std::string Next() {
            while (true) {
                std::string ret;
                for (auto it = bb_.begin() + current_; it != bb_.end(); it++) {
                    if (C7A_UNLIKELY(*it == '\n')) {
                        size_t strlen = it - bb_.begin() - current_;
                        current_ = it - bb_.begin() + 1;
                        return ret.append(bb_.PartialToString(current_ - strlen - 1, strlen));
                    }
                }
                ret.append(bb_.PartialToString(current_, bb_.size() - current_));
                current_ = 0;
                ssize_t buffer_size = read(c_file_, bb_.data(), read_size);
                offset_ += bb_.size();
                if (buffer_size) {
                    bb_.set_size(buffer_size);
                }
                else {
                    close(c_file_);
                    current_file_++;
                    offset_ = 0;

                    // REVIEW(an): you must extract all the open() commands
                    // (this and first) into a function OpenFile() if we are to
                    // add decompressors.

                    c_file_ = OpenFile(files_[current_file_].first);
                    ssize_t buffer_size = read(c_file_, bb_.data(), read_size);
                    bb_.set_size(buffer_size);

                    if (ret.length()) {
                        return ret;
                    }
                }
            }
        }

        //! returns true, if an element is available in local part
        bool HasNext() {
            if (current_file_) {
                return (offset_ + current_ + files_[current_file_ - 1].second < my_end_);
            }
            else {
                return offset_ + current_ < my_end_;
            }
        }

		//! Open file and return file handle
		//! \param path Path to open
		int OpenFile(const std::string& path) {
			return open(path.c_str(), O_RDONLY);
		}

    private:
        //! Input files with inclusive size prefixsum.
        std::vector<FileSizePair> files_;
        //! Index of current file in files_
        size_t current_file_ = 0;
        //! Size of current file in bytes
        size_t current_size_;
		//! File handle to files_[current_file_]
        int c_file_;
		//! Offset of current block in c_file_.
        size_t offset_;
        //! Size of all files combined (in bytes)
        size_t input_size_;
        //! Worker ID
        size_t my_id_;
        //! total number of workers
        size_t num_workers_;
        //! (exclusive) end of local block
        size_t my_end_;
		//! Byte buffer to create line-std::strings
        net::BufferBuilder bb_;
		//! Start of next element in current buffer.
        size_t current_ = 0;
    };

    //! Returns an InputLineIterator with a given input file stream.
    //!
    //! \param file Input file stream
    //! \param my_id Id of this worker
    //! \param num_work Number of workers
    //!
    //! \return An InputLineIterator for a given file stream
    InputLineIterator GetInputLineIterator(
        // REVIEW(an): please make some using typedefs!
        std::vector<FileSizePair> files, size_t my_id, size_t num_work) {
        return InputLineIterator(files, my_id, num_work);
    }
};

DIARef<std::string> ReadLines(Context& ctx, std::string filepath) {

    StatsNode* stats_node = ctx.stats_graph().AddNode("ReadLines", NodeType::DOP);

    auto shared_node =
        std::make_shared<ReadLinesNode>(
            ctx, filepath, stats_node);

    auto read_stack = shared_node->ProduceStack();

    return DIARef<std::string, decltype(read_stack)>(
        shared_node, read_stack, { stats_node });
}

//! \}

} // namespace api
} // namespace c7a

#endif // !C7A_API_READ_LINES_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>#include "LDLTResponse.h"

#include <sofa/core/ObjectFactory.h>

namespace sofa {
namespace component {
namespace linearsolver {

SOFA_DECL_CLASS(LDLTResponse)
int LDLTResponseClass = core::RegisterObject("A sparse Cholesky factorization of the response matrix.").add< LDLTResponse >();

LDLTResponse::LDLTResponse()
    : regularize( initData(&regularize,
                           std::numeric_limits<real>::epsilon(),
						   "regularize",
						   "add identity*regularize to matrix H to make it definite.")),
	  constant( initData(&constant,
						 false,
						 "constant",
                         "reuse first factorization")),
    factorized( false )
{}

void LDLTResponse::reinit()
{
    Response::reinit();
    factorized = false;
}

void LDLTResponse::factor(const mat& H, bool semidefinite ) {

    if( constant.getValue() && factorized ) return;

    factorized = true;

    if( regularize.getValue() && semidefinite ) {
		// add a tiny diagonal matrix to make H psd.
        // TODO add epsilon only on the empty diagonal entries?
        system_type::rmat identity(H.rows(),H.cols());
        identity.setIdentity();
        response.compute( ( H + identity * regularize.getValue() ).selfadjointView<Eigen::Upper>() );
    }
    else
    {
        // TODO make sure no temporary is used ?
        response.compute( H.selfadjointView<Eigen::Upper>() );
    }

	if( response.info() != Eigen::Success ) {
        serr << "non invertible response" << sendl;
	}

	assert( response.info() == Eigen::Success );

}

void LDLTResponse::solve(cmat& res, const cmat& M) const {
	assert( response.rows() );
	res = response.solve( M );
}

void LDLTResponse::solve(vec& res, const vec& x) const {
	assert( response.rows() );
	res = response.solve( x );
}

}
}
}
<commit_msg>Flexible_test: fixing crashes. But these tests are suspicious, because they are fixing all independent dofs (projective constraints).<commit_after>#include "LDLTResponse.h"

#include <sofa/core/ObjectFactory.h>

namespace sofa {
namespace component {
namespace linearsolver {

SOFA_DECL_CLASS(LDLTResponse)
int LDLTResponseClass = core::RegisterObject("A sparse Cholesky factorization of the response matrix.").add< LDLTResponse >();

LDLTResponse::LDLTResponse()
    : regularize( initData(&regularize,
                           std::numeric_limits<real>::epsilon(),
						   "regularize",
						   "add identity*regularize to matrix H to make it definite.")),
	  constant( initData(&constant,
						 false,
						 "constant",
                         "reuse first factorization")),
    factorized( false )
{}

void LDLTResponse::reinit()
{
    Response::reinit();
    factorized = false;
}

void LDLTResponse::factor(const mat& H, bool semidefinite ) {

#ifndef NDEBUG
    if( !H.rows() ) serr<<"factor - null matrix"<<sendl;
#endif

    if( constant.getValue() && factorized ) return;

    factorized = true;

    if( regularize.getValue() && semidefinite ) {
		// add a tiny diagonal matrix to make H psd.
        // TODO add epsilon only on the empty diagonal entries?
        system_type::rmat identity(H.rows(),H.cols());
        identity.setIdentity();
        response.compute( ( H + identity * regularize.getValue() ).selfadjointView<Eigen::Upper>() );
    }
    else
    {
        // TODO make sure no temporary is used ?
        response.compute( H.selfadjointView<Eigen::Upper>() );
    }

	if( response.info() != Eigen::Success ) {
        serr << "non invertible response" << sendl;
	}

	assert( response.info() == Eigen::Success );

}

void LDLTResponse::solve(cmat& res, const cmat& M) const {
	res = response.solve( M );
}

void LDLTResponse::solve(vec& res, const vec& x) const {
	res = response.solve( x );
}

}
}
}
<|endoftext|>


<commit_before>#include "ninja.h"

#include <gtest/gtest.h>

struct NinjaTest : public testing::Test {
  NinjaTest() {
    rule_cat_ = state_.AddRule("cat", "cat @in > $out");
  }

  Rule* rule_cat_;
  State state_;
};

TEST_F(NinjaTest, Basic) {
  Edge* edge = state_.AddEdge(rule_cat_);
  state_.AddInOut(edge, Edge::IN, "in1");
  state_.AddInOut(edge, Edge::IN, "in2");
  state_.AddInOut(edge, Edge::OUT, "out");

  EXPECT_EQ("cat in1 in2 > out", edge->EvaluateCommand());

  EXPECT_FALSE(state_.GetNode("in1")->dirty());
  EXPECT_FALSE(state_.GetNode("in2")->dirty());
  EXPECT_FALSE(state_.GetNode("out")->dirty());

  state_.stat_cache()->GetFile("in1")->Touch(1);
  EXPECT_TRUE(state_.GetNode("in1")->dirty());
  EXPECT_FALSE(state_.GetNode("in2")->dirty());
  EXPECT_TRUE(state_.GetNode("out")->dirty());

  Plan plan(&state_);
  plan.AddTarget("out");
  ASSERT_TRUE(plan.FindWork());
  ASSERT_FALSE(plan.FindWork());
}

struct TestEnv : public EvalString::Env {
  virtual string Evaluate(const string& var) {
    return vars[var];
  }
  map<string, string> vars;
};
TEST(EvalString, PlainText) {
  EvalString str;
  str.Parse("plain text");
  ASSERT_EQ("plain text", str.Evaluate(NULL));
}
TEST(EvalString, OneVariable) {
  EvalString str;
  ASSERT_TRUE(str.Parse("hi $var"));
  TestEnv env;
  EXPECT_EQ("hi ", str.Evaluate(&env));
  env.vars["$var"] = "there";
  EXPECT_EQ("hi there", str.Evaluate(&env));
}
<commit_msg>more test<commit_after>#include "ninja.h"

#include <gtest/gtest.h>

struct NinjaTest : public testing::Test {
  NinjaTest() {
    rule_cat_ = state_.AddRule("cat", "cat @in > $out");
  }

  Rule* rule_cat_;
  State state_;
};

TEST_F(NinjaTest, Basic) {
  Edge* edge = state_.AddEdge(rule_cat_);
  state_.AddInOut(edge, Edge::IN, "in1");
  state_.AddInOut(edge, Edge::IN, "in2");
  state_.AddInOut(edge, Edge::OUT, "out");

  EXPECT_EQ("cat in1 in2 > out", edge->EvaluateCommand());

  EXPECT_FALSE(state_.GetNode("in1")->dirty());
  EXPECT_FALSE(state_.GetNode("in2")->dirty());
  EXPECT_FALSE(state_.GetNode("out")->dirty());

  state_.stat_cache()->GetFile("in1")->Touch(1);
  EXPECT_TRUE(state_.GetNode("in1")->dirty());
  EXPECT_FALSE(state_.GetNode("in2")->dirty());
  EXPECT_TRUE(state_.GetNode("out")->dirty());

  Plan plan(&state_);
  plan.AddTarget("out");
  edge = plan.FindWork();
  ASSERT_TRUE(edge);
  EXPECT_EQ("cat in1 in2 > out", edge->EvaluateCommand());
  ASSERT_FALSE(plan.FindWork());
}

struct TestEnv : public EvalString::Env {
  virtual string Evaluate(const string& var) {
    return vars[var];
  }
  map<string, string> vars;
};
TEST(EvalString, PlainText) {
  EvalString str;
  str.Parse("plain text");
  ASSERT_EQ("plain text", str.Evaluate(NULL));
}
TEST(EvalString, OneVariable) {
  EvalString str;
  ASSERT_TRUE(str.Parse("hi $var"));
  TestEnv env;
  EXPECT_EQ("hi ", str.Evaluate(&env));
  env.vars["$var"] = "there";
  EXPECT_EQ("hi there", str.Evaluate(&env));
}
<|endoftext|>