<commit_before>// Copyright (c)2008-2011, Preferred Infrastructure Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of Preferred Infrastructure nor the names of other
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "socket.h"

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#include "../../system/syscall.h"

namespace pfi {
namespace network {
namespace mprpc {

pfi::lang::shared_ptr<dns_resolver> socket::resolver;
pfi::concurrent::r_mutex socket::resolver_m;

socket::socket() : fd(-1) { }
socket::socket(int fd) : fd(fd) { }

socket::~socket()
{
  close();
}

bool socket::close()
{
  if(fd < 0) { return false; }

  int ret;
  ::shutdown(fd, SHUT_RDWR);
  NO_INTR(ret,::close(fd));

  if (FAILED(ret)){
    fd = -1;
    return false;
  }

  fd = -1;
  return true;
}

bool socket::connect(const std::string& host, uint16_t port)
{
  int nfd = connect_sock(host, port);
  if(nfd < 0) {
    return false;
  }
  close();
  fd = nfd;
  return true;
}

bool socket::listen(uint16_t port, int backlog)
{
  int nfd = listen_sock(port, backlog);
  if(nfd < 0) {
    return false;
  }
  close();
  fd = nfd;
  return true;
}

std::vector<ipv4_address> socket::resolve(const std::string& host, uint16_t port)
{
  pfi::lang::shared_ptr<dns_resolver> res;
  {
    pfi::concurrent::scoped_lock lock(resolver_m);
    if (lock) {
      if (!resolver) {
        resolver.reset( new normal_dns_resolver() );
      }
      res = resolver;
    }
  }
  return res->resolve(host, port);
}

int socket::connect_sock(const std::string& host, uint16_t port)
{
  int sock;
  NO_INTR(sock, ::socket(PF_INET, SOCK_STREAM, 0));
  if (FAILED(sock)){
    return -1;
  }

  int res;

  std::vector<ipv4_address> ips = resolve(host, port);
  for (int i=0; i < (int)ips.size(); i++){
    sockaddr_in addrin={};
    addrin.sin_family = PF_INET;
    addrin.sin_addr.s_addr = inet_addr(ips[i].to_string().c_str());
    addrin.sin_port = htons(port);

    NO_INTR(res,::connect(sock,(sockaddr*)&addrin,sizeof(addrin)));
    if (SUCCEEDED(res)) {
      return sock;
    }
  }

  NO_INTR(res, ::close(sock));
  return -1;
}

int socket::listen_sock(uint16_t port, int backlog)
{
  int res;
  int sock;

  NO_INTR(sock, ::socket(PF_INET, SOCK_STREAM, 0));
  if (FAILED(sock)) {
    return -1;
  }

  int yes = 1;
  NO_INTR(res, ::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
        (const char*)&yes, sizeof(yes)));

  if (FAILED(res)){
    NO_INTR(res, ::close(sock));
    return -1;
  }

  sockaddr_in saddr = {};
  saddr.sin_family = PF_INET;
  saddr.sin_addr.s_addr = htonl(INADDR_ANY);
  saddr.sin_port = htons(port);

  NO_INTR(res, ::bind(sock, (sockaddr*)&saddr, sizeof(saddr)));
  if (FAILED(res)){
    NO_INTR(res, ::close(sock));
    return -1;
  }

  linger ling={0,0};
  NO_INTR(res, ::setsockopt(sock, SOL_SOCKET, SO_LINGER,
        &ling, sizeof(ling)));
  if (FAILED(res)){
    NO_INTR(res, ::close(sock));
    return -1;
  }

  NO_INTR(res, ::listen(sock, backlog));
  if (FAILED(res)){
    NO_INTR(res, ::close(sock));
    return -1;
  }

  return sock;
}

bool socket::set_nodelay(bool on)
{
  return set_nodelay_sock(fd, on);
}

bool socket::set_nodelay_sock(int sock, bool on)
{
  if(sock < 0) { return false; }
#ifdef __linux__
  int n=on?1:0;
  int res;
  NO_INTR(res,setsockopt(sock,SOL_TCP,TCP_NODELAY,&n,sizeof(n)));
  if (FAILED(res)) return false;
  NO_INTR(res,setsockopt(sock,SOL_SOCKET,TCP_DEFER_ACCEPT,&n,sizeof(n)));
  return SUCCEEDED(res);
#else
  return true;
#endif
}

bool socket::set_timeout(double sec)
{
  return set_timeout_sock(fd, sec);
}

bool socket::set_recv_timeout(double sec)
{
  return set_recv_timeout_sock(fd, sec);
}

bool socket::set_send_timeout(double sec)
{
  return set_send_timeout_sock(fd, sec);
}

bool socket::set_timeout_sock(int sock, double sec)
{
  return set_recv_timeout_sock(sock, sec) &&
    set_send_timeout_sock(sock, sec);
}

bool socket::set_recv_timeout_sock(int sock, double sec)
{
  return set_timeout_sockopt(sock, SO_RCVTIMEO, sec);
}

bool socket::set_send_timeout_sock(int sock, double sec)
{
  return set_timeout_sockopt(sock, SO_SNDTIMEO, sec);
}

bool socket::set_timeout_sockopt(int sock, int optname, double sec)
{
  if(sock < 0) { return false; }

  if (sec < 0) {
    sec = 0.0;
  }
  timeval tv;
  tv.tv_sec = std::max(0,(int)sec);
  tv.tv_usec = std::min(999999, std::max(0,(int)((sec-tv.tv_sec)*1e6)));

  int res;
  NO_INTR(res,setsockopt(sock,SOL_SOCKET,optname,&tv,sizeof(tv)));
  return SUCCEEDED(res);
}

}  // namespace mprpc
}  // namespace network
}  // namespace pfi

<commit_msg>Revert "Fixed pfi::network::mprpc::socket to adjust timeout to 0 when it is negative number"<commit_after>// Copyright (c)2008-2011, Preferred Infrastructure Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of Preferred Infrastructure nor the names of other
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "socket.h"

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#include "../../system/syscall.h"

namespace pfi {
namespace network {
namespace mprpc {

pfi::lang::shared_ptr<dns_resolver> socket::resolver;
pfi::concurrent::r_mutex socket::resolver_m;

socket::socket() : fd(-1) { }
socket::socket(int fd) : fd(fd) { }

socket::~socket()
{
  close();
}

bool socket::close()
{
  if(fd < 0) { return false; }

  int ret;
  ::shutdown(fd, SHUT_RDWR);
  NO_INTR(ret,::close(fd));

  if (FAILED(ret)){
    fd = -1;
    return false;
  }

  fd = -1;
  return true;
}

bool socket::connect(const std::string& host, uint16_t port)
{
  int nfd = connect_sock(host, port);
  if(nfd < 0) {
    return false;
  }
  close();
  fd = nfd;
  return true;
}

bool socket::listen(uint16_t port, int backlog)
{
  int nfd = listen_sock(port, backlog);
  if(nfd < 0) {
    return false;
  }
  close();
  fd = nfd;
  return true;
}

std::vector<ipv4_address> socket::resolve(const std::string& host, uint16_t port)
{
  pfi::lang::shared_ptr<dns_resolver> res;
  {
    pfi::concurrent::scoped_lock lock(resolver_m);
    if (lock) {
      if (!resolver) {
        resolver.reset( new normal_dns_resolver() );
      }
      res = resolver;
    }
  }
  return res->resolve(host, port);
}

int socket::connect_sock(const std::string& host, uint16_t port)
{
  int sock;
  NO_INTR(sock, ::socket(PF_INET, SOCK_STREAM, 0));
  if (FAILED(sock)){
    return -1;
  }

  int res;

  std::vector<ipv4_address> ips = resolve(host, port);
  for (int i=0; i < (int)ips.size(); i++){
    sockaddr_in addrin={};
    addrin.sin_family = PF_INET;
    addrin.sin_addr.s_addr = inet_addr(ips[i].to_string().c_str());
    addrin.sin_port = htons(port);

    NO_INTR(res,::connect(sock,(sockaddr*)&addrin,sizeof(addrin)));
    if (SUCCEEDED(res)) {
      return sock;
    }
  }

  NO_INTR(res, ::close(sock));
  return -1;
}

int socket::listen_sock(uint16_t port, int backlog)
{
  int res;
  int sock;

  NO_INTR(sock, ::socket(PF_INET, SOCK_STREAM, 0));
  if (FAILED(sock)) {
    return -1;
  }

  int yes = 1;
  NO_INTR(res, ::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
        (const char*)&yes, sizeof(yes)));

  if (FAILED(res)){
    NO_INTR(res, ::close(sock));
    return -1;
  }

  sockaddr_in saddr = {};
  saddr.sin_family = PF_INET;
  saddr.sin_addr.s_addr = htonl(INADDR_ANY);
  saddr.sin_port = htons(port);

  NO_INTR(res, ::bind(sock, (sockaddr*)&saddr, sizeof(saddr)));
  if (FAILED(res)){
    NO_INTR(res, ::close(sock));
    return -1;
  }

  linger ling={0,0};
  NO_INTR(res, ::setsockopt(sock, SOL_SOCKET, SO_LINGER,
        &ling, sizeof(ling)));
  if (FAILED(res)){
    NO_INTR(res, ::close(sock));
    return -1;
  }

  NO_INTR(res, ::listen(sock, backlog));
  if (FAILED(res)){
    NO_INTR(res, ::close(sock));
    return -1;
  }

  return sock;
}

bool socket::set_nodelay(bool on)
{
  return set_nodelay_sock(fd, on);
}

bool socket::set_nodelay_sock(int sock, bool on)
{
  if(sock < 0) { return false; }
#ifdef __linux__
  int n=on?1:0;
  int res;
  NO_INTR(res,setsockopt(sock,SOL_TCP,TCP_NODELAY,&n,sizeof(n)));
  if (FAILED(res)) return false;
  NO_INTR(res,setsockopt(sock,SOL_SOCKET,TCP_DEFER_ACCEPT,&n,sizeof(n)));
  return SUCCEEDED(res);
#else
  return true;
#endif
}

bool socket::set_timeout(double sec)
{
  return set_timeout_sock(fd, sec);
}

bool socket::set_recv_timeout(double sec)
{
  return set_recv_timeout_sock(fd, sec);
}

bool socket::set_send_timeout(double sec)
{
  return set_send_timeout_sock(fd, sec);
}

bool socket::set_timeout_sock(int sock, double sec)
{
  return set_recv_timeout_sock(sock, sec) &&
    set_send_timeout_sock(sock, sec);
}

bool socket::set_recv_timeout_sock(int sock, double sec)
{
  return set_timeout_sockopt(sock, SO_RCVTIMEO, sec);
}

bool socket::set_send_timeout_sock(int sock, double sec)
{
  return set_timeout_sockopt(sock, SO_SNDTIMEO, sec);
}

bool socket::set_timeout_sockopt(int sock, int optname, double sec)
{
  if(sock < 0) { return false; }

  timeval tv;
  tv.tv_sec = std::max(0,(int)sec);
  tv.tv_usec = std::min(999999, std::max(0,(int)((sec-tv.tv_sec)*1e6)));

  int res;
  NO_INTR(res,setsockopt(sock,SOL_SOCKET,optname,&tv,sizeof(tv)));
  return SUCCEEDED(res);
}

}  // namespace mprpc
}  // namespace network
}  // namespace pfi

<|endoftext|>


<commit_before>#include "opt/ssa/phi_injector.h"

#include "design/design_tool.h"
#include "design/design_util.h"
#include "iroha/i_design.h"
#include "iroha/logging.h"
#include "iroha/resource_class.h"
#include "opt/bb_set.h"
#include "opt/data_flow.h"
#include "opt/dominator_tree.h"
#include "opt/opt_util.h"

namespace iroha {
namespace opt {
namespace ssa {

PhiInjector::PhiInjector(ITable *table, DebugAnnotation *annotation)
  : table_(table), annotation_(annotation), phi_(nullptr) {
}

PhiInjector::~PhiInjector() {
}

void PhiInjector::Perform() {
  phi_ = DesignTool::GetOneResource(table_, resource::kPhi);
  tr_ = DesignUtil::FindTransitionResource(table_);
  bset_.reset(BBSet::Create(table_, false, annotation_));
  data_flow_.reset(DataFlow::Create(bset_.get(), annotation_));
  dom_tree_.reset(DominatorTree::Create(bset_.get(), annotation_));

  // Insert PHIs.
  CollectSingularRegister();
  for (IRegister *reg : table_->registers_) {
    if (reg->IsNormal()) {
      reg_phis_map_[reg] = new PerRegister;
    }
  }
  CollectOriginalDefs();
  PropagatePHIs();
  CommitPHIInsn();
}

void PhiInjector::CollectSingularRegister() {
  map<IRegister *, set<IInsn *> > define_insns;
  for (BB *bb : bset_->bbs_) {
    vector<RegDef *> reaches;
    data_flow_->GetReachDefs(bb, &reaches);
    map<IRegister *, set<IInsn *> > local_define_insns;
    // fill initial value by reaching assignments.
    for (RegDef *reg_def : reaches) {
      local_define_insns[reg_def->reg].insert(reg_def->insn);
    }
    for (IState *st : bb->states_) {
      for (auto *insn : st->insns_) {
	for (auto *ireg : insn->inputs_) {
	  set<IInsn *> &s = local_define_insns[ireg];
	  for (auto *local_insn : s) {
	    define_insns[ireg].insert(local_insn);
	  }
	}
      }
      // update write insns.
      for (IInsn *insn : st->insns_) {
	for (IRegister *oreg : insn->outputs_) {
	  // overwrite by this 1 assignment insn.
	  set<IInsn *> s;
	  s.insert(insn);
	  local_define_insns[oreg] = s;
	}
      }
    }
  }
  for (auto p : define_insns) {
    set<IInsn *> &s = p.second;
    IRegister *reg = p.first;
    if (s.size() == 1 && reg->IsNormal()) {
      singular_regs_.insert(reg);
    }
  }
}

void PhiInjector::CollectOriginalDefs() {
  for (BB *bb : bset_->bbs_) {
    vector<RegDef *> reach_defs;
    data_flow_->GetReachDefs(bb, &reach_defs);
    for (RegDef *reg_def : reach_defs) {
      if (singular_regs_.find(reg_def->reg) != singular_regs_.end()) {
	continue;
      }
      PerRegister *pr = GetPerRegister(reg_def->reg);
      pr->original_defs_.insert(reg_def);
    }
  }
}

PhiInjector::PerRegister *PhiInjector::GetPerRegister(IRegister *reg) {
  return reg_phis_map_[reg];
}

void PhiInjector::PropagatePHIs() {
  for (auto it : reg_phis_map_) {
    PerRegister *pr = it.second;
    // Setp 1. Generate PHIs from original assigns.
    for (RegDef *reg_def : pr->original_defs_) {
      PropagatePHIforBB(pr, reg_def->bb);
    }
    // Step 2. Propagete PHIs.
    int num_phis;
    do {
      num_phis = pr->phi_bbs_.size();
      for (BB *bb : pr->phi_bbs_) {
	PropagatePHIforBB(pr, bb);
      }
    } while (num_phis != pr->phi_bbs_.size());
  }
}

void PhiInjector::PropagatePHIforBB(PhiInjector::PerRegister *pr,
				     BB *bb) {
  vector<BB *> frontier;
  dom_tree_->GetFrontier(bb, &frontier);
  for (BB *bb : frontier) {
    pr->phi_bbs_.insert(bb);
  }
}

void PhiInjector::CommitPHIInsn() {
  // Allocate states for new PHI insns.
  set<BB *> bbs_with_phi;
  for (auto it : reg_phis_map_) {
    PerRegister *pr = it.second;
    for (BB *bb : pr->phi_bbs_) {
      bbs_with_phi.insert(bb);
    }
  }
  for (BB *bb : bbs_with_phi) {
    PrependState(bb);
  }
  // Order regs in reg_phis_map_
  map<int, IRegister *> id_to_reg;
  for (auto it : reg_phis_map_) {
    IRegister *ireg = it.first;
    id_to_reg[ireg->GetId()] = ireg;
  }
  // Allocate insns.
  for (auto it : id_to_reg) {
    IRegister *reg = it.second;
    PerRegister *pr = reg_phis_map_[reg];
    for (BB *bb : pr->phi_bbs_) {
      IInsn *insn = new IInsn(phi_);
      insn->outputs_.push_back(reg);
      bb->states_[0]->insns_.push_back(insn);
    }
  }
}

void PhiInjector::PrependState(BB *bb) {
  IState *head_st = bb->states_[0];
  ITable *tab = head_st->GetTable();
  // Finds the iterator *belongs to the table*
  auto it = tab->states_.begin();
  for (; it != tab->states_.end(); ++it) {
    if (*it == head_st) {
      break;
    }
  }
  CHECK(it != tab->states_.end());
  // vector.insert inserts before the iterator.
  ++it;
  IState *second_st = new IState(tab);
  tab->states_.insert(it, second_st);
  // Updates transitions.
  IInsn *head_tr_insn = DesignUtil::GetTransitionInsn(head_st);
  if (bb->states_.size() == 1) {
    if (head_tr_insn->target_states_.size() > 0) {
      IInsn *second_tr_insn = DesignUtil::GetTransitionInsn(second_st);
      second_tr_insn->target_states_ = head_tr_insn->target_states_;
    }
    head_tr_insn->target_states_.clear();
    DesignTool::AddNextState(head_st, second_st);
  } else {
    // head=states_[0]
    // second.
    // states_[1]
    for (auto jt = head_tr_insn->target_states_.begin();
	 jt != head_tr_insn->target_states_.end(); ++jt) {
      if ((*jt) == bb->states_[1]) {
	*jt = second_st;
      }
    }
    DesignTool::AddNextState(second_st, bb->states_[1]);
  }
  // Move insns.
  bool again = true;
  while (again) {
    again = false;
    for (IInsn *insn : head_st->insns_) {
      if (insn->GetResource() != tr_) {
	again = true;
	DesignTool::MoveInsn(insn, head_st, second_st);
	break;
      }
    }
  }
}

}  // namespace ssa
}  // namespace opt
}  // namespace iroha
<commit_msg>Fix to copy transition conditions.<commit_after>#include "opt/ssa/phi_injector.h"

#include "design/design_tool.h"
#include "design/design_util.h"
#include "iroha/i_design.h"
#include "iroha/logging.h"
#include "iroha/resource_class.h"
#include "opt/bb_set.h"
#include "opt/data_flow.h"
#include "opt/dominator_tree.h"
#include "opt/opt_util.h"

namespace iroha {
namespace opt {
namespace ssa {

PhiInjector::PhiInjector(ITable *table, DebugAnnotation *annotation)
  : table_(table), annotation_(annotation), phi_(nullptr) {
}

PhiInjector::~PhiInjector() {
}

void PhiInjector::Perform() {
  phi_ = DesignTool::GetOneResource(table_, resource::kPhi);
  tr_ = DesignUtil::FindTransitionResource(table_);
  bset_.reset(BBSet::Create(table_, false, annotation_));
  data_flow_.reset(DataFlow::Create(bset_.get(), annotation_));
  dom_tree_.reset(DominatorTree::Create(bset_.get(), annotation_));

  // Insert PHIs.
  CollectSingularRegister();
  for (IRegister *reg : table_->registers_) {
    if (reg->IsNormal()) {
      reg_phis_map_[reg] = new PerRegister;
    }
  }
  CollectOriginalDefs();
  PropagatePHIs();
  CommitPHIInsn();
}

void PhiInjector::CollectSingularRegister() {
  map<IRegister *, set<IInsn *> > define_insns;
  for (BB *bb : bset_->bbs_) {
    vector<RegDef *> reaches;
    data_flow_->GetReachDefs(bb, &reaches);
    map<IRegister *, set<IInsn *> > local_define_insns;
    // fill initial value by reaching assignments.
    for (RegDef *reg_def : reaches) {
      local_define_insns[reg_def->reg].insert(reg_def->insn);
    }
    for (IState *st : bb->states_) {
      for (auto *insn : st->insns_) {
	for (auto *ireg : insn->inputs_) {
	  set<IInsn *> &s = local_define_insns[ireg];
	  for (auto *local_insn : s) {
	    define_insns[ireg].insert(local_insn);
	  }
	}
      }
      // update write insns.
      for (IInsn *insn : st->insns_) {
	for (IRegister *oreg : insn->outputs_) {
	  // overwrite by this 1 assignment insn.
	  set<IInsn *> s;
	  s.insert(insn);
	  local_define_insns[oreg] = s;
	}
      }
    }
  }
  for (auto p : define_insns) {
    set<IInsn *> &s = p.second;
    IRegister *reg = p.first;
    if (s.size() == 1 && reg->IsNormal()) {
      singular_regs_.insert(reg);
    }
  }
}

void PhiInjector::CollectOriginalDefs() {
  for (BB *bb : bset_->bbs_) {
    vector<RegDef *> reach_defs;
    data_flow_->GetReachDefs(bb, &reach_defs);
    for (RegDef *reg_def : reach_defs) {
      if (singular_regs_.find(reg_def->reg) != singular_regs_.end()) {
	continue;
      }
      PerRegister *pr = GetPerRegister(reg_def->reg);
      pr->original_defs_.insert(reg_def);
    }
  }
}

PhiInjector::PerRegister *PhiInjector::GetPerRegister(IRegister *reg) {
  return reg_phis_map_[reg];
}

void PhiInjector::PropagatePHIs() {
  for (auto it : reg_phis_map_) {
    PerRegister *pr = it.second;
    // Setp 1. Generate PHIs from original assigns.
    for (RegDef *reg_def : pr->original_defs_) {
      PropagatePHIforBB(pr, reg_def->bb);
    }
    // Step 2. Propagete PHIs.
    int num_phis;
    do {
      num_phis = pr->phi_bbs_.size();
      for (BB *bb : pr->phi_bbs_) {
	PropagatePHIforBB(pr, bb);
      }
    } while (num_phis != pr->phi_bbs_.size());
  }
}

void PhiInjector::PropagatePHIforBB(PhiInjector::PerRegister *pr,
				     BB *bb) {
  vector<BB *> frontier;
  dom_tree_->GetFrontier(bb, &frontier);
  for (BB *bb : frontier) {
    pr->phi_bbs_.insert(bb);
  }
}

void PhiInjector::CommitPHIInsn() {
  // Allocate states for new PHI insns.
  set<BB *> bbs_with_phi;
  for (auto it : reg_phis_map_) {
    PerRegister *pr = it.second;
    for (BB *bb : pr->phi_bbs_) {
      bbs_with_phi.insert(bb);
    }
  }
  for (BB *bb : bbs_with_phi) {
    PrependState(bb);
  }
  // Order regs in reg_phis_map_
  map<int, IRegister *> id_to_reg;
  for (auto it : reg_phis_map_) {
    IRegister *ireg = it.first;
    id_to_reg[ireg->GetId()] = ireg;
  }
  // Allocate insns.
  for (auto it : id_to_reg) {
    IRegister *reg = it.second;
    PerRegister *pr = reg_phis_map_[reg];
    for (BB *bb : pr->phi_bbs_) {
      IInsn *insn = new IInsn(phi_);
      insn->outputs_.push_back(reg);
      bb->states_[0]->insns_.push_back(insn);
    }
  }
}

void PhiInjector::PrependState(BB *bb) {
  IState *head_st = bb->states_[0];
  ITable *tab = head_st->GetTable();
  // Finds the iterator *belongs to the table*
  auto it = tab->states_.begin();
  for (; it != tab->states_.end(); ++it) {
    if (*it == head_st) {
      break;
    }
  }
  CHECK(it != tab->states_.end());
  // vector.insert inserts before the iterator.
  ++it;
  IState *second_st = new IState(tab);
  tab->states_.insert(it, second_st);
  // Updates transitions.
  IInsn *head_tr_insn = DesignUtil::GetTransitionInsn(head_st);
  if (bb->states_.size() == 1) {
    if (head_tr_insn->target_states_.size() > 0) {
      IInsn *second_tr_insn = DesignUtil::GetTransitionInsn(second_st);
      second_tr_insn->target_states_ = head_tr_insn->target_states_;
      second_tr_insn->inputs_ = head_tr_insn->inputs_;
      head_tr_insn->inputs_.clear();
    }
    head_tr_insn->target_states_.clear();
    DesignTool::AddNextState(head_st, second_st);
  } else {
    // head=states_[0]
    // second.
    // states_[1]
    for (auto jt = head_tr_insn->target_states_.begin();
	 jt != head_tr_insn->target_states_.end(); ++jt) {
      if ((*jt) == bb->states_[1]) {
	*jt = second_st;
      }
    }
    DesignTool::AddNextState(second_st, bb->states_[1]);
  }
  // Move insns.
  bool again = true;
  while (again) {
    again = false;
    for (IInsn *insn : head_st->insns_) {
      if (insn->GetResource() != tr_) {
	again = true;
	DesignTool::MoveInsn(insn, head_st, second_st);
	break;
      }
    }
  }
}

}  // namespace ssa
}  // namespace opt
}  // namespace iroha
<|endoftext|>


<commit_before>/****************************************************************************
 *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
 *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
 *                                                                          *
 *   This library is free software; you can redistribute it and/or          *
 *   modify it under the terms of the GNU Lesser General Public             *
 *   License as published by the Free Software Foundation; either           *
 *   version 2.1 of the License, or (at your option) any later version.     *
 *                                                                          *
 *   This library 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      *
 *   Lesser General Public License for more details.                        *
 *                                                                          *
 *   You should have received a copy of the GNU General Public License      *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 ***************************************************************************/
#include "codecmodel.h"

//Qt
#include <QtCore/QDebug>
#include <QtCore/QCoreApplication>
#include <QtCore/QSortFilterProxyModel>
#include <QMimeData>

//DRing
#include <account_const.h>

//Ring
#include "account.h"
#include "dbus/configurationmanager.h"
#include "mime.h"
#include "callmodel.h"

class CodecModelPrivate : public QObject
{
   Q_OBJECT
public:
   CodecModelPrivate(CodecModel* parent);
   ///@struct CodecData store audio codec information
   struct CodecData {
      int              id        ;
      QString          name      ;
      QString          bitrate   ;
      QString          samplerate;
      QString          type      ;
   };

   //Attributes
   QList<CodecData*>      m_lCodecs  ;
   QMap<int,bool>         m_lEnabledCodecs;
   Account*               m_pAccount      ;
   QSortFilterProxyModel* m_pAudioProxy   ;
   QSortFilterProxyModel* m_pVideoProxy   ;
   QStringList            m_lMimes        ;

   //Helpers
   bool findCodec(int id);

private:
   CodecModel* q_ptr;
};

CodecModelPrivate::CodecModelPrivate(CodecModel* parent) : q_ptr(parent),
m_pAudioProxy(nullptr),m_pVideoProxy(nullptr)
{

}

///Constructor
CodecModel::CodecModel(Account* account) :
QAbstractListModel(account?(QObject*)account:(QObject*)QCoreApplication::instance()), d_ptr(new CodecModelPrivate(this))
{
   d_ptr->m_pAccount = account;
   setObjectName("CodecModel: "+(account?account->id():"Unknown"));
   d_ptr->m_lMimes << RingMimes::AUDIO_CODEC << RingMimes::VIDEO_CODEC;
}

CodecModel::~CodecModel()
{
   while (d_ptr->m_lCodecs.size()) {
      CodecModelPrivate::CodecData* c = d_ptr->m_lCodecs[0];
      d_ptr->m_lCodecs.removeAt(0);
      delete c;
   }
}

QHash<int,QByteArray> CodecModel::roleNames() const
{
   static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
   static bool initRoles = false;
   if (!initRoles) {
      initRoles = true;
      roles.insert(CodecModel::Role::ID        ,QByteArray("id"));
      roles.insert(CodecModel::Role::NAME      ,QByteArray("name"));
      roles.insert(CodecModel::Role::BITRATE   ,QByteArray("bitrate"));
      roles.insert(CodecModel::Role::SAMPLERATE,QByteArray("samplerate"));
      roles.insert(CodecModel::Role::TYPE      ,QByteArray("type"));
   }
   return roles;
}

///Model data
QVariant CodecModel::data(const QModelIndex& idx, int role) const {
   if(idx.column() == 0      && role == Qt::DisplayRole                   ) {
      return QVariant(d_ptr->m_lCodecs[idx.row()]->name);
   }
   else if(idx.column() == 0 && role == Qt::CheckStateRole                ) {
      return QVariant(d_ptr->m_lEnabledCodecs[d_ptr->m_lCodecs[idx.row()]->id] ? Qt::Checked : Qt::Unchecked);
   }
   else if (idx.column() == 0 && role == CodecModel::Role::NAME       ) {
      return d_ptr->m_lCodecs[idx.row()]->name;
   }
   else if (idx.column() == 0 && role == CodecModel::Role::BITRATE    ) {
      return d_ptr->m_lCodecs[idx.row()]->bitrate;
   }
   else if (idx.column() == 0 && role == CodecModel::Role::SAMPLERATE ) {
      return d_ptr->m_lCodecs[idx.row()]->samplerate;
   }
   else if (idx.column() == 0 && role == CodecModel::Role::ID         ) {
      return d_ptr->m_lCodecs[idx.row()]->id;
   }
   else if (idx.column() == 0 && role == CodecModel::Role::TYPE         ) {
      return d_ptr->m_lCodecs[idx.row()]->type;
   }
   return QVariant();
}

///Number of audio codecs
int CodecModel::rowCount(const QModelIndex& par) const {
   Q_UNUSED(par)
   return d_ptr->m_lCodecs.size();
}

///Model flags
Qt::ItemFlags CodecModel::flags(const QModelIndex& idx) const {
   if (idx.column() == 0)
      return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable
                                            | Qt::ItemIsEnabled
                                            | Qt::ItemIsSelectable
                                            | Qt::ItemIsDragEnabled
                                            | Qt::ItemIsDropEnabled;
   return QAbstractItemModel::flags(idx);
}

///Set audio codec data
bool CodecModel::setData( const QModelIndex& idx, const QVariant &value, int role) {
   if (idx.column() == 0 && role == CodecModel::NAME) {
      d_ptr->m_lCodecs[idx.row()]->name = value.toString();
      emit dataChanged(idx, idx);
      return true;
   }
   else if (idx.column() == 0 && role == CodecModel::BITRATE) {
      d_ptr->m_lCodecs[idx.row()]->bitrate = value.toString();
      emit dataChanged(idx, idx);
      return true;
   }
   else if(idx.column() == 0 && role == Qt::CheckStateRole) {
      d_ptr->m_lEnabledCodecs[d_ptr->m_lCodecs[idx.row()]->id] = value.toBool();
      emit dataChanged(idx, idx);
      return true;
   }
   else if (idx.column() == 0 && role == CodecModel::SAMPLERATE) {
      d_ptr->m_lCodecs[idx.row()]->samplerate = value.toString();
      emit dataChanged(idx, idx);
      return true;
   }
   else if (idx.column() == 0 && role == CodecModel::ID) {
      d_ptr->m_lCodecs[idx.row()]->id = value.toInt();
      emit dataChanged(idx, idx);
      return true;
   }
   else if (idx.column() == 0 && role == CodecModel::TYPE) {
      d_ptr->m_lCodecs[idx.row()]->type = value.toString();
      emit dataChanged(idx, idx);
      return true;
   }
   return false;
}

///Add a new audio codec
QModelIndex CodecModel::add() {
   d_ptr->m_lCodecs << new CodecModelPrivate::CodecData;
   emit dataChanged(index(d_ptr->m_lCodecs.size()-1,0), index(d_ptr->m_lCodecs.size()-1,0));
   return index(d_ptr->m_lCodecs.size()-1,0);
}

///Remove audio codec at 'idx'
void CodecModel::remove(const QModelIndex& idx) {
   if (idx.isValid()) {
      CodecModelPrivate::CodecData* d = d_ptr->m_lCodecs[idx.row()];
      d_ptr->m_lCodecs.removeAt(idx.row());
      delete d;
      emit dataChanged(idx, index(d_ptr->m_lCodecs.size()-1,0));
   }
   else {
      qDebug() << "Failed to remove an invalid audio codec";
   }
}

///Remove everything
void CodecModel::clear()
{
   while(d_ptr->m_lCodecs.size()) {
      CodecModelPrivate::CodecData* d = d_ptr->m_lCodecs[0];
      d_ptr->m_lCodecs.removeAt(0);
      delete d;
   }
   d_ptr->m_lCodecs.clear();
   d_ptr->m_lEnabledCodecs.clear();
}

///Reload the codeclist
void CodecModel::reload()
{
   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
   QVector<uint> codecIdList = configurationManager.getCodecList();
      QVector<uint> activeCodecList = configurationManager.getActiveCodecList(d_ptr->m_pAccount->id());
      QStringList tmpNameList;

  foreach (const int aCodec, activeCodecList) {
     if (!d_ptr->findCodec(aCodec)) {

        const QMap<QString,QString> codec = configurationManager.getCodecDetails(d_ptr->m_pAccount->id(),aCodec);

        QModelIndex idx = add();
        setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::NAME        ] ,CodecModel::Role::NAME       );
        setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] ,CodecModel::Role::SAMPLERATE );
        setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::BITRATE     ] ,CodecModel::Role::BITRATE    );
        setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::TYPE        ] ,CodecModel::Role::TYPE       );
        setData(idx,QString::number(aCodec)  ,CodecModel::Role::ID         );
        setData(idx, Qt::Checked ,Qt::CheckStateRole               );

        if (codecIdList.indexOf(aCodec)!=-1)
           codecIdList.remove(codecIdList.indexOf(aCodec));
     }
  }

   foreach (const int aCodec, codecIdList) {
      if (!d_ptr->findCodec(aCodec)) {
         const QMap<QString,QString> codec = configurationManager.getCodecDetails(d_ptr->m_pAccount->id(),aCodec);
         const QModelIndex& idx = add();
         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::NAME        ] ,CodecModel::Role::NAME       );
         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] ,CodecModel::Role::SAMPLERATE );
         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::BITRATE     ] ,CodecModel::Role::BITRATE    );
         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::TYPE        ] ,CodecModel::Role::TYPE       );
         setData(idx,QString::number(aCodec)  ,CodecModel::Role::ID         );
         setData(idx, Qt::Unchecked ,Qt::CheckStateRole);
      }
   }
}

///Save details
void CodecModel::save()
{
   VectorUInt _codecList;
   for (int i = 0; i < rowCount();i++) {
      const QModelIndex& idx = index(i,0);
      if (data(idx,Qt::CheckStateRole) == Qt::Checked) {
         _codecList << data(idx,CodecModel::Role::ID).toInt();
      }
   }

   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
   configurationManager.setActiveCodecList(d_ptr->m_pAccount->id(), _codecList);
}

///Check is a codec is already in the list
bool CodecModelPrivate::findCodec(int id)
{
   foreach(const CodecData* data, m_lCodecs) {
      if (data->id == id)
         return true;
   }
   return false;
}

QSortFilterProxyModel* CodecModel::audioCodecs() const
{
    if (!d_ptr->m_pAudioProxy) {
        d_ptr->m_pAudioProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this));
        d_ptr->m_pAudioProxy->setSourceModel(const_cast<CodecModel*>(this));
        d_ptr->m_pAudioProxy->setFilterRole(CodecModel::Role::TYPE);
        d_ptr->m_pAudioProxy->setFilterFixedString("AUDIO");
    }
    return d_ptr->m_pAudioProxy;
}

QSortFilterProxyModel* CodecModel::videoCodecs() const
{
    if (!d_ptr->m_pVideoProxy) {
        d_ptr->m_pVideoProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this));
        d_ptr->m_pVideoProxy->setSourceModel(const_cast<CodecModel*>(this));
        d_ptr->m_pVideoProxy->setFilterRole(CodecModel::Role::TYPE);
        d_ptr->m_pVideoProxy->setFilterFixedString("VIDEO");
    }
    return d_ptr->m_pVideoProxy;
}

QModelIndex CodecModel::getIndexofCodecByID(int id)
{
    for (int i=0; i < rowCount();i++) {
       const QModelIndex& idx = index(i,0);
       if (data(idx, CodecModel::Role::ID) == id) {
           qDebug() << "FOUND";
          return idx;
       }
    }
    return QModelIndex();
}

// ======== DnD Api =========

///Return valid payload types
int CodecModel::acceptedPayloadTypes() const
{
   return CallModel::DropPayloadType::AUDIO_CODEC | CallModel::DropPayloadType::VIDEO_CODEC;
}

QStringList CodecModel::mimeTypes() const
{
   return d_ptr->m_lMimes;
}

bool CodecModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
{
   Q_UNUSED(action)
   if(parent.isValid() || column > 0) {
      qDebug() << "column invalid";
      return false;
   }

   if (data->hasFormat(RingMimes::AUDIO_CODEC) || data->hasFormat(RingMimes::VIDEO_CODEC)) {
      int destinationRow = -1;

      if(row < 0) {
         //drop on top
         destinationRow = d_ptr->m_lCodecs.size() - 1;
      }
      else if(row >= d_ptr->m_lCodecs.size()) {
         destinationRow = 0;
      }
      else if(data->hasFormat(RingMimes::VIDEO_CODEC) && row >= d_ptr->m_pVideoProxy->rowCount()) {
         destinationRow = 0;
      }
      else {
         destinationRow = row;
      }

      const int codecId = data->data(data->hasFormat(RingMimes::AUDIO_CODEC)
                                                    ? RingMimes::AUDIO_CODEC
                                                    : RingMimes::VIDEO_CODEC).toInt();
      const QModelIndex codecIdx = getIndexofCodecByID(codecId);

      beginRemoveRows(QModelIndex(), codecIdx.row(), codecIdx.row());
      CodecModelPrivate::CodecData* codecInfo = d_ptr->m_lCodecs[codecIdx.row()];
      d_ptr->m_lCodecs.removeAt(codecIdx.row());
      endRemoveRows();

      beginInsertRows(QModelIndex(), destinationRow, destinationRow);
      d_ptr->m_lCodecs.insert(destinationRow,codecInfo);
      endInsertRows();

      return true;
   }

   return false;
}

QMimeData* CodecModel::mimeData(const QModelIndexList& indexes) const
{
   QMimeData* mMimeData = new QMimeData();

   for (const QModelIndex& index : indexes) {
      if (index.isValid()) {
          qDebug() << "setting mime data for row: " << index.row();
         if(index.data(CodecModel::Role::TYPE).toString() == "AUDIO")
            mMimeData->setData(RingMimes::AUDIO_CODEC , index.data(CodecModel::Role::ID).toByteArray());
         else
            mMimeData->setData(RingMimes::VIDEO_CODEC , index.data(CodecModel::Role::ID).toByteArray());

      }
   }
   return mMimeData;
}

#include <codecmodel.moc>
<commit_msg>codecmodel: remove unnecessary log<commit_after>/****************************************************************************
 *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
 *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
 *                                                                          *
 *   This library is free software; you can redistribute it and/or          *
 *   modify it under the terms of the GNU Lesser General Public             *
 *   License as published by the Free Software Foundation; either           *
 *   version 2.1 of the License, or (at your option) any later version.     *
 *                                                                          *
 *   This library 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      *
 *   Lesser General Public License for more details.                        *
 *                                                                          *
 *   You should have received a copy of the GNU General Public License      *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 ***************************************************************************/
#include "codecmodel.h"

//Qt
#include <QtCore/QDebug>
#include <QtCore/QCoreApplication>
#include <QtCore/QSortFilterProxyModel>
#include <QMimeData>

//DRing
#include <account_const.h>

//Ring
#include "account.h"
#include "dbus/configurationmanager.h"
#include "mime.h"
#include "callmodel.h"

class CodecModelPrivate : public QObject
{
   Q_OBJECT
public:
   CodecModelPrivate(CodecModel* parent);
   ///@struct CodecData store audio codec information
   struct CodecData {
      int              id        ;
      QString          name      ;
      QString          bitrate   ;
      QString          samplerate;
      QString          type      ;
   };

   //Attributes
   QList<CodecData*>      m_lCodecs  ;
   QMap<int,bool>         m_lEnabledCodecs;
   Account*               m_pAccount      ;
   QSortFilterProxyModel* m_pAudioProxy   ;
   QSortFilterProxyModel* m_pVideoProxy   ;
   QStringList            m_lMimes        ;

   //Helpers
   bool findCodec(int id);

private:
   CodecModel* q_ptr;
};

CodecModelPrivate::CodecModelPrivate(CodecModel* parent) : q_ptr(parent),
m_pAudioProxy(nullptr),m_pVideoProxy(nullptr)
{

}

///Constructor
CodecModel::CodecModel(Account* account) :
QAbstractListModel(account?(QObject*)account:(QObject*)QCoreApplication::instance()), d_ptr(new CodecModelPrivate(this))
{
   d_ptr->m_pAccount = account;
   setObjectName("CodecModel: "+(account?account->id():"Unknown"));
   d_ptr->m_lMimes << RingMimes::AUDIO_CODEC << RingMimes::VIDEO_CODEC;
}

CodecModel::~CodecModel()
{
   while (d_ptr->m_lCodecs.size()) {
      CodecModelPrivate::CodecData* c = d_ptr->m_lCodecs[0];
      d_ptr->m_lCodecs.removeAt(0);
      delete c;
   }
}

QHash<int,QByteArray> CodecModel::roleNames() const
{
   static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
   static bool initRoles = false;
   if (!initRoles) {
      initRoles = true;
      roles.insert(CodecModel::Role::ID        ,QByteArray("id"));
      roles.insert(CodecModel::Role::NAME      ,QByteArray("name"));
      roles.insert(CodecModel::Role::BITRATE   ,QByteArray("bitrate"));
      roles.insert(CodecModel::Role::SAMPLERATE,QByteArray("samplerate"));
      roles.insert(CodecModel::Role::TYPE      ,QByteArray("type"));
   }
   return roles;
}

///Model data
QVariant CodecModel::data(const QModelIndex& idx, int role) const {
   if(idx.column() == 0      && role == Qt::DisplayRole                   ) {
      return QVariant(d_ptr->m_lCodecs[idx.row()]->name);
   }
   else if(idx.column() == 0 && role == Qt::CheckStateRole                ) {
      return QVariant(d_ptr->m_lEnabledCodecs[d_ptr->m_lCodecs[idx.row()]->id] ? Qt::Checked : Qt::Unchecked);
   }
   else if (idx.column() == 0 && role == CodecModel::Role::NAME       ) {
      return d_ptr->m_lCodecs[idx.row()]->name;
   }
   else if (idx.column() == 0 && role == CodecModel::Role::BITRATE    ) {
      return d_ptr->m_lCodecs[idx.row()]->bitrate;
   }
   else if (idx.column() == 0 && role == CodecModel::Role::SAMPLERATE ) {
      return d_ptr->m_lCodecs[idx.row()]->samplerate;
   }
   else if (idx.column() == 0 && role == CodecModel::Role::ID         ) {
      return d_ptr->m_lCodecs[idx.row()]->id;
   }
   else if (idx.column() == 0 && role == CodecModel::Role::TYPE         ) {
      return d_ptr->m_lCodecs[idx.row()]->type;
   }
   return QVariant();
}

///Number of audio codecs
int CodecModel::rowCount(const QModelIndex& par) const {
   Q_UNUSED(par)
   return d_ptr->m_lCodecs.size();
}

///Model flags
Qt::ItemFlags CodecModel::flags(const QModelIndex& idx) const {
   if (idx.column() == 0)
      return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable
                                            | Qt::ItemIsEnabled
                                            | Qt::ItemIsSelectable
                                            | Qt::ItemIsDragEnabled
                                            | Qt::ItemIsDropEnabled;
   return QAbstractItemModel::flags(idx);
}

///Set audio codec data
bool CodecModel::setData( const QModelIndex& idx, const QVariant &value, int role) {
   if (idx.column() == 0 && role == CodecModel::NAME) {
      d_ptr->m_lCodecs[idx.row()]->name = value.toString();
      emit dataChanged(idx, idx);
      return true;
   }
   else if (idx.column() == 0 && role == CodecModel::BITRATE) {
      d_ptr->m_lCodecs[idx.row()]->bitrate = value.toString();
      emit dataChanged(idx, idx);
      return true;
   }
   else if(idx.column() == 0 && role == Qt::CheckStateRole) {
      d_ptr->m_lEnabledCodecs[d_ptr->m_lCodecs[idx.row()]->id] = value.toBool();
      emit dataChanged(idx, idx);
      return true;
   }
   else if (idx.column() == 0 && role == CodecModel::SAMPLERATE) {
      d_ptr->m_lCodecs[idx.row()]->samplerate = value.toString();
      emit dataChanged(idx, idx);
      return true;
   }
   else if (idx.column() == 0 && role == CodecModel::ID) {
      d_ptr->m_lCodecs[idx.row()]->id = value.toInt();
      emit dataChanged(idx, idx);
      return true;
   }
   else if (idx.column() == 0 && role == CodecModel::TYPE) {
      d_ptr->m_lCodecs[idx.row()]->type = value.toString();
      emit dataChanged(idx, idx);
      return true;
   }
   return false;
}

///Add a new audio codec
QModelIndex CodecModel::add() {
   d_ptr->m_lCodecs << new CodecModelPrivate::CodecData;
   emit dataChanged(index(d_ptr->m_lCodecs.size()-1,0), index(d_ptr->m_lCodecs.size()-1,0));
   return index(d_ptr->m_lCodecs.size()-1,0);
}

///Remove audio codec at 'idx'
void CodecModel::remove(const QModelIndex& idx) {
   if (idx.isValid()) {
      CodecModelPrivate::CodecData* d = d_ptr->m_lCodecs[idx.row()];
      d_ptr->m_lCodecs.removeAt(idx.row());
      delete d;
      emit dataChanged(idx, index(d_ptr->m_lCodecs.size()-1,0));
   }
   else {
      qDebug() << "Failed to remove an invalid audio codec";
   }
}

///Remove everything
void CodecModel::clear()
{
   while(d_ptr->m_lCodecs.size()) {
      CodecModelPrivate::CodecData* d = d_ptr->m_lCodecs[0];
      d_ptr->m_lCodecs.removeAt(0);
      delete d;
   }
   d_ptr->m_lCodecs.clear();
   d_ptr->m_lEnabledCodecs.clear();
}

///Reload the codeclist
void CodecModel::reload()
{
   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
   QVector<uint> codecIdList = configurationManager.getCodecList();
      QVector<uint> activeCodecList = configurationManager.getActiveCodecList(d_ptr->m_pAccount->id());
      QStringList tmpNameList;

  foreach (const int aCodec, activeCodecList) {
     if (!d_ptr->findCodec(aCodec)) {

        const QMap<QString,QString> codec = configurationManager.getCodecDetails(d_ptr->m_pAccount->id(),aCodec);

        QModelIndex idx = add();
        setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::NAME        ] ,CodecModel::Role::NAME       );
        setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] ,CodecModel::Role::SAMPLERATE );
        setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::BITRATE     ] ,CodecModel::Role::BITRATE    );
        setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::TYPE        ] ,CodecModel::Role::TYPE       );
        setData(idx,QString::number(aCodec)  ,CodecModel::Role::ID         );
        setData(idx, Qt::Checked ,Qt::CheckStateRole               );

        if (codecIdList.indexOf(aCodec)!=-1)
           codecIdList.remove(codecIdList.indexOf(aCodec));
     }
  }

   foreach (const int aCodec, codecIdList) {
      if (!d_ptr->findCodec(aCodec)) {
         const QMap<QString,QString> codec = configurationManager.getCodecDetails(d_ptr->m_pAccount->id(),aCodec);
         const QModelIndex& idx = add();
         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::NAME        ] ,CodecModel::Role::NAME       );
         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] ,CodecModel::Role::SAMPLERATE );
         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::BITRATE     ] ,CodecModel::Role::BITRATE    );
         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::TYPE        ] ,CodecModel::Role::TYPE       );
         setData(idx,QString::number(aCodec)  ,CodecModel::Role::ID         );
         setData(idx, Qt::Unchecked ,Qt::CheckStateRole);
      }
   }
}

///Save details
void CodecModel::save()
{
   VectorUInt _codecList;
   for (int i = 0; i < rowCount();i++) {
      const QModelIndex& idx = index(i,0);
      if (data(idx,Qt::CheckStateRole) == Qt::Checked) {
         _codecList << data(idx,CodecModel::Role::ID).toInt();
      }
   }

   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
   configurationManager.setActiveCodecList(d_ptr->m_pAccount->id(), _codecList);
}

///Check is a codec is already in the list
bool CodecModelPrivate::findCodec(int id)
{
   foreach(const CodecData* data, m_lCodecs) {
      if (data->id == id)
         return true;
   }
   return false;
}

QSortFilterProxyModel* CodecModel::audioCodecs() const
{
    if (!d_ptr->m_pAudioProxy) {
        d_ptr->m_pAudioProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this));
        d_ptr->m_pAudioProxy->setSourceModel(const_cast<CodecModel*>(this));
        d_ptr->m_pAudioProxy->setFilterRole(CodecModel::Role::TYPE);
        d_ptr->m_pAudioProxy->setFilterFixedString("AUDIO");
    }
    return d_ptr->m_pAudioProxy;
}

QSortFilterProxyModel* CodecModel::videoCodecs() const
{
    if (!d_ptr->m_pVideoProxy) {
        d_ptr->m_pVideoProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this));
        d_ptr->m_pVideoProxy->setSourceModel(const_cast<CodecModel*>(this));
        d_ptr->m_pVideoProxy->setFilterRole(CodecModel::Role::TYPE);
        d_ptr->m_pVideoProxy->setFilterFixedString("VIDEO");
    }
    return d_ptr->m_pVideoProxy;
}

QModelIndex CodecModel::getIndexofCodecByID(int id)
{
    for (int i=0; i < rowCount();i++) {
       const QModelIndex& idx = index(i,0);
       if (data(idx, CodecModel::Role::ID) == id) {
          return idx;
       }
    }
    return QModelIndex();
}

// ======== DnD Api =========

///Return valid payload types
int CodecModel::acceptedPayloadTypes() const
{
   return CallModel::DropPayloadType::AUDIO_CODEC | CallModel::DropPayloadType::VIDEO_CODEC;
}

QStringList CodecModel::mimeTypes() const
{
   return d_ptr->m_lMimes;
}

bool CodecModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
{
   Q_UNUSED(action)
   if(parent.isValid() || column > 0) {
      qDebug() << "column invalid";
      return false;
   }

   if (data->hasFormat(RingMimes::AUDIO_CODEC) || data->hasFormat(RingMimes::VIDEO_CODEC)) {
      int destinationRow = -1;

      if(row < 0) {
         //drop on top
         destinationRow = d_ptr->m_lCodecs.size() - 1;
      }
      else if(row >= d_ptr->m_lCodecs.size()) {
         destinationRow = 0;
      }
      else if(data->hasFormat(RingMimes::VIDEO_CODEC) && row >= d_ptr->m_pVideoProxy->rowCount()) {
         destinationRow = 0;
      }
      else {
         destinationRow = row;
      }

      const int codecId = data->data(data->hasFormat(RingMimes::AUDIO_CODEC)
                                                    ? RingMimes::AUDIO_CODEC
                                                    : RingMimes::VIDEO_CODEC).toInt();
      const QModelIndex codecIdx = getIndexofCodecByID(codecId);

      beginRemoveRows(QModelIndex(), codecIdx.row(), codecIdx.row());
      CodecModelPrivate::CodecData* codecInfo = d_ptr->m_lCodecs[codecIdx.row()];
      d_ptr->m_lCodecs.removeAt(codecIdx.row());
      endRemoveRows();

      beginInsertRows(QModelIndex(), destinationRow, destinationRow);
      d_ptr->m_lCodecs.insert(destinationRow,codecInfo);
      endInsertRows();

      return true;
   }

   return false;
}

QMimeData* CodecModel::mimeData(const QModelIndexList& indexes) const
{
   QMimeData* mMimeData = new QMimeData();

   for (const QModelIndex& index : indexes) {
      if (index.isValid()) {
         if(index.data(CodecModel::Role::TYPE).toString() == "AUDIO")
            mMimeData->setData(RingMimes::AUDIO_CODEC , index.data(CodecModel::Role::ID).toByteArray());
         else
            mMimeData->setData(RingMimes::VIDEO_CODEC , index.data(CodecModel::Role::ID).toByteArray());

      }
   }
   return mMimeData;
}

#include <codecmodel.moc>
<|endoftext|>


<commit_before>#include <cmath>
#include <ctime>
#include <sstream>
#include "Elemental.h"
#include "ElementalLAPACKInternal.h"
using namespace std;
using namespace Elemental;
using namespace Elemental::wrappers::MPI;

void Usage()
{
    cout << "Generates SPD matrix then solves for its Cholesky factor."
         << endl << endl;
    cout << "  Chol <r> <c> <shape> <var2/3> <m> <nb> <test correctness?> "
         << "<print matrices?>" << endl << endl;
    cout << "  r: number of process rows      " << endl;
    cout << "  c: number of process cols      " << endl;
    cout << "  shape: {L,U}                   " << endl;
    cout << "  var2/3: 2 iff 0                " << endl;
    cout << "  m: height of matrix            " << endl;
    cout << "  nb: algorithmic blocksize      " << endl;
    cout << "  test correctness?: false iff 0 " << endl;
    cout << "  print matrices?: false iff 0   " << endl;
    cout << endl;
}

template<typename T>
bool OKRelativeError( T truth, T computed );

template<>
bool OKRelativeError( float truth, float computed )
{
    return ( fabs(truth-computed) / max(fabs(truth),(float)1) <= 1e-3 );
}

template<>
bool OKRelativeError( double truth, double computed )
{
    return ( fabs(truth-computed) / max(fabs(truth),(double)1) <= 1e-10 );
}

#ifndef WITHOUT_COMPLEX
template<>
bool OKRelativeError( scomplex truth, scomplex computed )
{
    return ( norm(truth-computed) / max(norm(truth),(float)1) <= 1e-3 );
}

template<>
bool OKRelativeError( dcomplex truth, dcomplex computed )
{
    return ( norm(truth-computed) / max(norm(truth),(double)1) <= 1e-10 );
}
#endif

template<typename T>
void TestCorrectness
( const Shape shape,
        DistMatrix<T,Star,Star>& A_ref,
  const DistMatrix<T,MC,MR>& A,
  const bool printMatrices                       )
{
    const Grid& grid = A.GetGrid();
    const int m = A_ref.Height();
    DistMatrix<T,Star,Star> A_copy(grid);

    if( grid.VCRank() == 0 )
    {
        cout << "  Gathering computed result...";
        cout.flush();
    }
    A_copy = A;
    if( grid.VCRank() == 0 )
        cout << "DONE" << endl;

    if( grid.VCRank() == 0 )
    {
        cout << "  Computing 'truth'...";
        cout.flush();
    }
    LAPACK::Chol( shape, A_ref.LocalMatrix() );
    if( grid.VCRank() == 0 )
        cout << "DONE" << endl;

    if( printMatrices )
        A_ref.Print("Truth");

    if( grid.VCRank() == 0 )
    {
        cout << "  Testing correctness...";
        cout.flush();
    }
    if( shape == Lower )
    {
        for( int j=0; j<m; ++j )
        {
            for( int i=j; i<m; ++i )
            {
                T truth = A_ref.LocalEntry(i,j);
                T computed = A_copy.LocalEntry(i,j);

                if( ! OKRelativeError( truth, computed ) )
                {
                    ostringstream msg;
                    msg << "FAILED at index (" << i << "," << j << "): truth="
                         << truth << ", computed=" << computed;
                    throw msg.str();
                }
            }
        }
    }
    else
    {
        for( int j=0; j<m; ++j )
        {
            for( int i=0; i<=j; ++i )
            {
                T truth = A_ref.LocalEntry(i,j);
                T computed = A_copy.LocalEntry(i,j);

                if( ! OKRelativeError( truth, computed ) )
                {
                    ostringstream msg;
                    msg << "FAILED at index (" << i << "," << j << "): truth="
                         << truth << ", computed=" << computed;
                    throw msg.str();
                }
            }
        }
    }
    Barrier( grid.VCComm() );
    if( grid.VCRank() == 0 )
        cout << "PASSED" << endl;
}

template<typename T>
void TestChol
( const Shape shape, const bool var3, const int m,
  const bool testCorrectness, const bool printMatrices, const Grid& grid )
{
    double startTime, endTime, runTime, gFlops;
    DistMatrix<T,MC,MR> A(grid);
    DistMatrix<T,MC,MR> B(grid);
    DistMatrix<T,Star,Star> A_ref(grid);

    A.ResizeTo( m, m );
    B.ResizeTo( m, m );

    // Make B diagonally dominant and triangular. If we are performing a lower
    // Cholesky factorization, make B lower, then form A := B B^T. Otherwise,
    // make B upper and form A := B^T B.
    B.SetToRandomDiagDominant();
    B.MakeTrapezoidal( Left, shape );
    if( printMatrices )
        B.Print("Triangular matrix for generating SPD matrix:");
    if( grid.VCRank() == 0 )
    {
        cout << "  Generating SPD matrix...";
        cout.flush();
    }
    if( shape == Lower )
        BLAS::Gemm( Normal, Transpose, (T)1, B, B, (T)0, A );
    else
        BLAS::Gemm( Transpose, Normal, (T)1, B, B, (T)0, A );
    if( grid.VCRank() == 0 )
        cout << "DONE" << endl;
    if( testCorrectness )
    {
        if( grid.VCRank() == 0 )
        {
            cout << "  Making copy of original matrix...";
            cout.flush();
        }
        A_ref = A;
        if( grid.VCRank() == 0 )
            cout << "DONE" << endl;
    }
    if( printMatrices )
    {
        A.Print("A");
    }

    if( grid.VCRank() == 0 )
    {
        cout << "  Starting Cholesky factorization...";
        cout.flush();
    }
    Barrier( MPI_COMM_WORLD );
    startTime = Time();
    if( var3 )
        LAPACK::Internal::CholVar3( shape, A );
    else
        LAPACK::Internal::CholVar2( shape, A );
    Barrier( MPI_COMM_WORLD );
    endTime = Time();
    runTime = endTime - startTime;
    gFlops = LAPACK::Internal::CholGFlops<T>( m, runTime );
    if( grid.VCRank() == 0 )
        cout << "DONE. GFlops = " << gFlops << endl;
    if( printMatrices )
    {
        A.Print("A after factorization");
    }
    if( testCorrectness )
    {
        TestCorrectness( shape, A_ref, A, printMatrices );
    }
}

int main( int argc, char* argv[] )
{
    int rank;
    Elemental::Init( &argc, &argv );
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    if( argc != 9 )
    {
        if( rank == 0 )
            Usage();
        Elemental::Finalize();
        return 0;
    }
    try
    {
        const int   r = atoi( argv[1] );
        const int   c = atoi( argv[2] );
        const Shape shape = CharToShape( *argv[3] );
        const bool  var3 = ( atoi(argv[4]) != 0 );
        const int   m = atoi( argv[5] );
        const int   nb = atoi( argv[6] );
        const bool  testCorrectness = atoi( argv[7] );
        const bool  printMatrices = atoi( argv[8] );
#ifndef RELEASE
        if( rank == 0 )
        {
            cout << "==========================================" << endl;
            cout << " In debug mode! Performance will be poor! " << endl;
            cout << "==========================================" << endl;
        }
#endif
        Grid grid( MPI_COMM_WORLD, r, c );
        SetBlocksize( nb );

        if( rank == 0 )
            cout << "Will test Chol" << ShapeToChar(shape) << ", Var"
                 << ( var3 ? "3" : "2" ) << endl;

        if( m<=200 )
        {
            if( rank == 0 )
            {
                cout << "--------------------" << endl;
                cout << "Testing with floats:" << endl;
                cout << "--------------------" << endl;
            }
            TestChol<float>
            ( shape, var3, m, testCorrectness, printMatrices, grid );
            if( rank == 0 )
                cout << endl;
        }
        else
        {
            if( rank == 0 )
            {
                cout << "--------------------------------" << endl;
                cout << "Floats unsuitable for this test." << endl;
                cout << "--------------------------------" << endl;
                cout << endl;
            }
        }

        if( rank == 0 )
        {
            cout << "---------------------" << endl;
            cout << "Testing with doubles:" << endl;
            cout << "---------------------" << endl;
        }
        TestChol<double>
        ( shape, var3, m, testCorrectness, printMatrices, grid );
        if( rank == 0 )
            cout << endl;

#ifndef WITHOUT_COMPLEX
        if( m <= 200 )
        {
            if( rank == 0 )
            {
                cout << "--------------------------------------" << endl;
                cout << "Testing with single-precision complex:" << endl;
                cout << "--------------------------------------" << endl;
            }
            TestChol<scomplex>
            ( shape, var3, m, testCorrectness, printMatrices, grid );
            if( rank == 0 )
                cout << endl;
        }
        else
        {
            if( rank == 0 )
            {
                cout << "----------------------------------------" << endl;
                cout << "Complex floats unsuitable for this test." << endl;
                cout << "----------------------------------------" << endl;
                cout << endl;
            }
        }

        if( rank == 0 )
        {
            cout << "--------------------------------------" << endl;
            cout << "Testing with double-precision complex:" << endl;
            cout << "--------------------------------------" << endl;
        }
        TestChol<dcomplex>
        ( shape, var3, m, testCorrectness, printMatrices, grid );
        if( rank == 0 )
            cout << endl;
#endif
    }
    catch( string errorMsg )
    {
#ifndef RELEASE
        DumpCallStack();
#endif
        cerr << "Process " << rank << " caught error message:" << endl
             << errorMsg << endl;
    }
    Elemental::Finalize();
    return 0;
}

<commit_msg>Modified Cholesky driver to avoid performing a gemm to form the SPD matrix. By instead creating it as diagonally dominant (and therefore positive definite) we can make the symmetry implicit.<commit_after>#include <cmath>
#include <ctime>
#include <sstream>
#include "Elemental.h"
#include "ElementalLAPACKInternal.h"
using namespace std;
using namespace Elemental;
using namespace Elemental::wrappers::MPI;

void Usage()
{
    cout << "Generates SPD matrix then solves for its Cholesky factor."
         << endl << endl;
    cout << "  Chol <r> <c> <shape> <var2/3> <m> <nb> <test correctness?> "
         << "<print matrices?>" << endl << endl;
    cout << "  r: number of process rows      " << endl;
    cout << "  c: number of process cols      " << endl;
    cout << "  shape: {L,U}                   " << endl;
    cout << "  var2/3: 2 iff 0                " << endl;
    cout << "  m: height of matrix            " << endl;
    cout << "  nb: algorithmic blocksize      " << endl;
    cout << "  test correctness?: false iff 0 " << endl;
    cout << "  print matrices?: false iff 0   " << endl;
    cout << endl;
}

template<typename T>
bool OKRelativeError( T truth, T computed );

template<>
bool OKRelativeError( float truth, float computed )
{
    return ( fabs(truth-computed) / max(fabs(truth),(float)1) <= 1e-3 );
}

template<>
bool OKRelativeError( double truth, double computed )
{
    return ( fabs(truth-computed) / max(fabs(truth),(double)1) <= 1e-10 );
}

#ifndef WITHOUT_COMPLEX
template<>
bool OKRelativeError( scomplex truth, scomplex computed )
{
    return ( norm(truth-computed) / max(norm(truth),(float)1) <= 1e-3 );
}

template<>
bool OKRelativeError( dcomplex truth, dcomplex computed )
{
    return ( norm(truth-computed) / max(norm(truth),(double)1) <= 1e-10 );
}
#endif

template<typename T>
void TestCorrectness
( const Shape shape,
        DistMatrix<T,Star,Star>& A_ref,
  const DistMatrix<T,MC,MR>& A,
  const bool printMatrices                       )
{
    const Grid& grid = A.GetGrid();
    const int m = A_ref.Height();
    DistMatrix<T,Star,Star> A_copy(grid);

    if( grid.VCRank() == 0 )
    {
        cout << "  Gathering computed result...";
        cout.flush();
    }
    A_copy = A;
    if( grid.VCRank() == 0 )
        cout << "DONE" << endl;

    if( grid.VCRank() == 0 )
    {
        cout << "  Computing 'truth'...";
        cout.flush();
    }
    LAPACK::Chol( shape, A_ref.LocalMatrix() );
    if( grid.VCRank() == 0 )
        cout << "DONE" << endl;

    if( printMatrices )
        A_ref.Print("Truth");

    if( grid.VCRank() == 0 )
    {
        cout << "  Testing correctness...";
        cout.flush();
    }
    if( shape == Lower )
    {
        for( int j=0; j<m; ++j )
        {
            for( int i=j; i<m; ++i )
            {
                T truth = A_ref.LocalEntry(i,j);
                T computed = A_copy.LocalEntry(i,j);

                if( ! OKRelativeError( truth, computed ) )
                {
                    ostringstream msg;
                    msg << "FAILED at index (" << i << "," << j << "): truth="
                         << truth << ", computed=" << computed;
                    throw msg.str();
                }
            }
        }
    }
    else
    {
        for( int j=0; j<m; ++j )
        {
            for( int i=0; i<=j; ++i )
            {
                T truth = A_ref.LocalEntry(i,j);
                T computed = A_copy.LocalEntry(i,j);

                if( ! OKRelativeError( truth, computed ) )
                {
                    ostringstream msg;
                    msg << "FAILED at index (" << i << "," << j << "): truth="
                         << truth << ", computed=" << computed;
                    throw msg.str();
                }
            }
        }
    }
    Barrier( grid.VCComm() );
    if( grid.VCRank() == 0 )
        cout << "PASSED" << endl;
}

template<typename T>
void TestChol
( const Shape shape, const bool var3, const int m,
  const bool testCorrectness, const bool printMatrices, const Grid& grid )
{
    double startTime, endTime, runTime, gFlops;
    DistMatrix<T,MC,MR> A(grid);
    DistMatrix<T,Star,Star> A_ref(grid);

    A.ResizeTo( m, m );

    A.SetToRandomDiagDominant();
    if( testCorrectness )
    {
        if( grid.VCRank() == 0 )
        {
            cout << "  Making copy of original matrix...";
            cout.flush();
        }
        A_ref = A;
        if( grid.VCRank() == 0 )
            cout << "DONE" << endl;
    }
    if( printMatrices )
    {
        A.Print("A");
    }

    if( grid.VCRank() == 0 )
    {
        cout << "  Starting Cholesky factorization...";
        cout.flush();
    }
    Barrier( MPI_COMM_WORLD );
    startTime = Time();
    if( var3 )
        LAPACK::Internal::CholVar3( shape, A );
    else
        LAPACK::Internal::CholVar2( shape, A );
    Barrier( MPI_COMM_WORLD );
    endTime = Time();
    runTime = endTime - startTime;
    gFlops = LAPACK::Internal::CholGFlops<T>( m, runTime );
    if( grid.VCRank() == 0 )
        cout << "DONE. GFlops = " << gFlops << endl;
    if( printMatrices )
    {
        A.Print("A after factorization");
    }
    if( testCorrectness )
    {
        TestCorrectness( shape, A_ref, A, printMatrices );
    }
}

int main( int argc, char* argv[] )
{
    int rank;
    Elemental::Init( &argc, &argv );
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    if( argc != 9 )
    {
        if( rank == 0 )
            Usage();
        Elemental::Finalize();
        return 0;
    }
    try
    {
        const int   r = atoi( argv[1] );
        const int   c = atoi( argv[2] );
        const Shape shape = CharToShape( *argv[3] );
        const bool  var3 = ( atoi(argv[4]) != 0 );
        const int   m = atoi( argv[5] );
        const int   nb = atoi( argv[6] );
        const bool  testCorrectness = atoi( argv[7] );
        const bool  printMatrices = atoi( argv[8] );
#ifndef RELEASE
        if( rank == 0 )
        {
            cout << "==========================================" << endl;
            cout << " In debug mode! Performance will be poor! " << endl;
            cout << "==========================================" << endl;
        }
#endif
        Grid grid( MPI_COMM_WORLD, r, c );
        SetBlocksize( nb );

        if( rank == 0 )
            cout << "Will test Chol" << ShapeToChar(shape) << ", Var"
                 << ( var3 ? "3" : "2" ) << endl;

        if( m<=200 )
        {
            if( rank == 0 )
            {
                cout << "--------------------" << endl;
                cout << "Testing with floats:" << endl;
                cout << "--------------------" << endl;
            }
            TestChol<float>
            ( shape, var3, m, testCorrectness, printMatrices, grid );
            if( rank == 0 )
                cout << endl;
        }
        else
        {
            if( rank == 0 )
            {
                cout << "--------------------------------" << endl;
                cout << "Floats unsuitable for this test." << endl;
                cout << "--------------------------------" << endl;
                cout << endl;
            }
        }

        if( rank == 0 )
        {
            cout << "---------------------" << endl;
            cout << "Testing with doubles:" << endl;
            cout << "---------------------" << endl;
        }
        TestChol<double>
        ( shape, var3, m, testCorrectness, printMatrices, grid );
        if( rank == 0 )
            cout << endl;

#ifndef WITHOUT_COMPLEX
        if( m <= 200 )
        {
            if( rank == 0 )
            {
                cout << "--------------------------------------" << endl;
                cout << "Testing with single-precision complex:" << endl;
                cout << "--------------------------------------" << endl;
            }
            TestChol<scomplex>
            ( shape, var3, m, testCorrectness, printMatrices, grid );
            if( rank == 0 )
                cout << endl;
        }
        else
        {
            if( rank == 0 )
            {
                cout << "----------------------------------------" << endl;
                cout << "Complex floats unsuitable for this test." << endl;
                cout << "----------------------------------------" << endl;
                cout << endl;
            }
        }

        if( rank == 0 )
        {
            cout << "--------------------------------------" << endl;
            cout << "Testing with double-precision complex:" << endl;
            cout << "--------------------------------------" << endl;
        }
        TestChol<dcomplex>
        ( shape, var3, m, testCorrectness, printMatrices, grid );
        if( rank == 0 )
            cout << endl;
#endif
    }
    catch( string errorMsg )
    {
#ifndef RELEASE
        DumpCallStack();
#endif
        cerr << "Process " << rank << " caught error message:" << endl
             << errorMsg << endl;
    }
    Elemental::Finalize();
    return 0;
}

<|endoftext|>


<commit_before>#include "common/ray.h"

Ray::Ray(Entity *entity) {
    Origin = entity->Pos + Vector3(0.25f, 0.25f, 1.6f);

    Direction = Vector3(
        sin((PI * entity->Rotation.Z) / 180),
        cos((PI * entity->Rotation.Z) / 180),
       -tan((PI * entity->Rotation.Y) / 180));

    if (Direction.X == 0.f) Direction.X = 0.0001f;
    if (Direction.Y == 0.f) Direction.Y = 0.0001f;
    if (Direction.Z == 0.f) Direction.Z = 0.0001f;
}

bool CheckBlockContact(PositionedBlock *block, Vector3 &collision) {
    return (collision.X >= block->pos.X && collision.X <= block->pos.X + block->sideLength
         && collision.Y >= block->pos.Y && collision.Y <= block->pos.Y + block->sideLength
         && collision.Z >= block->pos.Z && collision.Z <= block->pos.Z + block->sideLength);
}

float Ray::CheckCollision(PositionedBlock *block) { // , char *face) {
    float x = 0.f, y = 0.f, z = 0.f;
    char face;

    Vector3 planes1, planes2, collision;
    planes1 = (block->pos - Origin) / Direction;
    planes2 = (block->pos + block->sideLength - Origin) / Direction;

    if (planes1.X != 0.f && Origin.X < block->pos.X && planes1.X > 0)
        collision = (Direction * planes1.X) + Origin;
    else if (planes2.X != 0.f && planes2.X > 0)
        collision = (Direction * planes2.X) + Origin;
    else
        collision = Vector3();

    if (CheckBlockContact(block, collision))
        x = Origin.distance(collision);
    else
        x = 0;

    if (planes1.Y != 0.f && Origin.Y < block->pos.Y && planes1.Y > 0)
        collision = (Direction * planes1.Y) + Origin;
    else if (planes2.Y != 0.f && planes2.Y > 0)
        collision = (Direction * planes2.Y) + Origin;
    else
        collision = Vector3();

    if (CheckBlockContact(block, collision))
        y = Origin.distance(collision);
    else
        y = 0;

    if (planes1.Z != 0.f && Origin.Z < block->pos.Z && planes1.Z > 0)
        collision = (Direction * planes1.Z) + Origin;
    else if (planes2.Z != 0.f && planes2.Z > 0)
        collision = (Direction * planes2.Z) + Origin;
    else
        collision = Vector3();

    if (CheckBlockContact(block, collision))
        z = Origin.distance(collision);
    else
        z = 0;

    float dist = 0;
    face = 0;
    if (                             x > 0.f) { dist = x; face = 1; }
    if ((dist == 0.f || y < dist) && y > 0.f) { dist = y; face = 2; }
    if ((dist == 0.f || z < dist) && z > 0.f) { dist = z; face = 4; }

    return dist;
}

bool Ray::FindClosest(std::list<PositionedBlock*> blocks) {
    Closest = NULL;
    Distance = 0.f;
    float dist;

    for (std::list<PositionedBlock*>::iterator it = blocks.begin(); it != blocks.end(); ++it) {
        dist = CheckCollision(*it);

        if (0.f < dist && (Distance == 0.f || dist < Distance)) {
            Distance = dist;
            Closest = *it;
            Face = 1;
        }
    }

    return Distance > 0.f;
}

// PositionedBlock* Closest;
// float Distance;
// char Face;
<commit_msg>Fixed undefined reference to NULL in src/common/ray.cpp<commit_after>#include "common/ray.h"
#include <cstring>

Ray::Ray(Entity *entity) {
    Origin = entity->Pos + Vector3(0.25f, 0.25f, 1.6f);

    Direction = Vector3(
        sin((PI * entity->Rotation.Z) / 180),
        cos((PI * entity->Rotation.Z) / 180),
       -tan((PI * entity->Rotation.Y) / 180));

    if (Direction.X == 0.f) Direction.X = 0.0001f;
    if (Direction.Y == 0.f) Direction.Y = 0.0001f;
    if (Direction.Z == 0.f) Direction.Z = 0.0001f;
}

bool CheckBlockContact(PositionedBlock *block, Vector3 &collision) {
    return (collision.X >= block->pos.X && collision.X <= block->pos.X + block->sideLength
         && collision.Y >= block->pos.Y && collision.Y <= block->pos.Y + block->sideLength
         && collision.Z >= block->pos.Z && collision.Z <= block->pos.Z + block->sideLength);
}

float Ray::CheckCollision(PositionedBlock *block) { // , char *face) {
    float x = 0.f, y = 0.f, z = 0.f;
    char face;

    Vector3 planes1, planes2, collision;
    planes1 = (block->pos - Origin) / Direction;
    planes2 = (block->pos + block->sideLength - Origin) / Direction;

    if (planes1.X != 0.f && Origin.X < block->pos.X && planes1.X > 0)
        collision = (Direction * planes1.X) + Origin;
    else if (planes2.X != 0.f && planes2.X > 0)
        collision = (Direction * planes2.X) + Origin;
    else
        collision = Vector3();

    if (CheckBlockContact(block, collision))
        x = Origin.distance(collision);
    else
        x = 0;

    if (planes1.Y != 0.f && Origin.Y < block->pos.Y && planes1.Y > 0)
        collision = (Direction * planes1.Y) + Origin;
    else if (planes2.Y != 0.f && planes2.Y > 0)
        collision = (Direction * planes2.Y) + Origin;
    else
        collision = Vector3();

    if (CheckBlockContact(block, collision))
        y = Origin.distance(collision);
    else
        y = 0;

    if (planes1.Z != 0.f && Origin.Z < block->pos.Z && planes1.Z > 0)
        collision = (Direction * planes1.Z) + Origin;
    else if (planes2.Z != 0.f && planes2.Z > 0)
        collision = (Direction * planes2.Z) + Origin;
    else
        collision = Vector3();

    if (CheckBlockContact(block, collision))
        z = Origin.distance(collision);
    else
        z = 0;

    float dist = 0;
    face = 0;
    if (                             x > 0.f) { dist = x; face = 1; }
    if ((dist == 0.f || y < dist) && y > 0.f) { dist = y; face = 2; }
    if ((dist == 0.f || z < dist) && z > 0.f) { dist = z; face = 4; }

    return dist;
}

bool Ray::FindClosest(std::list<PositionedBlock*> blocks) {
    Closest = NULL;
    Distance = 0.f;
    float dist;

    for (std::list<PositionedBlock*>::iterator it = blocks.begin(); it != blocks.end(); ++it) {
        dist = CheckCollision(*it);

        if (0.f < dist && (Distance == 0.f || dist < Distance)) {
            Distance = dist;
            Closest = *it;
            Face = 1;
        }
    }

    return Distance > 0.f;
}

// PositionedBlock* Closest;
// float Distance;
// char Face;
<|endoftext|>


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

#include <iostream>
#include <sqlpp11/exception.h>
#include <sqlpp11/sqlite3/connection.h>
#include "detail/prepared_statement_handle.h"
#include "detail/connection_handle.h"

namespace sqlpp
{
	namespace sqlite3
	{
		namespace
		{
			detail::prepared_statement_handle_t prepare_statement(detail::connection_handle& handle, const std::string& statement)
			{
				if (handle.config->debug)
					std::cerr << "Sqlite3 debug: Preparing: '" << statement << "'" << std::endl;

				detail::prepared_statement_handle_t result(nullptr, handle.config->debug);

				auto rc = sqlite3_prepare_v2(
						handle.sqlite,
						statement.c_str(),
						statement.size(),
						&result.sqlite_statement,
						nullptr);

				if (rc != SQLITE_OK)
        {
					throw sqlpp::exception("Sqlite3 error: Could not prepare statement: " + std::string(sqlite3_errmsg(handle.sqlite)) + " (statement was >>" + statement + "<<\n");
        }

				return result;
			}

			void execute_statement(detail::connection_handle& handle, detail::prepared_statement_handle_t& prepared)
			{
				auto rc = sqlite3_step(prepared.sqlite_statement);
				if (rc != SQLITE_OK and rc != SQLITE_DONE)
				{
					std::cerr << "Sqlite3 debug: sqlite3_step return code: " << rc << std::endl;
					throw sqlpp::exception("Sqlite3 error: Could not execute statement: " + std::string(sqlite3_errmsg(handle.sqlite)));
				}
			}
		}

		connection::connection(const std::shared_ptr<connection_config>& config):
			_handle(new detail::connection_handle(config))
		{
		}

		connection::~connection()
		{
		}

		bind_result_t connection::select_impl(const std::string& statement)
		{
			std::unique_ptr<detail::prepared_statement_handle_t> prepared(new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement)));
			if (!prepared)
			{
				throw sqlpp::exception("Sqlite3 error: Could not store result set");
			}

			return {std::move(prepared)};
		}

		bind_result_t connection::run_prepared_select_impl(prepared_statement_t& prepared_statement)
		{
			sqlite3_reset(prepared_statement._handle->sqlite_statement);
			execute_statement(*_handle, *prepared_statement._handle.get());

			return { prepared_statement._handle };
		}

		size_t connection::insert_impl(const std::string& statement)
		{
			auto prepared = prepare_statement(*_handle, statement);
			execute_statement(*_handle, prepared);

			return sqlite3_last_insert_rowid(_handle->sqlite);
		}

		prepared_statement_t connection::prepare_impl(const std::string& statement)
		{
			return { std::unique_ptr<detail::prepared_statement_handle_t>(new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement))) };
		}

		size_t connection::run_prepared_insert_impl(prepared_statement_t& prepared_statement)
		{
			sqlite3_reset(prepared_statement._handle->sqlite_statement);
			execute_statement(*_handle, *prepared_statement._handle.get());

			return sqlite3_last_insert_rowid(_handle->sqlite);
		}

		void connection::execute(const std::string& statement)
		{
			auto prepared = prepare_statement(*_handle, statement);
			execute_statement(*_handle, prepared);
		}

		size_t connection::update_impl(const std::string& statement)
		{
			auto prepared = prepare_statement(*_handle, statement);
			execute_statement(*_handle, prepared);
			return sqlite3_changes(_handle->sqlite);
		}

		size_t connection::run_prepared_update_impl(prepared_statement_t& prepared_statement)
		{
			sqlite3_reset(prepared_statement._handle->sqlite_statement);
			execute_statement(*_handle, *prepared_statement._handle.get());

			return sqlite3_changes(_handle->sqlite);
		}

		size_t connection::remove_impl(const std::string& statement)
		{
			auto prepared = prepare_statement(*_handle, statement);
			execute_statement(*_handle, prepared);
			return sqlite3_changes(_handle->sqlite);
		}

		size_t connection::run_prepared_remove_impl(prepared_statement_t& prepared_statement)
		{
			sqlite3_reset(prepared_statement._handle->sqlite_statement);
			execute_statement(*_handle, *prepared_statement._handle.get());

			return sqlite3_changes(_handle->sqlite);
		}

		std::string connection::escape(const std::string& s) const
		{
			std::string t;
			t.reserve(s.size());

			for (const char c : s)
			{
				if (c == '\'')
					t.push_back(c);
				t.push_back(c);
			}

			return t;
		}

		void connection::start_transaction()
		{
			if (_transaction_active)
			{
				throw sqlpp::exception("Sqlite3 error: Cannot have more than one open transaction per connection");
			}
			auto prepared = prepare_statement(*_handle, "BEGIN");
			execute_statement(*_handle, prepared);
			_transaction_active = true;
		}

		void connection::commit_transaction()
		{
			if (not _transaction_active)
			{
				throw sqlpp::exception("Sqlite3 error: Cannot commit a finished or failed transaction");
			}
			_transaction_active = false;
			auto prepared = prepare_statement(*_handle, "COMMIT");
			execute_statement(*_handle, prepared);
		}

		void connection::rollback_transaction(bool report)
		{
			if (not _transaction_active)
			{
				throw sqlpp::exception("Sqlite3 error: Cannot rollback a finished or failed transaction");
			}
			if (report)
			{
				std::cerr << "Sqlite3 warning: Rolling back unfinished transaction" << std::endl;
			}
			_transaction_active = false;
			auto prepared = prepare_statement(*_handle, "ROLLBACK");
			execute_statement(*_handle, prepared);
		}

		void connection::report_rollback_failure(const std::string message) noexcept
		{
			std::cerr << "Sqlite3 message:" << message << std::endl;
		}
	}
}

<commit_msg>Added SQLITE_ROW to the accepted return values for slite3_step<commit_after>/*
 * Copyright (c) 2013, Roland Bock
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>
#include <sqlpp11/exception.h>
#include <sqlpp11/sqlite3/connection.h>
#include "detail/prepared_statement_handle.h"
#include "detail/connection_handle.h"

namespace sqlpp
{
	namespace sqlite3
	{
		namespace
		{
			detail::prepared_statement_handle_t prepare_statement(detail::connection_handle& handle, const std::string& statement)
			{
				if (handle.config->debug)
					std::cerr << "Sqlite3 debug: Preparing: '" << statement << "'" << std::endl;

				detail::prepared_statement_handle_t result(nullptr, handle.config->debug);

				auto rc = sqlite3_prepare_v2(
						handle.sqlite,
						statement.c_str(),
						statement.size(),
						&result.sqlite_statement,
						nullptr);

				if (rc != SQLITE_OK)
        {
					throw sqlpp::exception("Sqlite3 error: Could not prepare statement: " + std::string(sqlite3_errmsg(handle.sqlite)) + " (statement was >>" + statement + "<<\n");
        }

				return result;
			}

			void execute_statement(detail::connection_handle& handle, detail::prepared_statement_handle_t& prepared)
			{
				auto rc = sqlite3_step(prepared.sqlite_statement);
				switch(rc)
				{
				case SQLITE_OK:
				case SQLITE_ROW:
				case SQLITE_DONE:
					return;
				default:
					std::cerr << "Sqlite3 debug: sqlite3_step return code: " << rc << std::endl;
					throw sqlpp::exception("Sqlite3 error: Could not execute statement: " + std::string(sqlite3_errmsg(handle.sqlite)));
				}
			}
		}

		connection::connection(const std::shared_ptr<connection_config>& config):
			_handle(new detail::connection_handle(config))
		{
		}

		connection::~connection()
		{
		}

		bind_result_t connection::select_impl(const std::string& statement)
		{
			std::unique_ptr<detail::prepared_statement_handle_t> prepared(new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement)));
			if (!prepared)
			{
				throw sqlpp::exception("Sqlite3 error: Could not store result set");
			}

			return {std::move(prepared)};
		}

		bind_result_t connection::run_prepared_select_impl(prepared_statement_t& prepared_statement)
		{
			sqlite3_reset(prepared_statement._handle->sqlite_statement);
			execute_statement(*_handle, *prepared_statement._handle.get());

			return { prepared_statement._handle };
		}

		size_t connection::insert_impl(const std::string& statement)
		{
			auto prepared = prepare_statement(*_handle, statement);
			execute_statement(*_handle, prepared);

			return sqlite3_last_insert_rowid(_handle->sqlite);
		}

		prepared_statement_t connection::prepare_impl(const std::string& statement)
		{
			return { std::unique_ptr<detail::prepared_statement_handle_t>(new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement))) };
		}

		size_t connection::run_prepared_insert_impl(prepared_statement_t& prepared_statement)
		{
			sqlite3_reset(prepared_statement._handle->sqlite_statement);
			execute_statement(*_handle, *prepared_statement._handle.get());

			return sqlite3_last_insert_rowid(_handle->sqlite);
		}

		void connection::execute(const std::string& statement)
		{
			auto prepared = prepare_statement(*_handle, statement);
			execute_statement(*_handle, prepared);
		}

		size_t connection::update_impl(const std::string& statement)
		{
			auto prepared = prepare_statement(*_handle, statement);
			execute_statement(*_handle, prepared);
			return sqlite3_changes(_handle->sqlite);
		}

		size_t connection::run_prepared_update_impl(prepared_statement_t& prepared_statement)
		{
			sqlite3_reset(prepared_statement._handle->sqlite_statement);
			execute_statement(*_handle, *prepared_statement._handle.get());

			return sqlite3_changes(_handle->sqlite);
		}

		size_t connection::remove_impl(const std::string& statement)
		{
			auto prepared = prepare_statement(*_handle, statement);
			execute_statement(*_handle, prepared);
			return sqlite3_changes(_handle->sqlite);
		}

		size_t connection::run_prepared_remove_impl(prepared_statement_t& prepared_statement)
		{
			sqlite3_reset(prepared_statement._handle->sqlite_statement);
			execute_statement(*_handle, *prepared_statement._handle.get());

			return sqlite3_changes(_handle->sqlite);
		}

		std::string connection::escape(const std::string& s) const
		{
			std::string t;
			t.reserve(s.size());

			for (const char c : s)
			{
				if (c == '\'')
					t.push_back(c);
				t.push_back(c);
			}

			return t;
		}

		void connection::start_transaction()
		{
			if (_transaction_active)
			{
				throw sqlpp::exception("Sqlite3 error: Cannot have more than one open transaction per connection");
			}
			auto prepared = prepare_statement(*_handle, "BEGIN");
			execute_statement(*_handle, prepared);
			_transaction_active = true;
		}

		void connection::commit_transaction()
		{
			if (not _transaction_active)
			{
				throw sqlpp::exception("Sqlite3 error: Cannot commit a finished or failed transaction");
			}
			_transaction_active = false;
			auto prepared = prepare_statement(*_handle, "COMMIT");
			execute_statement(*_handle, prepared);
		}

		void connection::rollback_transaction(bool report)
		{
			if (not _transaction_active)
			{
				throw sqlpp::exception("Sqlite3 error: Cannot rollback a finished or failed transaction");
			}
			if (report)
			{
				std::cerr << "Sqlite3 warning: Rolling back unfinished transaction" << std::endl;
			}
			_transaction_active = false;
			auto prepared = prepare_statement(*_handle, "ROLLBACK");
			execute_statement(*_handle, prepared);
		}

		void connection::report_rollback_failure(const std::string message) noexcept
		{
			std::cerr << "Sqlite3 message:" << message << std::endl;
		}
	}
}

<|endoftext|>


<commit_before>/* mbed Microcontroller Library
 * Copyright (c) 2013-2014 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "mbed.h"

DigitalOut myled(LED1);

void blink(){
    myled = !myled;
}

void app_start(int, char*[]) {
    minar::Scheduler::postCallback(&blink).period(minar::milliseconds(200));
}
<commit_msg>Add instrumentation to blinky<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2013-2014 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "mbed.h"
#include "test_env.h"

DigitalOut myled(LED1);
uint32_t count = 20;

void blink() {
    if (count) {
    	if (count == 1) {
    		printf("{{success}}\r\n");
    	}
    	count--;
    }
    myled = !myled;
}

void app_start(int, char*[]) {
    MBED_HOSTTEST_TIMEOUT(20);
    MBED_HOSTTEST_SELECT(default_auto);
    MBED_HOSTTEST_DESCRIPTION(Blinky);
    MBED_HOSTTEST_START("MBED_BLINKY");
    minar::Scheduler::postCallback(&blink).period(minar::milliseconds(200));
}
<|endoftext|>


<commit_before>#include "ros/ros.h"
#include "ros/topic.h"
#include "geometry_msgs/Wrench.h"

#if 0
class Controller
{
public:
    Controller()
    {

    }
private:
    ros::NodeHandle n;
    ros::Publisher pub;
    ros::
}

// Node-global state variable
geometry_msgs::Pose state;

void stateCallback(const geometry_msgs::Pose& state)
{

}

#endif

int main(int argc, char **argv)
{
    ros::init(argc, argv, "controller");

    ros::NodeHandle n;

    // Subscribe to setpoints and state
    std::string stateTopicName = "stateTopic";
    // ros::Subscriber sub = n.subscribe<geometry_msgs::Pose>(stateTopicName, 1, stateCallback);

    // Publish a Wrench message for commanded forces and moments
    ros::Publisher pub = n.advertise<geometry_msgs::Wrench>("tau", 1);

    // Run the controller at 10 Hz
    ros::Rate loop_rate(10);

    while (ros::ok())
    {
        // state = ros::topic::waitForMessage<geometry_msgs::Pose>(stateTopicName);

        ros::spinOnce();
        loop_rate.sleep();
    }

    return 0;
}
<commit_msg>Finish controller placeholder<commit_after>#include "ros/ros.h"
#include "geometry_msgs/Pose.h"
#include "geometry_msgs/Wrench.h"

// NOTE: For now, I juse use Pose messages for state and setpoints, which is probably insufficient.

class Controller
{
public:
    Controller()
    {
        outputPub = n.advertise<geometry_msgs::Wrench>("outputTopic", 1);

        // I don't know why, but "this" is necessary here
        stateSub = n.subscribe("state", 1, &Controller::stateCallback, this);
        setpointSub = n.subscribe("setpoint", 1, &Controller::setpointCallback, this);
    }

    // stateCallback updates the private state variable when a new state message arrives.
    void stateCallback(const geometry_msgs::Pose &state_msg)
    {
        state = state_msg;
    }

    // setpointCallback updates the private setpoint variable when a new setpoint message arrives.
    void setpointCallback(const geometry_msgs::Pose &setpoint_msg)
    {
        setpoint = setpoint_msg;
    }

    // calculate contains the control algorithm, and calculates the control output based on the
    // current state and setpoint.
    void calculate(void)
    {
        geometry_msgs::Wrench output;

        // Put control algorithm here.

        output.force.x = 0;
        output.force.y = 0;
        output.force.z = 0;
        output.torque.x = 0;
        output.torque.y = 0;
        output.torque.z = 0;

        outputPub.publish(output);
    }
private:
    ros::NodeHandle n;
    ros::Publisher  outputPub;
    ros::Subscriber stateSub;
    ros::Subscriber setpointSub;
    geometry_msgs::Pose state;
    geometry_msgs::Pose setpoint;
}; // End of class Controller

int main(int argc, char **argv)
{
    ros::init(argc, argv, "controller");

    Controller controllerObject;

    // Run the controller at 10 Hz
    ros::Rate loop_rate(10);
    while (ros::ok())
    {
        ros::spinOnce();

        controllerObject.calculate();

        loop_rate.sleep();
    }

    return 0;
}
<|endoftext|>