text:
/*
   +----------------------------------------------------------------------+
   | HipHop for PHP                                                       |
   +----------------------------------------------------------------------+
   | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com)  |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
*/
#include "hphp/util/process.h"

#include <sys/types.h>
#include <stdlib.h>

#ifdef _MSC_VER
#include <lmcons.h>
#include <Windows.h>
#include <ShlObj.h>
#else
#include <sys/fcntl.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <pwd.h>
#include <folly/portability/Sockets.h>
#include <folly/portability/SysMman.h>
#include <folly/portability/Unistd.h>
#endif

#ifdef __APPLE__
#include <crt_externs.h>
#endif

#include <folly/Conv.h>
#include <folly/Format.h>
#include <folly/ScopeGuard.h>
#include <folly/String.h>

#include <boost/filesystem.hpp>

#include <set>

#include "hphp/util/hugetlb.h"
#include "hphp/util/managed-arena.h"
#include "hphp/util/text-color.h"
#include "hphp/util/user-info.h"

namespace HPHP {
///////////////////////////////////////////////////////////////////////////////

using std::string;

static void readString(FILE *f, string &out) {
  size_t nread = 0;
  constexpr unsigned int BUFFER_SIZE = 1024;
  char buf[BUFFER_SIZE];
  while ((nread = fread(buf, 1, BUFFER_SIZE, f)) != 0) {
    out.append(buf, nread);
  }
}

///////////////////////////////////////////////////////////////////////////////

// Cached process statics
std::string Process::HostName;
std::string Process::CurrentWorkingDirectory;
char** Process::Argv;
std::atomic_int64_t ProcStatus::VmSizeKb;
std::atomic_int64_t ProcStatus::VmRSSKb;
std::atomic_int64_t ProcStatus::VmHWMKb;
std::atomic_int64_t ProcStatus::VmSwapKb;
std::atomic_int64_t ProcStatus::HugetlbPagesKb;
std::atomic_int64_t ProcStatus::UnusedKb;
std::atomic_int ProcStatus::threads;
std::atomic_uint ProcStatus::lastUpdate;

void Process::InitProcessStatics() {
  HostName = GetHostName();
  CurrentWorkingDirectory = GetCurrentDirectory();
}

///////////////////////////////////////////////////////////////////////////////
// /proc/* parsing functions

std::string Process::GetCommandLine(pid_t pid) {
  auto const name = folly::sformat("/proc/{}/cmdline", pid);

  std::string cmdline;
  auto const f = fopen(name.c_str(), "r");
  if (f) {
    readString(f, cmdline);
    fclose(f);
  }

  std::string converted;
  for (auto ch : cmdline) {
    converted += ch ? ch : ' ';
  }
  return converted;
}

bool Process::IsUnderGDB() {
  auto const cmdStr = GetCommandLine(getppid());
  auto const cmdPiece = folly::StringPiece{cmdStr};

  if (cmdPiece.empty()) return false;

  auto const spaceIdx = std::min(cmdPiece.find(' '), cmdPiece.size() - 1);
  auto const binaryPiece = cmdPiece.subpiece(0, spaceIdx + 1);

  boost::filesystem::path binaryPath(binaryPiece.begin(), binaryPiece.end());
  return binaryPath.filename() == "gdb ";
}

int64_t Process::GetMemUsageMb() {
  ProcStatus::update();
  return ProcStatus::valid() ? ProcStatus::adjustedRssKb() / 1024 : 0;
}

int64_t Process::GetSystemCPUDelayMS() {
  static FILE* fp = nullptr;
  if (!fp) {
    if (!(fp = fopen("/proc/schedstat", "r"))) {
      return -1;
    }
  }
  // Refresh the proc info.
  rewind(fp);
  fflush(fp);

  int64_t totalCpuDelay = 0;
  // Supposedly this should be enough to hold th important lines of the
  // schedstat file.
  char buf[320];
  while (fgets(buf, sizeof(buf), fp) != nullptr) {
    if (strncmp(buf, "cpu", 3) == 0) {
      uint64_t cpuDelay;
      if (sscanf(buf,
                 "%*s %*u %*u %*u %*u %*u %*u %*u %lu %*u",
                 &cpuDelay) != 1) {
        return -1;
      }
      totalCpuDelay += cpuDelay;
    }
  }
  // The kernel reports the information in nanoseconds.  Convert it
  // to milliseconds.
  return totalCpuDelay / 1000000;
}

int Process::GetNumThreads() {
  ProcStatus::update();
  return ProcStatus::valid() ? ProcStatus::nThreads() : 1;
}

// Files such as /proc/meminfo and /proc/self/status contain many lines
// formatted as one of the following:
//   <fieldName>: <number>
//   <fieldName>: <number> kB
// This function parses the line and return the number in it.  -1 is returned
// when the line isn't formatted as expected (until one day we need to read a
// line where -1 is a legit value).
static int64_t readSize(const char* line, bool expectKB = false) {
  int64_t result = -1;
  char tail[8];
  auto n = sscanf(line, "%*s %" SCNd64 " %7s", &result, tail);
  if (expectKB) {
    if (n < 2) return -1;
    if (tail[0] != 'k' || tail[1] != 'B') return -1;
  }
  return result;
}

bool Process::GetMemoryInfo(MemInfo& info) {
#ifdef _WIN32
#error "Process::GetMemoryInfo() doesn't support Windows (yet)."
  return false;
#endif

  info = MemInfo{};
  FILE* f = fopen("/proc/meminfo", "r");
  if (f) {
    SCOPE_EXIT{ fclose(f); };

    char line[128];
    while (fgets(line, sizeof(line), f)) {
      auto const kb = readSize(line, true);
      if (!strncmp(line, "MemTotal:", 9)) {
        if (kb >= 0) info.totalMb = kb / 1024;
      } else if (!strncmp(line, "MemFree:", 8)) {
        if (kb >= 0) info.freeMb = kb / 1024;
      } else if (!strncmp(line, "Buffers:", 8)) {
        if (kb >= 0) info.buffersMb = kb / 1024;
      } else if (!strncmp(line, "Cached:", 7)) {
        if (kb >= 0) info.cachedMb = kb / 1024;
      } else if (!strncmp(line, "MemAvailable:", 13)) {
        if (kb >= 0) info.availableMb = kb / 1024;
      }
      if (info.valid()) return true;
    }
    // If MemAvailable isn't available, which shouldn't be the case for kernel
    // versions later than 3.14, we get a rough esitmation.
    if (info.availableMb < 0 && info.freeMb >= 0 &&
        info.cachedMb >= 0 && info.buffersMb >= 0) {
      info.availableMb = info.freeMb + info.cachedMb;
      return true;
    }
  }
  return false;
}

int Process::GetCPUCount() {
  return sysconf(_SC_NPROCESSORS_ONLN);
}

#ifdef __x86_64__
static __inline void do_cpuid(u_int ax, u_int *p) {
  asm volatile ("cpuid"
                : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
                : "0" (ax));
}
#elif defined(_M_X64)
#include <intrin.h>
static ALWAYS_INLINE void do_cpuid(int func, uint32_t* p) {
  __cpuid((int*)p, func);
}
#endif

std::string Process::GetCPUModel() {
#if defined(__x86_64__) || defined(_M_X64)
  uint32_t regs[4];
  do_cpuid(0, regs);

  const int vendor_size = sizeof(regs[1])*3;
  std::swap(regs[2], regs[3]);
  uint32_t cpu_exthigh = 0;
  if (memcmp(regs + 1, "GenuineIntel", vendor_size) == 0 ||
      memcmp(regs + 1, "AuthenticAMD", vendor_size) == 0) {
    do_cpuid(0x80000000, regs);
    cpu_exthigh = regs[0];
  }

  char cpu_brand[3 * sizeof(regs) + 1];
  char *brand = cpu_brand;
  if (cpu_exthigh >= 0x80000004) {
    for (u_int i = 0x80000002; i < 0x80000005; i++) {
      do_cpuid(i, regs);
      memcpy(brand, regs, sizeof(regs));
      brand += sizeof(regs);
    }
  }
  *brand = '\0';
  assert(brand - cpu_brand < sizeof(cpu_brand));
  return cpu_brand;

#else
  // On non-x64, fall back to calling uname
  std::string model = "Unknown ";
  struct utsname uname_buf;
  uname(&uname_buf);
  model.append(uname_buf.machine);
  return model;

#endif  // __x86_64__
}

///////////////////////////////////////////////////////////////////////////////

std::string Process::GetAppName() {
  const char* progname = getenv("_");
  if (!progname || !*progname) {
    progname = "unknown program";
  }
  return progname;
}

std::string Process::GetHostName() {
  char hostbuf[128];
  hostbuf[0] = '\0'; // for cleaner valgrind output when gethostname() fails
  gethostname(hostbuf, sizeof(hostbuf));
  hostbuf[sizeof(hostbuf) - 1] = '\0';
  return hostbuf;
}

std::string Process::GetCurrentUser() {
  const char *name = getenv("LOGNAME");
  if (name && *name) {
    return name;
  }

#ifdef _MSC_VER
  char username[UNLEN + 1];
  DWORD username_len = UNLEN + 1;
  if (GetUserName(username, &username_len))
    return std::string(username, username_len);
#else
  auto buf = PasswdBuffer{};
  passwd *pwd;
  if (!getpwuid_r(geteuid(), &buf.ent, buf.data.get(), buf.size, &pwd) &&
      pwd && pwd->pw_name) {
    return pwd->pw_name;
  }
#endif
  return "";
}

std::string Process::GetCurrentDirectory() {
  char buf[PATH_MAX + 64];   // additional space for suffixes like " (deleted)";
  memset(buf, 0, sizeof(buf));
  if (char* cwd = getcwd(buf, PATH_MAX)) return cwd;

#if defined(__linux__)
  if (errno != ENOENT) {
    return "";
  }
  // Read cwd symlink directly if it leads to the deleted path.
  int r = readlink("/proc/self/cwd", buf, sizeof(buf));
  if (r == -1) {
    return "";
  }
  auto const kDeleted = " (deleted)";
  auto const kDeletedLen = strlen(kDeleted);
  if (r >= kDeletedLen && !strcmp(buf + r - kDeletedLen, kDeleted)) {
    buf[r - kDeletedLen] = 0;
  }
  return &(buf[0]);
#else
  // /proc/self/cwd is not available.
  return "";
#endif
}

std::string Process::GetHomeDirectory() {
  string ret;

  const char *home = getenv("HOME");
  if (home && *home) {
    ret = home;
  } else {
#ifdef _MSC_VER
    PWSTR path;
    if (SHGetKnownFolderPath(FOLDERID_UsersFiles, 0, nullptr, &path) == S_OK) {
      char hPath[PATH_MAX];
      size_t len = wcstombs(hPath, path, MAX_PATH);
      CoTaskMemFree(path);
      ret = std::string(hPath, len);
    }
#else
    passwd *pwd = getpwent();
    if (pwd && pwd->pw_dir) {
      ret = pwd->pw_dir;
    }
#endif
  }

  if (ret.empty() || ret[ret.size() - 1] != '/') {
    ret += '/';
  }
  return ret;
}

void Process::SetCoreDumpHugePages() {
#if defined(__linux__)
  /*
   * From documentation athttp://man7.org/linux/man-pages/man5/core.5.html
   *
   * The bits in coredump_filter have the following meanings:
   *
   *   bit 0  Dump anonymous private mappings.
   *   bit 1  Dump anonymous shared mappings.
   *   bit 2  Dump file-backed private mappings.
   *   bit 3  Dump file-backed shared mappings.
   *   bit 4 (since Linux 2.6.24) Dump ELF headers.
   *   bit 5 (since Linux 2.6.28) Dump private huge pages.
   *   bit 6 (since Linux 2.6.28) Dump shared huge pages.
   *   bit 7 (since Linux 4.4) Dump private DAX pages.
   *   bit 8 (since Linux 4.4) Dump shared DAX pages.
   */
  if (FILE* f = fopen("/proc/self/coredump_filter", "r+")) {
    unsigned mask = 0;
    if (fscanf(f, "%x", &mask)) {
      constexpr unsigned hugetlbMask = 0x60;
      if ((mask & hugetlbMask) != hugetlbMask) {
        mask |= hugetlbMask;
        rewind(f);
        fprintf(f, "0x%x", mask);
      }
    }
    fclose(f);
  }
#endif
}

void ProcStatus::update() {
  if (FILE* f = fopen("/proc/self/status", "r")) {
    char line[128];
    int64_t vmsize = 0, vmrss = 0, vmhwm = 0, vmswap = 0, hugetlb = 0;
    while (fgets(line, sizeof(line), f)) {
      if (!strncmp(line, "VmSize:", 7)) {
        vmsize = readSize(line, true);
      } else if (!strncmp(line, "VmRSS:", 6)) {
        vmrss = readSize(line, true);
      } else if (!strncmp(line, "VmHWM:", 6)) {
        vmhwm = readSize(line, true);
      } else if (!strncmp(line, "VmSwap:", 7)) {
        vmswap = readSize(line, true);
      } else if (!strncmp(line, "HugetlbPages:", 13)) {
        hugetlb = readSize(line, true);
      } else if (!strncmp(line, "Threads:", 8)) {
        threads.store(readSize(line, false), std::memory_order_relaxed);
      }
    }
    fclose(f);
    if (vmrss <= 0) {
      // Invalid
      lastUpdate.store(0, std::memory_order_release);
    } else {
      VmSizeKb.store(vmsize, std::memory_order_relaxed);
      VmRSSKb.store(vmrss, std::memory_order_relaxed);
      VmSwapKb.store(vmswap, std::memory_order_relaxed);
      VmHWMKb.store(vmhwm + hugetlb, std::memory_order_relaxed);
      HugetlbPagesKb.store(hugetlb, std::memory_order_relaxed);
      lastUpdate.store(time(), std::memory_order_release);
    }
#ifdef USE_JEMALLOC
    mallctl_epoch();
#if USE_JEMALLOC_EXTENT_HOOKS
    size_t unused = 0;
    // Various arenas where range of hugetlb pages can be reserved but only
    // partially used.
    unused += alloc::getRange(alloc::AddrRangeClass::VeryLow).retained();
    unused += alloc::getRange(alloc::AddrRangeClass::Low).retained();
    unused += alloc::getRange(alloc::AddrRangeClass::Uncounted).retained();
    if (alloc::g_arena0) {
      unused += alloc::g_arena0->retained();
    }
    for (auto const arena : alloc::g_local_arenas) {
      if (arena) unused += arena->retained();
    }
    updateUnused(unused >> 10); // convert to kB
#endif
#endif
  }
}

bool Process::OOMScoreAdj(int adj) {
#ifdef __linux__
  if (adj >= -1000 && adj < 1000) {
    if (auto f = fopen("/proc/self/oom_score_adj", "r+")) {
      fprintf(f, "%d", adj);
      fclose(f);
      return true;
    }
  }
#endif
  return false;
}

int Process::Relaunch() {
  if (!Argv) {
    errno = EINVAL;
    return -1;
  }
  return execvp(Argv[0], Argv);
}

std::map<int, int> Process::RemapFDsPreExec(const std::map<int, int>& fds) {
  std::map<int, int> unspecified;
  // 1. copy all to FDs outside of STDIO range
  std::map<int, int> dups;
  std::set<int> preserve_set;
  for (auto& [_target, current] : fds) {
    if (dups.find(current) != dups.end()) {
      continue;
    }

    int next_fd;
    bool conflict;
    do {
      conflict = false;
      // don't conflict with STDIO
      next_fd = dup(current);
      if (next_fd <= STDERR_FILENO) {
        conflict = true;
        continue;
      }
      // don't conflict with targets
      conflict = false;
      for (auto [target, _current] : fds) {
        if (next_fd == target) {
          conflict = true;
          break;
        }
      }
    } while (conflict);
    dups[current] = next_fd;
    preserve_set.emplace(next_fd);
  }

  // 2. clean up libc STDIO
  //
  // Don't want to swap the FD underlying these FILE*...
  //
  // If they are closed already, these are silent no-ops.
  fclose(stdin);
  fclose(stdout);
  fclose(stderr);

  // 3. close all FDs except our dups
  //
  // This includes the STDIO FDs as it's possible that:
  // - the FILE* were previously closed (so the fclose above were no-ops)
  // - the FDs were then re-used
#ifdef __APPLE__
  const char* fd_dir = "/dev/fd";
#endif
#ifdef __linux__
  const char* fd_dir = "/proc/self/fd";
#endif
  // If you close FDs while in this loop, they get removed from /proc/self/fd
  // and the iterator gets sad ("Bad file descriptor: /proc/self/fd")
  std::set<int> fds_to_close;
  for (const auto& entry : boost::filesystem::directory_iterator(fd_dir)) {
    char* endptr = nullptr;
    auto filename = entry.path().filename();
    const char* filename_c = filename.c_str();
    const int fd = strtol(filename_c, &endptr, 10);
    assert(endptr != filename_c); // no matching characters
    assert(*endptr == '\0'); // entire string
    if (preserve_set.find(fd) != preserve_set.end()) {
      continue;
    }
    fds_to_close.emplace(fd);
  }
  for (const auto& fd: fds_to_close) {
    close(fd);
  }

  // 4. Move the dups into place.
  for (const auto& [target, orig] : fds) {
    int tmp = dups[orig];

    if (target < 0 /* don't care what the FD is */) {
      unspecified[target] = tmp;
    } else {
      dup2(tmp, target);
    }
  }

  // 5. Close the dups; do this separately to above in case
  // the same orig was used for multiple targets
  for (const auto& [target, orig] : fds) {
    if (target < 0) {
      continue;
    }
    close(dups.at(orig));
  }
  return unspecified;
}

namespace {
  char **build_cstrarr(const std::vector<std::string> &vec) {
    char **cstrarr = nullptr;
    int size = vec.size();
    if (size) {
      cstrarr = (char **)malloc((size + 1) * sizeof(char *));
      int j = 0;
      for (unsigned int i = 0; i < vec.size(); i++, j++) {
        *(cstrarr + j) = (char *)vec[i].c_str();
      }
      *(cstrarr + j) = nullptr;
    }
    return cstrarr;
  }
} // namespace {

pid_t Process::ForkAndExecve(
  const std::string& path,
  const std::vector<std::string>& argv,
  const std::vector<std::string>& envp,
  const std::string& cwd,
  const std::map<int, int>& orig_fds,
  int flags,
  pid_t pgid
) {
  // Distinguish execve failure: if the write side of the pipe
  // is closed with no data, it succeeded.
  int fork_fds[2];
  pipe(fork_fds);
  int fork_r = fork_fds[0];
  int fork_w = fork_fds[1];
  fcntl(fork_w, F_SETFD, fcntl(fork_w, F_GETFD) | O_CLOEXEC);

  pid_t child = fork();

  if (child == -1) {
    return -1;
  }

  if (child == 0) {
    mprotect_1g_pages(PROT_READ);
    Process::OOMScoreAdj(1000);

    close(fork_r);

    // Need mutable copy
    std::map<int, int> fds(orig_fds);
    fds[-1] = fork_w;
    const auto remapped = Process::RemapFDsPreExec(fds);
    fork_w = remapped.at(-1);

    if (!cwd.empty()) {
      if (cwd != Process::GetCurrentDirectory()) {
        if (chdir(cwd.c_str()) == -1) {
          dprintf(fork_w, "%s %d", "chdir", errno);
          _Exit(1);
        }
      }
    }

    if (flags & Process::FORK_AND_EXECVE_FLAG_SETSID) {
      if (setsid() == -1) {
        dprintf(fork_w, "%s\n%d\n", "setsid", errno);
        _Exit(1);
      }
    } else if (flags & Process::FORK_AND_EXECVE_FLAG_SETPGID) {
      if (setpgid(0, pgid) == -1) {
        dprintf(fork_w, "%s %d", "setpgid", errno);
        _Exit(1);
      }
    }

    char** argv_arr = build_cstrarr(argv);
    char** envp_arr = build_cstrarr(envp);
    SCOPE_EXIT { free(argv_arr); free(envp_arr); };

    if (flags & Process::FORK_AND_EXECVE_FLAG_EXECVPE) {
#if defined(__APPLE__)
      // execvpe() is a glibcism
      //
      // We could either:
      // - use `execve()` and implement our own $PATH behavior
      // - use `execvp()` and implement our own envp behavior
      // The latter seems less likely to lead to accidental problems, so let's
      // do that.
      char**& environ = *_NSGetEnviron();
      // We could also use this implementation on Linux (using the standard
      // `extern char** environ` instead of the Apple-specific call above)...
      environ = envp_arr;
      execvp(path.c_str(), argv_arr);
#else
      // ... but it feels nasty enough that I'll use the glibcism
      execvpe(path.c_str(), argv_arr, envp_arr);
#endif
    } else {
      execve(path.c_str(), argv_arr, envp_arr);
    }
    dprintf(fork_w, "%s %d", "execve", errno);
    _Exit(1);
  }

  close(fork_w);

  pollfd pfd[1];
  pfd[0].fd = fork_w;
  pfd[0].events = POLLIN;
  int ret;
  do {
    ret = poll(pfd, /* number of fds = */ 1, /* timeout = no timeout*/ -1);
  } while (ret == -1 && errno == EINTR);

  char buf[16];
  auto len = read(fork_r, &buf, sizeof(buf));
  close(fork_r);

  // Closed without write, which means close-on-exec
  if (len < 1) {
    return child;
  }

  char failed_call_buf[17]; // 16 + trailing null
  int saved_errno;
  if (sscanf(buf, "%16s %d", failed_call_buf, &saved_errno) != 2) {
    return -999;
  }

  // Doing the call => return value here instead of sending return values over
  // the pipe so that it's all in one place, and we're less likely to introduce
  // bugs when/if we add additional features.
  const std::string failed_call(failed_call_buf);
  SCOPE_EXIT { errno = saved_errno; };
  if (failed_call == "chdir") {
    return -2;
  }
  if (failed_call == "setsid") {
    return -3;
  }
  if (failed_call == "setpgid") {
    return -4;
  }
  if (failed_call == "execve") {
    return -5;
  }
  if (failed_call == "putenv") {
    return -6;
  }
  return -9999;
}

///////////////////////////////////////////////////////////////////////////////
}

max_stars_repo_name: donsbot/hhvm

max_issues_repo_name: donsbot/hhvm

max_forks_repo_name: donsbot/hhvm


text:
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.

#include "carla/streaming/detail/tcp/Client.h"

#include "carla/Debug.h"
#include "carla/Logging.h"
#include "carla/Time.h"

#include <boost/asio/connect.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/write.hpp>

namespace carla {
namespace streaming {
namespace detail {
namespace tcp {

  // ===========================================================================
  // -- Decoder ----------------------------------------------------------------
  // ===========================================================================

  class Decoder {
  public:

    boost::asio::mutable_buffer header() {
      return boost::asio::buffer(&_size, sizeof(_size));
    }

    boost::asio::mutable_buffer body() {
      DEBUG_ASSERT(_size > 0u);
      DEBUG_ASSERT(_message == nullptr);
      _message = std::make_shared<Message>(_size);
      return _message->buffer();
    }

    auto size() const {
      return _size;
    }

    auto pop() {
      return std::move(_message);
    }

  private:

    message_size_type _size = 0u;

    std::shared_ptr<Message> _message;
  };

  // ===========================================================================
  // -- Client -----------------------------------------------------------------
  // ===========================================================================

  Client::Client(
      boost::asio::io_service &io_service,
      endpoint ep,
      stream_id_type stream_id,
      callback_function_type callback)
    : _endpoint(std::move(ep)),
      _stream_id(stream_id),
      _callback(std::move(callback)),
      _socket(io_service),
      _strand(io_service),
      _connection_timer(io_service) {
    Connect();
  }

  Client::~Client() {
    Stop();
  }

  void Client::Stop() {
    _connection_timer.cancel();
    _strand.post([this]() {
      _done = true;
      if (_socket.is_open()) {
        _socket.close();
      }
    });
  }

  void Client::Connect() {
    _strand.post([this]() {
      if (_done) {
        return;
      }

      using boost::system::error_code;

      if (_socket.is_open()) {
        _socket.close();
      }

      auto handle_connect = [=](error_code ec) {
        if (!ec) {
          // Send the stream id to subscribe to the stream.
          log_debug("streaming client: sending stream id", _stream_id);
          boost::asio::async_write(
          _socket,
          boost::asio::buffer(&_stream_id, sizeof(_stream_id)),
          _strand.wrap([=](error_code ec, size_t DEBUG_ONLY(bytes)) {
            if (!ec) {
              DEBUG_ASSERT_EQ(bytes, sizeof(_stream_id));
              // If succeeded start reading data.
              ReadData();
            } else {
              // Else try again.
              log_debug("streaming client: failed to send stream id:", ec.message());
              Connect();
            }
          }));
        } else {
          log_debug("streaming client: connection failed:", ec.message());
          Reconnect();
        }
      };

      log_debug("streaming client: connecting to", _endpoint);
      _socket.async_connect(_endpoint, _strand.wrap(handle_connect));
    });
  }

  void Client::Reconnect() {
    _connection_timer.expires_from_now(time_duration::seconds(1u));
    _connection_timer.async_wait([this](boost::system::error_code ec) {
      if (!ec) {
        Connect();
      }
    });
  }

  void Client::ReadData() {
    _strand.post([this]() {
      if (_done) {
        return;
      }

      log_debug("streaming client: Client::ReadData");

      auto encoder = std::make_shared<Decoder>();

      auto handle_read_data = [=](boost::system::error_code ec, size_t DEBUG_ONLY(bytes)) {
        DEBUG_ONLY(log_debug("streaming client: Client::ReadData.handle_read_data", bytes, "bytes"));
        if (!ec) {
          DEBUG_ASSERT_EQ(bytes, encoder->size());
          DEBUG_ASSERT_NE(bytes, 0u);
          // Move the buffer to the callback function and start reading
          // the next
          // piece of data.
          log_debug("streaming client: success reading data, calling the callback");
          _socket.get_io_service().post([this, encoder]() { _callback(encoder->pop()); });
          ReadData();
        } else {
          // As usual, if anything fails start over from the very top.
          log_debug("streaming client: failed to read data:", ec.message());
          Connect();
        }
      };

      auto handle_read_header = [=](boost::system::error_code ec, size_t DEBUG_ONLY(bytes)) {
        DEBUG_ONLY(log_debug("streaming client: Client::ReadData.handle_read_header", bytes, "bytes"));
        if (!ec && (encoder->size() > 0u)) {
          DEBUG_ASSERT_EQ(bytes, sizeof(message_size_type));
          // Now that we know the size of the coming buffer, we can
          // allocate
          // our buffer and start putting data into it.
          boost::asio::async_read(
              _socket,
              encoder->body(),
              _strand.wrap(handle_read_data));
        } else {
          log_debug("streaming client: failed to read header:", ec.message());
          DEBUG_ONLY(log_debug("size  = ", encoder->size()));
          DEBUG_ONLY(log_debug("bytes = ", bytes));
          Connect();
        }
      };

      // Read the size of the buffer that is coming.
      boost::asio::async_read(
          _socket,
          encoder->header(),
          _strand.wrap(handle_read_header));
    });
  }

} // namespace tcp
} // namespace detail
} // namespace streaming
} // namespace carla

ext: cpp

max_stars_repo_name: edufford/carla

max_issues_repo_name: edufford/carla

max_forks_repo_name: edufford/carla


text:
//
// 2018 Rico Schulz
//
#pragma once
#include <iostream>
#include <cstdlib>
#include <csignal>
#include <boost/log/trivial.hpp>
#include "operator.h"
#include "dht22.h"
#include "ldr.h"
#include "hygrometer.h"
#include "servo.h"
#include "pump.h"
#include "debug.h"

#ifdef DEBUG
#define SERVO_PIN 1
#define DHT_PIN 6
#define HYGRO_PIN 42
#define PUMP_PIN 42
#define LAMP_PIN 16
#define FAN_PIN 5
#define INTERVALL 10000
#endif

using namespace ghpi;

bool STOP = false;

// Set STOP to true, so we will break
// out of the infinite loop and exit the main function
// this will call the destructors of our object and the pins will
// set to their default init state
void exiting(int i) {
	STOP = true;
}

int main() {

    wiringPiSetup();
    Operator ghoperator;

    signal(SIGABRT, exiting);
    signal(SIGTERM, exiting);
    //signal(SIGTSTP, exiting);
    signal(SIGINT, exiting);

    // Instantiate some devices for testing
    DHT22 dht;
    ADConverter adcon(14, 12, 13, 10, 0, 1023);
    Hygrometer hygro(&adcon, 7);
    LDR ldr1(&adcon, 0);
    LDR ldr2(&adcon, 1);
    Servo servo(270, 0);
    Pump pump;
    Actuator lamp("Lamp");
    Actuator fan("Fan");
    LCDDisplay* lcd = nullptr;

    try {
      // Write welcome screen to display
      lcd = new LCDDisplay();
      lcd->writeLine("GreenHousePi V1.0", 1);
      lcd->writeLine("Made by", 2);
      lcd->writeLine(" Tobi          Pei ", 3);
      lcd->writeLine(" Rico        Marcos", 4);
    }
    catch (...) {
      std::cout << "LCD has thrown an error" << std::endl;
    }

    ghoperator.Set_LCDDisplay(lcd);

    Pin dht_data_pin(DHT_PIN, PinMode::input, PinState::low);
    Pin hygro_pin(HYGRO_PIN, PinMode::output, PinState::high);
    Pin servo_pin(SERVO_PIN, PinMode::pwmoutput, PinState::low);
    Pin pump_pin(PUMP_PIN, PinMode::output, PinState::high);
    Pin lamp_pin(LAMP_PIN, PinMode::output, PinState::high);
    Pin fan_pin(FAN_PIN, PinMode::output, PinState::high);

    // Register pins for the devices
    dht.RegisterPin(&dht_data_pin, PinUsage::BI_DATA, OnState::OS_NONE);
    hygro.RegisterPin(&hygro_pin, PinUsage::SWITCH, OnState::OS_LOW);
    servo.RegisterPin(&servo_pin, PinUsage::PWM, OnState::OS_NONE);
    pump.RegisterPin(&pump_pin, PinUsage::SWITCH, OnState::OS_LOW);
    lamp.RegisterPin(&lamp_pin, PinUsage::SWITCH, OnState::OS_LOW);
    fan.RegisterPin(&fan_pin, PinUsage::SWITCH, OnState::OS_LOW);

    // Register Devices
    ghoperator.RegisterDevice(&dht);
    ghoperator.RegisterDevice(&hygro);
    ghoperator.RegisterDevice(&servo);
    ghoperator.RegisterDevice(&pump);
    ghoperator.RegisterDevice(&ldr1);
    ghoperator.RegisterDevice(&ldr2);
    ghoperator.RegisterDevice(&lamp);
    ghoperator.RegisterDevice(&fan);

    // Creating Constraints
    Constraint temp("TempBelow18°C", EnvironmentValueStrings[EnvironmentValue::TEMPERATURE],
                      18.f, ConstraintConditionStrings[ConstraintCondition::BELOW]);
    Constraint hum("HumBelow80%", EnvironmentValueStrings[EnvironmentValue::HUMIDITY],
                      80.f, ConstraintConditionStrings[ConstraintCondition::BELOW]);
    Constraint lightlow("LightIntOver300", EnvironmentValueStrings[EnvironmentValue::LIGHT_INTENSITY],
                      300.f, ConstraintConditionStrings[ConstraintCondition::OVER]);
    Constraint lighthigh("LightIntUnder500", EnvironmentValueStrings[EnvironmentValue::LIGHT_INTENSITY],
                      500.f, ConstraintConditionStrings[ConstraintCondition::BELOW]);

    // Creating Actions for Devices
    Action open_roof("OpenRoof", ActionFn::AFN_ON, NULL);
    Action close_roof("CloseRoof", ActionFn::AFN_OFF, NULL);
    Action turn_on_light("TurnOnLight", ActionFn::AFN_ON, NULL);
    Action turn_off_light("TurnOffLight", ActionFn::AFN_OFF, NULL);
    Action turn_on_fan("TurnOnFan", ActionFn::AFN_ON, NULL);
    Action toggle_servo("ToggleServo", ActionFn::AFN_TOGGLE, NULL);
    Action toggle_lamp("ToggleLamp", ActionFn::AFN_TOGGLE, NULL);
    Action toggle_fan("ToggleFan", ActionFn::AFN_TOGGLE, NULL);
		Action op_man("OperateManually", ActionFn::AFN_OP_MANU, NULL);
		Action op_auto("OperateAutonomous", ActionFn::AFN_OP_AUTO, NULL);

    // Register Actions on devices
    servo.RegisterAction(open_roof);
    servo.RegisterAction(close_roof);
    servo.RegisterAction(toggle_servo);
    fan.RegisterAction(turn_on_fan);
    fan.RegisterAction(toggle_fan);
    lamp.RegisterAction(turn_off_light);
    lamp.RegisterAction(turn_on_light);
    lamp.RegisterAction(toggle_lamp);
		servo.RegisterAction(op_man);
		lamp.RegisterAction(op_man);
		fan.RegisterAction(op_man);
		servo.RegisterAction(op_auto);
		lamp.RegisterAction(op_auto);
		fan.RegisterAction(op_auto);

    // Register Constraints
    ghoperator.RegisterConstraint(temp, open_roof);
    ghoperator.RegisterConstraint(hum, turn_on_fan);
    ghoperator.RegisterConstraint(lightlow, turn_on_light);
    ghoperator.RegisterConstraint(lighthigh, turn_off_light);

    // Initialize Devices
    servo.Initialize();

    ghoperator.PrintDevices();
    ghoperator.PrintConstraints();
    std::cout << "Start running operator" << std::endl;
    std::cout << "Running in intervalls of " << INTERVALL << " milliseconds" << std::endl;

    while (!STOP) {
      ghoperator.Run();
      delay(INTERVALL);
    }
    std::cout << "Exiting..." << std::endl;
    lcd->ClrLcd();
    lcd->writeLine("Goodbye...", 2);
    delay(2000);
    lcd->ClrLcd();
    delete lcd;

    return 0;
}

ext: cc


text:
/**
 * @Copyright 2011 GanJi Inc.
 * @file    ganji/util/cache/redis/gtest/pressure_test.cc
 * @namespace ganji::crawler::conf_crawler::dedup
 * @version 1.0
 * @author  zdn
 * @date    2014-02-20
 *
 * 改动程序后， 请使用tools/cpplint/cpplint.py 检查代码是否符合编码规范!
 * 遵循的编码规范请参考: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
 * Change Log:
 */

#include <boost/regex.hpp>
#include "ganji/util/cache/redis/gtest/pressure_test.h"
#include "ganji/util/cache/redis/redis.h"
#include "ganji/util/log/thread_fast_log.h"
#include "ganji/util/thread/sleep.h"
#include "ganji/util/system/system.h"
#include "ganji/util/time/time.h"
#include "gtest/gtest.h"

using std::string;

using boost::smatch;
using boost::regex;
using boost::regex_search;
using boost::regex_error;

namespace FastLog = ::ganji::util::log::ThreadFastLog;
using FastLog::WriteLog;
using FastLog::kLogFatal;
using FastLog::kLogDebug;
using FastLog::kLogNotice;
using FastLog::kLogWarning;

using ganji::util::thread::Thread;
using namespace ganji::util::cache::redis;
namespace Sleep = ::ganji::util::thread::Sleep;
namespace System = ::ganji::util::system::System;
namespace Time = ::ganji::util::time;
namespace redis = ::ganji::util::cache::redis;
namespace ganji { namespace util { namespace cache {namespace redis { namespace gtest {
PressureTest::PressureTest()
{

}

PressureTest::~PressureTest()
{
  if (redis_client_ != NULL)
    delete redis_client_;
}

int PressureTest::BatchRemove(const std::string &url) {
  hashkey_lock_.RdLock();
  if ( REDIS_SUCCESS != redis_client_->RedisKeyDEL(current_hash_key_))
  {
      hashkey_lock_.Unlock();
      return -1;
  }
  hashkey_lock_.Unlock();
  return 0;
}

void PressureTest::ComposeHashKey(string prefix, string suffix)
{
  // current hash key is dynYYYYMMDD for static dedup module
  WriteLog(kLogDebug, "%s", current_hash_key_.c_str());
  current_hash_key_ = prefix;
  current_hash_key_.append(suffix);
}

int PressureTest::Init() {
  redis_client_ = new Redis;
  if (redis_client_ == NULL || redis_client_->Init() != redis::REDIS_SUCCESS)
     return -1;
  string today;
  Time::GetY4MD2(time(NULL),&today);
  ComposeHashKey("stat", today);
  string batchkey("stat*"); //flash db for static dedup
  BatchRemove(batchkey);
  return 0;
}
TEST_T(PressureTest, getset)
{

}

}}}}}


text:
// Copyright (c) 2015-2019 Daniel Cooke
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

#include "quality_by_depth.hpp"

#include <boost/variant.hpp>
#include <boost/optional.hpp>

#include "io/variant/vcf_record.hpp"

namespace octopus { namespace csr {

const std::string QualityByDepth::name_ = "QD";

QualityByDepth::QualityByDepth(bool recalculate) : depth_ {recalculate, true} {}

std::unique_ptr<Measure> QualityByDepth::do_clone() const
{
    return std::make_unique<QualityByDepth>(*this);
}

Measure::ResultType QualityByDepth::get_default_result() const
{
    return boost::optional<double> {};
}

Measure::ResultType QualityByDepth::do_evaluate(const VcfRecord& call, const FacetMap& facets) const
{
    auto depth = boost::get<std::size_t>(depth_.evaluate(call, facets));
    boost::optional<double> result {};
    if (depth > 0) {
        result = static_cast<double>(*call.qual()) / depth;
    }
    return result;
}

Measure::ResultCardinality QualityByDepth::do_cardinality() const noexcept
{
    return depth_.cardinality();
}

const std::string& QualityByDepth::do_name() const
{
    return name_;
}

std::string QualityByDepth::do_describe() const
{
    return "QUAL divided by DP";
}

std::vector<std::string> QualityByDepth::do_requirements() const
{
    return depth_.requirements();
}

bool QualityByDepth::is_equal(const Measure& other) const noexcept
{
    return depth_ == static_cast<const QualityByDepth&>(other).depth_;
}

} // namespace csr
} // namespace octopus

max_stars_repo_name: gunjanbaid/octopus

max_issues_repo_name: gunjanbaid/octopus

max_forks_repo_name: gunjanbaid/octopus


text:
/*
 * NOTE:  I mainly left this in here because this is working with waf, and
 * I didn't want to have to figure out how to do this again if problems arose.
 * I suspect some tests might be necessary in the near or remote future.
 *
 * For now functionality will be covered under STU tests, since there's GPU
 * access there.
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE gpusimilarity

#include <cstdlib>
#include <vector>

#include <boost/test/unit_test.hpp>

#include "gpusim.h"
#include "fingerprintdb_cuda.h"

using namespace gpusim;
using std::vector;

using gpusim::GPUSimServer;

BOOST_AUTO_TEST_CASE(CompareGPUtoCPU)
{
    // TODO:  Replace Schrodinger function that is commented out here
    // Only run this if there's a GPU available
    // if(!schrodinger::gpgpu::is_any_gpu_available()) return;

    GPUSimServer server("small.fsim");
    // Fetch a fingerprint to search against, this should always
    // guarantee a 100% match
    const Fingerprint& fp = server.getFingerprint(std::rand() % 20);
    const vector<int> return_counts = {10, 15};

    for(auto return_count : return_counts) {
        std::vector<char*> gpu_smiles;
        std::vector<char*> gpu_ids;
        std::vector<float> gpu_scores;
        server.similaritySearch(fp, gpu_smiles, gpu_ids, gpu_scores, return_count, CalcType::GPU);

        std::vector<char*> cpu_smiles;
        std::vector<char*> cpu_ids;
        std::vector<float> cpu_scores;
        server.similaritySearch(fp, cpu_smiles, cpu_ids, cpu_scores, return_count, CalcType::CPU);

        BOOST_CHECK_EQUAL(gpu_smiles.size(), return_count);
        for(unsigned int i=0; i<gpu_smiles.size(); i++) {
            BOOST_CHECK_EQUAL(gpu_smiles[i], cpu_smiles[i]);
        }
    }

}

/*
 * This tests our custom sort function, modified bubble sort to get
 * O(num_required * len(indices))
 */
BOOST_AUTO_TEST_CASE(CPUSort)
{
    vector<int> indices = {0,1,2,3,4,5};
    vector<float> scores = {1,3,2,4,0,7};
    top_results_bubble_sort(indices, scores, 3);

    // Verify that this pushed the top 3 values to the far right of arrays
    BOOST_CHECK_EQUAL(indices[5], 5);
    BOOST_CHECK_EQUAL(scores[5], 7);

    BOOST_CHECK_EQUAL(indices[3], 1);
    BOOST_CHECK_EQUAL(scores[3], 3);

}

BOOST_AUTO_TEST_CASE(FoldFingerprint)
{
    int factor = 2;
    vector<int> fp = {32, 24, 11, 7};
    vector<int> ref_answer = {43, 31};
    vector<int> answer = fold_fingerprint(fp, factor);
    for(int i=0; i<ref_answer.size(); i++){
    	BOOST_CHECK_EQUAL(answer[i], ref_answer[i]);
    }

    factor = 4;
    answer = fold_fingerprint(fp, factor);
    BOOST_CHECK_EQUAL(answer.size(), 1);
    BOOST_CHECK_EQUAL(answer[0], 63);
}

max_stars_repo_name: greglandrum/gpusimilarity

max_issues_repo_name: greglandrum/gpusimilarity

max_forks_repo_name: greglandrum/gpusimilarity


text: #include <boost/geometry/algorithms/is_convex.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
 * Copyright 2022 HEAVY.AI, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file    DataMgr.cpp
 * @brief
 */

#include "DataMgr/DataMgr.h"
#include "BufferMgr/CpuBufferMgr/CpuBufferMgr.h"
#include "BufferMgr/CpuBufferMgr/TieredCpuBufferMgr.h"
#include "BufferMgr/GpuCudaBufferMgr/GpuCudaBufferMgr.h"
#include "CudaMgr/CudaMgr.h"
#include "DataMgr/Allocators/CudaAllocator.h"
#include "FileMgr/GlobalFileMgr.h"
#include "PersistentStorageMgr/PersistentStorageMgr.h"

#ifdef __APPLE__
#include <sys/sysctl.h>
#include <sys/types.h>
#endif

#include <boost/filesystem.hpp>

#include <algorithm>
#include <limits>

extern bool g_enable_fsi;

#ifdef ENABLE_MEMKIND
bool g_enable_tiered_cpu_mem{false};
std::string g_pmem_path{};
size_t g_pmem_size{0};
#endif

namespace Data_Namespace {

DataMgr::DataMgr(const std::string& dataDir,
                 const SystemParameters& system_parameters,
                 std::unique_ptr<CudaMgr_Namespace::CudaMgr> cudaMgr,
                 const bool useGpus,
                 const size_t reservedGpuMem,
                 const size_t numReaderThreads,
                 const File_Namespace::DiskCacheConfig cache_config)
    : cudaMgr_{std::move(cudaMgr)}
    , dataDir_{dataDir}
    , hasGpus_{false}
    , reservedGpuMem_{reservedGpuMem} {
  if (useGpus) {
    if (cudaMgr_) {
      hasGpus_ = true;
    } else {
      LOG(ERROR) << "CudaMgr instance is invalid, falling back to CPU-only mode.";
      hasGpus_ = false;
    }
  } else {
    // NOTE: useGpus == false with a valid cudaMgr is a potentially valid configuration.
    // i.e. QueryEngine can be set to cpu-only for a cuda-enabled build, but still have
    // rendering enabled. The renderer would require a CudaMgr in this case, in addition
    // to a GpuCudaBufferMgr for cuda-backed thrust allocations.
    // We're still setting hasGpus_ to false in that case tho to enforce cpu-only query
    // execution.
    hasGpus_ = false;
  }

  populateMgrs(system_parameters, numReaderThreads, cache_config);
  createTopLevelMetadata();
}

DataMgr::~DataMgr() {
  int numLevels = bufferMgrs_.size();
  for (int level = numLevels - 1; level >= 0; --level) {
    for (size_t device = 0; device < bufferMgrs_[level].size(); device++) {
      delete bufferMgrs_[level][device];
    }
  }
}

DataMgr::SystemMemoryUsage DataMgr::getSystemMemoryUsage() const {
  SystemMemoryUsage usage;

#ifdef __linux__

  // Determine Linux available memory and total memory.
  // Available memory is different from free memory because
  // when Linux sees free memory, it tries to use it for
  // stuff like disk caching. However, the memory is not
  // reserved and is still available to be allocated by
  // user processes.
  // Parsing /proc/meminfo for this info isn't very elegant
  // but as a virtual file it should be reasonably fast.
  // See also:
  //   https://github.com/torvalds/linux/commit/34e431b0ae398fc54ea69ff85ec700722c9da773
  ProcMeminfoParser mi;
  usage.free = mi["MemAvailable"];
  usage.total = mi["MemTotal"];

  // Determine process memory in use.
  // See also:
  //   https://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-runtime-using-c
  //   http://man7.org/linux/man-pages/man5/proc.5.html
  int64_t size = 0;
  int64_t resident = 0;
  int64_t shared = 0;

  std::ifstream fstatm("/proc/self/statm");
  fstatm >> size >> resident >> shared;
  fstatm.close();

  long page_size =
      sysconf(_SC_PAGE_SIZE);  // in case x86-64 is configured to use 2MB pages

  usage.resident = resident * page_size;
  usage.vtotal = size * page_size;
  usage.regular = (resident - shared) * page_size;
  usage.shared = shared * page_size;

  ProcBuddyinfoParser bi;
  usage.frag = bi.getFragmentationPercent();

#else

  usage.total = 0;
  usage.free = 0;
  usage.resident = 0;
  usage.vtotal = 0;
  usage.regular = 0;
  usage.shared = 0;
  usage.frag = 0;

#endif

  return usage;
}

size_t DataMgr::getTotalSystemMemory() {
#ifdef __APPLE__
  int mib[2];
  size_t physical_memory;
  size_t length;
  // Get the Physical memory size
  mib[0] = CTL_HW;
  mib[1] = HW_MEMSIZE;
  length = sizeof(size_t);
  sysctl(mib, 2, &physical_memory, &length, NULL, 0);
  return physical_memory;
#elif defined(_MSC_VER)
  MEMORYSTATUSEX status;
  status.dwLength = sizeof(status);
  GlobalMemoryStatusEx(&status);
  return status.ullTotalPhys;
#else  // Linux
  long pages = sysconf(_SC_PHYS_PAGES);
  long page_size = sysconf(_SC_PAGE_SIZE);
  return pages * page_size;
#endif
}

void DataMgr::allocateCpuBufferMgr(int32_t device_id,
                                   size_t total_cpu_size,
                                   size_t minCpuSlabSize,
                                   size_t maxCpuSlabSize,
                                   size_t page_size,
                                   const CpuTierSizeVector& cpu_tier_sizes) {
#ifdef ENABLE_MEMKIND
  if (g_enable_tiered_cpu_mem) {
    bufferMgrs_[1].push_back(new Buffer_Namespace::TieredCpuBufferMgr(0,
                                                                      total_cpu_size,
                                                                      cudaMgr_.get(),
                                                                      minCpuSlabSize,
                                                                      maxCpuSlabSize,
                                                                      page_size,
                                                                      cpu_tier_sizes,
                                                                      bufferMgrs_[0][0]));
    return;
  }
#endif

  bufferMgrs_[1].push_back(new Buffer_Namespace::CpuBufferMgr(0,
                                                              total_cpu_size,
                                                              cudaMgr_.get(),
                                                              minCpuSlabSize,
                                                              maxCpuSlabSize,
                                                              page_size,
                                                              bufferMgrs_[0][0]));
}

// This function exists for testing purposes so that we can test a reset of the cache.
void DataMgr::resetPersistentStorage(const File_Namespace::DiskCacheConfig& cache_config,
                                     const size_t num_reader_threads,
                                     const SystemParameters& sys_params) {
  int numLevels = bufferMgrs_.size();
  for (int level = numLevels - 1; level >= 0; --level) {
    for (size_t device = 0; device < bufferMgrs_[level].size(); device++) {
      delete bufferMgrs_[level][device];
    }
  }
  bufferMgrs_.clear();
  populateMgrs(sys_params, num_reader_threads, cache_config);
  createTopLevelMetadata();
}

void DataMgr::populateMgrs(const SystemParameters& system_parameters,
                           const size_t userSpecifiedNumReaderThreads,
                           const File_Namespace::DiskCacheConfig& cache_config) {
  // no need for locking, as this is only called in the constructor
  bufferMgrs_.resize(2);
  bufferMgrs_[0].push_back(
      new PersistentStorageMgr(dataDir_, userSpecifiedNumReaderThreads, cache_config));

  levelSizes_.push_back(1);
  size_t page_size{512};
  size_t cpuBufferSize = system_parameters.cpu_buffer_mem_bytes;
  if (cpuBufferSize == 0) {  // if size is not specified
    const auto total_system_memory = getTotalSystemMemory();
    VLOG(1) << "Detected " << (float)total_system_memory / (1024 * 1024)
            << "M of total system memory.";
    cpuBufferSize = total_system_memory *
                    0.8;  // should get free memory instead of this ugly heuristic
  }
  size_t minCpuSlabSize = std::min(system_parameters.min_cpu_slab_size, cpuBufferSize);
  minCpuSlabSize = (minCpuSlabSize / page_size) * page_size;
  size_t maxCpuSlabSize = std::min(system_parameters.max_cpu_slab_size, cpuBufferSize);
  maxCpuSlabSize = (maxCpuSlabSize / page_size) * page_size;
  LOG(INFO) << "Min CPU Slab Size is " << (float)minCpuSlabSize / (1024 * 1024) << "MB";
  LOG(INFO) << "Max CPU Slab Size is " << (float)maxCpuSlabSize / (1024 * 1024) << "MB";
  LOG(INFO) << "Max memory pool size for CPU is " << (float)cpuBufferSize / (1024 * 1024)
            << "MB";

  size_t total_cpu_size = 0;

#ifdef ENABLE_MEMKIND
  CpuTierSizeVector cpu_tier_sizes(numCpuTiers, 0);
  cpu_tier_sizes[CpuTier::DRAM] = cpuBufferSize;
  if (g_enable_tiered_cpu_mem) {
    cpu_tier_sizes[CpuTier::PMEM] = g_pmem_size;
    LOG(INFO) << "Max memory pool size for PMEM is " << (float)g_pmem_size / (1024 * 1024)
              << "MB";
  }
  for (auto cpu_tier_size : cpu_tier_sizes) {
    total_cpu_size += cpu_tier_size;
  }
#else
  CpuTierSizeVector cpu_tier_sizes{};
  total_cpu_size = cpuBufferSize;
#endif

  if (hasGpus_ || cudaMgr_) {
    LOG(INFO) << "Reserved GPU memory is " << (float)reservedGpuMem_ / (1024 * 1024)
              << "MB includes render buffer allocation";
    bufferMgrs_.resize(3);
    allocateCpuBufferMgr(
        0, total_cpu_size, minCpuSlabSize, maxCpuSlabSize, page_size, cpu_tier_sizes);

    levelSizes_.push_back(1);
    int numGpus = cudaMgr_->getDeviceCount();
    for (int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
      size_t gpuMaxMemSize =
          system_parameters.gpu_buffer_mem_bytes != 0
              ? system_parameters.gpu_buffer_mem_bytes
              : (cudaMgr_->getDeviceProperties(gpuNum)->globalMem) - (reservedGpuMem_);
      size_t minGpuSlabSize =
          std::min(system_parameters.min_gpu_slab_size, gpuMaxMemSize);
      minGpuSlabSize = (minGpuSlabSize / page_size) * page_size;
      size_t maxGpuSlabSize =
          std::min(system_parameters.max_gpu_slab_size, gpuMaxMemSize);
      maxGpuSlabSize = (maxGpuSlabSize / page_size) * page_size;
      LOG(INFO) << "Min GPU Slab size for GPU " << gpuNum << " is "
                << (float)minGpuSlabSize / (1024 * 1024) << "MB";
      LOG(INFO) << "Max GPU Slab size for GPU " << gpuNum << " is "
                << (float)maxGpuSlabSize / (1024 * 1024) << "MB";
      LOG(INFO) << "Max memory pool size for GPU " << gpuNum << " is "
                << (float)gpuMaxMemSize / (1024 * 1024) << "MB";
      bufferMgrs_[2].push_back(new Buffer_Namespace::GpuCudaBufferMgr(gpuNum,
                                                                      gpuMaxMemSize,
                                                                      cudaMgr_.get(),
                                                                      minGpuSlabSize,
                                                                      maxGpuSlabSize,
                                                                      page_size,
                                                                      bufferMgrs_[1][0]));
    }
    levelSizes_.push_back(numGpus);
  } else {
    allocateCpuBufferMgr(
        0, total_cpu_size, minCpuSlabSize, maxCpuSlabSize, page_size, cpu_tier_sizes);
    levelSizes_.push_back(1);
  }
}

void DataMgr::convertDB(const std::string basePath) {
  // no need for locking, as this is only called in the constructor

  /* check that the data directory exists and it's empty */
  std::string mapdDataPath(basePath + "/../" + shared::kDataDirectoryName + "/");
  boost::filesystem::path path(mapdDataPath);
  if (boost::filesystem::exists(path)) {
    if (!boost::filesystem::is_directory(path)) {
      LOG(FATAL) << "Path to directory \"" + shared::kDataDirectoryName +
                        "\" to convert DB is not a directory.";
    }
  } else {  // data directory does not exist
    LOG(FATAL) << "Path to directory \"" + shared::kDataDirectoryName +
                      "\" to convert DB does not exist.";
  }

  File_Namespace::GlobalFileMgr* gfm{nullptr};
  gfm = dynamic_cast<PersistentStorageMgr*>(bufferMgrs_[0][0])->getGlobalFileMgr();
  CHECK(gfm);

  size_t defaultPageSize = gfm->getDefaultPageSize();
  LOG(INFO) << "Database conversion started.";
  File_Namespace::FileMgr* fm_base_db = new File_Namespace::FileMgr(
      gfm,
      defaultPageSize,
      basePath);  // this call also copies data into new DB structure
  delete fm_base_db;

  /* write content of DB into newly created/converted DB structure & location */
  checkpoint();  // outputs data files as well as metadata files
  LOG(INFO) << "Database conversion completed.";
}

void DataMgr::createTopLevelMetadata()
    const {  // create metadata shared by all tables of all DBs
  ChunkKey chunkKey(2);
  chunkKey[0] = 0;  // top level db_id
  chunkKey[1] = 0;  // top level tb_id

  File_Namespace::GlobalFileMgr* gfm{nullptr};
  gfm = dynamic_cast<PersistentStorageMgr*>(bufferMgrs_[0][0])->getGlobalFileMgr();
  CHECK(gfm);

  auto fm_top = gfm->getFileMgr(chunkKey);
  if (dynamic_cast<File_Namespace::FileMgr*>(fm_top)) {
    static_cast<File_Namespace::FileMgr*>(fm_top)->createTopLevelMetadata();
  }
}

std::vector<MemoryInfo> DataMgr::getMemoryInfo(const MemoryLevel mem_level) const {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  return getMemoryInfoUnlocked(mem_level);
}

std::vector<MemoryInfo> DataMgr::getMemoryInfoUnlocked(
    const MemoryLevel mem_level) const {
  std::vector<MemoryInfo> mem_info;
  if (mem_level == MemoryLevel::CPU_LEVEL) {
    Buffer_Namespace::CpuBufferMgr* cpu_buffer =
        dynamic_cast<Buffer_Namespace::CpuBufferMgr*>(
            bufferMgrs_[MemoryLevel::CPU_LEVEL][0]);
    CHECK(cpu_buffer);
    MemoryInfo mi;

    mi.pageSize = cpu_buffer->getPageSize();
    mi.maxNumPages = cpu_buffer->getMaxSize() / mi.pageSize;
    mi.isAllocationCapped = cpu_buffer->isAllocationCapped();
    mi.numPageAllocated = cpu_buffer->getAllocated() / mi.pageSize;

    const auto& slab_segments = cpu_buffer->getSlabSegments();
    for (size_t slab_num = 0; slab_num < slab_segments.size(); ++slab_num) {
      for (auto segment : slab_segments[slab_num]) {
        MemoryData md;
        md.slabNum = slab_num;
        md.startPage = segment.start_page;
        md.numPages = segment.num_pages;
        md.touch = segment.last_touched;
        md.memStatus = segment.mem_status;
        md.chunk_key.insert(
            md.chunk_key.end(), segment.chunk_key.begin(), segment.chunk_key.end());
        mi.nodeMemoryData.push_back(md);
      }
    }
    mem_info.push_back(mi);
  } else if (hasGpus_) {
    int numGpus = cudaMgr_->getDeviceCount();
    for (int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
      Buffer_Namespace::GpuCudaBufferMgr* gpu_buffer =
          dynamic_cast<Buffer_Namespace::GpuCudaBufferMgr*>(
              bufferMgrs_[MemoryLevel::GPU_LEVEL][gpuNum]);
      CHECK(gpu_buffer);
      MemoryInfo mi;

      mi.pageSize = gpu_buffer->getPageSize();
      mi.maxNumPages = gpu_buffer->getMaxSize() / mi.pageSize;
      mi.isAllocationCapped = gpu_buffer->isAllocationCapped();
      mi.numPageAllocated = gpu_buffer->getAllocated() / mi.pageSize;

      const auto& slab_segments = gpu_buffer->getSlabSegments();
      for (size_t slab_num = 0; slab_num < slab_segments.size(); ++slab_num) {
        for (auto segment : slab_segments[slab_num]) {
          MemoryData md;
          md.slabNum = slab_num;
          md.startPage = segment.start_page;
          md.numPages = segment.num_pages;
          md.touch = segment.last_touched;
          md.chunk_key.insert(
              md.chunk_key.end(), segment.chunk_key.begin(), segment.chunk_key.end());
          md.memStatus = segment.mem_status;
          mi.nodeMemoryData.push_back(md);
        }
      }
      mem_info.push_back(mi);
    }
  }
  return mem_info;
}

std::string DataMgr::dumpLevel(const MemoryLevel memLevel) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);

  // if gpu we need to iterate through all the buffermanagers for each card
  if (memLevel == MemoryLevel::GPU_LEVEL) {
    int numGpus = cudaMgr_->getDeviceCount();
    std::ostringstream tss;
    for (int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
      tss << bufferMgrs_[memLevel][gpuNum]->printSlabs();
    }
    return tss.str();
  } else {
    return bufferMgrs_[memLevel][0]->printSlabs();
  }
}

void DataMgr::clearMemory(const MemoryLevel memLevel) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);

  // if gpu we need to iterate through all the buffermanagers for each card
  if (memLevel == MemoryLevel::GPU_LEVEL) {
    if (cudaMgr_) {
      int numGpus = cudaMgr_->getDeviceCount();
      for (int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
        LOG(INFO) << "clear slabs on gpu " << gpuNum;
        auto buffer_mgr_for_gpu =
            dynamic_cast<Buffer_Namespace::BufferMgr*>(bufferMgrs_[memLevel][gpuNum]);
        CHECK(buffer_mgr_for_gpu);
        buffer_mgr_for_gpu->clearSlabs();
      }
    } else {
      LOG(WARNING) << "Unable to clear GPU memory: No GPUs detected";
    }
  } else {
    auto buffer_mgr_for_cpu =
        dynamic_cast<Buffer_Namespace::BufferMgr*>(bufferMgrs_[memLevel][0]);
    CHECK(buffer_mgr_for_cpu);
    buffer_mgr_for_cpu->clearSlabs();
  }
}

bool DataMgr::isBufferOnDevice(const ChunkKey& key,
                               const MemoryLevel memLevel,
                               const int deviceId) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  return bufferMgrs_[memLevel][deviceId]->isBufferOnDevice(key);
}

void DataMgr::getChunkMetadataVecForKeyPrefix(ChunkMetadataVector& chunkMetadataVec,
                                              const ChunkKey& keyPrefix) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  bufferMgrs_[0][0]->getChunkMetadataVecForKeyPrefix(chunkMetadataVec, keyPrefix);
}

AbstractBuffer* DataMgr::createChunkBuffer(const ChunkKey& key,
                                           const MemoryLevel memoryLevel,
                                           const int deviceId,
                                           const size_t page_size) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  int level = static_cast<int>(memoryLevel);
  return bufferMgrs_[level][deviceId]->createBuffer(key, page_size);
}

AbstractBuffer* DataMgr::getChunkBuffer(const ChunkKey& key,
                                        const MemoryLevel memoryLevel,
                                        const int deviceId,
                                        const size_t numBytes) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  const auto level = static_cast<size_t>(memoryLevel);
  CHECK_LT(level, levelSizes_.size());     // make sure we have a legit buffermgr
  CHECK_LT(deviceId, levelSizes_[level]);  // make sure we have a legit buffermgr
  return bufferMgrs_[level][deviceId]->getBuffer(key, numBytes);
}

void DataMgr::deleteChunksWithPrefix(const ChunkKey& keyPrefix) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);

  int numLevels = bufferMgrs_.size();
  for (int level = numLevels - 1; level >= 0; --level) {
    for (int device = 0; device < levelSizes_[level]; ++device) {
      bufferMgrs_[level][device]->deleteBuffersWithPrefix(keyPrefix);
    }
  }
}

// only deletes the chunks at the given memory level
void DataMgr::deleteChunksWithPrefix(const ChunkKey& keyPrefix,
                                     const MemoryLevel memLevel) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);

  if (bufferMgrs_.size() <= memLevel) {
    return;
  }
  for (int device = 0; device < levelSizes_[memLevel]; ++device) {
    bufferMgrs_[memLevel][device]->deleteBuffersWithPrefix(keyPrefix);
  }
}

AbstractBuffer* DataMgr::alloc(const MemoryLevel memoryLevel,
                               const int deviceId,
                               const size_t numBytes) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  const auto level = static_cast<int>(memoryLevel);
  CHECK_LT(deviceId, levelSizes_[level]);
  return bufferMgrs_[level][deviceId]->alloc(numBytes);
}

void DataMgr::free(AbstractBuffer* buffer) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  int level = static_cast<int>(buffer->getType());
  bufferMgrs_[level][buffer->getDeviceId()]->free(buffer);
}

void DataMgr::copy(AbstractBuffer* destBuffer, AbstractBuffer* srcBuffer) {
  destBuffer->write(srcBuffer->getMemoryPtr(),
                    srcBuffer->size(),
                    0,
                    srcBuffer->getType(),
                    srcBuffer->getDeviceId());
}

// could add function below to do arbitrary copies between buffers

// void DataMgr::copy(AbstractBuffer *destBuffer, const AbstractBuffer *srcBuffer, const
// size_t numBytes, const size_t destOffset, const size_t srcOffset) {
//} /

void DataMgr::checkpoint(const int db_id, const int tb_id) {
  // TODO(adb): do we need a buffer mgr lock here?
  // MAT Yes to reduce Parallel Executor TSAN issues (and correctness for now)
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  for (auto levelIt = bufferMgrs_.rbegin(); levelIt != bufferMgrs_.rend(); ++levelIt) {
    // use reverse iterator so we start at GPU level, then CPU then DISK
    for (auto deviceIt = levelIt->begin(); deviceIt != levelIt->end(); ++deviceIt) {
      (*deviceIt)->checkpoint(db_id, tb_id);
    }
  }
}

void DataMgr::checkpoint(const int db_id,
                         const int table_id,
                         const MemoryLevel memory_level) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  CHECK_LT(static_cast<size_t>(memory_level), bufferMgrs_.size());
  CHECK_LT(static_cast<size_t>(memory_level), levelSizes_.size());
  for (int device_id = 0; device_id < levelSizes_[memory_level]; device_id++) {
    bufferMgrs_[memory_level][device_id]->checkpoint(db_id, table_id);
  }
}

void DataMgr::checkpoint() {
  // TODO(adb): SAA
  // MAT Yes to reduce Parallel Executor TSAN issues (and correctness for now)
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  for (auto levelIt = bufferMgrs_.rbegin(); levelIt != bufferMgrs_.rend(); ++levelIt) {
    // use reverse iterator so we start at GPU level, then CPU then DISK
    for (auto deviceIt = levelIt->begin(); deviceIt != levelIt->end(); ++deviceIt) {
      (*deviceIt)->checkpoint();
    }
  }
}

void DataMgr::removeTableRelatedDS(const int db_id, const int tb_id) {
  std::lock_guard<std::mutex> buffer_lock(buffer_access_mutex_);
  bufferMgrs_[0][0]->removeTableRelatedDS(db_id, tb_id);
}

void DataMgr::setTableEpoch(const int db_id, const int tb_id, const int start_epoch) {
  File_Namespace::GlobalFileMgr* gfm{nullptr};
  gfm = dynamic_cast<PersistentStorageMgr*>(bufferMgrs_[0][0])->getGlobalFileMgr();
  CHECK(gfm);
  gfm->setTableEpoch(db_id, tb_id, start_epoch);
}

size_t DataMgr::getTableEpoch(const int db_id, const int tb_id) {
  File_Namespace::GlobalFileMgr* gfm{nullptr};
  gfm = dynamic_cast<PersistentStorageMgr*>(bufferMgrs_[0][0])->getGlobalFileMgr();
  CHECK(gfm);
  return gfm->getTableEpoch(db_id, tb_id);
}

void DataMgr::resetTableEpochFloor(const int32_t db_id, const int32_t tb_id) {
  File_Namespace::GlobalFileMgr* gfm{nullptr};
  gfm = dynamic_cast<PersistentStorageMgr*>(bufferMgrs_[0][0])->getGlobalFileMgr();
  CHECK(gfm);
  gfm->resetTableEpochFloor(db_id, tb_id);
}

File_Namespace::GlobalFileMgr* DataMgr::getGlobalFileMgr() const {
  File_Namespace::GlobalFileMgr* global_file_mgr{nullptr};
  global_file_mgr =
      dynamic_cast<PersistentStorageMgr*>(bufferMgrs_[0][0])->getGlobalFileMgr();
  CHECK(global_file_mgr);
  return global_file_mgr;
}

std::shared_ptr<ForeignStorageInterface> DataMgr::getForeignStorageInterface() const {
  return dynamic_cast<PersistentStorageMgr*>(bufferMgrs_[0][0])
      ->getForeignStorageInterface();
}

std::ostream& operator<<(std::ostream& os, const DataMgr::SystemMemoryUsage& mem_info) {
  os << "jsonlog ";
  os << "{";
  os << " \"name\": \"CPU Memory Info\",";
  os << " \"TotalMB\": " << mem_info.total / (1024. * 1024.) << ",";
  os << " \"FreeMB\": " << mem_info.free / (1024. * 1024.) << ",";
  os << " \"ProcessMB\": " << mem_info.resident / (1024. * 1024.) << ",";
  os << " \"VirtualMB\": " << mem_info.vtotal / (1024. * 1024.) << ",";
  os << " \"ProcessPlusSwapMB\": " << mem_info.regular / (1024. * 1024.) << ",";
  os << " \"ProcessSharedMB\": " << mem_info.shared / (1024. * 1024.) << ",";
  os << " \"FragmentationPercent\": " << mem_info.frag;
  os << " }";
  return os;
}

PersistentStorageMgr* DataMgr::getPersistentStorageMgr() const {
  return dynamic_cast<PersistentStorageMgr*>(bufferMgrs_[MemoryLevel::DISK_LEVEL][0]);
}

Buffer_Namespace::CpuBufferMgr* DataMgr::getCpuBufferMgr() const {
  return dynamic_cast<Buffer_Namespace::CpuBufferMgr*>(
      bufferMgrs_[MemoryLevel::CPU_LEVEL][0]);
}

Buffer_Namespace::GpuCudaBufferMgr* DataMgr::getGpuBufferMgr(int32_t device_id) const {
  if (bufferMgrs_.size() > MemoryLevel::GPU_LEVEL) {
    CHECK_GT(bufferMgrs_[MemoryLevel::GPU_LEVEL].size(), static_cast<size_t>(device_id));
    return dynamic_cast<Buffer_Namespace::GpuCudaBufferMgr*>(
        bufferMgrs_[MemoryLevel::GPU_LEVEL][device_id]);
  } else {
    return nullptr;
  }
}

}  // namespace Data_Namespace

max_stars_repo_name: omnisci/mapd-core

max_issues_repo_name: omnisci/mapd-core

max_forks_repo_name: omnisci/mapd-core


text:
#pragma once

#include <exception>
#include <boost/noncopyable.hpp>

namespace mdw { namespace formula {

  class ValueException: public std::exception
  {
    const char *_message;
  public:
    // Make sure iMessage lives longer than the exception!
    explicit ValueException(const char *iMessage):
      _message(iMessage)
    {}

    ValueException():
      _message(NULL)
    {}

    ~ValueException() throw() {}

    const char *what()
    {
      if (_message)
      {
        return _message;
      } else {
        return "Invalid or missing data to compute the formula";
      }
    }
  };

}}

max_stars_repo_name: AmadeusITGroup/Formula

max_issues_repo_name: AmadeusITGroup/Formula

max_forks_repo_name: AmadeusITGroup/Formula


text:
// Copyright (C) 2014 The Regents of the University of California (Regents).
// 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 The Regents or University of California 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 HOLDERS 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.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include "theia/sfm/pose/sim_transform_partial_rotation.h"

#include <Eigen/Core>
#include <Eigen/Eigenvalues>
#include <Eigen/Geometry>
#include <Eigen/LU>
#include <glog/logging.h>
#include <limits>
#include <math.h>

#include "theia/alignment/alignment.h"
#include "theia/sfm/pose/util.h"

namespace theia {

using Eigen::EigenSolver;
using Eigen::Matrix;
using Eigen::Matrix3d;
using Eigen::Quaterniond;
using Eigen::Vector3d;

typedef Eigen::Matrix<double, 5, 5> Matrix5d;
typedef Eigen::Matrix<double, 5, 1> Vector5d;

namespace {

bool SolveQEP(const Matrix5d& M,
              const Matrix5d& C,
              const Matrix5d& K,
              std::vector<double>* eigenvalues,
              std::vector<Vector5d>* eigenvectors) {
  // Solves the quadratic eigenvalue problem:
  //
  //   Q(s)x = 0
  //
  // where:
  //
  //   Q(s) = s^2*M + s*C + K
  //
  // Returns true if the problem could be solved, false otherwise.
  //
  // This is converted to a generalized eigenvalue as described in:
  //   http://en.wikipedia.org/wiki/Quadratic_eigenvalue_problem
  //
  // The generalized eigenvalue problem is in this form:
  //
  // [ C  K ]z = s[ -M  0  ]z
  // [-I  0 ]     [ 0   -I ]
  //
  // With eigenvector z = [ sx ] and s is the eigenvalue.
  //                      [  x ]
  //
  // The eigenvector of the quadratic eigenvalue problem can be extracted from
  // z.
  //
  // Where z is the eigenvector, s is the eigenvalue.
  // This generalized eigenvalue can be converted to a standard eigenvalue
  // problem by multiplying by the inverse of the RHS matrix. The inverse of
  // the RHS matrix is particularly simple:
  //
  // [ -inv(M)  0 ]
  // [ 0       -I ]
  //
  // So the generalized eigenvalue problem reduces to a standard eigenvalue
  // problem on the constraint matrix:
  //
  // [ -inv(M)C  -inv(M)K ]z = sz
  // [ I         0        ]

  const Eigen::FullPivLU<Matrix5d> lu(M);
  if (!lu.isInvertible()) {
    VLOG(2) << "Matrix M is not invertible (rank " << lu.rank() << ")";
    return false;
  }

  // Negate inverse of M.
  const Matrix5d inv_M = -1.0 * lu.inverse();

  // Set up constraint matrix.
  Matrix<double, 10, 10> constraint = Matrix<double, 10, 10>::Zero();
  // Set upper-left to - inv(M) * C.
  constraint.block<5, 5>(0, 0) = inv_M * C;
  // Set upper-right to -inv(M) * K.
  constraint.block<5, 5>(0, 5) = inv_M * K;
  // Set lower-left to identity.
  constraint.block<5, 5>(5, 0) = Matrix5d::Identity();

  // Extract the left eigenvectors and values from the constraint matrix.
  EigenSolver<Matrix<double, 10, 10> > eig_solver(constraint);
  for (int i = 0; i < eig_solver.eigenvalues().size(); i++) {
    // Two solutions that always occur correspond to (s^2 + 1) so skip these
    // solutions.
    if (fabs(eig_solver.eigenvalues()[i].imag()) == 1 ||
        (i > 0 && eig_solver.eigenvalues()[i].real() ==
                      eig_solver.eigenvalues()[i - 1].real())) {
      continue;
    }
    eigenvalues->push_back(eig_solver.eigenvalues()[i].real());
    eigenvectors->push_back(
        Vector5d(eig_solver.eigenvectors().col(i).tail<5>().real()));
  }
  return true;
}

}  // namespace

void SimTransformPartialRotation(const Vector3d& axis,
                                 const Vector3d image_one_ray_directions[5],
                                 const Vector3d image_one_ray_origins[5],
                                 const Vector3d image_two_ray_directions[5],
                                 const Vector3d image_two_ray_origins[5],
                                 std::vector<Quaterniond>* soln_rotations,
                                 std::vector<Vector3d>* soln_translations,
                                 std::vector<double>* soln_scales) {
  CHECK_DOUBLE_EQ(axis.squaredNorm(), 1.0);
  CHECK_NOTNULL(soln_rotations)->clear();
  CHECK_NOTNULL(soln_translations)->clear();

  // The generalized epipolar constraint between two sets of rays in different
  // coordinate systems (two generalized cameras).
  //
  // The rays are converted to plucker coordinates:
  //   L = [ q  ]
  //       [ p  ]
  //
  // Assuming the first coordinate system has zero rotation and translation,
  // the generalized epipolar constraint is:
  //
  //   q2' * [t]x R * q1 + q2' * R * p1 + q1' * R * p2 = 0
  //
  // v' means transpose v, t is unknown translation, [t]x is the matrix
  // cross product form.
  //
  // Re-arranging to isolate t:
  //
  //   -(q2 x (R * q1))' * t + q2' * R * p1 + q1' * R' * p2 = 0
  //
  // In vector form:
  //
  //  [-(q2 x (R * q1))', q2' * R * p1 + q1' * R' * p2 ] * [ t ] = 0
  //                                                       [ 1 ]
  //
  // If we consider that L2 may not have the same scale as L1, then we must
  // additionally reconcile a scale s. Our equation then becomes:
  //
  //  [-(q2 x (R * q1))',  q1' * R' * p2, q2' * R * p1 ] * [ t ] = 0
  //                                                       [ s ]
  //                                                       [ 1 ]
  //
  // Each correspondence gives another constraint and the constraints can
  // be stacked to create a constraint matrix.
  //
  // The rotation matrix R can be parameterized, up to scale factor, as:
  //
  //   R ~ 2 * (v * v' + alpha * [v]x) + (alpha^2 - 1)I
  //
  //   I = Identity matrix.
  //
  // where is v is the known (unit length) axis and alpha is related to the
  // unknown angle of rotation.
  //
  // The epipolar constraint holds if the rotation matrix is scaled, so the
  // rotation matrix parameterization above can be used. Each row of the
  // constraint matrix is thus a quadratic function in alpha, so the constraint
  // can be written as:
  //
  //   [ M * alpha^2 + C * alpha + k ] * [ t ] = 0
  //                                     [ s ]
  //                                     [ 1 ]
  //
  // This is standard quadratic eigenvalue problem (QEP) and is solved using
  // standard methods.

  // Creates the matrices for the QEP problem.
  Matrix5d M;
  Matrix5d C;
  Matrix5d K;

  // Based on the rotation parameterization above,
  //   R = alpha^2 * rot_alpha_sq + alpha * rot_alpha + rot_constant
  const Matrix3d rot_alpha_sq = Matrix3d::Identity();
  const Matrix3d rot_alpha = 2.0 * CrossProductMatrix(axis);
  const Matrix3d rot_constant =
      2 * axis * axis.transpose() - Matrix3d::Identity();

  for (int i = 0; i < 5; ++i) {
    const Vector3d& f1(image_one_ray_directions[i]);
    const Vector3d& f2(image_two_ray_directions[i]);
    const Matrix3d pos1 = CrossProductMatrix(image_one_ray_origins[i]);
    const Matrix3d pos2 = CrossProductMatrix(image_two_ray_origins[i]);

    M.row(i).head(3) = f1.cross(rot_alpha_sq * f2);
    M.row(i)[3] = -f1.transpose() * (rot_alpha_sq * pos2) * f2;
    M.row(i)[4] = f1.transpose() * (pos1 * rot_alpha_sq) * f2;

    C.row(i).head(3) = f1.cross(rot_alpha * f2);
    C.row(i)[3] = -f1.transpose() * (rot_alpha * pos2) * f2;
    C.row(i)[4] = f1.transpose() * (pos1 * rot_alpha) * f2;

    K.row(i).head(3) = f1.cross(rot_constant * f2);
    K.row(i)[3] = -f1.transpose() * (rot_constant * pos2) * f2;
    K.row(i)[4] = f1.transpose() * (pos1 * rot_constant) * f2;
  }

  std::vector<double> eigenvalues;
  std::vector<Vector5d> eigenvectors;
  static const double kWTolerance = 1e-12;
  if (SolveQEP(M, C, K, &eigenvalues, &eigenvectors)) {
    // Extracts the translations and rotations from the eigenvalues and
    // eigenvectors of the QEP problem.
    for (int i = 0; i < eigenvalues.size(); ++i) {
      if (fabs(eigenvectors[i][4]) < kWTolerance ||
          eigenvectors[i][3] / eigenvectors[i][4] < 0) {
        continue;
      }

      Quaterniond quat(eigenvalues[i], axis[0], axis[1], axis[2]);
      quat.normalize();
      soln_rotations->push_back(quat);
      const Vector3d rotated_translation =
          Vector3d(eigenvectors[i][0] / eigenvectors[i][4],
                   eigenvectors[i][1] / eigenvectors[i][4],
                   eigenvectors[i][2] / eigenvectors[i][4]);
      soln_translations->push_back(rotated_translation);
      soln_scales->push_back(eigenvectors[i][3] / eigenvectors[i][4]);
    }
  } else {
    // When there is zero rotation the vector part of the quaternion disappears
    // and it becomes ([0], 1) (where [0] is the zero vector) and the SolveQEP
    // method cannot be used.
    // However from the equations for M, C, and K above we can see that the
    // C and K matrices contain the axis, which is 0 assuming zero rotation,
    // so to solve for the translation we can directly extract the null space
    // of M.
    const Eigen::FullPivLU<Matrix5d> lu(M);
    if (lu.dimensionOfKernel() != 1) {
      LOG(WARNING) << "The input is a degenerate configuration resulting in a "
                      "rank deficient matrix!";
      return;
    }

    const Vector5d kernel = lu.kernel();
    if (fabs(kernel[4]) > kWTolerance) {
      soln_rotations->push_back(Quaterniond::Identity());
      soln_translations->push_back(kernel.head<3>() / kernel[4]);
      soln_scales->push_back(kernel[3] / kernel[4]);
    }
  }
}

}  // namespace theia

max_stars_repo_name: urbste/TheiaSfM

max_issues_repo_name: urbste/TheiaSfM

max_forks_repo_name: urbste/TheiaSfM


text:
#include <boost/static_views/view_concept.hpp>

int main() {}


text:
#include <iostream>
#include <fstream>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include "date.hpp"
#include "serialize-method.hpp"

void save() {
  std::ofstream file("archive.xml");
  boost::archive::xml_oarchive oa(file);
  date d(15, 8, 1947);
  oa & BOOST_SERIALIZATION_NVP(d);
}

void load() {
  std::ifstream file("archive.xml");
  boost::archive::xml_iarchive ia(file);
  date dr;
  ia >> BOOST_SERIALIZATION_NVP(dr);
  std::cout << dr;
}

int main(int argc, char** argv) {
  save();
  load();
  return 0;
}

max_stars_repo_name: gusenov/examples-boost

max_issues_repo_name: gusenov/examples-boost

max_forks_repo_name: gusenov/examples-boost


text:
#pragma once

#include <boost/utility.hpp>
#include "utility/StackOnly.hpp"

namespace Utility{
	template< void _OnConstruction(), void _OnDestruction() >
	class PairedCall:boost::noncopyable,StackOnly{
	public:
		PairedCall(){ _OnConstruction(); }
		~PairedCall(){ _OnDestruction(); }
	};
}

max_stars_repo_name: ducis/pile-of-cpp

max_issues_repo_name: ducis/pile-of-cpp

max_forks_repo_name: ducis/pile-of-cpp


text:
#include <iostream>
#include <asio_utp.hpp>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/streambuf.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <unistd.h> // dup

#include "block.h"

#if BOOST_VERSION < 106400
#error "The ucat.cpp example requires Boost version 1.47 or higher"
// Because posix::stream_descriptor has trouble reading from STDIN_FILENO in
// earlier versions.
#endif

using namespace std;
namespace asio = boost::asio;
namespace ip   = asio::ip;
namespace sys  = boost::system;
namespace utp  = asio_utp;

struct defer {
    std::function<void()> f;
    ~defer() { f(); }
};

ip::udp::endpoint parse_endpoint(string s)
{
    auto pos = s.find(':');

    if (pos == string::npos) {
        throw runtime_error("Failed to parse endpoint");
    }

    auto addr = ip::address::from_string(s.substr(0, pos));
    auto port = s.substr(pos + 1);

    if (port.empty()) port = "0";

    return {addr, uint16_t(stoi(port))};
}

template<class S1, class S2>
void half_duplex_forward(S1& s1, S2& s2, asio::yield_context yield)
{
    std::vector<unsigned char> buffer(4*1024);

    sys::error_code ec;

    while (true) {
        size_t n = s1.async_read_some(asio::buffer(buffer), yield[ec]);
        if (ec) return;
        asio::async_write(s2, asio::buffer(buffer.data(), n), yield[ec]);
        if (ec) return;
    }
}

void full_duplex_forward(utp::socket s, asio::yield_context yield)
{
    auto ex = s.get_executor();

    block b1(ex), b2(ex);

    asio::posix::stream_descriptor output(ex, ::dup(STDOUT_FILENO));
    asio::posix::stream_descriptor input (ex, ::dup(STDIN_FILENO));

    auto close_everything = [&] {
        s.close();
        if (output.is_open()) output.close();
        if (input .is_open()) input .close();
    };

    asio::spawn(ex, [&] (asio::yield_context yield) {
        defer on_exit{[&] { close_everything(); b1.release(); }};
        half_duplex_forward(s, output, yield);
    });

    asio::spawn(ex, [&] (asio::yield_context yield) {
        defer on_exit{[&] { close_everything(); b2.release(); }};
        half_duplex_forward(input, s, yield);
    });

    b1.wait(yield);
    b2.wait(yield);
}

void server( asio::io_context& ioc
           , int argc
           , const char** argv
           , asio::yield_context yield)
{
    assert(argc >= 3);

    utp::socket s(ioc);

    sys::error_code ec;
    auto ep = parse_endpoint(argv[2]);
    s.bind(ep, ec);

    if (ec) {
        cerr << "Failed to bind on endpoint " << ep
            << " ec:" << ec.message() << "\n";
        return;
    }

    cerr << "Accepting on: " << s.local_endpoint() << endl;
    s.async_accept(yield);
    cerr << "Accepted"  << endl;

    full_duplex_forward(move(s), yield);
}

void client( asio::io_context& ioc
           , int argc
           , const char** argv
           , asio::yield_context yield)
{
    assert(argc >= 3);

    sys::error_code ec;
    utp::socket s(ioc);
    s.bind({ip::address_v4::loopback(), 0}, ec);
    assert(!ec);

    auto remote_ep = parse_endpoint(argv[2]);

    cerr << "Connecting to: " << remote_ep << endl;
    s.async_connect(remote_ep, yield);
    cerr << "Connected" << endl;

    full_duplex_forward(move(s), yield);
}

void usage(const char* app_name)
{
    cerr << "Usage:\n"
         << "  " << app_name << " s <endpoint-to-accept-on>" << endl
         << "  " << app_name << " c <endpoint-to-connect-to>" << endl;
}

int main(int argc, const char** argv)
{
    asio::io_context ioc;

    if (argc < 2) {
        usage(argv[0]);
        return 1;
    }

    if (argv[1] == string("c")) {
        asio::spawn(ioc, [&] (asio::yield_context yield) {
            client(ioc, argc, argv, yield);
        });
    }
    else if (argv[1] == string("s")) {
        asio::spawn(ioc, [&] (asio::yield_context yield) {
            server(ioc, argc, argv, yield);
        });
    }
    else {
        usage(argv[0]);
        return 1;
    }

    try {
        ioc.run();
    }
    catch(const std::exception& e) {
        cerr << "Exception: " << e.what() << endl;
    }
}

max_stars_repo_name: inetic/asio-utp

max_issues_repo_name: inetic/asio-utp

max_forks_repo_name: equalitie/asio-utp


text: #include <boost/spirit/home/karma.hpp>


text:
/**
 * tvgutil: LineUtil.cpp
 * Copyright (c) Torr Vision Group, University of Oxford, 2015. All rights reserved.
 */

#include "persistence/LineUtil.h"

#include <stdexcept>

#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>

namespace tvgutil {

//#################### PUBLIC STATIC MEMBER FUNCTIONS ####################

std::vector<std::string> LineUtil::extract_lines(std::istream& is)
{
  std::vector<std::string> lines;

  std::string line;
  while(std::getline(is, line))
  {
    boost::trim(line);
    if(!line.empty()) lines.push_back(line);
  }

  return lines;
}

std::vector<std::vector<std::string> > LineUtil::extract_word_lines(std::istream& is, const std::string& delimiters)
{
  std::vector<std::vector<std::string> > wordLines;

  std::string internalDelimiters = delimiters + '\r';

  std::string line;
  while(std::getline(is, line))
  {
    typedef boost::char_separator<char> sep;
    typedef boost::tokenizer<sep> tokenizer;

    tokenizer tok(line.begin(), line.end(), sep(internalDelimiters.c_str()));
    std::vector<std::string> words(tok.begin(), tok.end());
    wordLines.push_back(words);
  }

  return wordLines;
}

void LineUtil::output_lines(std::ostream& os, const std::vector<std::string>& lines)
{
  if(!os) throw std::runtime_error("Unable to write to the output stream");

  for(size_t i = 0, count = lines.size(); i < count; ++i)
  {
    os << lines[i] << '\n';
  }
}

}

max_stars_repo_name: torrvision/spaint

max_issues_repo_name: GucciPrada/spaint

max_forks_repo_name: GucciPrada/spaint


text:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2018,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "face/transport.hpp"
#include "face/face.hpp"
#include "dummy-transport.hpp"
#include "dummy-receive-link-service.hpp"
#include "transport-test-common.hpp"

#include <boost/mpl/fold.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/vector.hpp>

namespace nfd {
namespace face {
namespace tests {

namespace mpl = boost::mpl;

BOOST_AUTO_TEST_SUITE(Face)
BOOST_AUTO_TEST_SUITE(TestTransport)

BOOST_AUTO_TEST_CASE(DummyTransportStaticProperties)
{
  auto transport = make_unique<DummyTransport>();
  checkStaticPropertiesInitialized(*transport);
}

class PersistencyTestTransport : public DummyTransport
{
public:
  PersistencyTestTransport()
    : DummyTransport("dummy://", "dummy://",
                     ndn::nfd::FACE_SCOPE_NON_LOCAL,
                     ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
  {
  }

protected:
  void
  afterChangePersistency(ndn::nfd::FacePersistency oldPersistency) final
  {
    persistencyHistory.push_back(oldPersistency);
  }

public:
  std::vector<ndn::nfd::FacePersistency> persistencyHistory;
};

BOOST_AUTO_TEST_CASE(PersistencyChange)
{
  auto transport = make_unique<PersistencyTestTransport>();
  BOOST_CHECK_EQUAL(transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
  BOOST_CHECK_EQUAL(transport->persistencyHistory.size(), 0);

  BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_NONE), false);
  BOOST_REQUIRE_EQUAL(transport->canChangePersistencyTo(transport->getPersistency()), true);
  BOOST_REQUIRE_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_PERMANENT), true);

  transport->setPersistency(transport->getPersistency());
  BOOST_CHECK_EQUAL(transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
  BOOST_CHECK_EQUAL(transport->persistencyHistory.size(), 0);

  transport->setPersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
  BOOST_CHECK_EQUAL(transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERMANENT);
  BOOST_REQUIRE_EQUAL(transport->persistencyHistory.size(), 1);
  BOOST_CHECK_EQUAL(transport->persistencyHistory.back(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
}

/** \brief a macro to declare a TransportState as a integral constant
 *  \note we cannot use mpl::integral_c because TransportState is not an integral type
 */
#define TRANSPORT_STATE_C(X) mpl::int_<static_cast<int>(TransportState::X)>

/** \brief a map from every TransportState to a valid state transition sequence
 *         for entering this state from UP
 */
typedef mpl::map<
  mpl::pair<TRANSPORT_STATE_C(UP),
    mpl::vector<>>,
  mpl::pair<TRANSPORT_STATE_C(DOWN),
    mpl::vector<
      TRANSPORT_STATE_C(DOWN)
    >>,
  mpl::pair<TRANSPORT_STATE_C(CLOSING),
    mpl::vector<
      TRANSPORT_STATE_C(CLOSING)
    >>,
  mpl::pair<TRANSPORT_STATE_C(FAILED),
    mpl::vector<
      TRANSPORT_STATE_C(FAILED)
    >>,
  mpl::pair<TRANSPORT_STATE_C(CLOSED),
    mpl::vector<
      TRANSPORT_STATE_C(CLOSING),
      TRANSPORT_STATE_C(CLOSED)
    >>
> StateEntering;

/** \brief a sequence of all valid TransportStates
 */
typedef mpl::fold<StateEntering,
  mpl::vector<>,
  mpl::push_back<mpl::_1, mpl::first<mpl::_2>>
>::type States;

/** \brief a set of all valid state transitions
 */
typedef mpl::set<
  mpl::pair<TRANSPORT_STATE_C(UP), TRANSPORT_STATE_C(DOWN)>,
  mpl::pair<TRANSPORT_STATE_C(DOWN), TRANSPORT_STATE_C(UP)>,
  mpl::pair<TRANSPORT_STATE_C(UP), TRANSPORT_STATE_C(CLOSING)>,
  mpl::pair<TRANSPORT_STATE_C(UP), TRANSPORT_STATE_C(FAILED)>,
  mpl::pair<TRANSPORT_STATE_C(DOWN), TRANSPORT_STATE_C(CLOSING)>,
  mpl::pair<TRANSPORT_STATE_C(DOWN), TRANSPORT_STATE_C(FAILED)>,
  mpl::pair<TRANSPORT_STATE_C(CLOSING), TRANSPORT_STATE_C(CLOSED)>,
  mpl::pair<TRANSPORT_STATE_C(FAILED), TRANSPORT_STATE_C(CLOSED)>
> ValidStateTransitions;

/** \brief a metafunction to generate a sequence of all state transitions
 *         from a specified state
 */
template<typename FromState, typename Result>
struct StateTransitionsFrom : mpl::fold<
                                States,
                                Result,
                                mpl::push_back<mpl::_1, mpl::pair<FromState, mpl::_2>>>
{
};

/** \brief a sequence of all state transitions
 */
typedef mpl::fold<
  States,
  mpl::vector<>,
  mpl::lambda<StateTransitionsFrom<mpl::_2, mpl::_1>>
>::type AllStateTransitions;

#undef TRANSPORT_STATE_C

BOOST_AUTO_TEST_CASE_TEMPLATE(SetState, T, AllStateTransitions)
{
  auto transport = make_unique<DummyTransport>();

  TransportState from = static_cast<TransportState>(T::first::value);
  TransportState to = static_cast<TransportState>(T::second::value);
  BOOST_TEST_MESSAGE("SetState " << from << " -> " << to);

  // enter from state
  using Steps = typename mpl::at<StateEntering, mpl::int_<T::first::value>>::type;
  mpl::for_each<Steps>([&transport] (int state) {
    transport->setState(static_cast<TransportState>(state));
  });
  BOOST_REQUIRE_EQUAL(transport->getState(), from);

  bool hasSignal = false;
  transport->afterStateChange.connect(
    [from, to, &hasSignal] (TransportState oldState, TransportState newState) {
      hasSignal = true;
      BOOST_CHECK_EQUAL(oldState, from);
      BOOST_CHECK_EQUAL(newState, to);
    });

  // do transition
  bool isValid = from == to ||
                 mpl::has_key<ValidStateTransitions,
                   mpl::pair<mpl::int_<T::first::value>, mpl::int_<T::second::value>>
                 >::value;
  if (isValid) {
    BOOST_REQUIRE_NO_THROW(transport->setState(to));
    BOOST_CHECK_EQUAL(hasSignal, from != to);
  }
  else {
    BOOST_CHECK_THROW(transport->setState(to), std::runtime_error);
  }
}

BOOST_AUTO_TEST_CASE(NoExpirationTime)
{
  auto transport = make_unique<DummyTransport>();

  BOOST_CHECK_EQUAL(transport->getExpirationTime(), time::steady_clock::TimePoint::max());
}

class DummyTransportFixture : public nfd::tests::BaseFixture
{
protected:
  DummyTransportFixture()
    : transport(nullptr)
    , sentPackets(nullptr)
    , receivedPackets(nullptr)
  {
    // Constructor does not initialize the fixture,
    // so that test case may specify different parameters to DummyTransport constructor.
  }

  void
  initialize(unique_ptr<DummyTransport> transport = make_unique<DummyTransport>())
  {
    this->face = make_unique<nfd::Face>(make_unique<DummyReceiveLinkService>(), std::move(transport));
    this->transport = static_cast<DummyTransport*>(face->getTransport());
    this->sentPackets = &this->transport->sentPackets;
    this->receivedPackets = &static_cast<DummyReceiveLinkService*>(face->getLinkService())->receivedPackets;
  }

protected:
  unique_ptr<nfd::Face> face;
  DummyTransport* transport;
  std::vector<Transport::Packet>* sentPackets;
  std::vector<Transport::Packet>* receivedPackets;
};

BOOST_FIXTURE_TEST_CASE(Send, DummyTransportFixture)
{
  this->initialize();

  Block pkt1 = ndn::encoding::makeStringBlock(300, "Lorem ipsum dolor sit amet,");
  transport->send(Transport::Packet(Block(pkt1)));

  Block pkt2 = ndn::encoding::makeStringBlock(301, "consectetur adipiscing elit,");
  transport->send(Transport::Packet(Block(pkt2)));

  transport->setState(TransportState::DOWN);
  Block pkt3 = ndn::encoding::makeStringBlock(302, "sed do eiusmod tempor incididunt ");
  transport->send(Transport::Packet(Block(pkt3)));

  transport->setState(TransportState::CLOSING);
  Block pkt4 = ndn::encoding::makeStringBlock(303, "ut labore et dolore magna aliqua.");
  transport->send(Transport::Packet(Block(pkt4)));

  BOOST_CHECK_EQUAL(transport->getCounters().nOutPackets, 2);
  BOOST_CHECK_EQUAL(transport->getCounters().nOutBytes, pkt1.size() + pkt2.size());
  BOOST_REQUIRE_EQUAL(sentPackets->size(), 3);
  BOOST_CHECK(sentPackets->at(0).packet == pkt1);
  BOOST_CHECK(sentPackets->at(1).packet == pkt2);
  BOOST_CHECK(sentPackets->at(2).packet == pkt3);
}

BOOST_FIXTURE_TEST_CASE(Receive, DummyTransportFixture)
{
  this->initialize();

  Block pkt1 = ndn::encoding::makeStringBlock(300, "Lorem ipsum dolor sit amet,");
  transport->receivePacket(pkt1);

  Block pkt2 = ndn::encoding::makeStringBlock(301, "consectetur adipiscing elit,");
  transport->receivePacket(pkt2);

  transport->setState(TransportState::DOWN);
  Block pkt3 = ndn::encoding::makeStringBlock(302, "sed do eiusmod tempor incididunt ");
  transport->receivePacket(pkt3);

  BOOST_CHECK_EQUAL(transport->getCounters().nInPackets, 3);
  BOOST_CHECK_EQUAL(transport->getCounters().nInBytes, pkt1.size() + pkt2.size() + pkt3.size());
  BOOST_REQUIRE_EQUAL(receivedPackets->size(), 3);
  BOOST_CHECK(receivedPackets->at(0).packet == pkt1);
  BOOST_CHECK(receivedPackets->at(1).packet == pkt2);
  BOOST_CHECK(receivedPackets->at(2).packet == pkt3);
}

BOOST_AUTO_TEST_SUITE_END() // TestTransport
BOOST_AUTO_TEST_SUITE_END() // Face

} // namespace tests
} // namespace face
} // namespace nfd

max_stars_repo_name: NDNLink/NDN-Chord

max_issues_repo_name: NDNLink/NDN-Chord

max_forks_repo_name: NDNLink/NDN-Chord


#ifndef _SERVERCONTROL_H_
#define _SERVERCONTROL_H_
#include <boost/filesystem.hpp>
#include <libxftp/xftpcommons.h++>
#include <unistd.h>
#include "fsutil.h++"

namespace xftp {
	class ServerControl : public ControlThread
	{
	private:
		boost::filesystem::path dir;
		FILE* file;
	public:
		typedef enum {SeekEnd = SEEK_END, SeekSet = SEEK_SET,
					  SeekCur = SEEK_CUR} SeekType;

		void Open(boost::filesystem::path &path) throw(OpenError, AlreadyOpened);
		size_t Read(char *buffer, size_t size) throw(ReadError, NotReady);
		void Write(char *buffer, size_t size) throw(WriteError, NotReady);
		void Seek(int pos, SeekType type = SeekSet) throw(SeekError, NotReady);
		int GetPos() throw(NotReady);
		void Close() throw(CloseError, NotReady);

		const std::string& GetDir();
		void SetDir(boost::filesystem::path& newdir) throw(OpenDirError);
		void ChDir(boost::filesystem::path& newdir) throw(OpenDirError);
		void ValidateDir(boost::filesystem::path& newdir)
			throw(OpenDirError);

		bool loggedIn;

		ServerControl(ClientBase& client,
					  streamcon::Stream& _stream) :
			ControlThread(client, _stream),file(NULL)
			{
				char * d = get_current_dir_name();
				dir=boost::filesystem::path(d);
				free(d);
			};
		virtual ~ServerControl() {
			if(file) {
				fclose(file);
			}
		}
	};
}

#endif // _SERVERCONTROL_H_


text:
/*
        This file is part of cpp-ethereum.

        cpp-ethereum is free software: you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.

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

        You should have received a copy of the GNU General Public License
        along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file FileSystem.cpp
 * @authors
 *	 Eric Lombrozo <elombrozo@gmail.com>
 *	 Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "FileSystem.h"
#include "Common.h"
#include "Log.h"

#if defined(_WIN32)
#include <shlobj.h>
#else
#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
#include <unistd.h>
#endif
#include <boost/filesystem.hpp>
using namespace std;
using namespace dev;

std::string dev::getDataDir(std::string _prefix)
{
	if (_prefix.empty())
		_prefix = "ethereum";
#ifdef _WIN32
	_prefix[0] = toupper(_prefix[0]);
	char path[1024] = "";
	if (SHGetSpecialFolderPathA(NULL, path, CSIDL_APPDATA, true))
		return (boost::filesystem::path(path) / _prefix).string();
	else
	{
	#ifndef _MSC_VER // todo?
		cwarn << "getDataDir(): SHGetSpecialFolderPathA() failed.";
	#endif
		BOOST_THROW_EXCEPTION(std::runtime_error("getDataDir() - SHGetSpecialFolderPathA() failed."));
	}
#else
	boost::filesystem::path dataDirPath;
	char const* homeDir = getenv("HOME");
	if (!homeDir || strlen(homeDir) == 0)
	{
		struct passwd* pwd = getpwuid(getuid());
		if (pwd)
			homeDir = pwd->pw_dir;
	}

	if (!homeDir || strlen(homeDir) == 0)
		dataDirPath = boost::filesystem::path("/");
	else
		dataDirPath = boost::filesystem::path(homeDir);

	return (dataDirPath / ("." + _prefix)).string();
#endif
}


text:
#include "matrixIO.hpp"
#include <Eigen/Dense>
#include <fstream>
#include <iostream>
#include <vector>

using namespace std;
using namespace Eigen;

namespace matrixIO {

void saveData(const string &fileName, const MatrixXd &matrix)
{
  // see https://eigen.tuxfamily.org/dox/structEigen_1_1IOFormat.html
  const static IOFormat CSVFormat(FullPrecision, DontAlignCols, ", ", "\n");

  ofstream file(fileName);
  if (file.is_open()) {
    file << matrix.format(CSVFormat);
    file.close();
  }
}

MatrixXd openData(const string &fileToOpen, const int matrixSize)
{
  ifstream matrixDataFile(fileToOpen);

  // one row of the matrix as a string with comma-separated values
  string matrixRowString;

  // a single matrix entry as a string
  string matrixEntry;

  // matrix entries row by row
  vector<double> matrixEntries;

  int matrixRowNumber = 0;
  int matrixColNumber = 0;

  // read matrixDataFile row by row
  while (getline(matrixDataFile, matrixRowString)) {
    // convert matrixRowString to a stream
    stringstream matrixRowStringStream(matrixRowString);

    // read matrixRowStringStream entry by entry
    while (getline(matrixRowStringStream, matrixEntry, ',')) {
      matrixEntries.push_back(stod(matrixEntry));
      ++matrixColNumber;
    }
    if (matrixColNumber != matrixSize) {
      throw std::runtime_error("The matrix stored in \"" + fileToOpen +
                               "\" has " + std::to_string(matrixColNumber) +
                               " columns, while the specified matrix size is " +
                               std::to_string(matrixSize));
    }
    matrixColNumber = 0;
    ++matrixRowNumber;
  }

  if (matrixRowNumber != matrixSize) {
    throw std::runtime_error("The matrix stored in \"" + fileToOpen +
                             "\" has " + std::to_string(matrixRowNumber) +
                             " rows, while the specified matrix size is " +
                             std::to_string(matrixSize));
  }

  // convert std vector into Eigen matrix and return the matrix
  return Map<Matrix<double, Dynamic, Dynamic, RowMajor>>(
      matrixEntries.data(), matrixRowNumber,
      matrixEntries.size() / matrixRowNumber);
}

} // namespace matrixIO

max_stars_repo_name: kimkroener/testing-boost-exercise

max_issues_repo_name: kimkroener/testing-boost-exercise

max_forks_repo_name: kimkroener/testing-boost-exercise