<commit_before>// =============================================================================
// File Name: DSDisplay.cpp
// Description: Receives IP address from remote host then sends HUD data there
// Author: FRC Team 3512, Spartatroniks
// =============================================================================

#include <DSDisplay.hpp>

DSDisplay::~DSDisplay() {
}

DSDisplay& DSDisplay::getInstance(unsigned short dsPort) {
    static DSDisplay dsDisplay(dsPort);
    return dsDisplay;
}

void DSDisplay::clear() {
    sf::Packet::clear();
}

void DSDisplay::sendToDS(sf::Packet* userData) {
    if (m_dsIP != sf::IpAddress::None) {
        if (userData == nullptr) {
            m_socket.send(*static_cast<sf::Packet*>(this),
                          m_dsIP,
                          m_dsPort);
        }
        else {
            m_socket.send(*userData, m_dsIP, m_dsPort);
        }
    }

    // Used for testing purposes
    sf::IpAddress testIP(10, 35, 12, 42);
    if (userData == nullptr) {
        m_socket.send(*static_cast<sf::Packet*>(this),
                      testIP,
                      m_dsPort);
    }
    else {
        m_socket.send(*userData, testIP, m_dsPort);
    }
}

const std::string DSDisplay::receiveFromDS() {
    if (m_socket.receive(m_recvBuffer, 256, m_recvAmount,
                         m_recvIP,
                         m_recvPort) == sf::Socket::Done) {
        if (std::strncmp(m_recvBuffer, "connect\r\n", 9) == 0) {
            m_dsIP = m_recvIP;
            m_dsPort = m_recvPort;

            // Send GUI element file to DS
            clear();

            *this << static_cast<std::string>("guiCreate\r\n");

            // Open the file
            // FIXME: May crash if file has \n for newlines instead of \r\n
            std::ifstream guiFile("GUISettings.txt", std::ifstream::binary);

            if (guiFile.is_open()) {
                // Get its length
                guiFile.seekg(0, guiFile.end);
                unsigned int fileSize = guiFile.tellg();
                guiFile.seekg(0, guiFile.beg);

                // Send the length
                *this << static_cast<uint32_t>(fileSize);

                // Allocate a buffer for the file
                char* tempBuf = new char[fileSize];

                // Send the data TODO: htonl() the data before it's sent
                guiFile.read(tempBuf, fileSize);
                append(tempBuf, fileSize);

                delete[] tempBuf;
                guiFile.close();
            }

            sendToDS();

            // Send a list of available autonomous modes
            clear();

            *this << static_cast<std::string>("autonList\r\n");

            for (unsigned int i = 0; i < m_autonModes.size(); i++) {
                *this << m_autonModes.name(i);
            }

            sendToDS();

            // Make sure driver knows which autonomous mode is selected
            clear();

            *this << static_cast<std::string>("autonConfirmed\r\n");
            *this << m_autonModes.name(curAutonMode);

            sendToDS();

            return "connect\r\n";
        }
        else if (std::strncmp(m_recvBuffer, "autonSelect\r\n", 13) == 0) {
            // Next byte after command is selection choice
            curAutonMode = m_recvBuffer[13];

            clear();

            *this << static_cast<std::string>("autonConfirmed\r\n");
            *this << m_autonModes.name(curAutonMode);

            // Store newest autonomous choice to file for persistent storage
            std::ofstream autonModeFile("autonMode.txt",
                                        std::ofstream::trunc);
            if (autonModeFile.is_open()) {
                autonModeFile << curAutonMode;

                autonModeFile.close();
            }

            sendToDS();

            return "autonSelect\r\n";
        }
    }

    return "NONE";
}

DSDisplay::DSDisplay(unsigned short portNumber) :
    m_dsIP(sf::IpAddress::None),
    m_dsPort(portNumber) {
    m_socket.bind(portNumber);
    m_socket.setBlocking(false);

    m_recvIP = sf::IpAddress(0, 0, 0, 0);
    m_recvPort = 0;
    m_recvAmount = 0;

    // Retrieve stored autonomous index
    std::ifstream autonModeFile("autonMode.txt");
    if (autonModeFile.is_open()) {
        autonModeFile >> curAutonMode;

        autonModeFile.close();
    }
    else {
        curAutonMode = 0;
    }
}

void DSDisplay::deleteAllMethods() {
    m_autonModes.deleteAllMethods();
}

void DSDisplay::execAutonomous() {
    m_autonModes.execAutonomous(curAutonMode);
}

void DSDisplay::addData(std::string ID, StatusLight data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('c');
    *this << ID;
    *this << static_cast<int8_t>(data);
}

void DSDisplay::addData(std::string ID, bool data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('c');
    *this << ID;

    if (data == true) {
        *this << static_cast<int8_t>(DSDisplay::active);
    }
    else {
        *this <<
            static_cast<int8_t>(DSDisplay::inactive);
    }
}

void DSDisplay::addData(std::string ID, int8_t data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('c');
    *this << ID;
    *this << static_cast<int8_t>(data);
}

void DSDisplay::addData(std::string ID, int32_t data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('i');
    *this << ID;
    *this << static_cast<int32_t>(data);
}

void DSDisplay::addData(std::string ID, uint32_t data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('u');
    *this << ID;
    *this << static_cast<uint32_t>(data);
}

void DSDisplay::addData(std::string ID, std::string data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('s');
    *this << ID;
    *this << data;
}

void DSDisplay::addData(std::string ID, float data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('s');
    *this << ID;

    std::stringstream ss;
    ss << data;
    *this << ss.str();
}

void DSDisplay::addData(std::string ID, double data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('s');
    *this << ID;

    std::stringstream ss;
    ss << data;
    *this << ss.str();
}

<commit_msg>Made default autonomous mode loading use an absolute path<commit_after>// =============================================================================
// File Name: DSDisplay.cpp
// Description: Receives IP address from remote host then sends HUD data there
// Author: FRC Team 3512, Spartatroniks
// =============================================================================

#include <DSDisplay.hpp>

DSDisplay::~DSDisplay() {
}

DSDisplay& DSDisplay::getInstance(unsigned short dsPort) {
    static DSDisplay dsDisplay(dsPort);
    return dsDisplay;
}

void DSDisplay::clear() {
    sf::Packet::clear();
}

void DSDisplay::sendToDS(sf::Packet* userData) {
    if (m_dsIP != sf::IpAddress::None) {
        if (userData == nullptr) {
            m_socket.send(*static_cast<sf::Packet*>(this),
                          m_dsIP,
                          m_dsPort);
        }
        else {
            m_socket.send(*userData, m_dsIP, m_dsPort);
        }
    }

    // Used for testing purposes
    sf::IpAddress testIP(10, 35, 12, 42);
    if (userData == nullptr) {
        m_socket.send(*static_cast<sf::Packet*>(this),
                      testIP,
                      m_dsPort);
    }
    else {
        m_socket.send(*userData, testIP, m_dsPort);
    }
}

const std::string DSDisplay::receiveFromDS() {
    if (m_socket.receive(m_recvBuffer, 256, m_recvAmount,
                         m_recvIP,
                         m_recvPort) == sf::Socket::Done) {
        if (std::strncmp(m_recvBuffer, "connect\r\n", 9) == 0) {
            m_dsIP = m_recvIP;
            m_dsPort = m_recvPort;

            // Send GUI element file to DS
            clear();

            *this << static_cast<std::string>("guiCreate\r\n");

            // Open the file
            // FIXME: May crash if file has \n for newlines instead of \r\n
            std::ifstream guiFile("GUISettings.txt", std::ifstream::binary);

            if (guiFile.is_open()) {
                // Get its length
                guiFile.seekg(0, guiFile.end);
                unsigned int fileSize = guiFile.tellg();
                guiFile.seekg(0, guiFile.beg);

                // Send the length
                *this << static_cast<uint32_t>(fileSize);

                // Allocate a buffer for the file
                char* tempBuf = new char[fileSize];

                // Send the data TODO: htonl() the data before it's sent
                guiFile.read(tempBuf, fileSize);
                append(tempBuf, fileSize);

                delete[] tempBuf;
                guiFile.close();
            }

            sendToDS();

            // Send a list of available autonomous modes
            clear();

            *this << static_cast<std::string>("autonList\r\n");

            for (unsigned int i = 0; i < m_autonModes.size(); i++) {
                *this << m_autonModes.name(i);
            }

            sendToDS();

            // Make sure driver knows which autonomous mode is selected
            clear();

            *this << static_cast<std::string>("autonConfirmed\r\n");
            *this << m_autonModes.name(curAutonMode);

            sendToDS();

            return "connect\r\n";
        }
        else if (std::strncmp(m_recvBuffer, "autonSelect\r\n", 13) == 0) {
            // Next byte after command is selection choice
            curAutonMode = m_recvBuffer[13];

            clear();

            *this << static_cast<std::string>("autonConfirmed\r\n");
            *this << m_autonModes.name(curAutonMode);

            // Store newest autonomous choice to file for persistent storage
            std::ofstream autonModeFile("/home/lvuser/autonMode.txt",
                                        std::ofstream::trunc);
            if (autonModeFile.is_open()) {
                autonModeFile << curAutonMode;

                autonModeFile.close();
            }

            sendToDS();

            return "autonSelect\r\n";
        }
    }

    return "NONE";
}

DSDisplay::DSDisplay(unsigned short portNumber) :
    m_dsIP(sf::IpAddress::None),
    m_dsPort(portNumber) {
    m_socket.bind(portNumber);
    m_socket.setBlocking(false);

    m_recvIP = sf::IpAddress(0, 0, 0, 0);
    m_recvPort = 0;
    m_recvAmount = 0;

    // Retrieve stored autonomous index
    std::ifstream autonModeFile("/home/lvuser/autonMode.txt");
    if (autonModeFile.is_open()) {
        autonModeFile >> curAutonMode;

        autonModeFile.close();
    }
    else {
        curAutonMode = 0;
    }
}

void DSDisplay::deleteAllMethods() {
    m_autonModes.deleteAllMethods();
}

void DSDisplay::execAutonomous() {
    m_autonModes.execAutonomous(curAutonMode);
}

void DSDisplay::addData(std::string ID, StatusLight data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('c');
    *this << ID;
    *this << static_cast<int8_t>(data);
}

void DSDisplay::addData(std::string ID, bool data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('c');
    *this << ID;

    if (data == true) {
        *this << static_cast<int8_t>(DSDisplay::active);
    }
    else {
        *this <<
            static_cast<int8_t>(DSDisplay::inactive);
    }
}

void DSDisplay::addData(std::string ID, int8_t data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('c');
    *this << ID;
    *this << static_cast<int8_t>(data);
}

void DSDisplay::addData(std::string ID, int32_t data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('i');
    *this << ID;
    *this << static_cast<int32_t>(data);
}

void DSDisplay::addData(std::string ID, uint32_t data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('u');
    *this << ID;
    *this << static_cast<uint32_t>(data);
}

void DSDisplay::addData(std::string ID, std::string data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('s');
    *this << ID;
    *this << data;
}

void DSDisplay::addData(std::string ID, float data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('s');
    *this << ID;

    std::stringstream ss;
    ss << data;
    *this << ss.str();
}

void DSDisplay::addData(std::string ID, double data) {
    // If packet is empty, add "display\r\n" header to packet
    if (sf::Packet::getData() == nullptr) {
        *this << std::string("display\r\n");
    }

    *this << static_cast<int8_t>('s');
    *this << ID;

    std::stringstream ss;
    ss << data;
    *this << ss.str();
}

<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/app/chrome_main.h"

#include <signal.h>

#include "base/global_descriptors_posix.h"
#include "base/logging.h"
#include "base/process_util.h"
#include "chrome/common/chrome_descriptors.h"

#if defined(OS_MACOSX)
#include "chrome/app/breakpad_mac.h"
#endif

namespace {

// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
void SetupSignalHandlers() {
  // Sanitise our signal handling state. Signals that were ignored by our
  // parent will also be ignored by us. We also inherit our parent's sigmask.
  sigset_t empty_signal_set;
  CHECK(0 == sigemptyset(&empty_signal_set));
  CHECK(0 == sigprocmask(SIG_SETMASK, &empty_signal_set, NULL));

  struct sigaction sigact;
  memset(&sigact, 0, sizeof(sigact));
  sigact.sa_handler = SIG_DFL;
  static const int signals_to_reset[] =
      {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
       SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};  // SIGPIPE is set below.
  for (unsigned i = 0; i < arraysize(signals_to_reset); i++) {
    CHECK(0 == sigaction(signals_to_reset[i], &sigact, NULL));
  }

  // Always ignore SIGPIPE.  We check the return value of write().
  CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR);
}

}  // anonymous namespace

namespace chrome_main {

void LowLevelInit(void* instance) {
#if defined(OS_MACOSX)
  // TODO(mark): Some of these things ought to be handled in
  // chrome_exe_main_mac.mm.  Under the current architecture, nothing
  // in chrome_exe_main can rely directly on chrome_dll code on the
  // Mac, though, so until some of this code is refactored to avoid
  // such a dependency, it lives here.  See also the TODO(mark)
  // at InitCrashReporter() and DestructCrashReporter().
  base::EnableTerminationOnHeapCorruption();
  base::EnableTerminationOnOutOfMemory();
#endif  // OS_MACOSX

  // Set C library locale to make sure CommandLine can parse argument values
  // in correct encoding.
  setlocale(LC_ALL, "");

  SetupSignalHandlers();

  base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
  g_fds->Set(kPrimaryIPCChannel,
             kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor);
#if defined(OS_LINUX)
  g_fds->Set(kCrashDumpSignal,
             kCrashDumpSignal + base::GlobalDescriptors::kBaseDescriptor);
#endif
}

void LowLevelShutdown() {
#if defined(OS_MACOSX) && defined(GOOGLE_CHROME_BUILD)
  // TODO(mark): See the TODO(mark) at InitCrashReporter.
  DestructCrashReporter();
#endif  // OS_MACOSX && GOOGLE_CHROME_BUILD
}

#if !defined(OS_MACOSX)
// This policy is not implemented for Linux and ChromeOS. The win and mac ver-
// sions are implemented in the platform specific version of chrome_main.cc e.g.
// chrome_main_win.cc or chrome_main_mac.mm .
void CheckUserDataDirPolicy(FilePath* user_data_dir) {}
#endif

}  // namespace chrome_main
<commit_msg>Fix build break<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/app/chrome_main.h"

#include <signal.h>

#include "base/global_descriptors_posix.h"
#include "base/logging.h"
#include "base/process_util.h"
#include "content/common/chrome_descriptors.h"

#if defined(OS_MACOSX)
#include "chrome/app/breakpad_mac.h"
#endif

namespace {

// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
void SetupSignalHandlers() {
  // Sanitise our signal handling state. Signals that were ignored by our
  // parent will also be ignored by us. We also inherit our parent's sigmask.
  sigset_t empty_signal_set;
  CHECK(0 == sigemptyset(&empty_signal_set));
  CHECK(0 == sigprocmask(SIG_SETMASK, &empty_signal_set, NULL));

  struct sigaction sigact;
  memset(&sigact, 0, sizeof(sigact));
  sigact.sa_handler = SIG_DFL;
  static const int signals_to_reset[] =
      {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
       SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};  // SIGPIPE is set below.
  for (unsigned i = 0; i < arraysize(signals_to_reset); i++) {
    CHECK(0 == sigaction(signals_to_reset[i], &sigact, NULL));
  }

  // Always ignore SIGPIPE.  We check the return value of write().
  CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR);
}

}  // anonymous namespace

namespace chrome_main {

void LowLevelInit(void* instance) {
#if defined(OS_MACOSX)
  // TODO(mark): Some of these things ought to be handled in
  // chrome_exe_main_mac.mm.  Under the current architecture, nothing
  // in chrome_exe_main can rely directly on chrome_dll code on the
  // Mac, though, so until some of this code is refactored to avoid
  // such a dependency, it lives here.  See also the TODO(mark)
  // at InitCrashReporter() and DestructCrashReporter().
  base::EnableTerminationOnHeapCorruption();
  base::EnableTerminationOnOutOfMemory();
#endif  // OS_MACOSX

  // Set C library locale to make sure CommandLine can parse argument values
  // in correct encoding.
  setlocale(LC_ALL, "");

  SetupSignalHandlers();

  base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
  g_fds->Set(kPrimaryIPCChannel,
             kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor);
#if defined(OS_LINUX)
  g_fds->Set(kCrashDumpSignal,
             kCrashDumpSignal + base::GlobalDescriptors::kBaseDescriptor);
#endif
}

void LowLevelShutdown() {
#if defined(OS_MACOSX) && defined(GOOGLE_CHROME_BUILD)
  // TODO(mark): See the TODO(mark) at InitCrashReporter.
  DestructCrashReporter();
#endif  // OS_MACOSX && GOOGLE_CHROME_BUILD
}

#if !defined(OS_MACOSX)
// This policy is not implemented for Linux and ChromeOS. The win and mac ver-
// sions are implemented in the platform specific version of chrome_main.cc e.g.
// chrome_main_win.cc or chrome_main_mac.mm .
void CheckUserDataDirPolicy(FilePath* user_data_dir) {}
#endif

}  // namespace chrome_main
<|endoftext|>


<commit_before>#include "ksp_plugin/pile_up.hpp"

#include "ksp_plugin/part.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/r3_element.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/si.hpp"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/componentwise.hpp"

namespace principia {
namespace ksp_plugin {
namespace internal_pile_up {

using geometry::Displacement;
using geometry::R3Element;
using geometry::Velocity;
using physics::DegreesOfFreedom;
using quantities::Length;
using quantities::Speed;
using quantities::si::Kilogram;
using quantities::si::Metre;
using quantities::si::Newton;
using quantities::si::Second;
using testing_utilities::AlmostEquals;
using testing_utilities::Componentwise;
using ::testing::Return;
using ::testing::ReturnRef;

class PileUpTest : public testing::Test {
 protected:
  PileUpTest()
      : p1_(part_id1_, mass1_, /*deletion_callback=*/nullptr),
        p2_(part_id2_, mass2_, /*deletion_callback=*/nullptr) {
    p1_.increment_intrinsic_force(
        Vector<Force, Barycentric>({1 * Newton, 2 * Newton, 3 * Newton}));
    p2_.increment_intrinsic_force(
        Vector<Force, Barycentric>({11 * Newton, 21 * Newton, 31 * Newton}));
    p1_.set_degrees_of_freedom(p1_dof_);
    p2_.set_degrees_of_freedom(p2_dof_);
  }

  using RigidPileUp = PileUp::RigidPileUp;

  PartId const part_id1_ = 111;
  PartId const part_id2_ = 222;
  Mass const mass1_ = 1 * Kilogram;
  Mass const mass2_ = 2 * Kilogram;
  DegreesOfFreedom<Bubble> const p1_dof_ = DegreesOfFreedom<Bubble>(
      Bubble::origin + Displacement<Bubble>({1 * Metre, 2 * Metre, 3 * Metre}),
      Velocity<Bubble>(
          {10 * Metre / Second, 20 * Metre / Second, 30 * Metre / Second}));
  DegreesOfFreedom<Bubble> const p2_dof_ = DegreesOfFreedom<Bubble>(
      Bubble::origin + Displacement<Bubble>({6 * Metre, 5 * Metre, 4 * Metre}),
      Velocity<Bubble>(
          {60 * Metre / Second, 50 * Metre / Second, 40 * Metre / Second}));
  DegreesOfFreedom<Barycentric> const bubble_barycentre =
      DegreesOfFreedom<Barycentric>(
          Barycentric::origin +
              Displacement<Barycentric>({7 * Metre, 8 * Metre, 9 * Metre}),
          Velocity<Barycentric>(
              {70 * Metre / Second, 80 * Metre / Second, 90 * Metre / Second}));

  Part p1_;
  Part p2_;
};

TEST_F(PileUpTest, Lifecycle) {
  PileUp pile_up({&p1_, &p2_}, bubble_barycentre, astronomy::J2000);

  EXPECT_EQ(3 * Kilogram, pile_up.mass_);
  EXPECT_THAT(pile_up.intrinsic_force_,
              AlmostEquals(Vector<Force, Barycentric>(
                  {12 * Newton, 23 * Newton, 34 * Newton}), 0));

  EXPECT_THAT(
      pile_up.psychohistory_.last().degrees_of_freedom(),
      Componentwise(AlmostEquals(Barycentric::origin +
                                     Displacement<Barycentric>(
                                         {34.0 / 3.0 * Metre,
                                          12.0 * Metre,
                                          38.0 / 3.0 * Metre}), 1),
                    AlmostEquals(Velocity<Barycentric>(
                                     {340.0 / 3.0 * Metre / Second,
                                      120.0 * Metre / Second,
                                      380.0 / 3.0 * Metre / Second}), 1)));

  EXPECT_THAT(
      pile_up.actual_part_degrees_of_freedom_.at(&p1_),
      Componentwise(AlmostEquals(RigidPileUp::origin +
                                     Displacement<RigidPileUp>(
                                         {-10.0 / 3.0 * Metre,
                                          -2.0 * Metre,
                                          -2.0 / 3.0 * Metre}), 1),
                    AlmostEquals(Velocity<RigidPileUp>(
                                     {-100.0 / 3.0 * Metre / Second,
                                      -20.0 * Metre / Second,
                                      -20.0 / 3.0 * Metre / Second}), 3)));
  EXPECT_THAT(
      pile_up.actual_part_degrees_of_freedom_.at(&p2_),
      Componentwise(AlmostEquals(RigidPileUp::origin +
                                     Displacement<RigidPileUp>(
                                         {5.0 / 3.0 * Metre,
                                          1.0 * Metre,
                                          1.0 / 3.0 * Metre}), 3),
                    AlmostEquals(Velocity<RigidPileUp>(
                                     {50.0 / 3.0 * Metre / Second,
                                      10.0 * Metre / Second,
                                      10.0 / 3.0 * Metre / Second}), 5)));

  pile_up.SetPartApparentDegreesOfFreedom(
      &p1_,
      DegreesOfFreedom<ApparentBubble>(
          ApparentBubble::origin +
              Displacement<ApparentBubble>({-11 / 3.0 * Metre,
                                            -1 * Metre,
                                            2.0 / 3.0 * Metre}),
          Velocity<ApparentBubble>({-110.0 / 3.0 * Metre / Second,
                                    -10.0 / 3.0 * Metre / Second,
                                    20.0 / 3.0 * Metre / Second})));
  pile_up.SetPartApparentDegreesOfFreedom(
      &p2_,
      DegreesOfFreedom<ApparentBubble>(
          ApparentBubble::origin +
              Displacement<ApparentBubble>({2 * Metre,
                                            0 * Metre,
                                            -2.0 / 3.0 * Metre}),
          Velocity<ApparentBubble>({20 * Metre / Second,
                                    0 * Metre / Second,
                                    -20.0 / 3.0 * Metre / Second})));

  EXPECT_THAT(
      pile_up.apparent_part_degrees_of_freedom_.at(&p1_),
      Componentwise(AlmostEquals(ApparentBubble::origin +
                                     Displacement<ApparentBubble>(
                                         {-11 / 3.0 * Metre,
                                          -1 * Metre,
                                          2.0 / 3.0 * Metre}), 0),
                    AlmostEquals(Velocity<ApparentBubble>(
                                     {-110.0 / 3.0 * Metre / Second,
                                      -10.0 / 3.0 * Metre / Second,
                                      20.0 / 3.0 * Metre / Second}), 0)));
  EXPECT_THAT(
      pile_up.apparent_part_degrees_of_freedom_.at(&p2_),
      Componentwise(AlmostEquals(ApparentBubble::origin +
                                     Displacement<ApparentBubble>(
                                         {2 * Metre,
                                          0 * Metre,
                                          -2.0 / 3.0 * Metre}), 0),
                    AlmostEquals(Velocity<ApparentBubble>(
                                     {20 * Metre / Second,
                                      0 * Metre / Second,
                                      -20.0 / 3.0 * Metre / Second}), 0)));

  //pile_up.DeformPileUpIfNeeded();

}

}  // namespace internal_pile_up
}  // namespace ksp_plugin
}  // namespace principia
<commit_msg>DeformPileUpIfNeeded.<commit_after>#include "ksp_plugin/pile_up.hpp"

#include "ksp_plugin/part.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/r3_element.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/si.hpp"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/componentwise.hpp"

namespace principia {
namespace ksp_plugin {
namespace internal_pile_up {

using geometry::Displacement;
using geometry::R3Element;
using geometry::Velocity;
using physics::DegreesOfFreedom;
using quantities::Length;
using quantities::Speed;
using quantities::si::Kilogram;
using quantities::si::Metre;
using quantities::si::Newton;
using quantities::si::Second;
using testing_utilities::AlmostEquals;
using testing_utilities::Componentwise;
using ::testing::IsEmpty;
using ::testing::Return;
using ::testing::ReturnRef;

class PileUpTest : public testing::Test {
 protected:
  PileUpTest()
      : p1_(part_id1_, mass1_, /*deletion_callback=*/nullptr),
        p2_(part_id2_, mass2_, /*deletion_callback=*/nullptr) {
    p1_.increment_intrinsic_force(
        Vector<Force, Barycentric>({1 * Newton, 2 * Newton, 3 * Newton}));
    p2_.increment_intrinsic_force(
        Vector<Force, Barycentric>({11 * Newton, 21 * Newton, 31 * Newton}));
    p1_.set_degrees_of_freedom(p1_dof_);
    p2_.set_degrees_of_freedom(p2_dof_);
  }

  using RigidPileUp = PileUp::RigidPileUp;

  PartId const part_id1_ = 111;
  PartId const part_id2_ = 222;
  Mass const mass1_ = 1 * Kilogram;
  Mass const mass2_ = 2 * Kilogram;

  // Centre of mass of |p1_| and |p2_| in |Bubble|, in SI units:
  //   {13 / 3, 4, 11 / 3} {130 / 3, 40, 110 / 3}
  DegreesOfFreedom<Bubble> const p1_dof_ = DegreesOfFreedom<Bubble>(
      Bubble::origin + Displacement<Bubble>({1 * Metre, 2 * Metre, 3 * Metre}),
      Velocity<Bubble>(
          {10 * Metre / Second, 20 * Metre / Second, 30 * Metre / Second}));
  DegreesOfFreedom<Bubble> const p2_dof_ = DegreesOfFreedom<Bubble>(
      Bubble::origin + Displacement<Bubble>({6 * Metre, 5 * Metre, 4 * Metre}),
      Velocity<Bubble>(
          {60 * Metre / Second, 50 * Metre / Second, 40 * Metre / Second}));

  DegreesOfFreedom<Barycentric> const bubble_barycentre =
      DegreesOfFreedom<Barycentric>(
          Barycentric::origin +
              Displacement<Barycentric>({7 * Metre, 8 * Metre, 9 * Metre}),
          Velocity<Barycentric>(
              {70 * Metre / Second, 80 * Metre / Second, 90 * Metre / Second}));

  Part p1_;
  Part p2_;
};

TEST_F(PileUpTest, Lifecycle) {
  PileUp pile_up({&p1_, &p2_}, bubble_barycentre, astronomy::J2000);

  EXPECT_EQ(3 * Kilogram, pile_up.mass_);
  EXPECT_THAT(pile_up.intrinsic_force_,
              AlmostEquals(Vector<Force, Barycentric>(
                  {12 * Newton, 23 * Newton, 34 * Newton}), 0));

  EXPECT_THAT(
      pile_up.psychohistory_.last().degrees_of_freedom(),
      Componentwise(AlmostEquals(Barycentric::origin +
                                     Displacement<Barycentric>(
                                         {34.0 / 3.0 * Metre,
                                          12.0 * Metre,
                                          38.0 / 3.0 * Metre}), 1),
                    AlmostEquals(Velocity<Barycentric>(
                                     {340.0 / 3.0 * Metre / Second,
                                      120.0 * Metre / Second,
                                      380.0 / 3.0 * Metre / Second}), 1)));

  EXPECT_THAT(
      pile_up.actual_part_degrees_of_freedom_.at(&p1_),
      Componentwise(AlmostEquals(RigidPileUp::origin +
                                     Displacement<RigidPileUp>(
                                         {-10.0 / 3.0 * Metre,
                                          -2.0 * Metre,
                                          -2.0 / 3.0 * Metre}), 1),
                    AlmostEquals(Velocity<RigidPileUp>(
                                     {-100.0 / 3.0 * Metre / Second,
                                      -20.0 * Metre / Second,
                                      -20.0 / 3.0 * Metre / Second}), 3)));
  EXPECT_THAT(
      pile_up.actual_part_degrees_of_freedom_.at(&p2_),
      Componentwise(AlmostEquals(RigidPileUp::origin +
                                     Displacement<RigidPileUp>(
                                         {5.0 / 3.0 * Metre,
                                          1.0 * Metre,
                                          1.0 / 3.0 * Metre}), 3),
                    AlmostEquals(Velocity<RigidPileUp>(
                                     {50.0 / 3.0 * Metre / Second,
                                      10.0 * Metre / Second,
                                      10.0 / 3.0 * Metre / Second}), 5)));

  // Centre of mass of |p1_| and |p2_| in |ApparentBubble|, in SI units:
  //   {1 / 9, -1 / 3, -2 / 9} {10 / 9, -10 / 3, -20 / 9}
  pile_up.SetPartApparentDegreesOfFreedom(
      &p1_,
      DegreesOfFreedom<ApparentBubble>(
          ApparentBubble::origin +
              Displacement<ApparentBubble>({-11.0 / 3.0 * Metre,
                                            -1.0 * Metre,
                                            2.0 / 3.0 * Metre}),
          Velocity<ApparentBubble>({-110.0 / 3.0 * Metre / Second,
                                    -10.0 / 3.0 * Metre / Second,
                                    20.0 / 3.0 * Metre / Second})));
  pile_up.SetPartApparentDegreesOfFreedom(
      &p2_,
      DegreesOfFreedom<ApparentBubble>(
          ApparentBubble::origin +
              Displacement<ApparentBubble>({2.0 * Metre,
                                            0.0 * Metre,
                                            -2.0 / 3.0 * Metre}),
          Velocity<ApparentBubble>({20.0 * Metre / Second,
                                    0.0 * Metre / Second,
                                    -20.0 / 3.0 * Metre / Second})));

  EXPECT_THAT(
      pile_up.apparent_part_degrees_of_freedom_.at(&p1_),
      Componentwise(AlmostEquals(ApparentBubble::origin +
                                     Displacement<ApparentBubble>(
                                         {-11.0 / 3.0 * Metre,
                                          -1.0 * Metre,
                                          2.0 / 3.0 * Metre}), 0),
                    AlmostEquals(Velocity<ApparentBubble>(
                                     {-110.0 / 3.0 * Metre / Second,
                                      -10.0 / 3.0 * Metre / Second,
                                      20.0 / 3.0 * Metre / Second}), 0)));
  EXPECT_THAT(
      pile_up.apparent_part_degrees_of_freedom_.at(&p2_),
      Componentwise(AlmostEquals(ApparentBubble::origin +
                                     Displacement<ApparentBubble>(
                                         {2.0 * Metre,
                                          0.0 * Metre,
                                          -2.0 / 3.0 * Metre}), 0),
                    AlmostEquals(Velocity<ApparentBubble>(
                                     {20.0 * Metre / Second,
                                      0.0 * Metre / Second,
                                      -20.0 / 3.0 * Metre / Second}), 0)));

  pile_up.DeformPileUpIfNeeded();

  EXPECT_THAT(
      pile_up.actual_part_degrees_of_freedom_.at(&p1_),
      Componentwise(AlmostEquals(RigidPileUp::origin +
                                     Displacement<RigidPileUp>(
                                         {-34.0 / 9.0 * Metre,
                                          -2.0 / 3.0 * Metre,
                                          8.0 / 9.0 * Metre}), 0),
                    AlmostEquals(Velocity<RigidPileUp>(
                                     {-340.0 / 9.0 * Metre / Second,
                                      -20.0 / 3.0 * Metre / Second,
                                      80.0 / 9.0 * Metre / Second}), 0)));
  EXPECT_THAT(
      pile_up.actual_part_degrees_of_freedom_.at(&p2_),
      Componentwise(AlmostEquals(RigidPileUp::origin +
                                     Displacement<RigidPileUp>(
                                         {17.0 / 9.0 * Metre,
                                          1.0 / 3.0 * Metre,
                                          -4.0 / 9.0 * Metre}), 0),
                    AlmostEquals(Velocity<RigidPileUp>(
                                     {170.0 / 9.0 * Metre / Second,
                                      10.0 / 3.0 * Metre / Second,
                                      -40.0 / 9.0 * Metre / Second}), 0)));
  EXPECT_THAT(pile_up.apparent_part_degrees_of_freedom_, IsEmpty());
}

}  // namespace internal_pile_up
}  // namespace ksp_plugin
}  // namespace principia
<|endoftext|>


<commit_before>//
//  Created by Lennart Oymanns on 03.05.17.
//

#ifndef NumberRepr_hpp
#define NumberRepr_hpp

#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <string>

namespace Equation {

class NumberRepr {
public:
  explicit NumberRepr();
  explicit NumberRepr(const std::string &s);
  explicit NumberRepr(long num, long denom = 1l) { SetFromInt(num, denom); }

  explicit NumberRepr(double l) { SetFromDouble(l); }

  NumberRepr &operator*=(const NumberRepr &rhs);
  NumberRepr &operator/=(const NumberRepr &rhs);
  NumberRepr &operator+=(const NumberRepr &rhs);
  NumberRepr &operator-=(const NumberRepr &rhs);

  void SetFromInt(long num, long denom = 1l);

  void SetFromDouble(double l) {
    isFraction = false;
    value_num = (long)l;
    value_denom = 1l;
    value_double = l;
    isValid = true;
  }

  bool IsValid() const { return isValid; }
  bool IsFraction() const { return isFraction; }

  double Double() const { return value_double; }
  std::string String() const {
    if (!isValid) {
      return "nan";
    }
    std::stringstream ss;
    if (isFraction) {
      ss << value_num;
      if (value_denom != 1l) {
        ss << " / " << value_denom;
      }
      return ss.str();
    }
    ss << std::setprecision(17) << value_double;
    return ss.str();
  }

  long Numerator() const { return value_num; }
  long Denominator() const { return value_denom; }

  bool operator==(const NumberRepr &n) const {
    if (!isValid || !n.isValid) {
      return false;
    }
    if (isFraction && n.isFraction) {
      return value_num == n.value_num && value_denom == n.value_denom;
    }
    if (!isFraction && !n.isFraction) {
      return value_double == n.value_double;
    }
    return false;
  }
  bool operator!=(const NumberRepr &n) const { return !(*this == n); }

  bool operator<(const NumberRepr &n) {
    if (!isValid || !n.isValid) {
      return false;
    }
    if (isFraction && n.isFraction) {
      auto a = value_num * n.value_denom;
      auto b = n.value_num * value_denom;
      return a < b;
    }
    if (!isFraction && !n.isFraction) {
      return value_double < n.value_double;
    }
    return false;
  }

  bool operator>(const NumberRepr &n) {
    if (*this < n) {
      return false;
    }
    if (*this == n) {
      return false;
    }
    return true;
  }

  static NumberRepr Pow(const NumberRepr &base, const NumberRepr &exp);

  void ToLatex(std::ostream &s) const {
    if (IsFraction()) {
      s << "\\frac{" << value_num << "}{" << value_denom << "}";
      return;
    }
    s << value_double;
  }

private:
  long value_num, value_denom;
  double value_double;
  bool isFraction = false;
  bool isValid = true;
};

inline NumberRepr operator+(NumberRepr lhs, const NumberRepr &rhs) {
  lhs += rhs;
  return lhs;
}

inline NumberRepr operator*(NumberRepr lhs, const NumberRepr &rhs) {
  lhs *= rhs;
  return lhs;
}

inline NumberRepr operator-(NumberRepr lhs, const NumberRepr &rhs) {
  lhs -= rhs;
  return lhs;
}

inline NumberRepr operator/(NumberRepr lhs, const NumberRepr &rhs) {
  lhs /= rhs;
  return lhs;
}

} // namespace Equation

std::ostream &operator<<(std::ostream &os, const Equation::NumberRepr &obj);

#endif /* NumberRepr_hpp */
<commit_msg>compare fractions and doubles as if both are doubles<commit_after>//
//  Created by Lennart Oymanns on 03.05.17.
//

#ifndef NumberRepr_hpp
#define NumberRepr_hpp

#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <string>

namespace Equation {

class NumberRepr {
public:
  explicit NumberRepr();
  explicit NumberRepr(const std::string &s);
  explicit NumberRepr(long num, long denom = 1l) { SetFromInt(num, denom); }

  explicit NumberRepr(double l) { SetFromDouble(l); }

  NumberRepr &operator*=(const NumberRepr &rhs);
  NumberRepr &operator/=(const NumberRepr &rhs);
  NumberRepr &operator+=(const NumberRepr &rhs);
  NumberRepr &operator-=(const NumberRepr &rhs);

  void SetFromInt(long num, long denom = 1l);

  void SetFromDouble(double l) {
    isFraction = false;
    value_num = (long)l;
    value_denom = 1l;
    value_double = l;
    isValid = true;
  }

  bool IsValid() const { return isValid; }
  bool IsFraction() const { return isFraction; }

  double Double() const { return value_double; }
  std::string String() const {
    if (!isValid) {
      return "nan";
    }
    std::stringstream ss;
    if (isFraction) {
      ss << value_num;
      if (value_denom != 1l) {
        ss << " / " << value_denom;
      }
      return ss.str();
    }
    ss << std::setprecision(17) << value_double;
    return ss.str();
  }

  long Numerator() const { return value_num; }
  long Denominator() const { return value_denom; }

  bool operator==(const NumberRepr &n) const {
    if (!isValid || !n.isValid) {
      return false;
    }
    if (isFraction && n.isFraction) {
      return value_num == n.value_num && value_denom == n.value_denom;
    }
    if (!isFraction && !n.isFraction) {
      return value_double == n.value_double;
    }
    return false;
  }
  bool operator!=(const NumberRepr &n) const { return !(*this == n); }

  bool operator<(const NumberRepr &n) {
    if (!isValid || !n.isValid) {
      return false;
    }
    if (isFraction && n.isFraction) {
      auto a = value_num * n.value_denom;
      auto b = n.value_num * value_denom;
      return a < b;
    }
    return value_double < n.value_double;
  }

  bool operator>(const NumberRepr &n) {
    if (*this < n) {
      return false;
    }
    if (*this == n) {
      return false;
    }
    return true;
  }

  static NumberRepr Pow(const NumberRepr &base, const NumberRepr &exp);

  void ToLatex(std::ostream &s) const {
    if (IsFraction()) {
      s << "\\frac{" << value_num << "}{" << value_denom << "}";
      return;
    }
    s << value_double;
  }

private:
  long value_num, value_denom;
  double value_double;
  bool isFraction = false;
  bool isValid = true;
};

inline NumberRepr operator+(NumberRepr lhs, const NumberRepr &rhs) {
  lhs += rhs;
  return lhs;
}

inline NumberRepr operator*(NumberRepr lhs, const NumberRepr &rhs) {
  lhs *= rhs;
  return lhs;
}

inline NumberRepr operator-(NumberRepr lhs, const NumberRepr &rhs) {
  lhs -= rhs;
  return lhs;
}

inline NumberRepr operator/(NumberRepr lhs, const NumberRepr &rhs) {
  lhs /= rhs;
  return lhs;
}

} // namespace Equation

std::ostream &operator<<(std::ostream &os, const Equation::NumberRepr &obj);

#endif /* NumberRepr_hpp */
<|endoftext|>


<commit_before>// Copyright 2017 The Ray Authors.
//
// 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 "ray/gcs/redis_gcs_client.h"

#include <unistd.h>
#include "ray/common/ray_config.h"
#include "ray/gcs/redis_accessor.h"
#include "ray/gcs/redis_context.h"

namespace ray {

namespace gcs {

RedisGcsClient::RedisGcsClient(const GcsClientOptions &options)
    : RedisGcsClient(options, CommandType::kRegular) {}

RedisGcsClient::RedisGcsClient(const GcsClientOptions &options, CommandType command_type)
    : GcsClient(options), command_type_(command_type) {
  RedisClientOptions redis_client_options(options.server_ip_, options.server_port_,
                                          options.password_, options.is_test_client_);
  redis_client_.reset(new RedisClient(redis_client_options));
}

Status RedisGcsClient::Connect(boost::asio::io_service &io_service) {
  RAY_CHECK(!is_connected_);

  Status status = redis_client_->Connect(io_service);
  if (!status.ok()) {
    RAY_LOG(INFO) << "RedisGcsClient::Connect failed, status " << status.ToString();
    return status;
  }

  std::shared_ptr<RedisContext> primary_context = redis_client_->GetPrimaryContext();
  std::vector<std::shared_ptr<RedisContext>> shard_contexts =
      redis_client_->GetShardContexts();

  log_based_actor_table_.reset(new LogBasedActorTable({primary_context}, this));
  actor_table_.reset(new ActorTable({primary_context}, this));

  // TODO(micafan) Modify ClientTable' Constructor(remove ClientID) in future.
  // We will use NodeID instead of ClientID.
  // For worker/driver, it might not have this field(NodeID).
  // For raylet, NodeID should be initialized in raylet layer(not here).
  client_table_.reset(new ClientTable({primary_context}, this));

  error_table_.reset(new ErrorTable({primary_context}, this));
  job_table_.reset(new JobTable({primary_context}, this));
  heartbeat_batch_table_.reset(new HeartbeatBatchTable({primary_context}, this));
  // Tables below would be sharded.
  object_table_.reset(new ObjectTable(shard_contexts, this));
  raylet_task_table_.reset(new raylet::TaskTable(shard_contexts, this, command_type_));
  task_reconstruction_log_.reset(new TaskReconstructionLog(shard_contexts, this));
  task_lease_table_.reset(new TaskLeaseTable(shard_contexts, this));
  heartbeat_table_.reset(new HeartbeatTable(shard_contexts, this));
  profile_table_.reset(new ProfileTable(shard_contexts, this));
  actor_checkpoint_table_.reset(new ActorCheckpointTable(shard_contexts, this));
  actor_checkpoint_id_table_.reset(new ActorCheckpointIdTable(shard_contexts, this));
  resource_table_.reset(new DynamicResourceTable({primary_context}, this));
  worker_failure_table_.reset(new WorkerFailureTable(shard_contexts, this));
  actor_accessor_.reset(new RedisActorInfoAccessor(this));
  job_accessor_.reset(new RedisJobInfoAccessor(this));
  object_accessor_.reset(new RedisObjectInfoAccessor(this));
  node_accessor_.reset(new RedisNodeInfoAccessor(this));
  task_accessor_.reset(new RedisTaskInfoAccessor(this));
  error_accessor_.reset(new RedisErrorInfoAccessor(this));
  stats_accessor_.reset(new RedisStatsInfoAccessor(this));
  worker_accessor_.reset(new RedisWorkerInfoAccessor(this));

  is_connected_ = true;

  RAY_LOG(INFO) << "RedisGcsClient Connected.";

  return Status::OK();
}

void RedisGcsClient::Disconnect() {
  RAY_CHECK(is_connected_);
  is_connected_ = false;
  redis_client_->Disconnect();
  RAY_LOG(DEBUG) << "RedisGcsClient Disconnected.";
}

std::string RedisGcsClient::DebugString() const {
  std::stringstream result;
  result << "RedisGcsClient:";
  result << "\n- TaskTable: " << raylet_task_table_->DebugString();
  result << "\n- LogBasedActorTable: " << log_based_actor_table_->DebugString();
  result << "\n- ActorTable: " << actor_table_->DebugString();
  result << "\n- TaskReconstructionLog: " << task_reconstruction_log_->DebugString();
  result << "\n- TaskLeaseTable: " << task_lease_table_->DebugString();
  result << "\n- HeartbeatTable: " << heartbeat_table_->DebugString();
  result << "\n- ErrorTable: " << error_table_->DebugString();
  result << "\n- ProfileTable: " << profile_table_->DebugString();
  result << "\n- ClientTable: " << client_table_->DebugString();
  result << "\n- JobTable: " << job_table_->DebugString();
  return result.str();
}

ObjectTable &RedisGcsClient::object_table() { return *object_table_; }

raylet::TaskTable &RedisGcsClient::raylet_task_table() { return *raylet_task_table_; }

LogBasedActorTable &RedisGcsClient::log_based_actor_table() {
  return *log_based_actor_table_;
}

ActorTable &RedisGcsClient::actor_table() { return *actor_table_; }

WorkerFailureTable &RedisGcsClient::worker_failure_table() {
  return *worker_failure_table_;
}

TaskReconstructionLog &RedisGcsClient::task_reconstruction_log() {
  return *task_reconstruction_log_;
}

TaskLeaseTable &RedisGcsClient::task_lease_table() { return *task_lease_table_; }

ClientTable &RedisGcsClient::client_table() { return *client_table_; }

HeartbeatTable &RedisGcsClient::heartbeat_table() { return *heartbeat_table_; }

HeartbeatBatchTable &RedisGcsClient::heartbeat_batch_table() {
  return *heartbeat_batch_table_;
}

ErrorTable &RedisGcsClient::error_table() { return *error_table_; }

JobTable &RedisGcsClient::job_table() { return *job_table_; }

ProfileTable &RedisGcsClient::profile_table() { return *profile_table_; }

ActorCheckpointTable &RedisGcsClient::actor_checkpoint_table() {
  return *actor_checkpoint_table_;
}

ActorCheckpointIdTable &RedisGcsClient::actor_checkpoint_id_table() {
  return *actor_checkpoint_id_table_;
}

DynamicResourceTable &RedisGcsClient::resource_table() { return *resource_table_; }

}  // namespace gcs

}  // namespace ray
<commit_msg>fix actor accessor initialize inside redis gcs client (#9284)<commit_after>// Copyright 2017 The Ray Authors.
//
// 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 "ray/gcs/redis_gcs_client.h"

#include <unistd.h>
#include "ray/common/ray_config.h"
#include "ray/gcs/redis_accessor.h"
#include "ray/gcs/redis_context.h"

namespace ray {

namespace gcs {

RedisGcsClient::RedisGcsClient(const GcsClientOptions &options)
    : RedisGcsClient(options, CommandType::kRegular) {}

RedisGcsClient::RedisGcsClient(const GcsClientOptions &options, CommandType command_type)
    : GcsClient(options), command_type_(command_type) {
  RedisClientOptions redis_client_options(options.server_ip_, options.server_port_,
                                          options.password_, options.is_test_client_);
  redis_client_.reset(new RedisClient(redis_client_options));
}

Status RedisGcsClient::Connect(boost::asio::io_service &io_service) {
  RAY_CHECK(!is_connected_);

  Status status = redis_client_->Connect(io_service);
  if (!status.ok()) {
    RAY_LOG(INFO) << "RedisGcsClient::Connect failed, status " << status.ToString();
    return status;
  }

  std::shared_ptr<RedisContext> primary_context = redis_client_->GetPrimaryContext();
  std::vector<std::shared_ptr<RedisContext>> shard_contexts =
      redis_client_->GetShardContexts();

  log_based_actor_table_.reset(new LogBasedActorTable({primary_context}, this));
  actor_table_.reset(new ActorTable({primary_context}, this));

  // TODO(micafan) Modify ClientTable' Constructor(remove ClientID) in future.
  // We will use NodeID instead of ClientID.
  // For worker/driver, it might not have this field(NodeID).
  // For raylet, NodeID should be initialized in raylet layer(not here).
  client_table_.reset(new ClientTable({primary_context}, this));

  error_table_.reset(new ErrorTable({primary_context}, this));
  job_table_.reset(new JobTable({primary_context}, this));
  heartbeat_batch_table_.reset(new HeartbeatBatchTable({primary_context}, this));
  // Tables below would be sharded.
  object_table_.reset(new ObjectTable(shard_contexts, this));
  raylet_task_table_.reset(new raylet::TaskTable(shard_contexts, this, command_type_));
  task_reconstruction_log_.reset(new TaskReconstructionLog(shard_contexts, this));
  task_lease_table_.reset(new TaskLeaseTable(shard_contexts, this));
  heartbeat_table_.reset(new HeartbeatTable(shard_contexts, this));
  profile_table_.reset(new ProfileTable(shard_contexts, this));
  actor_checkpoint_table_.reset(new ActorCheckpointTable(shard_contexts, this));
  actor_checkpoint_id_table_.reset(new ActorCheckpointIdTable(shard_contexts, this));
  resource_table_.reset(new DynamicResourceTable({primary_context}, this));
  worker_failure_table_.reset(new WorkerFailureTable(shard_contexts, this));

  if (RayConfig::instance().gcs_actor_service_enabled()) {
    actor_accessor_.reset(new RedisActorInfoAccessor(this));
  } else {
    actor_accessor_.reset(new RedisLogBasedActorInfoAccessor(this));
  }
  job_accessor_.reset(new RedisJobInfoAccessor(this));
  object_accessor_.reset(new RedisObjectInfoAccessor(this));
  node_accessor_.reset(new RedisNodeInfoAccessor(this));
  task_accessor_.reset(new RedisTaskInfoAccessor(this));
  error_accessor_.reset(new RedisErrorInfoAccessor(this));
  stats_accessor_.reset(new RedisStatsInfoAccessor(this));
  worker_accessor_.reset(new RedisWorkerInfoAccessor(this));

  is_connected_ = true;

  RAY_LOG(INFO) << "RedisGcsClient Connected.";

  return Status::OK();
}

void RedisGcsClient::Disconnect() {
  RAY_CHECK(is_connected_);
  is_connected_ = false;
  redis_client_->Disconnect();
  RAY_LOG(DEBUG) << "RedisGcsClient Disconnected.";
}

std::string RedisGcsClient::DebugString() const {
  std::stringstream result;
  result << "RedisGcsClient:";
  result << "\n- TaskTable: " << raylet_task_table_->DebugString();
  result << "\n- LogBasedActorTable: " << log_based_actor_table_->DebugString();
  result << "\n- ActorTable: " << actor_table_->DebugString();
  result << "\n- TaskReconstructionLog: " << task_reconstruction_log_->DebugString();
  result << "\n- TaskLeaseTable: " << task_lease_table_->DebugString();
  result << "\n- HeartbeatTable: " << heartbeat_table_->DebugString();
  result << "\n- ErrorTable: " << error_table_->DebugString();
  result << "\n- ProfileTable: " << profile_table_->DebugString();
  result << "\n- ClientTable: " << client_table_->DebugString();
  result << "\n- JobTable: " << job_table_->DebugString();
  return result.str();
}

ObjectTable &RedisGcsClient::object_table() { return *object_table_; }

raylet::TaskTable &RedisGcsClient::raylet_task_table() { return *raylet_task_table_; }

LogBasedActorTable &RedisGcsClient::log_based_actor_table() {
  return *log_based_actor_table_;
}

ActorTable &RedisGcsClient::actor_table() { return *actor_table_; }

WorkerFailureTable &RedisGcsClient::worker_failure_table() {
  return *worker_failure_table_;
}

TaskReconstructionLog &RedisGcsClient::task_reconstruction_log() {
  return *task_reconstruction_log_;
}

TaskLeaseTable &RedisGcsClient::task_lease_table() { return *task_lease_table_; }

ClientTable &RedisGcsClient::client_table() { return *client_table_; }

HeartbeatTable &RedisGcsClient::heartbeat_table() { return *heartbeat_table_; }

HeartbeatBatchTable &RedisGcsClient::heartbeat_batch_table() {
  return *heartbeat_batch_table_;
}

ErrorTable &RedisGcsClient::error_table() { return *error_table_; }

JobTable &RedisGcsClient::job_table() { return *job_table_; }

ProfileTable &RedisGcsClient::profile_table() { return *profile_table_; }

ActorCheckpointTable &RedisGcsClient::actor_checkpoint_table() {
  return *actor_checkpoint_table_;
}

ActorCheckpointIdTable &RedisGcsClient::actor_checkpoint_id_table() {
  return *actor_checkpoint_id_table_;
}

DynamicResourceTable &RedisGcsClient::resource_table() { return *resource_table_; }

}  // namespace gcs

}  // namespace ray
<|endoftext|>


<commit_before>// Copyright 2012, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//   * Redistributions of source code must retain the above copyright
//     notice, this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above
//     copyright notice, this list of conditions and the following disclaimer
//     in the documentation and/or other materials provided with the
//     distribution.
//   * Neither the name of Google Inc. nor the names of its
//     contributors may be used to endorse or promote products derived from
//     this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER 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.
// -----------------------------------------------------------------------------
//
//
/// \file
/// Provides an environment for variables and their values, either primitive
/// or Factory-constructible objects.
/// \author dbikel@google.com (Dan Bikel)

#ifndef RERANKER_ENVIRONMENT_IMPL_H_
#define RERANKER_ENVIRONMENT_IMPL_H_

#include <sstream>
#include <string>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <typeinfo>

#include "environment.H"

namespace reranker {

using std::ostringstream;
using std::string;
using std::tr1::unordered_map;
using std::tr1::unordered_set;

/// Provides a set of named variables and their types, as well as the values
/// for those variable.
///
/// N.B.: Primitive values are stored as strings, and are converted on demand
/// to a concrete primitive type, one of <tt>{bool,int,double,string}</tt>.
/// Because of this, this class only considers variables to have one of
/// four types (even if their concrete types are more specific):
/// <ul>
/// <li> primitive
/// <li> vector of a primitive type
/// <li> \link reranker::Factory Factory\endlink-constructible type
/// <li> vector of a \link reranker::Factory Factory\endlink-constructible type
/// </ul>
///
/// \see Interpreter
class EnvironmentImpl : public Environment {
 public:
  /// Constructs a new, empty environment.
  ///
  /// \param debug the debug level; if greater than 0, various debugging
  ///              messages will be output to <tt>std::cerr</tt>
  EnvironmentImpl(int debug = 0);

  /// Destroys this environment.
  virtual ~EnvironmentImpl() {
    for (unordered_map<string, VarMapBase *>::iterator it = var_map_.begin();
         it != var_map_.end(); ++it) {
      delete it->second;
    }
  }

  /// Returns whether the specified variable has been defined in this
  /// environment.
  virtual bool Defined(const string &varname) const {
    unordered_map<string, string>::const_iterator it = types_.find(varname);
    return it != types_.end();
  }

  /// Sets the specified variable to the value obtained from the following
  /// tokens available from the specified token stream.
  virtual void ReadAndSet(const string &varname, StreamTokenizer &st);

  virtual const string &GetType(const string &varname) const {
    unordered_map<string, string>::const_iterator type_it =
        types_.find(varname);
    if (type_it == types_.end()) {
      // Error or warning.
    }
    return type_it->second;
  }

  virtual VarMapBase *GetVarMap(const string &varname) {
    return GetVarMapForType(GetType(varname));
  }

  /// Retrieves the VarMap instance for the specified type.
  virtual VarMapBase *GetVarMapForType(const string &type) {
    string lookup_type = type;
    // First, check if this is a concrete Factory-constructible type.
    // If so, map to its abstract type name.
    unordered_map<string, string>::const_iterator factory_type_it =
        concrete_to_factory_type_.find(type);
    if (factory_type_it != concrete_to_factory_type_.end()) {
      lookup_type = factory_type_it->second;
    }

    unordered_map<string, VarMapBase *>::const_iterator var_map_it =
        var_map_.find(lookup_type);
    if (var_map_it == var_map_.end()) {
      // Error.
    }
    return var_map_it->second;
  }

  /// \copydoc reranker::Environment::Print
  virtual void Print(ostream &os) const {
    for (unordered_map<string, VarMapBase *>::const_iterator var_map_it =
             var_map_.begin();
         var_map_it != var_map_.end(); ++var_map_it) {
      var_map_it->second->Print(os);
    }
  }

  /// \copydoc reranker::Environment::PrintFactories
  virtual void PrintFactories(ostream &os) const;

  /// \copydoc reranker::Environment::Copy
  virtual Environment *Copy() const {
    EnvironmentImpl *new_env = new EnvironmentImpl(*this);
    // Now go through and create copies of each VarMap.
    for (unordered_map<string, VarMapBase *>::iterator new_env_var_map_it =
             new_env->var_map_.begin();
         new_env_var_map_it != new_env->var_map_.end(); ++new_env_var_map_it) {
      new_env_var_map_it->second = new_env_var_map_it->second->Copy(new_env);
    }
    return new_env;
  }

  /// Retrieves the value of the variable with the specified name and puts
  /// into into the object pointed to by the <tt>value</tt> parameter.
  ///
  /// \param      varname the name of the variable whose value is to be
  ///             retrieved
  /// \param[out] value a pointer to the object whose value is to be set
  /// \return whether the specified variable exists and its value was
  ///         successfully set by this method
  template<typename T>
  bool Get(const string &varname, T *value) const;

 private:
  /// Infer the type based on the next token and its token type.
  string InferType(const string &varname,
                   const StreamTokenizer &st, bool is_vector,
                   bool *is_object_type);

  /// A map from all variable names to their types.
  unordered_map<string, string> types_;

  /// A map from type name strings (as returned by the \link TypeName \endlink
  /// method) to VarMap instances for those types.
  unordered_map<string, VarMapBase *> var_map_;

  /// A map from concrete Factory-constructible type names to their abstract
  /// Factory type names.
  unordered_map<string, string> concrete_to_factory_type_;

  int debug_;
};

template<typename T>
bool
EnvironmentImpl::Get(const string &varname, T *value) const {
  unordered_map<string, string>::const_iterator type_it =
      types_.find(varname);
  if (type_it == types_.end()) {
    if (debug_ >= 1) {
      ostringstream err_ss;
      err_ss << "Environment::Get: error: no value for variable "
             << varname;
      cerr << err_ss.str() << endl;
    }
    return false;
  }

  // Now that we have the type, look up the VarMap.
  const string &type = type_it->second;
  unordered_map<string, VarMapBase*>::const_iterator var_map_it =
      var_map_.find(type);

  if (var_map_it == var_map_.end()) {
    ostringstream err_ss;
    err_ss << "Environment::Get: error: types_ and var_map_ data members "
           << "are out of sync";
    throw std::runtime_error(err_ss.str());
  }

  // Do a dynamic_cast down to the type-specific VarMap.
  VarMapBase *var_map = var_map_it->second;
  VarMap<T> *typed_var_map = dynamic_cast<VarMap<T> *>(var_map);

  if (typed_var_map == NULL) {
    ostringstream err_ss;
    err_ss << "Environment::Get: error: no value for variable "
           << varname << " of type " << typeid(*value).name()
           << "; perhaps you meant " << type << "?";
    cerr << err_ss.str() << endl;
    return false;
  }
  bool success = typed_var_map->Get(varname, value);
  if (!success) {
    ostringstream err_ss;
    err_ss << "Environment::Get: error: no value for variable "
           << varname << " of type " << typeid(*value).name()
           << "; types_ and var_map_ data members are out of sync";
    throw std::runtime_error(err_ss.str());
  }
  return success;
  }

}  // namespace reranker

#endif
<commit_msg>Fixed out-of-date comments.<commit_after>// Copyright 2012, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//   * Redistributions of source code must retain the above copyright
//     notice, this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above
//     copyright notice, this list of conditions and the following disclaimer
//     in the documentation and/or other materials provided with the
//     distribution.
//   * Neither the name of Google Inc. nor the names of its
//     contributors may be used to endorse or promote products derived from
//     this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER 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.
// -----------------------------------------------------------------------------
//
//
/// \file
/// Provides an environment for variables and their values, either primitive
/// or Factory-constructible objects, or vectors thereof.
/// \author dbikel@google.com (Dan Bikel)

#ifndef RERANKER_ENVIRONMENT_IMPL_H_
#define RERANKER_ENVIRONMENT_IMPL_H_

#include <sstream>
#include <string>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <typeinfo>

#include "environment.H"

namespace reranker {

using std::ostringstream;
using std::string;
using std::tr1::unordered_map;
using std::tr1::unordered_set;

/// Provides a set of named variables and their types, as well as the values
/// for those variables.
///
/// \see Interpreter
class EnvironmentImpl : public Environment {
 public:
  /// Constructs a new, empty environment.
  ///
  /// \param debug the debug level; if greater than 0, various debugging
  ///              messages will be output to <tt>std::cerr</tt>
  EnvironmentImpl(int debug = 0);

  /// Destroys this environment.
  virtual ~EnvironmentImpl() {
    for (unordered_map<string, VarMapBase *>::iterator it = var_map_.begin();
         it != var_map_.end(); ++it) {
      delete it->second;
    }
  }

  /// Returns whether the specified variable has been defined in this
  /// environment.
  virtual bool Defined(const string &varname) const {
    unordered_map<string, string>::const_iterator it = types_.find(varname);
    return it != types_.end();
  }

  /// Sets the specified variable to the value obtained from the following
  /// tokens available from the specified token stream.
  virtual void ReadAndSet(const string &varname, StreamTokenizer &st);

  virtual const string &GetType(const string &varname) const {
    unordered_map<string, string>::const_iterator type_it =
        types_.find(varname);
    if (type_it == types_.end()) {
      // Error or warning.
    }
    return type_it->second;
  }

  virtual VarMapBase *GetVarMap(const string &varname) {
    return GetVarMapForType(GetType(varname));
  }

  /// Retrieves the VarMap instance for the specified type.
  virtual VarMapBase *GetVarMapForType(const string &type) {
    string lookup_type = type;
    // First, check if this is a concrete Factory-constructible type.
    // If so, map to its abstract type name.
    unordered_map<string, string>::const_iterator factory_type_it =
        concrete_to_factory_type_.find(type);
    if (factory_type_it != concrete_to_factory_type_.end()) {
      lookup_type = factory_type_it->second;
    }

    unordered_map<string, VarMapBase *>::const_iterator var_map_it =
        var_map_.find(lookup_type);
    if (var_map_it == var_map_.end()) {
      // Error.
    }
    return var_map_it->second;
  }

  /// \copydoc reranker::Environment::Print
  virtual void Print(ostream &os) const {
    for (unordered_map<string, VarMapBase *>::const_iterator var_map_it =
             var_map_.begin();
         var_map_it != var_map_.end(); ++var_map_it) {
      var_map_it->second->Print(os);
    }
  }

  /// \copydoc reranker::Environment::PrintFactories
  virtual void PrintFactories(ostream &os) const;

  /// \copydoc reranker::Environment::Copy
  virtual Environment *Copy() const {
    EnvironmentImpl *new_env = new EnvironmentImpl(*this);
    // Now go through and create copies of each VarMap.
    for (unordered_map<string, VarMapBase *>::iterator new_env_var_map_it =
             new_env->var_map_.begin();
         new_env_var_map_it != new_env->var_map_.end(); ++new_env_var_map_it) {
      new_env_var_map_it->second = new_env_var_map_it->second->Copy(new_env);
    }
    return new_env;
  }

  /// Retrieves the value of the variable with the specified name and puts
  /// into into the object pointed to by the <tt>value</tt> parameter.
  ///
  /// \param      varname the name of the variable whose value is to be
  ///             retrieved
  /// \param[out] value a pointer to the object whose value is to be set
  /// \return whether the specified variable exists and its value was
  ///         successfully set by this method
  template<typename T>
  bool Get(const string &varname, T *value) const;

 private:
  /// Infer the type based on the next token and its token type.
  string InferType(const string &varname,
                   const StreamTokenizer &st, bool is_vector,
                   bool *is_object_type);

  /// A map from all variable names to their types.
  unordered_map<string, string> types_;

  /// A map from type name strings (as returned by the \link TypeName \endlink
  /// method) to VarMap instances for those types.
  unordered_map<string, VarMapBase *> var_map_;

  /// A map from concrete Factory-constructible type names to their abstract
  /// Factory type names.
  unordered_map<string, string> concrete_to_factory_type_;

  int debug_;
};

template<typename T>
bool
EnvironmentImpl::Get(const string &varname, T *value) const {
  unordered_map<string, string>::const_iterator type_it =
      types_.find(varname);
  if (type_it == types_.end()) {
    if (debug_ >= 1) {
      ostringstream err_ss;
      err_ss << "Environment::Get: error: no value for variable "
             << varname;
      cerr << err_ss.str() << endl;
    }
    return false;
  }

  // Now that we have the type, look up the VarMap.
  const string &type = type_it->second;
  unordered_map<string, VarMapBase*>::const_iterator var_map_it =
      var_map_.find(type);

  if (var_map_it == var_map_.end()) {
    ostringstream err_ss;
    err_ss << "Environment::Get: error: types_ and var_map_ data members "
           << "are out of sync";
    throw std::runtime_error(err_ss.str());
  }

  // Do a dynamic_cast down to the type-specific VarMap.
  VarMapBase *var_map = var_map_it->second;
  VarMap<T> *typed_var_map = dynamic_cast<VarMap<T> *>(var_map);

  if (typed_var_map == NULL) {
    ostringstream err_ss;
    err_ss << "Environment::Get: error: no value for variable "
           << varname << " of type " << typeid(*value).name()
           << "; perhaps you meant " << type << "?";
    cerr << err_ss.str() << endl;
    return false;
  }
  bool success = typed_var_map->Get(varname, value);
  if (!success) {
    ostringstream err_ss;
    err_ss << "Environment::Get: error: no value for variable "
           << varname << " of type " << typeid(*value).name()
           << "; types_ and var_map_ data members are out of sync";
    throw std::runtime_error(err_ss.str());
  }
  return success;
  }

}  // namespace reranker

#endif
<|endoftext|>


<commit_before>//==- DeadStores.cpp - Check for stores to dead variables --------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines a DeadStores, a flow-sensitive checker that looks for
//  stores to variables that are no longer live.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/LocalCheckers.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ParentMap.h"
#include "llvm/Support/Compiler.h"

using namespace clang;

namespace {

class VISIBILITY_HIDDEN DeadStoreObs : public LiveVariables::ObserverTy {
  ASTContext &Ctx;
  BugReporter& BR;
  ParentMap& Parents;

  enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };

public:
  DeadStoreObs(ASTContext &ctx, BugReporter& br, ParentMap& parents)
    : Ctx(ctx), BR(br), Parents(parents) {}

  virtual ~DeadStoreObs() {}

  void Report(VarDecl* V, DeadStoreKind dsk, SourceLocation L, SourceRange R) {

    std::string name = V->getNameAsString();

    const char* BugType = 0;
    std::string msg;

    switch (dsk) {
      default:
        assert(false && "Impossible dead store type.");

      case DeadInit:
        BugType = "dead initialization";
        msg = "Value stored to '" + name +
          "' during its initialization is never read";
        break;

      case DeadIncrement:
        BugType = "dead increment";
      case Standard:
        if (!BugType) BugType = "dead assignment";
        msg = "Value stored to '" + name + "' is never read";
        break;

      case Enclosing:
        BugType = "dead nested assignment";
        msg = "Although the value stored to '" + name +
          "' is used in the enclosing expression, the value is never actually"
          " read from '" + name + "'";
        break;
    }

    BR.EmitBasicReport(BugType, "Dead Store", msg.c_str(), L, R);
  }

  void CheckVarDecl(VarDecl* VD, Expr* Ex, Expr* Val,
                    DeadStoreKind dsk,
                    const LiveVariables::AnalysisDataTy& AD,
                    const LiveVariables::ValTy& Live) {

    if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>())
      Report(VD, dsk, Ex->getSourceRange().getBegin(),
             Val->getSourceRange());
  }

  void CheckDeclRef(DeclRefExpr* DR, Expr* Val, DeadStoreKind dsk,
                    const LiveVariables::AnalysisDataTy& AD,
                    const LiveVariables::ValTy& Live) {

    if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
      CheckVarDecl(VD, DR, Val, dsk, AD, Live);
  }

  bool isIncrement(VarDecl* VD, BinaryOperator* B) {
    if (B->isCompoundAssignmentOp())
      return true;

    Expr* RHS = B->getRHS()->IgnoreParenCasts();
    BinaryOperator* BRHS = dyn_cast<BinaryOperator>(RHS);

    if (!BRHS)
      return false;

    DeclRefExpr *DR;

    if ((DR = dyn_cast<DeclRefExpr>(BRHS->getLHS()->IgnoreParenCasts())))
      if (DR->getDecl() == VD)
        return true;

    if ((DR = dyn_cast<DeclRefExpr>(BRHS->getRHS()->IgnoreParenCasts())))
      if (DR->getDecl() == VD)
        return true;

    return false;
  }

  virtual void ObserveStmt(Stmt* S,
                           const LiveVariables::AnalysisDataTy& AD,
                           const LiveVariables::ValTy& Live) {

    // Skip statements in macros.
    if (S->getLocStart().isMacroID())
      return;

    if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
      if (!B->isAssignmentOp()) return; // Skip non-assignments.

      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()))
        if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
          Expr* RHS = B->getRHS()->IgnoreParenCasts();

          // Special case: check for assigning null to a pointer.
          //  This is a common form of defensive programming.
          if (VD->getType()->isPointerType()) {
            if (IntegerLiteral* L = dyn_cast<IntegerLiteral>(RHS))
              // FIXME: Probably should have an Expr::isNullPointerConstant.
              if (L->getValue() == 0)
                return;
          }
          // Special case: self-assignments.  These are often used to shut up
          //  "unused variable" compiler warnings.
          if (DeclRefExpr* RhsDR = dyn_cast<DeclRefExpr>(RHS))
            if (VD == dyn_cast<VarDecl>(RhsDR->getDecl()))
              return;

          // Otherwise, issue a warning.
          DeadStoreKind dsk = Parents.isConsumedExpr(B)
                              ? Enclosing
                              : (isIncrement(VD,B) ? DeadIncrement : Standard);

          CheckVarDecl(VD, DR, B->getRHS(), dsk, AD, Live);
        }
    }
    else if (UnaryOperator* U = dyn_cast<UnaryOperator>(S)) {
      if (!U->isIncrementOp())
        return;

      // Handle: ++x within a subexpression.  The solution is not warn
      //  about preincrements to dead variables when the preincrement occurs
      //  as a subexpression.  This can lead to false negatives, e.g. "(++x);"
      //  A generalized dead code checker should find such issues.
      if (U->isPrefix() && Parents.isConsumedExpr(U))
        return;

      Expr *Ex = U->getSubExpr()->IgnoreParenCasts();

      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex))
        CheckDeclRef(DR, U, DeadIncrement, AD, Live);
    }
    else if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
      // Iterate through the decls.  Warn if any initializers are complex
      // expressions that are not live (never used).
      for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
           DI != DE; ++DI) {

        VarDecl* V = dyn_cast<VarDecl>(*DI);

        if (!V)
          continue;

        if (V->hasLocalStorage())
          if (Expr* E = V->getInit()) {
            // A dead initialization is a variable that is dead after it
            // is initialized.  We don't flag warnings for those variables
            // marked 'unused'.
            if (!Live(V, AD) && V->getAttr<UnusedAttr>() == 0) {
              // Special case: check for initializations with constants.
              //
              //  e.g. : int x = 0;
              //
              // If x is EVER assigned a new value later, don't issue
              // a warning.  This is because such initialization can be
              // due to defensive programming.
              if (E->isConstantInitializer(Ctx))
                return;

              // Special case: check for initializations from constant
              //  variables.
              //
              //  e.g. extern const int MyConstant;
              //       int x = MyConstant;
              //
              if (DeclRefExpr *DRE=dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
                if (VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
                  if (VD->hasGlobalStorage() &&
                      VD->getType().isConstQualified()) return;

              Report(V, DeadInit, V->getLocation(), E->getSourceRange());
            }
          }
      }
  }
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Driver function to invoke the Dead-Stores checker on a CFG.
//===----------------------------------------------------------------------===//

void clang::CheckDeadStores(LiveVariables& L, BugReporter& BR) {
  DeadStoreObs A(BR.getContext(), BR, BR.getParentMap());
  L.runOnAllBlocks(*BR.getCFG(), &A);
}
<commit_msg>Sentence-type bug type and category.<commit_after>//==- DeadStores.cpp - Check for stores to dead variables --------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines a DeadStores, a flow-sensitive checker that looks for
//  stores to variables that are no longer live.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/LocalCheckers.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ParentMap.h"
#include "llvm/Support/Compiler.h"

using namespace clang;

namespace {

class VISIBILITY_HIDDEN DeadStoreObs : public LiveVariables::ObserverTy {
  ASTContext &Ctx;
  BugReporter& BR;
  ParentMap& Parents;

  enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };

public:
  DeadStoreObs(ASTContext &ctx, BugReporter& br, ParentMap& parents)
    : Ctx(ctx), BR(br), Parents(parents) {}

  virtual ~DeadStoreObs() {}

  void Report(VarDecl* V, DeadStoreKind dsk, SourceLocation L, SourceRange R) {

    std::string name = V->getNameAsString();

    const char* BugType = 0;
    std::string msg;

    switch (dsk) {
      default:
        assert(false && "Impossible dead store type.");

      case DeadInit:
        BugType = "Dead initialization";
        msg = "Value stored to '" + name +
          "' during its initialization is never read";
        break;

      case DeadIncrement:
        BugType = "Dead increment";
      case Standard:
        if (!BugType) BugType = "Dead assignment";
        msg = "Value stored to '" + name + "' is never read";
        break;

      case Enclosing:
        BugType = "Dead nested assignment";
        msg = "Although the value stored to '" + name +
          "' is used in the enclosing expression, the value is never actually"
          " read from '" + name + "'";
        break;
    }

    BR.EmitBasicReport(BugType, "Dead store", msg.c_str(), L, R);
  }

  void CheckVarDecl(VarDecl* VD, Expr* Ex, Expr* Val,
                    DeadStoreKind dsk,
                    const LiveVariables::AnalysisDataTy& AD,
                    const LiveVariables::ValTy& Live) {

    if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>())
      Report(VD, dsk, Ex->getSourceRange().getBegin(),
             Val->getSourceRange());
  }

  void CheckDeclRef(DeclRefExpr* DR, Expr* Val, DeadStoreKind dsk,
                    const LiveVariables::AnalysisDataTy& AD,
                    const LiveVariables::ValTy& Live) {

    if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
      CheckVarDecl(VD, DR, Val, dsk, AD, Live);
  }

  bool isIncrement(VarDecl* VD, BinaryOperator* B) {
    if (B->isCompoundAssignmentOp())
      return true;

    Expr* RHS = B->getRHS()->IgnoreParenCasts();
    BinaryOperator* BRHS = dyn_cast<BinaryOperator>(RHS);

    if (!BRHS)
      return false;

    DeclRefExpr *DR;

    if ((DR = dyn_cast<DeclRefExpr>(BRHS->getLHS()->IgnoreParenCasts())))
      if (DR->getDecl() == VD)
        return true;

    if ((DR = dyn_cast<DeclRefExpr>(BRHS->getRHS()->IgnoreParenCasts())))
      if (DR->getDecl() == VD)
        return true;

    return false;
  }

  virtual void ObserveStmt(Stmt* S,
                           const LiveVariables::AnalysisDataTy& AD,
                           const LiveVariables::ValTy& Live) {

    // Skip statements in macros.
    if (S->getLocStart().isMacroID())
      return;

    if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
      if (!B->isAssignmentOp()) return; // Skip non-assignments.

      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()))
        if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
          Expr* RHS = B->getRHS()->IgnoreParenCasts();

          // Special case: check for assigning null to a pointer.
          //  This is a common form of defensive programming.
          if (VD->getType()->isPointerType()) {
            if (IntegerLiteral* L = dyn_cast<IntegerLiteral>(RHS))
              // FIXME: Probably should have an Expr::isNullPointerConstant.
              if (L->getValue() == 0)
                return;
          }
          // Special case: self-assignments.  These are often used to shut up
          //  "unused variable" compiler warnings.
          if (DeclRefExpr* RhsDR = dyn_cast<DeclRefExpr>(RHS))
            if (VD == dyn_cast<VarDecl>(RhsDR->getDecl()))
              return;

          // Otherwise, issue a warning.
          DeadStoreKind dsk = Parents.isConsumedExpr(B)
                              ? Enclosing
                              : (isIncrement(VD,B) ? DeadIncrement : Standard);

          CheckVarDecl(VD, DR, B->getRHS(), dsk, AD, Live);
        }
    }
    else if (UnaryOperator* U = dyn_cast<UnaryOperator>(S)) {
      if (!U->isIncrementOp())
        return;

      // Handle: ++x within a subexpression.  The solution is not warn
      //  about preincrements to dead variables when the preincrement occurs
      //  as a subexpression.  This can lead to false negatives, e.g. "(++x);"
      //  A generalized dead code checker should find such issues.
      if (U->isPrefix() && Parents.isConsumedExpr(U))
        return;

      Expr *Ex = U->getSubExpr()->IgnoreParenCasts();

      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex))
        CheckDeclRef(DR, U, DeadIncrement, AD, Live);
    }
    else if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
      // Iterate through the decls.  Warn if any initializers are complex
      // expressions that are not live (never used).
      for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
           DI != DE; ++DI) {

        VarDecl* V = dyn_cast<VarDecl>(*DI);

        if (!V)
          continue;

        if (V->hasLocalStorage())
          if (Expr* E = V->getInit()) {
            // A dead initialization is a variable that is dead after it
            // is initialized.  We don't flag warnings for those variables
            // marked 'unused'.
            if (!Live(V, AD) && V->getAttr<UnusedAttr>() == 0) {
              // Special case: check for initializations with constants.
              //
              //  e.g. : int x = 0;
              //
              // If x is EVER assigned a new value later, don't issue
              // a warning.  This is because such initialization can be
              // due to defensive programming.
              if (E->isConstantInitializer(Ctx))
                return;

              // Special case: check for initializations from constant
              //  variables.
              //
              //  e.g. extern const int MyConstant;
              //       int x = MyConstant;
              //
              if (DeclRefExpr *DRE=dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
                if (VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
                  if (VD->hasGlobalStorage() &&
                      VD->getType().isConstQualified()) return;

              Report(V, DeadInit, V->getLocation(), E->getSourceRange());
            }
          }
      }
  }
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Driver function to invoke the Dead-Stores checker on a CFG.
//===----------------------------------------------------------------------===//

void clang::CheckDeadStores(LiveVariables& L, BugReporter& BR) {
  DeadStoreObs A(BR.getContext(), BR, BR.getParentMap());
  L.runOnAllBlocks(*BR.getCFG(), &A);
}
<|endoftext|>


<commit_before>#include "Logger.h"

#include "spectral/SpectrumDescriptor.h"
#include "spectral/RGBConverter.h"

#include <OpenImageIO/imageio.h>
#include <boost/filesystem.hpp>
#include <sstream>

OIIO_NAMESPACE_USING
using namespace PR;
namespace bf = boost::filesystem;

static void save_image(const std::string& path,
    float r, float g, float b,
    float r2, float g2, float b2)
{
    const int xres = 32, yres = 32;
    const int channels = 3;
    unsigned char pixels[xres*yres*channels];

    for(uint32 i = 0; i < xres/2; ++i)
    {
        for(uint32 j = 0; j < yres; ++j)
        {
            pixels[j*xres*3 + i*3] = int(r*255);
            pixels[j*xres*3 + i*3 + 1] = int(g*255);
            pixels[j*xres*3 + i*3 + 2] = int(b*255);
        }
    }

    for(uint32 i = xres/2; i < xres; ++i)
    {
        for(uint32 j = 0; j < yres; ++j)
        {
            pixels[j*xres*3 + i*3] = int(r2*255);
            pixels[j*xres*3 + i*3 + 1] = int(g2*255);
            pixels[j*xres*3 + i*3 + 2] = int(b2*255);
        }
    }

    ImageOutput *out = ImageOutput::create (path);
    if (! out)
    {
        std::cout << "Couldn't save image " << path << std::endl;
        return;
    }

    ImageSpec spec(xres, yres, channels, TypeDesc::UINT8);
    out->open(path, spec);
    out->write_image(TypeDesc::UINT8, pixels);
    out->close();

    ImageOutput::destroy(out);
}

static void handle_color(float r, float g, float b)
{
    std::shared_ptr<SpectrumDescriptor> desc = SpectrumDescriptor::createStandardSpectral();
    Spectrum spec(desc);

    PR::RGBConverter::toSpec(spec, r,g,b);
    float R, G, B;
    PR::RGBConverter::convert(spec, R, G, B);

    std::stringstream stream;
    stream << "results/spectral1/"
        << int(r*255) << "_" << int(g*255) << "_" << int(b*255) << ".png";
    save_image(stream.str(), r,g,b, R,G,B);
}

void suite_spectral1()
{
    bf::create_directory("results/spectral1");

    constexpr float step=0.1;
    for(float r = 0; r <= 1; r+=step)
    {
        for(float g = 0; g <= 1; g+=step)
        {
            for(float b = 0; b <= 1; b+=step)
            {
                handle_color(r,g,b);
            }
        }
    }
}<commit_msg>Improved spectral sandbox... Its obvious that the convert functions has to be adapted.<commit_after>#include "Logger.h"

#include "spectral/RGBConverter.h"
#include "spectral/SpectrumDescriptor.h"

#include <OpenImageIO/imageio.h>
#include <boost/filesystem.hpp>
#include <fstream>
#include <sstream>

OIIO_NAMESPACE_USING
using namespace PR;
namespace bf = boost::filesystem;

static void save_spec(const std::string& path,
					  const Spectrum& spec)
{
	constexpr float MAX_INTENSITY = 2.0f;
	const size_t xres = spec.samples(), yres = 100;
	const size_t channels = 3;
	const size_t size	 = xres * yres * channels;
	std::vector<uint8> pixels(size, 255);

	for (uint32 i = 0; i < xres; ++i) {
		const float f = spec(i);

		if (f < 0) {
			pixels[(yres - 1) * xres * 3 + i * 3]	 = 255;
			pixels[(yres - 1) * xres * 3 + i * 3 + 1] = 0;
			pixels[(yres - 1) * xres * 3 + i * 3 + 2] = 0;
		} else if (f > MAX_INTENSITY) {
			pixels[0 * xres * 3 + i * 3]	  = 0;
			pixels[0 * xres * 3 + i * 3 + 1] = 255;
			pixels[0 * xres * 3 + i * 3 + 2]  = 0;
		} else {
			uint32 y = yres - std::min<uint32>(yres - 1, std::max<uint32>(0, yres * f / MAX_INTENSITY)) - 1;

			pixels[y * xres * 3 + i * 3]	 = 0;
			pixels[y * xres * 3 + i * 3 + 1] = 0;
			pixels[y * xres * 3 + i * 3 + 2] = 255;
		}
	}

	ImageOutput* out = ImageOutput::create(path);
	if (!out) {
		std::cout << "Couldn't save image " << path << std::endl;
		return;
	}

	ImageSpec imgSpec(xres, yres, channels, TypeDesc::UINT8);
	out->open(path, imgSpec);
	out->write_image(TypeDesc::UINT8, pixels.data());
	out->close();

	ImageOutput::destroy(out);
}

static void save_image(const std::string& path,
					   float r, float g, float b,
					   float r2, float g2, float b2)
{
	const size_t xres = 32, yres = 32;
	const size_t channels = 3;
	uint8 pixels[xres * yres * channels];

	for (uint32 i = 0; i < xres / 2; ++i) {
		for (uint32 j = 0; j < yres; ++j) {
			pixels[j * xres * 3 + i * 3]	 = int(r * 255);
			pixels[j * xres * 3 + i * 3 + 1] = int(g * 255);
			pixels[j * xres * 3 + i * 3 + 2] = int(b * 255);
		}
	}

	for (uint32 i = xres / 2; i < xres; ++i) {
		for (uint32 j = 0; j < yres; ++j) {
			pixels[j * xres * 3 + i * 3]	 = int(r2 * 255);
			pixels[j * xres * 3 + i * 3 + 1] = int(g2 * 255);
			pixels[j * xres * 3 + i * 3 + 2] = int(b2 * 255);
		}
	}

	ImageOutput* out = ImageOutput::create(path);
	if (!out) {
		std::cout << "Couldn't save image " << path << std::endl;
		return;
	}

	ImageSpec spec(xres, yres, channels, TypeDesc::UINT8);
	out->open(path, spec);
	out->write_image(TypeDesc::UINT8, pixels);
	out->close();

	ImageOutput::destroy(out);
}

static float maxE = 0;
static float minE = std::numeric_limits<float>::infinity();

static void handle_color(float r, float g, float b, std::ofstream& log)
{
	std::shared_ptr<SpectrumDescriptor> desc = SpectrumDescriptor::createStandardSpectral();
	Spectrum spec(desc);

	PR::RGBConverter::toSpec(spec, r, g, b);
	float R, G, B;
	PR::RGBConverter::convert(spec, R, G, B);

	float err = std::sqrt(std::pow(r - R, 2) + std::pow(g - G, 2) + std::pow(b - B, 2));
	log << "[" << r << "," << g << "," << b << "]=" << err << std::endl;
	maxE = std::max(err, maxE);
	minE = std::min(err, minE);

	std::stringstream stream;
	stream << "results/spectral1/"
		   << int(r * 255) << "_" << int(g * 255) << "_" << int(b * 255);
	save_image(stream.str() + ".png", r, g, b, R, G, B);
	save_spec(stream.str() + "_spec.png", spec);
}

void suite_spectral1()
{
	bf::create_directory("results/spectral1");

	std::ofstream log("results/spectral1/errors.log");

	maxE = 0;
	minE = std::numeric_limits<float>::infinity();

    constexpr size_t count = 11;
	constexpr float step = 1.0f/(count-1);
	for (size_t r = 0; r < count; ++r) {
		for (size_t g = 0; g < count; ++g) {
			for (size_t b = 0; b < count; ++b) {
				handle_color(r*step, g*step, b*step, log);
			}
		}
	}

	log << std::endl
		<< "MAX = " << maxE << std::endl
		<< "MIN = " << minE << std::endl;
}<|endoftext|>