<commit_before>#include "net.h"
#include "util.h"
#include "logging.h"
#include <netinet/tcp.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <string>

using namespace std;
namespace handy {

int net::setNonBlock(int fd, bool value) {
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags < 0) {
        return errno;
    }
    if (value) {
        return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    }
    return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
}

int net::setReuseAddr(int fd, bool value) {
    int flag = value;
    int len = sizeof flag;
    return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len);
}

int net::setReusePort(int fd, bool value) {
#ifndef SO_REUSEPORT
    fatalif(value, "SO_REUSEPORT not supported");
#endif
    int flag = value;
    int len = sizeof flag;
    return setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &flag, len);
}

int net::setNoDelay(int fd, bool value) {
    int flag = value;
    int len = sizeof flag;
    return setsockopt(fd, SOL_SOCKET, TCP_NODELAY, &flag, len);
}

Ip4Addr::Ip4Addr(const string& host, short port) {
    memset(&addr_, 0, sizeof addr_);
    addr_.sin_family = AF_INET;
    addr_.sin_port = htons(port);
    if (host.size()) {
        addr_.sin_addr = port::getHostByName(host);
    } else {
        addr_.sin_addr.s_addr = INADDR_ANY;
    }
    if (addr_.sin_addr.s_addr == INADDR_NONE){
        error("cannot resove %s to ip", host.c_str());
    }
}

string Ip4Addr::toString() const {
    uint32_t uip = addr_.sin_addr.s_addr;
    return util::format("%d.%d.%d.%d:%d",
        (uip >> 0)&0xff,
        (uip >> 8)&0xff,
        (uip >> 16)&0xff,
        (uip >> 24)&0xff,
        ntohs(addr_.sin_port));
}

string Ip4Addr::ip() const {
    uint32_t uip = addr_.sin_addr.s_addr;
    return util::format("%d.%d.%d.%d",
        (uip >> 0)&0xff,
        (uip >> 8)&0xff,
        (uip >> 16)&0xff,
        (uip >> 24)&0xff);
}

short Ip4Addr::port() const {
    return ntohs(addr_.sin_port);
}

unsigned int Ip4Addr::ipInt() const {
    return ntohl(addr_.sin_addr.s_addr);
}
bool Ip4Addr::isIpValid() const {
    return addr_.sin_addr.s_addr != INADDR_NONE;
}

char* Buffer::makeRoom(size_t len) {
    if (e_ + len <= cap_) {
    } else if (size() + len < cap_ / 2) {
        moveHead();
    } else {
        expand(len);
    }
    return end();
}

void Buffer::expand(size_t len) {
    size_t ncap = std::max(exp_, std::max(2*cap_, size()+len));
    char* p = new char[ncap];
    std::copy(begin(), end(), p);
    e_ -= b_;
    b_ = 0;
    delete[] buf_;
    buf_ = p;
    cap_ = ncap;
}

void Buffer::copyFrom(const Buffer& b) {
    memcpy(this, &b, sizeof b);
    if (size()) {
        buf_ = new char[cap_];
        memcpy(data(), b.begin(), b.size());
    }
}

Buffer& Buffer::absorb(Buffer& buf) {
    if (&buf != this) {
        if (size() == 0) {
            char b[sizeof buf];
            memcpy(b, this, sizeof b);
            memcpy(this, &buf, sizeof b);
            memcpy(&buf, b, sizeof b);
            std::swap(exp_, buf.exp_); //keep the origin exp_
        } else {
            append(buf.begin(), buf.size());
            buf.clear();
        }
    }
    return *this;
}

}<commit_msg>use port error fixed<commit_after>#include "net.h"
#include "util.h"
#include "logging.h"
#include <netinet/tcp.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <string>

using namespace std;
namespace handy {

int net::setNonBlock(int fd, bool value) {
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags < 0) {
        return errno;
    }
    if (value) {
        return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    }
    return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
}

int net::setReuseAddr(int fd, bool value) {
    int flag = value;
    int len = sizeof flag;
    return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len);
}

int net::setReusePort(int fd, bool value) {
#ifndef SO_REUSEPORT
    fatalif(value, "SO_REUSEPORT not supported");
    return 0;
#else
    int flag = value;
    int len = sizeof flag;
    return setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &flag, len);
#endif
}

int net::setNoDelay(int fd, bool value) {
    int flag = value;
    int len = sizeof flag;
    return setsockopt(fd, SOL_SOCKET, TCP_NODELAY, &flag, len);
}

Ip4Addr::Ip4Addr(const string& host, short port) {
    memset(&addr_, 0, sizeof addr_);
    addr_.sin_family = AF_INET;
    addr_.sin_port = htons(port);
    if (host.size()) {
        addr_.sin_addr = port::getHostByName(host);
    } else {
        addr_.sin_addr.s_addr = INADDR_ANY;
    }
    if (addr_.sin_addr.s_addr == INADDR_NONE){
        error("cannot resove %s to ip", host.c_str());
    }
}

string Ip4Addr::toString() const {
    uint32_t uip = addr_.sin_addr.s_addr;
    return util::format("%d.%d.%d.%d:%d",
        (uip >> 0)&0xff,
        (uip >> 8)&0xff,
        (uip >> 16)&0xff,
        (uip >> 24)&0xff,
        ntohs(addr_.sin_port));
}

string Ip4Addr::ip() const {
    uint32_t uip = addr_.sin_addr.s_addr;
    return util::format("%d.%d.%d.%d",
        (uip >> 0)&0xff,
        (uip >> 8)&0xff,
        (uip >> 16)&0xff,
        (uip >> 24)&0xff);
}

short Ip4Addr::port() const {
    return ntohs(addr_.sin_port);
}

unsigned int Ip4Addr::ipInt() const {
    return ntohl(addr_.sin_addr.s_addr);
}
bool Ip4Addr::isIpValid() const {
    return addr_.sin_addr.s_addr != INADDR_NONE;
}

char* Buffer::makeRoom(size_t len) {
    if (e_ + len <= cap_) {
    } else if (size() + len < cap_ / 2) {
        moveHead();
    } else {
        expand(len);
    }
    return end();
}

void Buffer::expand(size_t len) {
    size_t ncap = std::max(exp_, std::max(2*cap_, size()+len));
    char* p = new char[ncap];
    std::copy(begin(), end(), p);
    e_ -= b_;
    b_ = 0;
    delete[] buf_;
    buf_ = p;
    cap_ = ncap;
}

void Buffer::copyFrom(const Buffer& b) {
    memcpy(this, &b, sizeof b);
    if (size()) {
        buf_ = new char[cap_];
        memcpy(data(), b.begin(), b.size());
    }
}

Buffer& Buffer::absorb(Buffer& buf) {
    if (&buf != this) {
        if (size() == 0) {
            char b[sizeof buf];
            memcpy(b, this, sizeof b);
            memcpy(this, &buf, sizeof b);
            memcpy(&buf, b, sizeof b);
            std::swap(exp_, buf.exp_); //keep the origin exp_
        } else {
            append(buf.begin(), buf.size());
            buf.clear();
        }
    }
    return *this;
}

}<|endoftext|>


<commit_before>//
//  main.cpp
//  Assignment
//
//  Created by Teodor on 09/01/2017.
//  Copyright © 2017 TeodorGarzdin. All rights reserved.
//

#include <string>
#include <fstream>
#include <iostream>

class Date {
public:
    unsigned int day;
    unsigned int month;
    unsigned int year;

    Date(const Date& d) {
        day = d.day;
        month = d.month;
        year = d.year;
    }

    Date(const unsigned int d = 0, const unsigned int m = 0, const unsigned int y = 0) {
        this->day = d;
        this->month = m;
        this->year = y;
    }

    friend std::ostream& operator<<(std::ostream& stream, Date& date);

    int operator==(const Date& d) {
        return day == d.day && month == d.month && year == d.year;
    }

    Date& operator=(const Date& d) {
        if(this != &d) {
            day = d.day;
            month = d.month;
            year = d.year;
        }

        return *this;
    }

    unsigned int getDay() {
        return day;
    }

    void setDay(const unsigned int d) {
        if (d > 0) {
            day = d;
        } else {
            throw new std::invalid_argument("Day can't be negative");
        }
    }

    unsigned int getMonth() {
        return month;
    }

    void setMonth(const unsigned int m) {
        if (m > 0) {
            month= m;
        } else {
            throw new std::invalid_argument("Month can't be negative");
        }
    }

    unsigned int getYear() {
        return year;
    }

    void setYear(const unsigned int y) {
        if (y > 0) {
            year = y;
        }
        else {
            throw new std::invalid_argument("Year can't be negative");
        }
    }

    ~Date () {
        std::cout<<"Destructing <Date>"<<std::endl;
    }
};

class Student {
public:
    std::string name;
    std::string facNumber;
    Date birthDate;
    float avScore;

    Student() {}

    Student(std::string n, std::string fn, Date* d, float s) {
        this->name = n;
        this->facNumber = fn;
        this->birthDate = *d;
        this->avScore = s;
    }

    ~Student() {
        std::cout<<"Destructing <Student>"<<std::endl;
    }

    friend std::ostream& operator<<(std::ostream& stream, Student& student);

    void setName(std::string n) { name = n; }

    std::string getName() { return name; }

    void setFacNumber(std::string id) { facNumber = id; }

    std::string getFacNumber() { return facNumber; }

    void setAvScore(float s) { avScore = s; }

    float getAvScore() { return avScore; }

    int showYears(Date date) {
        if (date.getMonth() > this->birthDate.getMonth()) {
            return (date.getYear() - this->birthDate.getYear());
        } else {
            if (date.getMonth() < this->birthDate.getMonth()) {
                return (date.getYear() - this->birthDate.getYear() - 1);
            } else {
                if (date.getDay() > this->birthDate.getDay()) {
                    return (date.getYear() - this->birthDate.getYear());
                } else {
                    return (date.getYear() - this->birthDate.getYear() - 1);
                }
            }
        }
    }
};

class Potok {
public:
    unsigned int number;
    unsigned int numberOfStudents;
    Student students[3];

    Potok() {}

    Potok(int number, Student students[]) {
        this->number = number;
        this->numberOfStudents = sizeof(this->students);
        for(int i = 0; i<= this->numberOfStudents; i++) {
            this->students[i] = students[i];
        }
    }

    friend std::ostream& operator<<(std::ostream& stream, Potok& potok);

    ~Potok() {
        std::cout<<"Destructing <Potok>"<<std::endl;
    }

    Student getStudentWithHighestGrade() {
        Student currentStudent;
        for(int i = 0; i <= this->numberOfStudents; i++) {
            if(this->students[i].avScore > currentStudent.avScore) currentStudent = this->students[i];
        }
        return currentStudent;
    }

    int writeStudentsIntoFile() {
        if(sizeof(this->students) == 0) {
            std::cout<<"Students array is empty."<<std::endl;
            return 1;
        }

        std::ofstream textFile;
        textFile.open("students.txt");

        if(!textFile) {
            std::cout<<"Cannot open output file."<<std::endl;
            return 1;
        }

        for(unsigned int i=0; i<=sizeof(this->students); i++) {
            textFile<<this->students[i]<<std::endl;
        }

        textFile.close();

        return 0;
    }
};

std::ostream& operator<<(std::ostream& stream, Date& date) {
    return stream<<date.day<<"/"<<date.month<<"/"<<date.year<<std::endl;
}

std::ostream& operator<<(std::ostream& stream, Student& student) {
    return stream<<"Name: "<<student.name<<"Birth date: "<<student.birthDate<<"GPA: "<<student.avScore<<std::endl;
}

std::ostream& operator<<(std::ostream& stream, Potok& potok) {
    for(int i = 0; i <= potok.numberOfStudents; i++) {
        if(potok.students[i].showYears(potok.students[i].birthDate) >= 18 && potok.students[i].showYears(potok.students[i].birthDate) <= 26) {
            stream<<potok.students[i].name;
        }
    }
    return stream<<std::endl;
}

int main (int argc, const char * argv[]) {
    Student *students[3];
    students[0] = new Student("Teodor", "5109238", new Date(14, 8, 1995), 5.95);
    students[1] = new Student("Julia", "5109237", new Date(17, 11, 1995), 5.12);
    students[2] = new Student("Georgi", "5109236", new Date(5, 9, 1995), 4.49);
    Potok *potok_1 = new Potok(1, *students);
    potok_1->writeStudentsIntoFile();

    return 0;
}
<commit_msg>Don't use the "new" keyword. Potential memory leaks.<commit_after>//
//  main.cpp
//  Assignment
//
//  Created by Teodor on 09/01/2017.
//  Copyright © 2017 TeodorGarzdin. All rights reserved.
//

#include <string>
#include <fstream>
#include <iostream>

class Date {
public:
    unsigned int day;
    unsigned int month;
    unsigned int year;

    Date(const Date& d) {
        day = d.day;
        month = d.month;
        year = d.year;
    }

    Date(const unsigned int d = 0, const unsigned int m = 0, const unsigned int y = 0) {
        this->day = d;
        this->month = m;
        this->year = y;
    }

    friend std::ostream& operator<<(std::ostream& stream, Date& date);

    int operator==(const Date& d) {
        return day == d.day && month == d.month && year == d.year;
    }

    Date& operator=(const Date& d) {
        if(this != &d) {
            day = d.day;
            month = d.month;
            year = d.year;
        }

        return *this;
    }

    unsigned int getDay() {
        return day;
    }

    void setDay(const unsigned int d) {
        if (d > 0) {
            day = d;
        } else {
            throw new std::invalid_argument("Day can't be negative");
        }
    }

    unsigned int getMonth() {
        return month;
    }

    void setMonth(const unsigned int m) {
        if (m > 0) {
            month= m;
        } else {
            throw new std::invalid_argument("Month can't be negative");
        }
    }

    unsigned int getYear() {
        return year;
    }

    void setYear(const unsigned int y) {
        if (y > 0) {
            year = y;
        }
        else {
            throw new std::invalid_argument("Year can't be negative");
        }
    }

    ~Date () {
        std::cout<<"Destructing <Date>"<<std::endl;
    }
};

class Student {
public:
    std::string name;
    std::string facNumber;
    Date birthDate;
    float avScore;

    Student() {}

    Student(std::string n, std::string fn, Date d, float s) {
        this->name = n;
        this->facNumber = fn;
        this->birthDate = d;
        this->avScore = s;
    }

    ~Student() {
        std::cout<<"Destructing <Student>"<<std::endl;
    }

    friend std::ostream& operator<<(std::ostream& stream, Student& student);

    void setName(std::string n) { name = n; }

    std::string getName() { return name; }

    void setFacNumber(std::string id) { facNumber = id; }

    std::string getFacNumber() { return facNumber; }

    void setAvScore(float s) { avScore = s; }

    float getAvScore() { return avScore; }

    int showYears(Date date) {
        if (date.getMonth() > this->birthDate.getMonth()) {
            return (date.getYear() - this->birthDate.getYear());
        } else {
            if (date.getMonth() < this->birthDate.getMonth()) {
                return (date.getYear() - this->birthDate.getYear() - 1);
            } else {
                if (date.getDay() > this->birthDate.getDay()) {
                    return (date.getYear() - this->birthDate.getYear());
                } else {
                    return (date.getYear() - this->birthDate.getYear() - 1);
                }
            }
        }
    }
};

class Potok {
public:
    unsigned int number;
    unsigned int numberOfStudents;
    Student students[3];

    Potok() {}

    Potok(int number, Student students[]) {
        this->number = number;
        this->numberOfStudents = sizeof(this->students);
        for(int i = 0; i<= this->numberOfStudents; i++) {
            this->students[i] = students[i];
        }
    }

    friend std::ostream& operator<<(std::ostream& stream, Potok& potok);

    ~Potok() {
        std::cout<<"Destructing <Potok>"<<std::endl;
    }

    Student getStudentWithHighestGrade() {
        Student currentStudent;
        for(int i = 0; i <= this->numberOfStudents; i++) {
            if(this->students[i].avScore > currentStudent.avScore) currentStudent = this->students[i];
        }
        return currentStudent;
    }

    int writeStudentsIntoFile() {
        if(sizeof(this->students) == 0) {
            std::cout<<"Students array is empty."<<std::endl;
            return 1;
        }

        std::ofstream textFile;
        textFile.open("students.txt");

        if(!textFile) {
            std::cout<<"Cannot open output file."<<std::endl;
            return 1;
        }

        for(unsigned int i=0; i<=sizeof(this->students); i++) {
            textFile<<this->students[i]<<std::endl;
        }

        textFile.close();

        return 0;
    }
};

std::ostream& operator<<(std::ostream& stream, Date& date) {
    return stream<<date.day<<"/"<<date.month<<"/"<<date.year<<std::endl;
}

std::ostream& operator<<(std::ostream& stream, Student& student) {
    return stream<<"Name: "<<student.name<<"Birth date: "<<student.birthDate<<"GPA: "<<student.avScore<<std::endl;
}

std::ostream& operator<<(std::ostream& stream, Potok& potok) {
    for(int i = 0; i <= potok.numberOfStudents; i++) {
        if(potok.students[i].showYears(potok.students[i].birthDate) >= 18 && potok.students[i].showYears(potok.students[i].birthDate) <= 26) {
            stream<<potok.students[i].name;
        }
    }
    return stream<<std::endl;
}

int main (int argc, const char * argv[]) {
    Student students[3];
    students[0] = Student("Teodor", "5109238", Date(14, 8, 1995), 5.95);
    students[1] = Student("Julia", "5109237", Date(17, 11, 1995), 5.12);
    students[2] = Student("Georgi", "5109236", Date(5, 9, 1995), 4.49);
    Potok potok_1 = Potok(1, students);
    potok_1.writeStudentsIntoFile();

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright(C) lichuang
 */
#include <map>
#include <list>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
#include "error_code.h"
#include "base.h"
#include "event.h"
#include "meta.h"
#include "rpc_channel.h"
#include "net_utility.h"
#include "callback.h"
#include "dispatcher.h"
#include "log.h"
namespace {
static const int kBufferLength = 100;
}
namespace eventrpc {
struct RpcChannelCallback : public Callback {
  RpcChannel::Impl *impl_;
  gpb::Closure *done;
  uint32 method_id;
  string send_message;
  ssize_t sent_count;
  gpb::Message *response;
  Meta recv_meta;
  RpcChannelCallback(RpcChannel::Impl *impl)
    : impl_(impl),
      done(NULL),
      method_id(0),
      send_message(""),
      sent_count(0),
      response(NULL) {
  }
  void Run();
};

struct RpcChannelEvent : public Event {
  RpcChannelEvent(int fd, RpcChannel::Impl *impl)
    : Event(fd, EVENT_WRITE | EVENT_READ),
      impl_(impl) {
  }

  virtual ~RpcChannelEvent() {
  }

  int HandleRead();

  int HandleWrite();

  RpcChannel::Impl *impl_;
};

struct RpcChannel::Impl {
 public:
  Impl(const char *host, int port, Dispatcher *dispatcher);

  ~Impl();

  bool Connect();

  void Close();

  void CallMethod(const gpb::MethodDescriptor* method,
                  gpb::RpcController* controller,
                  const gpb::Message* request,
                  gpb::Message* response,
                  gpb::Closure* done);

  int HandleRead();

  int HandleWrite();

  int SendServiceRequest(RpcChannelCallback *callback);

  int DecodeBuffer(ssize_t recv_count);

  RpcChannelCallback *get_callback();

  void FreeCurrentReadCallback();

  RpcChannelEvent event_;
  const char *host_;
  int port_;
  Dispatcher *dispatcher_;
  char buffer_[kBufferLength];
  typedef std::list<RpcChannelCallback*> RpcChannelCallbackList;
  RpcChannelCallbackList send_callback_list_;
  RpcChannelCallbackList free_callback_list_;
  typedef std::map<uint32, RpcChannelCallback*> RpcChannelCallbackMap;
  RpcChannelCallbackMap callback_map_;
  RpcChannelCallback *current_read_callback_;
  std::string recv_message_;
};

RpcChannel::Impl::Impl(const char *host, int port, Dispatcher *dispatcher)
  : host_(host),
    port_(port),
    dispatcher_(dispatcher),
    event_(-1, this),
    current_read_callback_(NULL) {
}

RpcChannel::Impl::~Impl() {
  Close();
}

bool RpcChannel::Impl::Connect() {
  event_.fd_ = NetUtility::Connect(host_, port_);
  if (event_.fd_ < 0) {
    VLOG_ERROR() << "connect to [" << host_ << " : " << port_ << "] fail";
    return false;
  }
  dispatcher_->AddEvent(&event_);
  return true;
}

void RpcChannel::Impl::Close() {
  if (event_.fd_ > 0) {
    VLOG_INFO() << "close connection to [" << host_ << " : " << port_ << "]";
    dispatcher_->DeleteEvent(&event_);
  }
}

void RpcChannel::Impl::CallMethod(const gpb::MethodDescriptor* method,
                                  gpb::RpcController* controller,
                                  const gpb::Message* request,
                                  gpb::Message* response,
                                  gpb::Closure* done) {
  Meta meta;
  RpcChannelCallback *callback = new RpcChannelCallback(this);
  callback->sent_count = 0;
  callback->method_id = meta.method_id();
  callback->response = response;
  callback->done = done;
  static uint32 request_id = 1;
  meta.set_request_id(request_id);
  ++request_id;
  meta.EncodeWithMessage(method->full_name(),
                         request,
                         &(callback->send_message));
  VLOG_INFO() << "call method send request "
    << method->full_name()
    << ", method id: " << meta.method_id()
    << ", message length: " << meta.message_length()
    << ", request id: " << meta.request_id();
  callback_map_[meta.request_id()] = callback;
  dispatcher_->PushTask(callback);
}

int RpcChannel::Impl::DecodeBuffer(int length) {
  ASSERT(strlen(buffer_) != 0);
  RpcChannelCallback *callback = NULL;
  Meta meta;
  recv_message_.append(buffer_, length);
  if (current_read_callback_ == NULL) {
    if (recv_message_.length() < META_LEN) {
      return kRecvMessageNotCompleted;
    }
    meta.EncodeWithBuffer(recv_message_.c_str());
    RpcChannelCallbackMap::iterator iter;
    iter = callback_map_.find(meta.request_id());
    if (iter == callback_map_.end()) {
      VLOG_INFO() << "cannot find request id: " << meta.request_id();
      return kCannotFindRequestId;
    }
    callback = iter->second;
    callback->recv_meta = meta;
    current_read_callback_ = callback;
  }
  if (current_read_callback_->recv_meta.message_length() !=
      (recv_message_.length() - META_LEN)) {
    return kRecvMessageNotCompleted;
  }
  if (!current_read_callback_->response->ParseFromString(
      recv_message_.substr(META_LEN))) {
    FreeCurrentReadCallback();
    return kDecodeMessageError;
  }
  if (current_read_callback_->done != NULL) {
    callback->done->Run();
  }
  FreeCurrentReadCallback();
  recv_message_ = "";
  return kSuccess;
}

void RpcChannel::Impl::FreeCurrentReadCallback() {
  callback_map_.erase(current_read_callback_->recv_meta.request_id());
  delete current_read_callback_;
  current_read_callback_ = NULL;
}

int RpcChannel::Impl::HandleRead() {
  VLOG_INFO() << "HandleRead";
  int32 length = 0;
  int32 result = 0;
  while (true) {
    length = 0;
    if (!NetUtility::Recv(event_.fd_, buffer_,
                          kBufferLength, &length)) {
      VLOG_ERROR() << "recv message from [" << host_ << " : " << port_ << "] error";
      Close();
      return -1;
    }
    result = DecodeBuffer(length);
    VLOG_INFO() << "result: " << result;
    if (result == kSuccess) {
      return kSuccess;
    }
    if (result == kRecvMessageNotCompleted && length == kBufferLength) {
      // should recv again
      continue;
    }
    if (result == kRecvMessageNotCompleted) {
      return result;
    }
    VLOG_ERROR() << "handle message from [" << host_ << " : " << port_ << "] error: " << result;
    Close();
    return result;
  }

  VLOG_FATAL() << "should not reach here";
  return kSuccess;
}

int RpcChannel::Impl::SendServiceRequest(RpcChannelCallback *callback) {
  // is no need response?
  if (callback->send_message.empty()) {
    free_callback_list_.push_back(callback);
    return kSuccess;
  }
  int length = 0;
  bool ret = false;
  while (true) {
    ret = NetUtility::Send(
        event_.fd_,
        callback->send_message.c_str() + callback->sent_count,
        callback->send_message.length() - callback->sent_count,
        &length);
    if (!ret) {
      VLOG_ERROR() << "send message to [" << host_ << " : " << port_ << "] error";
      Close();
      free_callback_list_.push_back(callback);
      return kSendMessageError;
    }
    callback->sent_count += length;
    if (callback->sent_count < callback->send_message.length()) {
      return kSendMessageNotCompleted;
    }
    VLOG_INFO() << "send service request done, count: "
      << callback->send_message.length();
    callback->sent_count = 0;
    callback->send_message = "";
    free_callback_list_.push_back(callback);
    return kSuccess;
  }

  LOG_FATAL() << "should never reach here!";
  return 0;
}

int RpcChannel::Impl::HandleWrite() {
  RpcChannelCallbackList::iterator iter, tmp_iter;
  int result = 0;
  for (iter = send_callback_list_.begin();
       iter != send_callback_list_.end(); ) {
    VLOG_INFO() << "HandleWrite";
    result = SendServiceRequest(*iter);
    if (result == kSuccess) {
      tmp_iter = iter;
      ++iter;
      send_callback_list_.erase(tmp_iter);
      continue;
    }
    if (result == kSendMessageError) {
      VLOG_ERROR() << "send service request error";
      Close();
      return result;
    }
    // when reach here, send not completed, return and
    // waiting the next send time
    return result;
  }
}

void RpcChannelCallback::Run() {
  int result = impl_->SendServiceRequest(this);
  if (result == kSuccess) {
    return;
  }
  if (result == kSendMessageError) {
    VLOG_ERROR() << "send service request error";
    return;
  }
  impl_->send_callback_list_.push_back(this);
}

int RpcChannelEvent::HandleRead() {
  return impl_->HandleRead();
}

int RpcChannelEvent::HandleWrite() {
  return impl_->HandleWrite();
}

RpcChannel::RpcChannel(const char *host, int port, Dispatcher *dispatcher) {
   impl_ = new Impl(host, port, dispatcher);
}

RpcChannel::~RpcChannel() {
  delete impl_;
}

bool RpcChannel::Connect() {
  return impl_->Connect();
}

void RpcChannel::Close() {
  impl_->Close();
}

void RpcChannel::CallMethod(const gpb::MethodDescriptor* method,
                            gpb::RpcController* controller,
                            const gpb::Message* request,
                            gpb::Message* response,
                            gpb::Closure* done) {
  impl_->CallMethod(method, controller, request, response, done);
}
};
<commit_msg>add no need response support<commit_after>/*
 * Copyright(C) lichuang
 */
#include <map>
#include <list>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
#include "error_code.h"
#include "base.h"
#include "event.h"
#include "meta.h"
#include "rpc_channel.h"
#include "net_utility.h"
#include "callback.h"
#include "dispatcher.h"
#include "log.h"
namespace {
static const int kBufferLength = 100;
}
namespace eventrpc {
struct RpcChannelCallback : public Callback {
  RpcChannel::Impl *impl_;
  gpb::Closure *done;
  uint32 method_id;
  string send_message;
  ssize_t sent_count;
  gpb::Message *response;
  Meta recv_meta;
  RpcChannelCallback(RpcChannel::Impl *impl)
    : impl_(impl),
      done(NULL),
      method_id(0),
      send_message(""),
      sent_count(0),
      response(NULL) {
  }
  void Run();
};

struct RpcChannelEvent : public Event {
  RpcChannelEvent(int fd, RpcChannel::Impl *impl)
    : Event(fd, EVENT_WRITE | EVENT_READ),
      impl_(impl) {
  }

  virtual ~RpcChannelEvent() {
  }

  int HandleRead();

  int HandleWrite();

  RpcChannel::Impl *impl_;
};

struct RpcChannel::Impl {
 public:
  Impl(const char *host, int port, Dispatcher *dispatcher);

  ~Impl();

  bool Connect();

  void Close();

  void CallMethod(const gpb::MethodDescriptor* method,
                  gpb::RpcController* controller,
                  const gpb::Message* request,
                  gpb::Message* response,
                  gpb::Closure* done);

  int HandleRead();

  int HandleWrite();

  int SendServiceRequest(RpcChannelCallback *callback);

  int DecodeBuffer(ssize_t recv_count);

  RpcChannelCallback *get_callback();

  void FreeCurrentReadCallback();

  RpcChannelEvent event_;
  const char *host_;
  int port_;
  Dispatcher *dispatcher_;
  char buffer_[kBufferLength];
  typedef std::list<RpcChannelCallback*> RpcChannelCallbackList;
  RpcChannelCallbackList send_callback_list_;
  RpcChannelCallbackList free_callback_list_;
  typedef std::map<uint32, RpcChannelCallback*> RpcChannelCallbackMap;
  RpcChannelCallbackMap callback_map_;
  RpcChannelCallback *current_read_callback_;
  std::string recv_message_;
};

RpcChannel::Impl::Impl(const char *host, int port, Dispatcher *dispatcher)
  : host_(host),
    port_(port),
    dispatcher_(dispatcher),
    event_(-1, this),
    current_read_callback_(NULL) {
}

RpcChannel::Impl::~Impl() {
  Close();
}

bool RpcChannel::Impl::Connect() {
  event_.fd_ = NetUtility::Connect(host_, port_);
  if (event_.fd_ < 0) {
    VLOG_ERROR() << "connect to [" << host_ << " : " << port_ << "] fail";
    return false;
  }
  dispatcher_->AddEvent(&event_);
  return true;
}

void RpcChannel::Impl::Close() {
  if (event_.fd_ > 0) {
    VLOG_INFO() << "close connection to [" << host_ << " : " << port_ << "]";
    dispatcher_->DeleteEvent(&event_);
  }
}

RpcChannelCallback *RpcChannel::Impl::get_callback() {
  if (free_callback_list_.empty()) {
    return new RpcChannelCallback(this);
  } else {
    RpcChannelCallback *callback = free_callback_list_.front();
    free_callback_list_.pop_front();
    return callback;
  }
}

void RpcChannel::Impl::CallMethod(const gpb::MethodDescriptor* method,
                                  gpb::RpcController* controller,
                                  const gpb::Message* request,
                                  gpb::Message* response,
                                  gpb::Closure* done) {
  Meta meta;
  RpcChannelCallback *callback = get_callback();
  callback->sent_count = 0;
  callback->method_id = meta.method_id();
  callback->response = response;
  callback->done = done;
  static uint32 request_id = 1;
  meta.set_request_id(request_id);
  ++request_id;
  meta.EncodeWithMessage(method->full_name(),
                         request,
                         &(callback->send_message));
  VLOG_INFO() << "call method send request "
    << method->full_name()
    << ", method id: " << meta.method_id()
    << ", message length: " << meta.message_length()
    << ", request id: " << meta.request_id();
  callback_map_[meta.request_id()] = callback;
  dispatcher_->PushTask(callback);
}

int RpcChannel::Impl::DecodeBuffer(int length) {
  ASSERT(strlen(buffer_) != 0);
  RpcChannelCallback *callback = NULL;
  Meta meta;
  recv_message_.append(buffer_, length);
  if (current_read_callback_ == NULL) {
    if (recv_message_.length() < META_LEN) {
      return kRecvMessageNotCompleted;
    }
    meta.EncodeWithBuffer(recv_message_.c_str());
    RpcChannelCallbackMap::iterator iter;
    iter = callback_map_.find(meta.request_id());
    if (iter == callback_map_.end()) {
      VLOG_INFO() << "cannot find request id: " << meta.request_id();
      return kCannotFindRequestId;
    }
    callback = iter->second;
    callback->recv_meta = meta;
    current_read_callback_ = callback;
  }
  if (current_read_callback_->recv_meta.message_length() !=
      (recv_message_.length() - META_LEN)) {
    return kRecvMessageNotCompleted;
  }
  if (!current_read_callback_->response->ParseFromString(
      recv_message_.substr(META_LEN))) {
    FreeCurrentReadCallback();
    return kDecodeMessageError;
  }
  if (current_read_callback_->done != NULL) {
    callback->done->Run();
  }
  FreeCurrentReadCallback();
  recv_message_ = "";
  return kSuccess;
}

void RpcChannel::Impl::FreeCurrentReadCallback() {
  callback_map_.erase(current_read_callback_->recv_meta.request_id());
  delete current_read_callback_;
  current_read_callback_ = NULL;
}

int RpcChannel::Impl::HandleRead() {
  VLOG_INFO() << "HandleRead";
  int32 length = 0;
  int32 result = 0;
  while (true) {
    length = 0;
    if (!NetUtility::Recv(event_.fd_, buffer_,
                          kBufferLength, &length)) {
      VLOG_ERROR() << "recv message from [" << host_ << " : " << port_ << "] error";
      Close();
      return -1;
    }
    result = DecodeBuffer(length);
    VLOG_INFO() << "result: " << result;
    if (result == kSuccess) {
      return kSuccess;
    }
    if (result == kRecvMessageNotCompleted && length == kBufferLength) {
      // should recv again
      continue;
    }
    if (result == kRecvMessageNotCompleted) {
      return result;
    }
    VLOG_ERROR() << "handle message from [" << host_ << " : " << port_ << "] error: " << result;
    Close();
    return result;
  }

  VLOG_FATAL() << "should not reach here";
  return kSuccess;
}

int RpcChannel::Impl::SendServiceRequest(RpcChannelCallback *callback) {
  // is no need response?
  if (callback->send_message.empty()) {
    free_callback_list_.push_back(callback);
    return kSuccess;
  }
  int length = 0;
  bool ret = false;
  while (true) {
    ret = NetUtility::Send(
        event_.fd_,
        callback->send_message.c_str() + callback->sent_count,
        callback->send_message.length() - callback->sent_count,
        &length);
    if (!ret) {
      VLOG_ERROR() << "send message to [" << host_ << " : " << port_ << "] error";
      Close();
      free_callback_list_.push_back(callback);
      return kSendMessageError;
    }
    callback->sent_count += length;
    if (callback->sent_count < callback->send_message.length()) {
      return kSendMessageNotCompleted;
    }
    VLOG_INFO() << "send service request done, count: "
      << callback->send_message.length();
    callback->sent_count = 0;
    callback->send_message = "";
    free_callback_list_.push_back(callback);
    return kSuccess;
  }

  LOG_FATAL() << "should never reach here!";
  return 0;
}

int RpcChannel::Impl::HandleWrite() {
  RpcChannelCallbackList::iterator iter, tmp_iter;
  int result = 0;
  for (iter = send_callback_list_.begin();
       iter != send_callback_list_.end(); ) {
    VLOG_INFO() << "HandleWrite";
    result = SendServiceRequest(*iter);
    if (result == kSuccess) {
      tmp_iter = iter;
      ++iter;
      send_callback_list_.erase(tmp_iter);
      continue;
    }
    if (result == kSendMessageError) {
      VLOG_ERROR() << "send service request error";
      Close();
      return result;
    }
    // when reach here, send not completed, return and
    // waiting the next send time
    return result;
  }
}

void RpcChannelCallback::Run() {
  int result = impl_->SendServiceRequest(this);
  if (result == kSuccess) {
    return;
  }
  if (result == kSendMessageError) {
    VLOG_ERROR() << "send service request error";
    return;
  }
  impl_->send_callback_list_.push_back(this);
}

int RpcChannelEvent::HandleRead() {
  return impl_->HandleRead();
}

int RpcChannelEvent::HandleWrite() {
  return impl_->HandleWrite();
}

RpcChannel::RpcChannel(const char *host, int port, Dispatcher *dispatcher) {
   impl_ = new Impl(host, port, dispatcher);
}

RpcChannel::~RpcChannel() {
  delete impl_;
}

bool RpcChannel::Connect() {
  return impl_->Connect();
}

void RpcChannel::Close() {
  impl_->Close();
}

void RpcChannel::CallMethod(const gpb::MethodDescriptor* method,
                            gpb::RpcController* controller,
                            const gpb::Message* request,
                            gpb::Message* response,
                            gpb::Closure* done) {
  impl_->CallMethod(method, controller, request, response, done);
}
};
<|endoftext|>


<commit_before>//Copyright (c) 2021 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include <gtest/gtest.h>

#include "../src/LayerPlan.h" //Code under test.

namespace cura
{

/*!
 * A fixture containing some sets of GCodePaths to test with.
 */
class ExtruderPlanTestPathCollection
{
public:
    /*!
     * One path with 5 vertices printing a 1000x1000 micron square starting from
     * 0,0.
     */
    std::vector<GCodePath> square;

    /*!
     * Three lines side by side, with two travel moves in between.
     */
    std::vector<GCodePath> lines;

    /*!
     * Three lines side by side with travel moves in between, but adjusted flow.
     *
     * The first line gets 120% flow.
     * The second line gets 80% flow.
     * The third line gets 40% flow.
     */
    std::vector<GCodePath> decreasing_flow;

    /*!
     * Three lines side by side with their speed factors adjusted.
     *
     * The first line gets 120% speed.
     * The second line gets 80% speed.
     * The third line gets 40% speed.
     */
    std::vector<GCodePath> decreasing_speed;

    /*!
     * Configuration to print extruded paths with in the fixture.
     *
     * This config is referred to via pointer, so changing it will immediately
     * change it for all extruded paths.
     */
    GCodePathConfig extrusion_config;

    /*!
     * Configuration to print travel paths with in the fixture.
     *
     * This config is referred to via pointer, so changing it will immediately
     * change it for all travel paths.
     */
    GCodePathConfig travel_config;

    ExtruderPlanTestPathCollection() :
        extrusion_config(
            PrintFeatureType::OuterWall,
            /*line_width=*/400,
            /*layer_thickness=*/100,
            /*flow=*/1.0_r,
            GCodePathConfig::SpeedDerivatives(50, 1000, 10)
        ),
        travel_config(
            PrintFeatureType::MoveCombing,
            /*line_width=*/0,
            /*layer_thickness=*/100,
            /*flow=*/0.0_r,
            GCodePathConfig::SpeedDerivatives(120, 5000, 30)
        )
    {
        const std::string mesh_id = "test_mesh";
        constexpr Ratio flow_1 = 1.0_r;
        constexpr bool no_spiralize = false;
        constexpr Ratio speed_1 = 1.0_r;
        square.assign({GCodePath(extrusion_config, mesh_id, SpaceFillType::PolyLines, flow_1, no_spiralize, speed_1)});
        square.back().points = {
            Point(0, 0),
            Point(1000, 0),
            Point(1000, 1000),
            Point(0, 1000),
            Point(0, 0)
        };

        lines.assign({
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1)
        });
        lines[0].points = {Point(0, 0), Point(1000, 0)};
        lines[1].points = {Point(1000, 0), Point(1000, 400)};
        lines[2].points = {Point(1000, 400), Point(0, 400)};
        lines[3].points = {Point(0, 400), Point(0, 800)};
        lines[4].points = {Point(0, 800), Point(1000, 800)};

        constexpr Ratio flow_12 = 1.2_r;
        constexpr Ratio flow_08 = 0.8_r;
        constexpr Ratio flow_04 = 0.4_r;
        decreasing_flow.assign({
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_12, no_spiralize, speed_1),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_08, no_spiralize, speed_1),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_04, no_spiralize, speed_1)
        });
        decreasing_flow[0].points = {Point(0, 0), Point(1000, 0)};
        decreasing_flow[1].points = {Point(1000, 0), Point(1000, 400)};
        decreasing_flow[2].points = {Point(1000, 400), Point(0, 400)};
        decreasing_flow[3].points = {Point(0, 400), Point(0, 800)};
        decreasing_flow[4].points = {Point(0, 800), Point(1000, 800)};

        constexpr Ratio speed_12 = 1.2_r;
        constexpr Ratio speed_08 = 0.8_r;
        constexpr Ratio speed_04 = 0.4_r;
        decreasing_speed.assign({
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_12),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_08),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_04)
        });
        decreasing_speed[0].points = {Point(0, 0), Point(1000, 0)};
        decreasing_speed[1].points = {Point(1000, 0), Point(1000, 400)};
        decreasing_speed[2].points = {Point(1000, 400), Point(0, 400)};
        decreasing_speed[3].points = {Point(0, 400), Point(0, 800)};
        decreasing_speed[4].points = {Point(0, 800), Point(1000, 800)};
    }
};

/*!
 * Tests in this class get parameterized with a vector of GCodePaths to put in
 * the extruder plan, and an extruder plan to put it in.
 */
class ExtruderPlanPathsParameterizedTest : public testing::TestWithParam<std::vector<GCodePath>> {
public:
    /*!
     * An extruder plan that can be used as a victim for testing.
     */
    ExtruderPlan extruder_plan;

    ExtruderPlanPathsParameterizedTest() :
        extruder_plan(
            /*extruder=*/0,
            /*layer_nr=*/50,
            /*is_initial_layer=*/false,
            /*is_raft_layer=*/false,
            /*layer_thickness=*/100,
            FanSpeedLayerTimeSettings(),
            RetractionConfig()
        )
    {}
};

/*!
 * Tests that paths remain unmodified if applying back pressure compensation
 * with factor 0.
 */
TEST_P(ExtruderPlanPathsParameterizedTest, BackPressureCompensationZeroIsUncompensated)
{
    extruder_plan.paths = GetParam();
    std::vector<Ratio> original_flows;
    for(const GCodePath& path : extruder_plan.paths)
    {
        original_flows.push_back(path.flow);
    }

    extruder_plan.applyBackPressureCompensation(0.0_r);

    ASSERT_EQ(extruder_plan.paths.size(), original_flows.size()) << "Number of paths may not have changed.";
    for(size_t i = 0; i < extruder_plan.paths.size(); ++i)
    {
        EXPECT_EQ(original_flows[i], extruder_plan.paths[i].flow) << "The flow rate did not change, because the back pressure compensation ratio was 0.";
    }
}

INSTANTIATE_TEST_CASE_P(ExtruderPlanTestInstantiation, ExtruderPlanPathsParameterizedTest, testing::Values(
        ExtruderPlanTestPathCollection().square,
        ExtruderPlanTestPathCollection().lines,
        ExtruderPlanTestPathCollection().decreasing_flow,
        ExtruderPlanTestPathCollection().decreasing_speed
));

}
<commit_msg>Also test if the speed factor got changed<commit_after>//Copyright (c) 2021 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include <gtest/gtest.h>

#include "../src/LayerPlan.h" //Code under test.

namespace cura
{

/*!
 * A fixture containing some sets of GCodePaths to test with.
 */
class ExtruderPlanTestPathCollection
{
public:
    /*!
     * One path with 5 vertices printing a 1000x1000 micron square starting from
     * 0,0.
     */
    std::vector<GCodePath> square;

    /*!
     * Three lines side by side, with two travel moves in between.
     */
    std::vector<GCodePath> lines;

    /*!
     * Three lines side by side with travel moves in between, but adjusted flow.
     *
     * The first line gets 120% flow.
     * The second line gets 80% flow.
     * The third line gets 40% flow.
     */
    std::vector<GCodePath> decreasing_flow;

    /*!
     * Three lines side by side with their speed factors adjusted.
     *
     * The first line gets 120% speed.
     * The second line gets 80% speed.
     * The third line gets 40% speed.
     */
    std::vector<GCodePath> decreasing_speed;

    /*!
     * Configuration to print extruded paths with in the fixture.
     *
     * This config is referred to via pointer, so changing it will immediately
     * change it for all extruded paths.
     */
    GCodePathConfig extrusion_config;

    /*!
     * Configuration to print travel paths with in the fixture.
     *
     * This config is referred to via pointer, so changing it will immediately
     * change it for all travel paths.
     */
    GCodePathConfig travel_config;

    ExtruderPlanTestPathCollection() :
        extrusion_config(
            PrintFeatureType::OuterWall,
            /*line_width=*/400,
            /*layer_thickness=*/100,
            /*flow=*/1.0_r,
            GCodePathConfig::SpeedDerivatives(50, 1000, 10)
        ),
        travel_config(
            PrintFeatureType::MoveCombing,
            /*line_width=*/0,
            /*layer_thickness=*/100,
            /*flow=*/0.0_r,
            GCodePathConfig::SpeedDerivatives(120, 5000, 30)
        )
    {
        const std::string mesh_id = "test_mesh";
        constexpr Ratio flow_1 = 1.0_r;
        constexpr bool no_spiralize = false;
        constexpr Ratio speed_1 = 1.0_r;
        square.assign({GCodePath(extrusion_config, mesh_id, SpaceFillType::PolyLines, flow_1, no_spiralize, speed_1)});
        square.back().points = {
            Point(0, 0),
            Point(1000, 0),
            Point(1000, 1000),
            Point(0, 1000),
            Point(0, 0)
        };

        lines.assign({
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1)
        });
        lines[0].points = {Point(0, 0), Point(1000, 0)};
        lines[1].points = {Point(1000, 0), Point(1000, 400)};
        lines[2].points = {Point(1000, 400), Point(0, 400)};
        lines[3].points = {Point(0, 400), Point(0, 800)};
        lines[4].points = {Point(0, 800), Point(1000, 800)};

        constexpr Ratio flow_12 = 1.2_r;
        constexpr Ratio flow_08 = 0.8_r;
        constexpr Ratio flow_04 = 0.4_r;
        decreasing_flow.assign({
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_12, no_spiralize, speed_1),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_08, no_spiralize, speed_1),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_04, no_spiralize, speed_1)
        });
        decreasing_flow[0].points = {Point(0, 0), Point(1000, 0)};
        decreasing_flow[1].points = {Point(1000, 0), Point(1000, 400)};
        decreasing_flow[2].points = {Point(1000, 400), Point(0, 400)};
        decreasing_flow[3].points = {Point(0, 400), Point(0, 800)};
        decreasing_flow[4].points = {Point(0, 800), Point(1000, 800)};

        constexpr Ratio speed_12 = 1.2_r;
        constexpr Ratio speed_08 = 0.8_r;
        constexpr Ratio speed_04 = 0.4_r;
        decreasing_speed.assign({
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_12),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_08),
            GCodePath(travel_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_1),
            GCodePath(extrusion_config, mesh_id, SpaceFillType::Lines, flow_1, no_spiralize, speed_04)
        });
        decreasing_speed[0].points = {Point(0, 0), Point(1000, 0)};
        decreasing_speed[1].points = {Point(1000, 0), Point(1000, 400)};
        decreasing_speed[2].points = {Point(1000, 400), Point(0, 400)};
        decreasing_speed[3].points = {Point(0, 400), Point(0, 800)};
        decreasing_speed[4].points = {Point(0, 800), Point(1000, 800)};
    }
};

/*!
 * Tests in this class get parameterized with a vector of GCodePaths to put in
 * the extruder plan, and an extruder plan to put it in.
 */
class ExtruderPlanPathsParameterizedTest : public testing::TestWithParam<std::vector<GCodePath>> {
public:
    /*!
     * An extruder plan that can be used as a victim for testing.
     */
    ExtruderPlan extruder_plan;

    ExtruderPlanPathsParameterizedTest() :
        extruder_plan(
            /*extruder=*/0,
            /*layer_nr=*/50,
            /*is_initial_layer=*/false,
            /*is_raft_layer=*/false,
            /*layer_thickness=*/100,
            FanSpeedLayerTimeSettings(),
            RetractionConfig()
        )
    {}
};

INSTANTIATE_TEST_CASE_P(ExtruderPlanTestInstantiation, ExtruderPlanPathsParameterizedTest, testing::Values(
        ExtruderPlanTestPathCollection().square,
        ExtruderPlanTestPathCollection().lines,
        ExtruderPlanTestPathCollection().decreasing_flow,
        ExtruderPlanTestPathCollection().decreasing_speed
));

/*!
 * Tests that paths remain unmodified if applying back pressure compensation
 * with factor 0.
 */
TEST_P(ExtruderPlanPathsParameterizedTest, BackPressureCompensationZeroIsUncompensated)
{
    extruder_plan.paths = GetParam();
    std::vector<Ratio> original_flows;
    std::vector<Ratio> original_speeds;
    for(const GCodePath& path : extruder_plan.paths)
    {
        original_flows.push_back(path.flow);
        original_speeds.push_back(path.speed_factor);
    }

    extruder_plan.applyBackPressureCompensation(0.0_r);

    ASSERT_EQ(extruder_plan.paths.size(), original_flows.size()) << "Number of paths may not have changed.";
    for(size_t i = 0; i < extruder_plan.paths.size(); ++i)
    {
        EXPECT_EQ(original_flows[i], extruder_plan.paths[i].flow) << "The flow rate did not change. Back pressure compensation doesn't adjust flow.";
        EXPECT_EQ(original_speeds[i], extruder_plan.paths[i].speed_factor) << "The speed factor did not change, since the compensation factor was 0.";
    }
}

}
<|endoftext|>


<commit_before>//
//  main.cpp
//  Assignment
//
//  Created by Teodor on 09/01/2017.
//  Copyright © 2017 TeodorGarzdin. All rights reserved.
//

#include <string>
#include <fstream>
#include <iostream>

class Date {
public:
    unsigned int day;
    unsigned int month;
    unsigned int year;

    Date(const Date& d) {
        day = d.day;
        month = d.month;
        year = d.year;
    }

    Date(const unsigned int d = 0, const unsigned int m = 0, const unsigned int y = 0) {
        this->day = d;
        this->month = m;
        this->year = y;
    }

    friend std::ostream& operator<<(std::ostream& stream, Date& date);

    int operator==(const Date& d) {
        return day == d.day && month == d.month && year == d.year;
    }

    Date& operator=(const Date& d) {
        if(this != &d) {
            day = d.day;
            month = d.month;
            year = d.year;
        }

        return *this;
    }

    unsigned int getDay() {
        return day;
    }

    void setDay(const unsigned int d) {
        if (d > 0) {
            day = d;
        } else {
            throw new std::invalid_argument("Day can't be negative");
        }
    }

    unsigned int getMonth() {
        return month;
    }

    void setMonth(const unsigned int m) {
        if (m > 0) {
            month= m;
        } else {
            throw new std::invalid_argument("Month can't be negative");
        }
    }

    unsigned int getYear() {
        return year;
    }

    void setYear(const unsigned int y) {
        if (y > 0) {
            year = y;
        }
        else {
            throw new std::invalid_argument("Year can't be negative");
        }
    }

    ~Date () {
        std::cout<<"Destructing <Date>"<<std::endl;
    }
};

class Student {
public:
    std::string name;
    std::string facNumber;
    Date birthDate;
    float avScore;

    Student() {}

    Student(std::string n, std::string fn, Date d, float s) {
        this->name = n;
        this->facNumber = fn;
        this->birthDate = d;
        this->avScore = s;
    }

    ~Student() {
        std::cout<<"Destructing <Student>"<<std::endl;
    }

    friend std::ostream& operator<<(std::ostream& stream, Student& student);

    void setName(std::string n) { name = n; }

    std::string getName() { return name; }

    void setFacNumber(std::string id) { facNumber = id; }

    std::string getFacNumber() { return facNumber; }

    void setAvScore(float s) { avScore = s; }

    float getAvScore() { return avScore; }

    int showYears(Date date) {
        if (date.getMonth() > this->birthDate.getMonth()) {
            return (date.getYear() - this->birthDate.getYear());
        } else {
            if (date.getMonth() < this->birthDate.getMonth()) {
                return (date.getYear() - this->birthDate.getYear() - 1);
            } else {
                if (date.getDay() > this->birthDate.getDay()) {
                    return (date.getYear() - this->birthDate.getYear());
                } else {
                    return (date.getYear() - this->birthDate.getYear() - 1);
                }
            }
        }
    }
};

class StudentStream {
public:
    unsigned int number;
    unsigned int numberOfStudents;
    Student students[3];

    StudentStream() {}

    StudentStream(int number, Student students[]) {
        this->number = number;
        this->numberOfStudents = sizeof(this->students);
        for(int i = 0; i<= this->numberOfStudents; i++) {
            this->students[i] = students[i];
        }
    }

    friend std::ostream& operator<<(std::ostream& stream, StudentStream& ss);

    ~StudentStream() {
        std::cout<<"Destructing <StudentStream>"<<std::endl;
    }

    Student getStudentWithHighestGrade() {
        Student currentStudent;
        for(int i = 0; i <= this->numberOfStudents; i++) {
            if(this->students[i].avScore > currentStudent.avScore) currentStudent = this->students[i];
        }
        return currentStudent;
    }

    int writeStudentsIntoFile() {
        if(sizeof(this->students) == 0) {
            std::cout<<"Students array is empty."<<std::endl;
            return 1;
        }

        std::ofstream textFile;
        textFile.open("students.txt");

        if(!textFile) {
            std::cout<<"Cannot open output file."<<std::endl;
            return 1;
        }

        for(unsigned int i=0; i<=sizeof(this->students); i++) {
            textFile<<this->students[i]<<std::endl;
        }

        textFile.close();

        return 0;
    }
};

std::ostream& operator<<(std::ostream& stream, Date& date) {
    return stream<<date.day<<"/"<<date.month<<"/"<<date.year<<std::endl;
}

std::ostream& operator<<(std::ostream& stream, Student& student) {
    return stream<<"Name: "<<student.name<<"Birth date: "<<student.birthDate<<"GPA: "<<student.avScore<<std::endl;
}

std::ostream& operator<<(std::ostream& stream, StudentStream& ss) {
    for(int i = 0; i <= ss.numberOfStudents; i++) {
        if(ss.students[i].showYears(ss.students[i].birthDate) >= 18 && ss.students[i].showYears(ss.students[i].birthDate) <= 26) {
            stream<<ss.students[i].name;
        }
    }
    return stream<<std::endl;
}

int main (int argc, const char * argv[]) {
    Student students[3];
    students[0] = Student("Teodor", "5109238", Date(14, 8, 1995), 5.95);
    students[1] = Student("Julia", "5109237", Date(17, 11, 1995), 5.12);
    students[2] = Student("Georgi", "5109236", Date(5, 9, 1995), 4.49);
    StudentStream ss = StudentStream(1, students);
    ss.writeStudentsIntoFile();

    return 0;
}
<commit_msg>Convert the student array to a vector. Offers better memory management.<commit_after>//
//  main.cpp
//  Assignment
//
//  Created by Teodor on 09/01/2017.
//  Copyright © 2017 TeodorGarzdin. All rights reserved.
//

#include <string>
#include <fstream>
#include <iostream>
#include <vector>

class Date {
public:
    unsigned int day;
    unsigned int month;
    unsigned int year;

    Date(const Date& d) {
        day = d.day;
        month = d.month;
        year = d.year;
    }

    Date(const unsigned int d = 0, const unsigned int m = 0, const unsigned int y = 0) {
        this->day = d;
        this->month = m;
        this->year = y;
    }

    friend std::ostream& operator<<(std::ostream& stream, Date& date);

    int operator==(const Date& d) {
        return day == d.day && month == d.month && year == d.year;
    }

    Date& operator=(const Date& d) {
        if(this != &d) {
            day = d.day;
            month = d.month;
            year = d.year;
        }

        return *this;
    }

    unsigned int getDay() {
        return day;
    }

    void setDay(const unsigned int d) {
        if (d > 0) {
            day = d;
        } else {
            throw new std::invalid_argument("Day can't be negative");
        }
    }

    unsigned int getMonth() {
        return month;
    }

    void setMonth(const unsigned int m) {
        if (m > 0) {
            month= m;
        } else {
            throw new std::invalid_argument("Month can't be negative");
        }
    }

    unsigned int getYear() {
        return year;
    }

    void setYear(const unsigned int y) {
        if (y > 0) {
            year = y;
        }
        else {
            throw new std::invalid_argument("Year can't be negative");
        }
    }

    ~Date () {
        std::cout<<"Destructing <Date>"<<std::endl;
    }
};

class Student {
public:
    std::string name;
    std::string facNumber;
    Date birthDate;
    float avScore;

    Student() {}

    Student(std::string n, std::string fn, Date d, float s) {
        this->name = n;
        this->facNumber = fn;
        this->birthDate = d;
        this->avScore = s;
    }

    ~Student() {
        std::cout<<"Destructing <Student>"<<std::endl;
    }

    friend std::ostream& operator<<(std::ostream& stream, Student& student);

    void setName(std::string n) { name = n; }

    std::string getName() { return name; }

    void setFacNumber(std::string id) { facNumber = id; }

    std::string getFacNumber() { return facNumber; }

    void setAvScore(float s) { avScore = s; }

    float getAvScore() { return avScore; }

    int showYears(Date date) {
        if (date.getMonth() > this->birthDate.getMonth()) {
            return (date.getYear() - this->birthDate.getYear());
        } else {
            if (date.getMonth() < this->birthDate.getMonth()) {
                return (date.getYear() - this->birthDate.getYear() - 1);
            } else {
                if (date.getDay() > this->birthDate.getDay()) {
                    return (date.getYear() - this->birthDate.getYear());
                } else {
                    return (date.getYear() - this->birthDate.getYear() - 1);
                }
            }
        }
    }
};

class StudentStream {
public:
    unsigned int number;
    std::vector<Student> students;

    StudentStream() {
        std::cout<<"Destructing <StudentStream>"<<std::endl;
    }

    StudentStream(int number, std::vector<Student> students) {
        this->number = number;
        this->students = students;
    }

    friend std::ostream& operator<<(std::ostream& stream, StudentStream& ss);

    ~StudentStream() {
        std::cout<<"Destructing <StudentStream>"<<std::endl;
    }

    Student getStudentWithHighestGrade() {
        Student currentStudent;
        for(int i = 0; i <= this->students.size(); i++) {
            if(this->students[i].avScore > currentStudent.avScore) currentStudent = this->students[i];
        }
        return currentStudent;
    }

    int writeStudentsIntoFile() {
        if(sizeof(this->students) == 0) {
            std::cout<<"Students array is empty."<<std::endl;
            return 1;
        }

        std::ofstream textFile;
        textFile.open("students.txt");

        if(!textFile) {
            std::cout<<"Cannot open output file."<<std::endl;
            return 1;
        }

        for(unsigned int i=0; i<=sizeof(this->students); i++) {
            textFile<<this->students[i]<<std::endl;
        }

        textFile.close();

        return 0;
    }
};

std::ostream& operator<<(std::ostream& stream, Date& date) {
    return stream<<date.day<<"/"<<date.month<<"/"<<date.year<<std::endl;
}

std::ostream& operator<<(std::ostream& stream, Student& student) {
    return stream<<"Name: "<<student.name<<"Birth date: "<<student.birthDate<<"GPA: "<<student.avScore<<std::endl;
}

std::ostream& operator<<(std::ostream& stream, StudentStream& ss) {
    for(int i = 0; i <= ss.students.size(); i++) {
        if(ss.students[i].showYears(ss.students[i].birthDate) >= 18 && ss.students[i].showYears(ss.students[i].birthDate) <= 26) {
            stream<<ss.students[i].name;
        }
    }
    return stream<<std::endl;
}

int main (int argc, const char * argv[]) {
    std::vector<Student> students;
    students[0] = Student("Teodor", "5109238", Date(14, 8, 1995), 5.95);
    students[1] = Student("Julia", "5109237", Date(17, 11, 1995), 5.12);
    students[2] = Student("Georgi", "5109236", Date(5, 9, 1995), 4.49);
    StudentStream ss = StudentStream(1, students);
    ss.writeStudentsIntoFile();

    return 0;
}
<|endoftext|>


<commit_before><commit_msg>Fail fast at least in debug builds<commit_after><|endoftext|>


<commit_before><commit_msg>refactored init code to use our FSM event loop<commit_after><|endoftext|>


<commit_before>#include <exception>
#include <iostream>
#include <vector>
#include <context.h>
#include <parser.h>
#include <image.h>
#include <exception.h>
#include <cxxopts.hpp>
#include <CLIbuiltinDrawAST.h>

using namespace std;
using namespace ast;
using namespace parser;
using namespace lexers;
using namespace cxxopts;
using namespace context;
using namespace exception;

INITIALIZE_EASYLOGGINGPP

int main(int argc, char *argv[]) {
    START_EASYLOGGINGPP(argc, argv);
    el::Logger *parserLogger = el::Loggers::getLogger("parser");
    el::Logger *exceptionLogger = el::Loggers::getLogger("exception");
    el::Loggers::reconfigureAllLoggers(el::ConfigurationType::ToFile, "false");
    el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Format,
                                       "[%logger] %msg [%fbase:%line]");
    try {
        Options options(argv[0], " - command line options");
        options.add_options()("o,output", "output filename", value<std::string>()->default_value("output.bmp"));
        options.parse(argc, argv);

        Scope scope;
        Image image(1000, 1000);
        scope.addBuiltinFunc("#painter", std::make_shared<ast::CLIBuiltinDrawAST>(image));
        Lexer lex;
        lex.appendExp("(load \"setup.scm\")").appendExp(string("(load \"") + argv[argc - 1] + "\")");
        shared_ptr<ExprAST> ptr = parseAllExpr(lex)->eval(scope);
        if (ptr) {
            cout << ptr->display();
        }
        image.save(options["output"].as<string>().c_str());
    } catch (RuntimeError &e) {
        cout << e.what() << endl;
        throw;
    } catch (const OptionException &e) {
        cout << "error parsing options: " << e.what()
             << "Try \' --help\' for more information." << endl;
        throw;
    } catch (std::exception &e) {
        cout << e.what() << endl;
        throw;
    }
    return 0;
}
<commit_msg>support positional arguments<commit_after>#include <exception>
#include <iostream>
#include <vector>
#include <context.h>
#include <parser.h>
#include <image.h>
#include <exception.h>
#include <cxxopts.hpp>
#include <CLIbuiltinDrawAST.h>

using namespace std;
using namespace ast;
using namespace parser;
using namespace lexers;
using namespace cxxopts;
using namespace context;
using namespace exception;

INITIALIZE_EASYLOGGINGPP

int main(int argc, char *argv[]) {
    START_EASYLOGGINGPP(argc, argv);
    el::Logger *parserLogger = el::Loggers::getLogger("parser");
    el::Logger *exceptionLogger = el::Loggers::getLogger("exception");
    el::Loggers::reconfigureAllLoggers(el::ConfigurationType::ToFile, "false");
    el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Format,
                                       "[%logger] %msg [%fbase:%line]");
    try {
        Options options(argv[0], " - command line options");
        options.add_options()("o,output", "output filename", value<std::string>()->default_value("output.bmp"))
                ("src", "src filename", cxxopts::value<std::vector<std::string>>());
        options.parse_positional("src");
        options.parse(argc, argv);

        Lexer lex;
        Scope scope;
        Image image(1000, 1000);
        scope.addBuiltinFunc("#painter", std::make_shared<ast::CLIBuiltinDrawAST>(image));
        lex.appendExp("(load \"setup.scm\")");
        parseAllExpr(lex)->eval(scope);
        auto &v = options["src"].as<std::vector<std::string>>();
        for (const auto &s : v) {
            lex.appendExp(string("(load \"") + s + "\")");
            shared_ptr<ExprAST> ptr = parseAllExpr(lex)->eval(scope);
            if (ptr) {
                cout << ptr->display();
            }
        }
        image.save(options["output"].as<string>().c_str());
    } catch (RuntimeError &e) {
        cout << e.what() << endl;
        throw;
    } catch (const OptionException &e) {
        cout << "error parsing options: " << e.what()
             << "Try \' --help\' for more information." << endl;
        throw;
    } catch (std::exception &e) {
        cout << e.what() << endl;
        throw;
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
   Clique: a scalable implementation of the multifrontal algorithm

   Copyright (C) 2011-2012 Jack Poulson, Lexing Ying, and
   The University of Texas at Austin

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

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

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "clique.hpp"
using namespace cliq;

void Usage()
{
    std::cout
      << "HelmholtzDirichlet2D <nx> <ny> <omega> <damping> "
      << "[analytic=true] [sequential=true] [cutoff=128] \n"
      << "[numDistSeps=1] [numSeqSeps=1]\n"
      << "  nx: first dimension of nx x ny x n3 mesh\n"
      << "  ny: second dimension of nx x ny x n3 mesh\n"
      << "  omega: frequency of problem in radians per second\n"
      << "  damping: imaginary damping in radians per second\n"
      << "  analytic: if nonzero, use an analytical reordering\n"
      << "  sequential: if nonzero, then run a sequential symbolic reordering\n"
      << "  cutoff: maximum size of leaf node\n"
      << "  numDistSeps: number of distributed separators to try\n"
      << "  numSeqSeps: number of sequential separators to try\n"
      << std::endl;
}

int
main( int argc, char* argv[] )
{
    cliq::Initialize( argc, argv );
    mpi::Comm comm = mpi::COMM_WORLD;
    const int commRank = mpi::CommRank( comm );
    typedef double R;
    typedef Complex<R> C;

    if( argc < 5 )
    {
        if( commRank == 0 )
            Usage();
        cliq::Finalize();
        return 0;
    }
    const int nx = atoi( argv[1] );
    const int ny = atoi( argv[2] );
    const double omega = atof( argv[3] );
    const double damping = atof( argv[4] );
    const bool analytic = ( argc >= 6 ? atoi( argv[5] ) : true );
    const bool sequential = ( argc >= 7 ? atoi( argv[6] ) : true );
    const int cutoff = ( argc >= 8 ? atoi( argv[7] ) : 128 );
    const int numDistSeps = ( argc >= 9 ? atoi( argv[8] ) : 1 );
    const int numSeqSeps = ( argc >= 10 ? atoi( argv[9] ) : 1 );

    try
    {
        const int N = nx*ny;
        DistSparseMatrix<C> A( N, comm );
        C dampedOmega( omega, damping );
        const double h1Inv = nx;
        const double h2Inv = ny;
        const double h1InvSquared = h1Inv*h1Inv;
        const double h2InvSquared = h2Inv*h2Inv;

        // Fill our portion of the 2D Helmholtz operator over the unit-square
        // using a nx x ny 7-point stencil in natural ordering:
        // (x,y) at x + y*nx
        if( commRank == 0 )
        {
            std::cout << "Filling local portion of matrix...";
            std::cout.flush();
        }
        const double fillStart = mpi::Time();
        const int firstLocalRow = A.FirstLocalRow();
        const int localHeight = A.LocalHeight();
        A.StartAssembly();
        A.Reserve( 5*localHeight );
        for( int iLocal=0; iLocal<localHeight; ++iLocal )
        {
            const int i = firstLocalRow + iLocal;
            const int x = i % nx;
            const int y = i/nx;

            A.Update( i, i, 6.-dampedOmega*dampedOmega );
            if( x != 0 )
                A.Update( i, i-1, -h1InvSquared );
            if( x != nx-1 )
                A.Update( i, i+1, -h1InvSquared );
            if( y != 0 )
                A.Update( i, i-nx, -h2InvSquared );
            if( y != ny-1 )
                A.Update( i, i+nx, -h2InvSquared );
        }
        A.StopAssembly();
        mpi::Barrier( comm );
        const double fillStop =  mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << fillStop-fillStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
        {
            std::cout << "Generating random vector x and forming y := A x...";
            std::cout.flush();
        }
        const double multiplyStart = mpi::Time();
        DistVector<C> x( N, comm ), y( N, comm );
        MakeUniform( x );
        MakeZeros( y );
        Multiply( (C)1., A, x, (C)0., y );
        const double yOrigNorm = Norm( y );
        mpi::Barrier( comm );
        const double multiplyStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << multiplyStop-multiplyStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
        {
            std::cout << "Running nested dissection...";
            std::cout.flush();
        }
        const double nestedStart = mpi::Time();
        const DistGraph& graph = A.Graph();
        DistSymmInfo info;
        DistSeparatorTree sepTree;
        DistMap map, inverseMap;
        if( analytic )
            NaturalNestedDissection
            ( nx, ny, 1, graph, map, sepTree, info, cutoff );
        else
            NestedDissection
            ( graph, map, sepTree, info,
              sequential, cutoff, numDistSeps, numSeqSeps );
        map.FormInverse( inverseMap );
        mpi::Barrier( comm );
        const double nestedStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << nestedStop-nestedStart << " seconds"
                      << std::endl;

        const int rootSepSize = info.distNodes.back().size;
        if( commRank == 0 )
        {
            const int numDistNodes = info.distNodes.size();
            const int numLocalNodes = info.localNodes.size();
            std::cout << "\n"
                      << "On the root process:\n"
                      << "-----------------------------------------\n"
                      << numLocalNodes << " local nodes\n"
                      << numDistNodes  << " distributed nodes\n"
                      << rootSepSize << " vertices in root separator\n"
                      << std::endl;
        }

        if( commRank == 0 )
        {
            std::cout << "Building DistSymmFrontTree...";
            std::cout.flush();
        }
        mpi::Barrier( comm );
        const double buildStart = mpi::Time();
        DistSymmFrontTree<C> frontTree( TRANSPOSE, A, map, sepTree, info );
        mpi::Barrier( comm );
        const double buildStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << buildStop-buildStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
        {
            std::cout << "Running block LDL^T...";
            std::cout.flush();
        }
        mpi::Barrier( comm );
        const double ldlStart = mpi::Time();
        BlockLDL( TRANSPOSE, info, frontTree );
        mpi::Barrier( comm );
        const double ldlStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << ldlStop-ldlStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
        {
            std::cout << "Computing SVD of the largest off-diagonal block of "
                         "numerical Green's function on root separator...";
            std::cout.flush();
        }
        const double svdStart = mpi::Time();
        const DistMatrix<C>& rootFront = frontTree.distFronts.back().front2dL;
        const Grid& rootGrid = rootFront.Grid();
        const int lowerHalf = rootSepSize/2;
        const int upperHalf = rootSepSize - lowerHalf;
        if( commRank == 0 )
            std::cout << "lowerHalf=" << lowerHalf
                      << ", upperHalf=" << upperHalf << std::endl;
        DistMatrix<C> offDiagBlock;
        offDiagBlock.LockedView
        ( rootFront, lowerHalf, 0, upperHalf, lowerHalf );
        DistMatrix<C> offDiagBlockCopy( offDiagBlock );
        DistMatrix<R,VR,STAR> singVals_VR_STAR( rootGrid );
        elem::SingularValues( offDiagBlockCopy, singVals_VR_STAR );
        const R twoNorm = elem::Norm( singVals_VR_STAR, elem::INFINITY_NORM );
        const R tolerance = 1e-4;
        DistMatrix<R,STAR,STAR> singVals( singVals_VR_STAR );
        int numRank = lowerHalf;
        for( int j=0; j<lowerHalf; ++j )
        {
            if( singVals.GetLocal(j,0) <= twoNorm*tolerance )
            {
                numRank = j;
                break;
            }
        }
        mpi::Barrier( comm );
        const double svdStop = mpi::Time();
        if( commRank == 0 )
        {
            std::cout << "done, " << svdStop-svdStart << " seconds\n"
                      << "  two norm=" << twoNorm << "\n"
                      << "  numerical rank=" << numRank << "/" << lowerHalf
                      << std::endl;
        }

        if( commRank == 0 )
        {
            std::cout << "Solving against y...";
            std::cout.flush();
        }
        const double solveStart = mpi::Time();
        DistNodalVector<C> yNodal;
        yNodal.Pull( inverseMap, info, y );
        BlockLDLSolve( TRANSPOSE, info, frontTree, yNodal.localVec );
        yNodal.Push( inverseMap, info, y );
        mpi::Barrier( comm );
        const double solveStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << solveStop-solveStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
            std::cout << "Checking error in computed solution..." << std::endl;
        const double xNorm = Norm( x );
        const double yNorm = Norm( y );
        Axpy( (C)-1., x, y );
        const double errorNorm = Norm( y );
        if( commRank == 0 )
        {
            std::cout << "|| x     ||_2 = " << xNorm << "\n"
                      << "|| xComp ||_2 = " << yNorm << "\n"
                      << "|| A x   ||_2 = " << yOrigNorm << "\n"
                      << "|| error ||_2 / || A x ||_2 = " << errorNorm/yOrigNorm
                      << std::endl;
        }
    }
    catch( std::exception& e )
    {
#ifndef RELEASE
        elem::DumpCallStack();
        cliq::DumpCallStack();
#endif
        std::ostringstream msg;
        msg << "Process " << commRank << " caught message:\n"
            << e.what() << "\n";
        std::cerr << msg.str() << std::endl;
    }

    cliq::Finalize();
    return 0;
}
<commit_msg>Fixing Helmholtz assembly.<commit_after>/*
   Clique: a scalable implementation of the multifrontal algorithm

   Copyright (C) 2011-2012 Jack Poulson, Lexing Ying, and
   The University of Texas at Austin

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

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

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "clique.hpp"
using namespace cliq;

void Usage()
{
    std::cout
      << "HelmholtzDirichlet2D <nx> <ny> <omega> <damping> "
      << "[analytic=true] [sequential=true] [cutoff=128] \n"
      << "[numDistSeps=1] [numSeqSeps=1]\n"
      << "  nx: first dimension of nx x ny x n3 mesh\n"
      << "  ny: second dimension of nx x ny x n3 mesh\n"
      << "  omega: frequency of problem in radians per second\n"
      << "  damping: imaginary damping in radians per second\n"
      << "  analytic: if nonzero, use an analytical reordering\n"
      << "  sequential: if nonzero, then run a sequential symbolic reordering\n"
      << "  cutoff: maximum size of leaf node\n"
      << "  numDistSeps: number of distributed separators to try\n"
      << "  numSeqSeps: number of sequential separators to try\n"
      << std::endl;
}

int
main( int argc, char* argv[] )
{
    cliq::Initialize( argc, argv );
    mpi::Comm comm = mpi::COMM_WORLD;
    const int commRank = mpi::CommRank( comm );
    typedef double R;
    typedef Complex<R> C;

    if( argc < 5 )
    {
        if( commRank == 0 )
            Usage();
        cliq::Finalize();
        return 0;
    }
    const int nx = atoi( argv[1] );
    const int ny = atoi( argv[2] );
    const double omega = atof( argv[3] );
    const double damping = atof( argv[4] );
    const bool analytic = ( argc >= 6 ? atoi( argv[5] ) : true );
    const bool sequential = ( argc >= 7 ? atoi( argv[6] ) : true );
    const int cutoff = ( argc >= 8 ? atoi( argv[7] ) : 128 );
    const int numDistSeps = ( argc >= 9 ? atoi( argv[8] ) : 1 );
    const int numSeqSeps = ( argc >= 10 ? atoi( argv[9] ) : 1 );

    try
    {
        const int N = nx*ny;
        DistSparseMatrix<C> A( N, comm );
        C dampedOmega( omega, damping );
        const double h1Inv = nx;
        const double h2Inv = ny;
        const double h1InvSquared = h1Inv*h1Inv;
        const double h2InvSquared = h2Inv*h2Inv;
        const C mainTerm =
            2*(h1InvSquared+h2InvSquared) - dampedOmega*dampedOmega;

        // Fill our portion of the 2D Helmholtz operator over the unit-square
        // using a nx x ny 7-point stencil in natural ordering:
        // (x,y) at x + y*nx
        if( commRank == 0 )
        {
            std::cout << "Filling local portion of matrix...";
            std::cout.flush();
        }
        const double fillStart = mpi::Time();
        const int firstLocalRow = A.FirstLocalRow();
        const int localHeight = A.LocalHeight();
        A.StartAssembly();
        A.Reserve( 5*localHeight );
        for( int iLocal=0; iLocal<localHeight; ++iLocal )
        {
            const int i = firstLocalRow + iLocal;
            const int x = i % nx;
            const int y = i/nx;

            A.Update( i, i, mainTerm );
            if( x != 0 )
                A.Update( i, i-1, -h1InvSquared );
            if( x != nx-1 )
                A.Update( i, i+1, -h1InvSquared );
            if( y != 0 )
                A.Update( i, i-nx, -h2InvSquared );
            if( y != ny-1 )
                A.Update( i, i+nx, -h2InvSquared );
        }
        A.StopAssembly();
        mpi::Barrier( comm );
        const double fillStop =  mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << fillStop-fillStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
        {
            std::cout << "Generating random vector x and forming y := A x...";
            std::cout.flush();
        }
        const double multiplyStart = mpi::Time();
        DistVector<C> x( N, comm ), y( N, comm );
        MakeUniform( x );
        MakeZeros( y );
        Multiply( (C)1., A, x, (C)0., y );
        const double yOrigNorm = Norm( y );
        mpi::Barrier( comm );
        const double multiplyStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << multiplyStop-multiplyStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
        {
            std::cout << "Running nested dissection...";
            std::cout.flush();
        }
        const double nestedStart = mpi::Time();
        const DistGraph& graph = A.Graph();
        DistSymmInfo info;
        DistSeparatorTree sepTree;
        DistMap map, inverseMap;
        if( analytic )
            NaturalNestedDissection
            ( nx, ny, 1, graph, map, sepTree, info, cutoff );
        else
            NestedDissection
            ( graph, map, sepTree, info,
              sequential, cutoff, numDistSeps, numSeqSeps );
        map.FormInverse( inverseMap );
        mpi::Barrier( comm );
        const double nestedStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << nestedStop-nestedStart << " seconds"
                      << std::endl;

        const int rootSepSize = info.distNodes.back().size;
        if( commRank == 0 )
        {
            const int numDistNodes = info.distNodes.size();
            const int numLocalNodes = info.localNodes.size();
            std::cout << "\n"
                      << "On the root process:\n"
                      << "-----------------------------------------\n"
                      << numLocalNodes << " local nodes\n"
                      << numDistNodes  << " distributed nodes\n"
                      << rootSepSize << " vertices in root separator\n"
                      << std::endl;
        }

        if( commRank == 0 )
        {
            std::cout << "Building DistSymmFrontTree...";
            std::cout.flush();
        }
        mpi::Barrier( comm );
        const double buildStart = mpi::Time();
        DistSymmFrontTree<C> frontTree( TRANSPOSE, A, map, sepTree, info );
        mpi::Barrier( comm );
        const double buildStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << buildStop-buildStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
        {
            std::cout << "Running block LDL^T...";
            std::cout.flush();
        }
        mpi::Barrier( comm );
        const double ldlStart = mpi::Time();
        BlockLDL( TRANSPOSE, info, frontTree );
        mpi::Barrier( comm );
        const double ldlStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << ldlStop-ldlStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
        {
            std::cout << "Computing SVD of the largest off-diagonal block of "
                         "numerical Green's function on root separator...";
            std::cout.flush();
        }
        const double svdStart = mpi::Time();
        const DistMatrix<C>& rootFront = frontTree.distFronts.back().front2dL;
        const Grid& rootGrid = rootFront.Grid();
        const int lowerHalf = rootSepSize/2;
        const int upperHalf = rootSepSize - lowerHalf;
        if( commRank == 0 )
            std::cout << "lowerHalf=" << lowerHalf
                      << ", upperHalf=" << upperHalf << std::endl;
        DistMatrix<C> offDiagBlock;
        offDiagBlock.LockedView
        ( rootFront, lowerHalf, 0, upperHalf, lowerHalf );
        DistMatrix<C> offDiagBlockCopy( offDiagBlock );
        DistMatrix<R,VR,STAR> singVals_VR_STAR( rootGrid );
        elem::SingularValues( offDiagBlockCopy, singVals_VR_STAR );
        const R twoNorm = elem::Norm( singVals_VR_STAR, elem::INFINITY_NORM );
        const R tolerance = 1e-4;
        DistMatrix<R,STAR,STAR> singVals( singVals_VR_STAR );
        int numRank = lowerHalf;
        for( int j=0; j<lowerHalf; ++j )
        {
            if( singVals.GetLocal(j,0) <= twoNorm*tolerance )
            {
                numRank = j;
                break;
            }
        }
        mpi::Barrier( comm );
        const double svdStop = mpi::Time();
        if( commRank == 0 )
        {
            std::cout << "done, " << svdStop-svdStart << " seconds\n"
                      << "  two norm=" << twoNorm << "\n"
                      << "  numerical rank=" << numRank << "/" << lowerHalf
                      << std::endl;
        }

        if( commRank == 0 )
        {
            std::cout << "Solving against y...";
            std::cout.flush();
        }
        const double solveStart = mpi::Time();
        DistNodalVector<C> yNodal;
        yNodal.Pull( inverseMap, info, y );
        BlockLDLSolve( TRANSPOSE, info, frontTree, yNodal.localVec );
        yNodal.Push( inverseMap, info, y );
        mpi::Barrier( comm );
        const double solveStop = mpi::Time();
        if( commRank == 0 )
            std::cout << "done, " << solveStop-solveStart << " seconds"
                      << std::endl;

        if( commRank == 0 )
            std::cout << "Checking error in computed solution..." << std::endl;
        const double xNorm = Norm( x );
        const double yNorm = Norm( y );
        Axpy( (C)-1., x, y );
        const double errorNorm = Norm( y );
        if( commRank == 0 )
        {
            std::cout << "|| x     ||_2 = " << xNorm << "\n"
                      << "|| xComp ||_2 = " << yNorm << "\n"
                      << "|| A x   ||_2 = " << yOrigNorm << "\n"
                      << "|| error ||_2 / || A x ||_2 = " << errorNorm/yOrigNorm
                      << std::endl;
        }
    }
    catch( std::exception& e )
    {
#ifndef RELEASE
        elem::DumpCallStack();
        cliq::DumpCallStack();
#endif
        std::ostringstream msg;
        msg << "Process " << commRank << " caught message:\n"
            << e.what() << "\n";
        std::cerr << msg.str() << std::endl;
    }

    cliq::Finalize();
    return 0;
}
<|endoftext|>


<commit_before>// Battleship_test.cpp
//
// For CS 372 Spring 2016
// Unit tests for Battleship Project
// Uses the "Catch" C++ Unit-Testing Framework

#define CATCH_CONFIG_MAIN  // We want Catch to write function main
#include "catch.hpp"       // For the "Catch" unit-testing framework

#include "Board.h"

#include <vector>
using std::vector;
#include <algorithm>
using std::equal;
#include <cstddef>
using std::size_t;
#include <functional>
using std::function;
using std::bind;
using namespace std::placeholders;
// For _1, used with std::bind

// ***** Test Cases *****

TEST_CASE("2 param  Constructor", "[Board]")
{
	Board primary(10,true);

	REQUIRE(primary.getSize() == 10);
	REQUIRE(primary.isPrimary() == true);

	Board target(10,false); //Testing Target board construction
	REQUIRE(target.getSize() == 10);
	REQUIRE(target.isPrimary() == false);

}

TEST_CASE("GUI Set-up Tests", "[ex b]")
{
	REQUIRE(gui_Include);
	REQUIRE(gui_Init);
	REQUIRE(gui_Board);

}

<commit_msg>Added more tests for Board and cell functionality<commit_after>// Battleship_test.cpp
//
// For CS 372 Spring 2016
// Unit tests for Battleship Project
// Uses the "Catch" C++ Unit-Testing Framework

#define CATCH_CONFIG_MAIN  // We want Catch to write function main
#include "catch.hpp"       // For the "Catch" unit-testing framework

#include "Board.h"
#include "Cell.h"

#include <vector>
using std::vector;
#include <algorithm>
using std::equal;
#include <cstddef>
using std::size_t;
#include <functional>
using std::function;
using std::bind;
using namespace std::placeholders;
// For _1, used with std::bind

// ***** Test Cases *****

TEST_CASE("2 param  Constructor", "[Board]")
{
	const int SIZE = 10;
	const int CELLS = SIZE*SIZE;
	Board primary(SIZE,true);

	REQUIRE(primary.getSize() == SIZE);
	REQUIRE(primary.isPrimary() == true);

	Board target(SIZE,false); //Testing Target board construction
	REQUIRE(target.getSize() == SIZE);
	REQUIRE(target.isPrimary() == false);

}

TEST_CASE(" Testing manipulating cells from board","[BOARD]")
{
	const int SIZE = 10;
	const int CELLS = SIZE*SIZE;
	Board cellTest(SIZE,true);

	REQUIRE(cellTest.isPrimary() == true);
	REQUIRE(cellTest.totalCells() == CELLS);
	cellTest.setHead(10);
	REQUIRE(cellTest.isHead(10) == true);
	cellTest.setOccupied(10);
	REQUIRE(cellTest.isOccupied(10) == true);

}

//Tests to see if cell properties are correctly returned
TEST_CASE("Setting Cell Properties", "[CELL]")
{
	Cell cell1;
	REQUIRE(cell1.isOccupied() == false);
	cell1.setOccupied();
	REQUIRE(cell1.isOccupied() == true);

	REQUIRE(cell1.isHead() == false);
	cell1.setHead();
	REQUIRE(cell1.isHead() == true);

}

TEST_CASE("GUI Set-up Tests", "[ex b]")
{
	REQUIRE(gui_Include);
	REQUIRE(gui_Init);
	REQUIRE(gui_Board);

}

<|endoftext|>