<commit_before>#include "dsa_common.h"

#include "tcp_connection.h"

#include <boost/bind.hpp>

#include "session_manager.h"

namespace dsa {

TcpConnection::TcpConnection(std::shared_ptr<App> app, const Config &config)
    : Connection(app, config), _socket(app->io_service()), _strand(app->io_service()) {
}

void TcpConnection::close() {
  _socket.cancel();
  _deadline->cancel();
}

void TcpConnection::read_loop(size_t from_prev, const boost::system::error_code &error, size_t bytes_transferred) {
  // reset deadline timer for each new message
  reset_standard_deadline_timer();

  if (!error /* && !destroyed() */) {
    std::cout << std::endl << "in read loop" << std::endl;

    BufferPtr buf = std::move(_read_buffer);
    _read_buffer.reset(new Buffer());

    size_t total_bytes = from_prev + bytes_transferred;
    uint8_t *data = buf->data();
    size_t cur = 0;

    while (cur < total_bytes) {
      // always want full static header instead of just message size to make sure it's a valid message
      if (total_bytes - cur < StaticHeaders::TotalSize) {
        size_t partial_size = total_bytes - cur;
        _read_buffer->assign(&data[cur], partial_size);
        _socket.async_read_some(boost::asio::buffer(_read_buffer->data() + partial_size,
                                                    _read_buffer->capacity() - partial_size),
                                boost::bind(&TcpConnection::read_loop, share_this<TcpConnection>(), partial_size,
                                            boost::asio::placeholders::error,
                                            boost::asio::placeholders::bytes_transferred));
        return;
      }

      StaticHeaders header(&data[cur]);
      if (header.message_size < total_bytes - cur) {
        size_t partial_size = total_bytes - cur;

        // make sure buffer capacity is enough to read full message
        _read_buffer->resize(header.message_size);
        _read_buffer->assign(&data[cur], partial_size);

        // read the rest of the message
        boost::asio::async_read(_socket,
                                boost::asio::buffer(_read_buffer->data() + partial_size,
                                                    _read_buffer->capacity() - partial_size),
                                boost::bind(&TcpConnection::read_loop, share_this<TcpConnection>(), partial_size,
                                            boost::asio::placeholders::error,
                                            boost::asio::placeholders::bytes_transferred));
        return;
      }

      // post job with message buffer
      _app->io_service().post(boost::bind(&TcpConnection::handle_message, shared_from_this(),
                                         buf->get_shared_buffer(cur, header.message_size)));

      cur += header.message_size;
    }

    _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                            boost::bind(&TcpConnection::read_loop, share_this<TcpConnection>(), 0,
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));
  }
}

void TcpConnection::write_handler(WriteHandler callback, const boost::system::error_code &error) {
  if (!error /* && !destroyed() */) callback();
}

void TcpConnection::write(BufferPtr buf, size_t size, WriteHandler callback) {
  // check to see if current number of pending messages is above allowed limit
  if (++_pending_messages > _config.max_pending_messages()) {
    close();
    return;
  }

  boost::asio::async_write(_socket, boost::asio::buffer(buf->data(), size),
                           boost::bind(&TcpConnection::write_handler, share_this<TcpConnection>(), callback,
                                       boost::asio::placeholders::error));
}

void TcpConnection::start() throw() {
  if (_session == nullptr)
    throw std::runtime_error("Error: connection started with no session");
  _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                          boost::bind(&TcpConnection::read_loop, share_this<TcpConnection>(), 0,
                                      boost::asio::placeholders::error, 0));
}

tcp_socket &TcpConnection::socket() { return _socket; }

//////////////////////////////////////
// TcpServerConnection
//////////////////////////////////////
TcpServerConnection::TcpServerConnection(std::shared_ptr<App> app, const Server::Config &config)
    : Connection(app, Config()), TcpConnection(app, Config(config.message_handler())) {
  _path = std::make_shared<Buffer>(config.path());
}

void TcpServerConnection::connect() {
  start_handshake();
}

void TcpServerConnection::start_handshake() {
  // start timeout timer with handshake timeout specified in config
  _deadline->expires_from_now(boost::posix_time::milliseconds(_config.handshake_timout()));
  _deadline->async_wait(boost::bind(&TcpServerConnection::timeout,
                                    share_this<TcpServerConnection>(),
                                    boost::asio::placeholders::error));

  // start listening for f0
  _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                          boost::bind(&TcpServerConnection::f0_received, share_this<TcpServerConnection>(),
                                      boost::asio::placeholders::error,
                                      boost::asio::placeholders::bytes_transferred));

  // prepare and send f1 then make sure it was successful [success_or_close(...)]
  size_t f1_size = load_f1(*_write_buffer);
  boost::asio::async_write(_socket, boost::asio::buffer(_write_buffer->data(), f1_size),
                           boost::bind(&TcpServerConnection::success_or_close, share_this<TcpServerConnection>(),
                                       boost::asio::placeholders::error));
}

void TcpServerConnection::f0_received(const boost::system::error_code &error, size_t bytes_transferred) {
  // reset timeout
  _deadline->expires_from_now(boost::posix_time::milliseconds(_config.handshake_timout()));
  _deadline->async_wait(boost::bind(&TcpServerConnection::timeout, share_this<TcpServerConnection>(),
                                    boost::asio::placeholders::error));

  if (!error /* && !destroyed() */ && parse_f0(bytes_transferred)) {
    // start shared_secret computation
    _strand.post(boost::bind(&TcpServerConnection::compute_secret, this));

    // read and goto -> f2_received()
    _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                            boost::bind(&TcpServerConnection::f2_received, share_this<TcpServerConnection>(),
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));
  }
}

void TcpServerConnection::f2_received(const boost::system::error_code &error, size_t bytes_transferred) {
  // stop timeout timer
  _deadline->cancel();

  if (!error /* && !destroyed() */ && parse_f2(bytes_transferred)) {
    // setup session now that client session id has been parsed
    if (auto server = _server.lock()) {
      std::string session_id = _session_id->to_string();
      _session = server->session_manager()->get_session(_app->security_context().dsid(), session_id);
      if (_session == nullptr) _session = server->session_manager()->create_session(_app->security_context().dsid());
    } else {
      // if server no longer exists, connection needs to shutdown
      return;
    }

    _session_id = _session->session_id();

    // wait for shared secret computation to finish then send f3
    _strand.post(boost::bind(&TcpServerConnection::send_f3, share_this<TcpServerConnection>()));

    // start session
    _session->set_connection(shared_from_this());
    _session->start();
  }
}

void TcpServerConnection::send_f3() {
  // send f3
  size_t f3_size = load_f3(*_read_buffer);
  boost::asio::async_write(_socket, boost::asio::buffer(_read_buffer->data(), f3_size),
                           boost::bind(&TcpServerConnection::success_or_close, shared_from_this(),
                                       boost::asio::placeholders::error));
}

//////////////////////////////////
// TcpClientConnection
//////////////////////////////////
TcpClientConnection::TcpClientConnection(std::shared_ptr<App> app)
    : Connection(app, Config()), TcpConnection(app, Config()) {}

TcpClientConnection::TcpClientConnection(std::shared_ptr<App> app, const Config &config)
    : Connection(app, Config()), TcpConnection(app, config) {}

void TcpClientConnection::connect() {
  using tcp = boost::asio::ip::tcp;
  tcp::resolver resolver(_app->io_service());
  tcp::resolver::query query(_config.host(), std::to_string(_config.port()));
  tcp::endpoint endpoint = *resolver.resolve(query);
  _socket.async_connect(*resolver.resolve(query),
                        boost::bind(&TcpClientConnection::start_handshake, share_this<TcpClientConnection>(),
                                    boost::asio::placeholders::error));
}

void TcpClientConnection::start_handshake(const boost::system::error_code &error) {
  if (error != nullptr) throw std::runtime_error("Couldn't connect to specified host");
  // start timeout timer
  _deadline->expires_from_now(boost::posix_time::milliseconds(_config.handshake_timout()));
  _deadline->async_wait(boost::bind(&TcpClientConnection::timeout, share_this<TcpClientConnection>(),
                                    boost::asio::placeholders::error));

  _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                          boost::bind(&TcpClientConnection::f1_received,
                                      share_this<TcpClientConnection>(),
                                      boost::asio::placeholders::error,
                                      boost::asio::placeholders::bytes_transferred));

  size_t f0_size = load_f0(*_write_buffer);
  boost::asio::async_write(_socket, boost::asio::buffer(_write_buffer->data(), f0_size),
                           boost::bind(&TcpClientConnection::success_or_close, share_this<TcpClientConnection>(),
                                       boost::asio::placeholders::error));
}

void TcpClientConnection::f1_received(const boost::system::error_code &error, size_t bytes_transferred) {
  if (!error /* && !destroyed() */ && parse_f1(bytes_transferred)) {
    // cancel timer before timeout
    _deadline->expires_from_now(boost::posix_time::milliseconds(_config.handshake_timout()));

    // server should be parsing f0 and waiting for f2 at this point
    // so we can compute the shared secret synchronously
    compute_secret();
    size_t f2_size = load_f2(*_write_buffer);
    boost::asio::async_write(_socket, boost::asio::buffer(_write_buffer->data(), f2_size),
                             boost::bind(&TcpClientConnection::success_or_close,
                                         share_this<TcpClientConnection>(),
                                         boost::asio::placeholders::error));

    // restart timeout timer
    _deadline->async_wait(boost::bind(&TcpClientConnection::timeout, share_this<TcpClientConnection>(),
                                      boost::asio::placeholders::error));

    _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                            boost::bind(&TcpClientConnection::f3_received,
                                        share_this<TcpClientConnection>(),
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));
  }
}

void TcpClientConnection::f3_received(const boost::system::error_code &error, size_t bytes_transferred) {
  // stop timeout timer
  _deadline->cancel();

  if (!error /* && !destroyed() */ && parse_f3(bytes_transferred)) {
    uint8_t *auth = _auth->data(), *other_auth = _other_auth->data();
    for (size_t i = 0; i < AuthLength; ++i)
      if (auth[i] != other_auth[i]) return;
    _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                            boost::bind(&TcpClientConnection::read_loop, share_this<TcpClientConnection>(), 0,
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));

    // start standard dsa 1 minute timeout
    reset_standard_deadline_timer();
  }
}

}  // namespace dsa<commit_msg>fix exception type of tcp_connection<commit_after>#include "dsa_common.h"

#include "tcp_connection.h"

#include <boost/bind.hpp>

#include "session_manager.h"

namespace dsa {

TcpConnection::TcpConnection(std::shared_ptr<App> app, const Config &config)
    : Connection(app, config), _socket(app->io_service()), _strand(app->io_service()) {
}

void TcpConnection::close() {
  _socket.cancel();
  _deadline->cancel();
}

void TcpConnection::read_loop(size_t from_prev, const boost::system::error_code &error, size_t bytes_transferred) {
  // reset deadline timer for each new message
  reset_standard_deadline_timer();

  if (!error /* && !destroyed() */) {
    std::cout << std::endl << "in read loop" << std::endl;

    BufferPtr buf = std::move(_read_buffer);
    _read_buffer.reset(new Buffer());

    size_t total_bytes = from_prev + bytes_transferred;
    uint8_t *data = buf->data();
    size_t cur = 0;

    while (cur < total_bytes) {
      // always want full static header instead of just message size to make sure it's a valid message
      if (total_bytes - cur < StaticHeaders::TotalSize) {
        size_t partial_size = total_bytes - cur;
        _read_buffer->assign(&data[cur], partial_size);
        _socket.async_read_some(boost::asio::buffer(_read_buffer->data() + partial_size,
                                                    _read_buffer->capacity() - partial_size),
                                boost::bind(&TcpConnection::read_loop, share_this<TcpConnection>(), partial_size,
                                            boost::asio::placeholders::error,
                                            boost::asio::placeholders::bytes_transferred));
        return;
      }

      StaticHeaders header(&data[cur]);
      if (header.message_size < total_bytes - cur) {
        size_t partial_size = total_bytes - cur;

        // make sure buffer capacity is enough to read full message
        _read_buffer->resize(header.message_size);
        _read_buffer->assign(&data[cur], partial_size);

        // read the rest of the message
        boost::asio::async_read(_socket,
                                boost::asio::buffer(_read_buffer->data() + partial_size,
                                                    _read_buffer->capacity() - partial_size),
                                boost::bind(&TcpConnection::read_loop, share_this<TcpConnection>(), partial_size,
                                            boost::asio::placeholders::error,
                                            boost::asio::placeholders::bytes_transferred));
        return;
      }

      // post job with message buffer
      _app->io_service().post(boost::bind(&TcpConnection::handle_message, shared_from_this(),
                                         buf->get_shared_buffer(cur, header.message_size)));

      cur += header.message_size;
    }

    _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                            boost::bind(&TcpConnection::read_loop, share_this<TcpConnection>(), 0,
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));
  }
}

void TcpConnection::write_handler(WriteHandler callback, const boost::system::error_code &error) {
  if (!error /* && !destroyed() */) callback();
}

void TcpConnection::write(BufferPtr buf, size_t size, WriteHandler callback) {
  // check to see if current number of pending messages is above allowed limit
  if (++_pending_messages > _config.max_pending_messages()) {
    close();
    return;
  }

  boost::asio::async_write(_socket, boost::asio::buffer(buf->data(), size),
                           boost::bind(&TcpConnection::write_handler, share_this<TcpConnection>(), callback,
                                       boost::asio::placeholders::error));
}

void TcpConnection::start() throw(const std::runtime_error&) {
  if (_session == nullptr)
    throw std::runtime_error("Error: connection started with no session");
  _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                          boost::bind(&TcpConnection::read_loop, share_this<TcpConnection>(), 0,
                                      boost::asio::placeholders::error, 0));
}

tcp_socket &TcpConnection::socket() { return _socket; }

//////////////////////////////////////
// TcpServerConnection
//////////////////////////////////////
TcpServerConnection::TcpServerConnection(std::shared_ptr<App> app, const Server::Config &config)
    : Connection(app, Config()), TcpConnection(app, Config(config.message_handler())) {
  _path = std::make_shared<Buffer>(config.path());
}

void TcpServerConnection::connect() {
  start_handshake();
}

void TcpServerConnection::start_handshake() {
  // start timeout timer with handshake timeout specified in config
  _deadline->expires_from_now(boost::posix_time::milliseconds(_config.handshake_timout()));
  _deadline->async_wait(boost::bind(&TcpServerConnection::timeout,
                                    share_this<TcpServerConnection>(),
                                    boost::asio::placeholders::error));

  // start listening for f0
  _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                          boost::bind(&TcpServerConnection::f0_received, share_this<TcpServerConnection>(),
                                      boost::asio::placeholders::error,
                                      boost::asio::placeholders::bytes_transferred));

  // prepare and send f1 then make sure it was successful [success_or_close(...)]
  size_t f1_size = load_f1(*_write_buffer);
  boost::asio::async_write(_socket, boost::asio::buffer(_write_buffer->data(), f1_size),
                           boost::bind(&TcpServerConnection::success_or_close, share_this<TcpServerConnection>(),
                                       boost::asio::placeholders::error));
}

void TcpServerConnection::f0_received(const boost::system::error_code &error, size_t bytes_transferred) {
  // reset timeout
  _deadline->expires_from_now(boost::posix_time::milliseconds(_config.handshake_timout()));
  _deadline->async_wait(boost::bind(&TcpServerConnection::timeout, share_this<TcpServerConnection>(),
                                    boost::asio::placeholders::error));

  if (!error /* && !destroyed() */ && parse_f0(bytes_transferred)) {
    // start shared_secret computation
    _strand.post(boost::bind(&TcpServerConnection::compute_secret, this));

    // read and goto -> f2_received()
    _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                            boost::bind(&TcpServerConnection::f2_received, share_this<TcpServerConnection>(),
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));
  }
}

void TcpServerConnection::f2_received(const boost::system::error_code &error, size_t bytes_transferred) {
  // stop timeout timer
  _deadline->cancel();

  if (!error /* && !destroyed() */ && parse_f2(bytes_transferred)) {
    // setup session now that client session id has been parsed
    if (auto server = _server.lock()) {
      std::string session_id = _session_id->to_string();
      _session = server->session_manager()->get_session(_app->security_context().dsid(), session_id);
      if (_session == nullptr) _session = server->session_manager()->create_session(_app->security_context().dsid());
    } else {
      // if server no longer exists, connection needs to shutdown
      return;
    }

    _session_id = _session->session_id();

    // wait for shared secret computation to finish then send f3
    _strand.post(boost::bind(&TcpServerConnection::send_f3, share_this<TcpServerConnection>()));

    // start session
    _session->set_connection(shared_from_this());
    _session->start();
  }
}

void TcpServerConnection::send_f3() {
  // send f3
  size_t f3_size = load_f3(*_read_buffer);
  boost::asio::async_write(_socket, boost::asio::buffer(_read_buffer->data(), f3_size),
                           boost::bind(&TcpServerConnection::success_or_close, shared_from_this(),
                                       boost::asio::placeholders::error));
}

//////////////////////////////////
// TcpClientConnection
//////////////////////////////////
TcpClientConnection::TcpClientConnection(std::shared_ptr<App> app)
    : Connection(app, Config()), TcpConnection(app, Config()) {}

TcpClientConnection::TcpClientConnection(std::shared_ptr<App> app, const Config &config)
    : Connection(app, Config()), TcpConnection(app, config) {}

void TcpClientConnection::connect() {
  using tcp = boost::asio::ip::tcp;
  tcp::resolver resolver(_app->io_service());
  tcp::resolver::query query(_config.host(), std::to_string(_config.port()));
  tcp::endpoint endpoint = *resolver.resolve(query);
  _socket.async_connect(*resolver.resolve(query),
                        boost::bind(&TcpClientConnection::start_handshake, share_this<TcpClientConnection>(),
                                    boost::asio::placeholders::error));
}

void TcpClientConnection::start_handshake(const boost::system::error_code &error) {
  if (error != nullptr) throw std::runtime_error("Couldn't connect to specified host");
  // start timeout timer
  _deadline->expires_from_now(boost::posix_time::milliseconds(_config.handshake_timout()));
  _deadline->async_wait(boost::bind(&TcpClientConnection::timeout, share_this<TcpClientConnection>(),
                                    boost::asio::placeholders::error));

  _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                          boost::bind(&TcpClientConnection::f1_received,
                                      share_this<TcpClientConnection>(),
                                      boost::asio::placeholders::error,
                                      boost::asio::placeholders::bytes_transferred));

  size_t f0_size = load_f0(*_write_buffer);
  boost::asio::async_write(_socket, boost::asio::buffer(_write_buffer->data(), f0_size),
                           boost::bind(&TcpClientConnection::success_or_close, share_this<TcpClientConnection>(),
                                       boost::asio::placeholders::error));
}

void TcpClientConnection::f1_received(const boost::system::error_code &error, size_t bytes_transferred) {
  if (!error /* && !destroyed() */ && parse_f1(bytes_transferred)) {
    // cancel timer before timeout
    _deadline->expires_from_now(boost::posix_time::milliseconds(_config.handshake_timout()));

    // server should be parsing f0 and waiting for f2 at this point
    // so we can compute the shared secret synchronously
    compute_secret();
    size_t f2_size = load_f2(*_write_buffer);
    boost::asio::async_write(_socket, boost::asio::buffer(_write_buffer->data(), f2_size),
                             boost::bind(&TcpClientConnection::success_or_close,
                                         share_this<TcpClientConnection>(),
                                         boost::asio::placeholders::error));

    // restart timeout timer
    _deadline->async_wait(boost::bind(&TcpClientConnection::timeout, share_this<TcpClientConnection>(),
                                      boost::asio::placeholders::error));

    _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                            boost::bind(&TcpClientConnection::f3_received,
                                        share_this<TcpClientConnection>(),
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));
  }
}

void TcpClientConnection::f3_received(const boost::system::error_code &error, size_t bytes_transferred) {
  // stop timeout timer
  _deadline->cancel();

  if (!error /* && !destroyed() */ && parse_f3(bytes_transferred)) {
    uint8_t *auth = _auth->data(), *other_auth = _other_auth->data();
    for (size_t i = 0; i < AuthLength; ++i)
      if (auth[i] != other_auth[i]) return;
    _socket.async_read_some(boost::asio::buffer(_read_buffer->data(), _read_buffer->capacity()),
                            boost::bind(&TcpClientConnection::read_loop, share_this<TcpClientConnection>(), 0,
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));

    // start standard dsa 1 minute timeout
    reset_standard_deadline_timer();
  }
}

}  // namespace dsa<|endoftext|>


<commit_before>#include "sequential_trim_simulator.h"

Sequential_Trim_Simulator::Sequential_Trim_Simulator(std::vector<Command*>& commands, int maxparallelops):Simulator(commands, maxparallelops)	{

}

Sequential_Trim_Simulator::~Sequential_Trim_Simulator()	{
	commandPtr = NULL;
}

void Sequential_Trim_Simulator::startSimulation(double readProcessTime, double writeProcessTime, double trimProcessTime)	{
	int commandCounter = 0;

	// bool driverBusy = false;

	// start simulation
	while(1)	{
		// if there are command that has not been issue yet
		if(commandCounter < commandPtr->size())	{
			Command* nextCommand = commandPtr->at(commandCounter);
			if(nextCommand->getIssueTime() <= clock)	{
				// put the command in to queue
				if(nextCommand->getType() == TRIM_COMMAND)	{
					trimQueue.push((Trim_Command*)nextCommand);
				}
				else	{
					ioQueue.push((IO_Command*)nextCommand);
				}
				// move on to the next command
				commandCounter++;
			}
		}
		advanceDriverBusyTime();
		// check if simulator can execute any command
		if(!availableDriverSlot.empty())	{
			// while there are available slot, and there are commands in the queue
			while(!availableDriverSlot.empty() && (!trimQueue.empty() || !ioQueue.empty()))	{

				// get the index of driver slot
				int driverSlotIndex = availableDriverSlot.front();

				// now check to see which command should be serve first
				Trim_Command* nextTrimCommand = NULL;
				IO_Command* nextIOCommand = NULL;
				// check both queue, see which one is not empty
				if(!trimQueue.empty())	{
					nextTrimCommand = trimQueue.front();
				}
				if(!ioQueue.empty())	{
					nextIOCommand = ioQueue.front();
				}

				// printf("%.9lf\n", clock);
				// std::cout<<"  "<<availableDriverSlot.size()<<"  "<<currentServingType<<"  "<<trimQueue.size()<<"  "<<ioQueue.size()<<"\n";

				double servicesTime = 0.0;
				// if both there are command from either queue
				if(nextTrimCommand != NULL && nextIOCommand != NULL)	{
					double timeDiff = nextIOCommand->getIssueTime() - nextTrimCommand->getIssueTime();
					if(currentServingType == ANY_COMMAND)	{
						// TRIM
						if(timeDiff > 0)	{
							// execute the command
							servicesTime = trimProcessTime;
							// pop it from the queue
							trimQueue.pop();
							currentServingType = TRIM_COMMAND;
						}
						// Normal IO
						else	{
							// set the driver busy time
							servicesTime = (nextIOCommand->getType() == WRITE_COMMAND)?writeProcessTime:readProcessTime;
							// pop the command off ioQueue
							ioQueue.pop();
							currentServingType = IO_COMMAND;
						}
					}
					else if(currentServingType == TRIM_COMMAND)	{
						if(timeDiff > 0)	{
							// execute the command
							servicesTime = trimProcessTime;
							// pop it from the queue
							trimQueue.pop();
							currentServingType = TRIM_COMMAND;
						}
						else
						{
							break;
						}
					}
					else if(currentServingType == IO_COMMAND)	{
						if(timeDiff < 0)	{
							// set the driver busy time
							servicesTime = (nextIOCommand->getType() == WRITE_COMMAND)?writeProcessTime:readProcessTime;
							// pop the command off ioQueue
							ioQueue.pop();
							currentServingType = IO_COMMAND;
						}
						else
						{
							break;
						}
					}
				}
				// if there is some trim command in trim queue
				else if(nextTrimCommand != NULL)	{
					if(currentServingType == TRIM_COMMAND || currentServingType == ANY_COMMAND)	{
						// execute the command
						servicesTime = trimProcessTime;
						// pop it from the queue
						trimQueue.pop();
						currentServingType = TRIM_COMMAND;
					}
					else
					{
						break;
					}
				}
				// if there is some trim command in io queue
				else if(nextIOCommand != NULL)	{
					if(currentServingType == IO_COMMAND || currentServingType == ANY_COMMAND)	{
						servicesTime = (nextIOCommand->getType() == WRITE_COMMAND)?writeProcessTime:readProcessTime;
						// pop the command off ioQueue
						ioQueue.pop();
						currentServingType = IO_COMMAND;
					}
					else
					{
						break;
					}
				}
				// set the slot with services time
				if(servicesTime > 0.0)	{
					setDriverBusyTimer(driverSlotIndex, servicesTime);
					// pop it off the queue
					availableDriverSlot.pop();
				}
			}
		}
		else	{
			totalBlockingTime += CLOCK_SPEED;
			// driverBusyTime -= CLOCK_SPEED;
		}
		if (allCompleted()) {
			currentServingType = ANY_COMMAND;
			//printf("all completed at: %.9lf, totalBusyTime: %.9lf\n", clock, totalBlockingTime);
		}

		// std::cout<<driverBusy<<"  "<<driverBusyTime<<"\n";
		if((commandCounter == commandPtr->size()) && trimQueue.empty() && ioQueue.empty() && allCompleted())	{
			break;
		}

		advanceClock();
	}

	std::cout << "System was blocking "<< totalBlockingTime /clock * 100<<"% of time\n";
	std::cout << "System was prcessing IO " << totalIOTime / clock * 100 << "% of time\n";
	std::cout << "System was processing TRIM " << totalTrimTime / clock * 100 << "% of time\n";
}<commit_msg>testing<commit_after>#include "sequential_trim_simulator.h"

Sequential_Trim_Simulator::Sequential_Trim_Simulator(std::vector<Command*>& commands, int maxparallelops):Simulator(commands, maxparallelops)	{

}

Sequential_Trim_Simulator::~Sequential_Trim_Simulator()	{
	commandPtr = NULL;
}

void Sequential_Trim_Simulator::startSimulation(double readProcessTime, double writeProcessTime, double trimProcessTime)	{
	int commandCounter = 0;

	// bool driverBusy = false;
	//test

	// start simulation
	while(1)	{
		// if there are command that has not been issue yet
		if(commandCounter < commandPtr->size())	{
			Command* nextCommand = commandPtr->at(commandCounter);
			if(nextCommand->getIssueTime() <= clock)	{
				// put the command in to queue
				if(nextCommand->getType() == TRIM_COMMAND)	{
					trimQueue.push((Trim_Command*)nextCommand);
				}
				else	{
					ioQueue.push((IO_Command*)nextCommand);
				}
				// move on to the next command
				commandCounter++;
			}
		}
		advanceDriverBusyTime();
		// check if simulator can execute any command
		if(!availableDriverSlot.empty())	{
			// while there are available slot, and there are commands in the queue
			while(!availableDriverSlot.empty() && (!trimQueue.empty() || !ioQueue.empty()))	{

				// get the index of driver slot
				int driverSlotIndex = availableDriverSlot.front();

				// now check to see which command should be serve first
				Trim_Command* nextTrimCommand = NULL;
				IO_Command* nextIOCommand = NULL;
				// check both queue, see which one is not empty
				if(!trimQueue.empty())	{
					nextTrimCommand = trimQueue.front();
				}
				if(!ioQueue.empty())	{
					nextIOCommand = ioQueue.front();
				}

				// printf("%.9lf\n", clock);
				// std::cout<<"  "<<availableDriverSlot.size()<<"  "<<currentServingType<<"  "<<trimQueue.size()<<"  "<<ioQueue.size()<<"\n";

				double servicesTime = 0.0;
				// if both there are command from either queue
				if(nextTrimCommand != NULL && nextIOCommand != NULL)	{
					double timeDiff = nextIOCommand->getIssueTime() - nextTrimCommand->getIssueTime();
					if(currentServingType == ANY_COMMAND)	{
						// TRIM
						if(timeDiff > 0)	{
							// execute the command
							servicesTime = trimProcessTime;
							// pop it from the queue
							trimQueue.pop();
							currentServingType = TRIM_COMMAND;
						}
						// Normal IO
						else	{
							// set the driver busy time
							servicesTime = (nextIOCommand->getType() == WRITE_COMMAND)?writeProcessTime:readProcessTime;
							// pop the command off ioQueue
							ioQueue.pop();
							currentServingType = IO_COMMAND;
						}
					}
					else if(currentServingType == TRIM_COMMAND)	{
						if(timeDiff > 0)	{
							// execute the command
							servicesTime = trimProcessTime;
							// pop it from the queue
							trimQueue.pop();
							currentServingType = TRIM_COMMAND;
						}
						else
						{
							break;
						}
					}
					else if(currentServingType == IO_COMMAND)	{
						if(timeDiff < 0)	{
							// set the driver busy time
							servicesTime = (nextIOCommand->getType() == WRITE_COMMAND)?writeProcessTime:readProcessTime;
							// pop the command off ioQueue
							ioQueue.pop();
							currentServingType = IO_COMMAND;
						}
						else
						{
							break;
						}
					}
				}
				// if there is some trim command in trim queue
				else if(nextTrimCommand != NULL)	{
					if(currentServingType == TRIM_COMMAND || currentServingType == ANY_COMMAND)	{
						// execute the command
						servicesTime = trimProcessTime;
						// pop it from the queue
						trimQueue.pop();
						currentServingType = TRIM_COMMAND;
					}
					else
					{
						break;
					}
				}
				// if there is some trim command in io queue
				else if(nextIOCommand != NULL)	{
					if(currentServingType == IO_COMMAND || currentServingType == ANY_COMMAND)	{
						servicesTime = (nextIOCommand->getType() == WRITE_COMMAND)?writeProcessTime:readProcessTime;
						// pop the command off ioQueue
						ioQueue.pop();
						currentServingType = IO_COMMAND;
					}
					else
					{
						break;
					}
				}
				// set the slot with services time
				if(servicesTime > 0.0)	{
					setDriverBusyTimer(driverSlotIndex, servicesTime);
					// pop it off the queue
					availableDriverSlot.pop();
				}
			}
		}
		else	{
			totalBlockingTime += CLOCK_SPEED;
			// driverBusyTime -= CLOCK_SPEED;
		}
		if (allCompleted()) {
			currentServingType = ANY_COMMAND;
			//printf("all completed at: %.9lf, totalBusyTime: %.9lf\n", clock, totalBlockingTime);
		}

		// std::cout<<driverBusy<<"  "<<driverBusyTime<<"\n";
		if((commandCounter == commandPtr->size()) && trimQueue.empty() && ioQueue.empty() && allCompleted())	{
			break;
		}

		advanceClock();
	}

	std::cout << "System was blocking "<< totalBlockingTime /clock * 100<<"% of time\n";
	std::cout << "System was prcessing IO " << totalIOTime / clock * 100 << "% of time\n";
	std::cout << "System was processing TRIM " << totalTrimTime / clock * 100 << "% of time\n";
}<|endoftext|>


<commit_before>#ifndef ARDUINO
/*
 *  CONTROLS:
 *
 * NW - Q
 * SW - A
 * NE - P
 * SE - L
 *
 * LEFT - <LEFT>
 * RIGHT - <RIGHT>
 * UP - <UP>
 * DOWN - <DOWN>
 * A - X
 * B - Z
 * SELECT - ,
 * START - .
 *
 */

#include <SFML/Graphics.hpp>
#include <stdint.h>
#include <libgame.h>
#include <sprite.h>
#include <font.h>
#include <storage.h>

const int SCALE = 8;

sf::VertexArray *screen;
sf::RenderWindow *window;
sf::Clock running_clock;

uint16_t buttons = 0;

bool paused = false;

void render();
void update(unsigned long delta);
void prepare();

unsigned long millis()
{
    return running_clock.getElapsedTime().asMilliseconds();
}

void storage_init() {}
void storage_format() {}

void storage_read(const char *name, void *buffer, size_t size){};
bool storage_write(const char *name, const void *buffer, size_t size){return 0;};

uint8_t game_sprite_width(const struct game_sprite *s)
{
    return s->width;
}

uint8_t game_sprite_height(const struct game_sprite *s)
{
    return s->height;
}

void game_draw_pixel(int x, int y, uint8_t c)
{
    if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT)
        return;
    int pos = 4 * (x * WIDTH + y);
    sf::Color color(((c >> 4) & 3) * 85, ((c >> 2) & 3) * 85, (c & 3) * 85);
    (*screen)[pos + 0].color = color;
    (*screen)[pos + 1].color = color;
    (*screen)[pos + 2].color = color;
    (*screen)[pos + 3].color = color;
}

void game_draw_vline(int x, int y1, int y2, uint8_t color)
{
    for (int i = y1 ; i <= y2 ; ++i)
        game_draw_pixel(x, i, color);
}

void clear_screen()
{
    for (int x = 0; x < HEIGHT; ++x)
    {
        for (int y = 0; y < WIDTH; ++y)
        {
            game_draw_pixel(x, y, BLACK);
        }
    }
}

bool game_is_button_pressed(uint8_t button)
{
    return (buttons >> button) & 1;
}

bool game_is_any_button_pressed(uint16_t bitmask)
{
    return buttons & bitmask;
}

void set_pressed(uint8_t button, bool pressed)
{
    if (pressed)
    {
        buttons |= (1 << button);
    }
    else
    {
        buttons &= ~(1 << button);
    }
}

void game_setup()
{
    screen = new sf::VertexArray(sf::Quads, WIDTH * HEIGHT * 4);
    for (int x = 0; x < WIDTH; ++x)
    {
        for (int y = 0; y < HEIGHT; ++y)
        {
            int pos = 4 * (x * HEIGHT + y);
            (*screen)[pos + 0].position = sf::Vector2f(x * SCALE, y * SCALE);
            (*screen)[pos + 1].position = sf::Vector2f((x + 1) * SCALE, y * SCALE);
            (*screen)[pos + 2].position = sf::Vector2f((x + 1) * SCALE, (y + 1) * SCALE);
            (*screen)[pos + 3].position = sf::Vector2f(x * SCALE, (y + 1) * SCALE);
            game_draw_pixel(x, y, BLACK);
        }
    }
    window = new sf::RenderWindow(sf::VideoMode(SCALE * WIDTH, SCALE * HEIGHT), "emulator", sf::Style::Close);
}

void game_set_ups(int ups)
{
    if (ups)
        window->setFramerateLimit(ups);
    else
        window->setFramerateLimit(30);
}

void game_draw_sprite(const struct game_sprite *s, int x, int y, uint8_t color)
{
    for (int dx = 0; dx < s->width; ++dx)
    {
        for (int dy = 0; dy < s->height; ++dy)
        {
            int xx = x + dx;
            int yy = y + dy;
            if (xx < 0 || xx >= WIDTH || yy < 0 || yy >= HEIGHT)
                continue;
            int byte = s->lineSize * dy + dx / 8;
            int bit = 7 - dx % 8;
            if ((s->lines[byte] >> bit) & 1)
                game_draw_pixel(xx, yy, color);
        }
    }
}

void game_draw_text(const uint8_t *s, int x, int y, uint8_t color)
{
    int xx = x;
    int yy = y;
    for (const uint8_t *c = s; *c; ++c)
    {
        game_draw_char(*c, xx, yy, color);
        xx += FONT_WIDTH + 1;
    }
}

void game_draw_char(uint8_t c, int x, int y, uint8_t color)
{
    int pos = (int)c * FONT_HEIGHT;
    for (int i = 0; i < FONT_WIDTH; ++i)
    {
        for (int j = 0; j < FONT_HEIGHT; ++j)
        {
            uint8_t d = font_data[pos + j];
            if ((d >> (FONT_WIDTH - 1 - i)) & 1)
                game_draw_pixel(x + i, y + j, color);
        }
    }
}

int main()
{
    prepare();
    running_clock.restart();
    sf::Clock elapsed;
    while (window->isOpen())
    {
        elapsed.restart();
        sf::Event event;
        while (window->pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                window->close();
            }
            if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased)
            {
                bool status = event.type == sf::Event::KeyPressed;
                if (event.key.code == sf::Keyboard::Q) set_pressed(BUTTON_NW, status);
                if (event.key.code == sf::Keyboard::A) set_pressed(BUTTON_SW, status);
                if (event.key.code == sf::Keyboard::P) set_pressed(BUTTON_NE, status);
                if (event.key.code == sf::Keyboard::L) set_pressed(BUTTON_SE, status);

                if (event.key.code == sf::Keyboard::Left) set_pressed(BUTTON_LEFT, status);
                if (event.key.code == sf::Keyboard::Right) set_pressed(BUTTON_RIGHT, status);
                if (event.key.code == sf::Keyboard::Up) set_pressed(BUTTON_UP, status);
                if (event.key.code == sf::Keyboard::Down) set_pressed(BUTTON_DOWN, status);
                if (event.key.code == sf::Keyboard::X) set_pressed(BUTTON_A, status);
                if (event.key.code == sf::Keyboard::Z) set_pressed(BUTTON_B, status);
                if (event.key.code == sf::Keyboard::Comma) set_pressed(BUTTON_SELECT, status);
                if (event.key.code == sf::Keyboard::Period) set_pressed(BUTTON_START, status);

                if (status && event.key.code == sf::Keyboard::Space) paused = !paused;
                if (status && event.key.code == sf::Keyboard::Escape) window->close();
            }
        }

        window->clear(sf::Color::Black);
        window->draw(*screen);
        window->display();

        if (!paused)
        {
            update(elapsed.getElapsedTime().asMilliseconds());
            clear_screen();
            render();
        }
    }

    return 0;
}
#endif
<commit_msg>Fixed emulator<commit_after>#ifndef ARDUINO
/*
 *  CONTROLS:
 *
 * NW - Q
 * SW - A
 * NE - P
 * SE - L
 *
 * LEFT - <LEFT>
 * RIGHT - <RIGHT>
 * UP - <UP>
 * DOWN - <DOWN>
 * A - X
 * B - Z
 * SELECT - ,
 * START - .
 *
 */

#include <SFML/Graphics.hpp>
#include <stdint.h>
#include <libgame.h>
#include "graphics.h"
#include "controls.h"
#include "font.h"
#include "storage.h"
#include "font_data.h"

const int SCALE = 8;

sf::VertexArray *screen;
sf::RenderWindow *window;
sf::Clock running_clock;

uint16_t buttons = 0;

bool paused = false;

void render();
void update(unsigned long delta);
void prepare();

unsigned long millis()
{
    return running_clock.getElapsedTime().asMilliseconds();
}

void storage_init() {}
void storage_format() {}

void storage_read(const char *name, void *buffer, size_t size){};
bool storage_write(const char *name, const void *buffer, size_t size){return 0;};

uint8_t game_sprite_width(const struct game_sprite *s)
{
    return s->width;
}

uint8_t game_sprite_height(const struct game_sprite *s)
{
    return s->height;
}

void game_draw_pixel(int x, int y, uint8_t c)
{
    if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT)
        return;
    int pos = 4 * (x * WIDTH + y);
    sf::Color color(((c >> 4) & 3) * 85, ((c >> 2) & 3) * 85, (c & 3) * 85);
    (*screen)[pos + 0].color = color;
    (*screen)[pos + 1].color = color;
    (*screen)[pos + 2].color = color;
    (*screen)[pos + 3].color = color;
}

void game_draw_vline(int x, int y1, int y2, uint8_t color)
{
    for (int i = y1 ; i <= y2 ; ++i)
        game_draw_pixel(x, i, color);
}

void clear_screen()
{
    for (int x = 0; x < HEIGHT; ++x)
    {
        for (int y = 0; y < WIDTH; ++y)
        {
            game_draw_pixel(x, y, BLACK);
        }
    }
}

bool game_is_button_pressed(uint8_t button)
{
    return (buttons >> button) & 1;
}

bool game_is_any_button_pressed(uint16_t bitmask)
{
    return buttons & bitmask;
}

void set_pressed(uint8_t button, bool pressed)
{
    if (pressed)
    {
        buttons |= (1 << button);
    }
    else
    {
        buttons &= ~(1 << button);
    }
}

void game_setup()
{
    screen = new sf::VertexArray(sf::Quads, WIDTH * HEIGHT * 4);
    for (int x = 0; x < WIDTH; ++x)
    {
        for (int y = 0; y < HEIGHT; ++y)
        {
            int pos = 4 * (x * HEIGHT + y);
            (*screen)[pos + 0].position = sf::Vector2f(x * SCALE, y * SCALE);
            (*screen)[pos + 1].position = sf::Vector2f((x + 1) * SCALE, y * SCALE);
            (*screen)[pos + 2].position = sf::Vector2f((x + 1) * SCALE, (y + 1) * SCALE);
            (*screen)[pos + 3].position = sf::Vector2f(x * SCALE, (y + 1) * SCALE);
            game_draw_pixel(x, y, BLACK);
        }
    }
    window = new sf::RenderWindow(sf::VideoMode(SCALE * WIDTH, SCALE * HEIGHT), "emulator", sf::Style::Close);
}

void game_set_ups(int ups)
{
    if (ups)
        window->setFramerateLimit(ups);
    else
        window->setFramerateLimit(30);
}

void game_draw_sprite(const struct game_sprite *s, int x, int y, uint8_t color)
{
    for (int dx = 0; dx < s->width; ++dx)
    {
        for (int dy = 0; dy < s->height; ++dy)
        {
            int xx = x + dx;
            int yy = y + dy;
            if (xx < 0 || xx >= WIDTH || yy < 0 || yy >= HEIGHT)
                continue;
            int byte = s->lineSize * dy + dx / 8;
            int bit = 7 - dx % 8;
            if ((s->lines[byte] >> bit) & 1)
                game_draw_pixel(xx, yy, color);
        }
    }
}

void game_draw_text(const uint8_t *s, int x, int y, uint8_t color)
{
    int xx = x;
    int yy = y;
    for (const uint8_t *c = s; *c; ++c)
    {
        game_draw_char(*c, xx, yy, color);
        xx += FONT_WIDTH + 1;
    }
}

void game_draw_char(uint8_t c, int x, int y, uint8_t color)
{
    int pos = (int)c * FONT_HEIGHT;
    for (int i = 0; i < FONT_WIDTH; ++i)
    {
        for (int j = 0; j < FONT_HEIGHT; ++j)
        {
            uint8_t d = font_data[pos + j];
            if ((d >> (FONT_WIDTH - 1 - i)) & 1)
                game_draw_pixel(x + i, y + j, color);
        }
    }
}

void game_draw_digits(uint16_t num, int len, int x, int y, uint8_t color)
{
    x += (len - 1) * (DIGIT_WIDTH + 1);
    for (int i = len - 1 ; i >= 0 ; --i, x -= DIGIT_WIDTH + 1)
    {
        uint8_t d = num % 10;
        num /= 10;
        for (int8_t dy = 0 ; dy < DIGIT_HEIGHT ; ++dy)
        {
            uint8_t dd = digits_data[d * DIGIT_HEIGHT + dy];
            for (int b = 0 ; b < DIGIT_WIDTH ; ++b)
            {
                if ((dd >> (DIGIT_WIDTH - 1 - b)) & 1)
                    game_draw_pixel(x + b, y + dy, color);
            }
        }
    }
}

int main()
{
    game_setup();
    running_clock.restart();
    sf::Clock elapsed;
    while (window->isOpen())
    {
        elapsed.restart();
        sf::Event event;
        while (window->pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                window->close();
            }
            if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased)
            {
                bool status = event.type == sf::Event::KeyPressed;
                if (event.key.code == sf::Keyboard::Q) set_pressed(BUTTON_NW, status);
                if (event.key.code == sf::Keyboard::A) set_pressed(BUTTON_SW, status);
                if (event.key.code == sf::Keyboard::P) set_pressed(BUTTON_NE, status);
                if (event.key.code == sf::Keyboard::L) set_pressed(BUTTON_SE, status);

                if (event.key.code == sf::Keyboard::Left) set_pressed(BUTTON_LEFT, status);
                if (event.key.code == sf::Keyboard::Right) set_pressed(BUTTON_RIGHT, status);
                if (event.key.code == sf::Keyboard::Up) set_pressed(BUTTON_UP, status);
                if (event.key.code == sf::Keyboard::Down) set_pressed(BUTTON_DOWN, status);
                if (event.key.code == sf::Keyboard::X) set_pressed(BUTTON_A, status);
                if (event.key.code == sf::Keyboard::Z) set_pressed(BUTTON_B, status);
                if (event.key.code == sf::Keyboard::Comma) set_pressed(BUTTON_SELECT, status);
                if (event.key.code == sf::Keyboard::Period) set_pressed(BUTTON_START, status);

                if (status && event.key.code == sf::Keyboard::Space) paused = !paused;
                if (status && event.key.code == sf::Keyboard::Escape) window->close();
            }
        }

        window->clear(sf::Color::Black);
        window->draw(*screen);
        window->display();

        if (!paused)
        {
            update(elapsed.getElapsedTime().asMilliseconds());
            clear_screen();
            render();
        }
    }

    return 0;
}
#endif
<|endoftext|>


<commit_before>//===-- AnalyzerOptions.cpp - Analysis Engine Options -----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains special accessors for analyzer configuration options
// with string representations.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "llvm/ADT/StringSwitch.h"

using namespace clang;
using namespace llvm;

bool
AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const {
  if (IPAMode < Inlining)
    return false;

  if (!CXXMemberInliningMode) {
    static const char *ModeKey = "c++-inlining";
    std::string ModeStr = Config.lookup(ModeKey);

    CXXInlineableMemberKind &MutableMode =
      const_cast<CXXInlineableMemberKind &>(CXXMemberInliningMode);

    MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
      .Case("", CIMK_MemberFunctions)
      .Case("constructors", CIMK_Constructors)
      .Case("destructors", CIMK_Destructors)
      .Case("none", CIMK_None)
      .Case("methods", CIMK_MemberFunctions)
      .Default(CXXInlineableMemberKind());

    if (!MutableMode) {
      // FIXME: We should emit a warning here about an unknown inlining kind,
      // but the AnalyzerOptions doesn't have access to a diagnostic engine.
      MutableMode = CIMK_None;
    }
  }

  return CXXMemberInliningMode >= K;
}

bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal) const {
  // FIXME: We should emit a warning here if the value is something other than
  // "true", "false", or the empty string (meaning the default value),
  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
  return llvm::StringSwitch<bool>(Config.lookup(Name))
    .Case("true", true)
    .Case("false", false)
    .Default(DefaultVal);
}

bool AnalyzerOptions::includeTemporaryDtorsInCFG() const {
  if (!IncludeTemporaryDtorsInCFG.hasValue())
    const_cast<llvm::Optional<bool> &>(IncludeTemporaryDtorsInCFG) =
      getBooleanOption("cfg-temporary-dtors", /*Default=*/false);

  return *IncludeTemporaryDtorsInCFG;
}

bool AnalyzerOptions::mayInlineCXXStandardLibrary() const {
  if (!InlineCXXStandardLibrary.hasValue())
    const_cast<llvm::Optional<bool> &>(InlineCXXStandardLibrary) =
      getBooleanOption("c++-stdlib-inlining", /*Default=*/true);

  return *InlineCXXStandardLibrary;
}

bool AnalyzerOptions::mayInlineTemplateFunctions() const {
  if (!InlineTemplateFunctions.hasValue())
    const_cast<llvm::Optional<bool> &>(InlineTemplateFunctions) =
      getBooleanOption("c++-template-inlining", /*Default=*/true);

  return *InlineTemplateFunctions;
}

bool AnalyzerOptions::mayInlineObjCMethod() const {
  if (!ObjCInliningMode.hasValue())
    const_cast<llvm::Optional<bool> &>(ObjCInliningMode) =
      getBooleanOption("objc-inlining", /*Default=*/true);

  return *ObjCInliningMode;
}

int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) const {
  std::string OptStr = Config.lookup(Name);
  if (OptStr.empty())
    return DefaultVal;

  int Res = DefaultVal;
  assert(StringRef(OptStr).getAsInteger(10, Res) == false &&
         "analyzer-config option should be numeric.");

  return Res;
}

unsigned AnalyzerOptions::getAlwaysInlineSize() const {
  if (!AlwaysInlineSize.hasValue()) {
    unsigned DefaultSize = 3;
    const_cast<Optional<unsigned> &>(AlwaysInlineSize) =
      getOptionAsInteger("ipa-always-inline-size", DefaultSize);
  }

  return AlwaysInlineSize.getValue();
}

bool AnalyzerOptions::shouldSynthesizeBodies() const {
  return getBooleanOption("faux-bodies", false);
}
<commit_msg>Flip "faux-bodies" in the analyzer on by default to flush out bugs.<commit_after>//===-- AnalyzerOptions.cpp - Analysis Engine Options -----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains special accessors for analyzer configuration options
// with string representations.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "llvm/ADT/StringSwitch.h"

using namespace clang;
using namespace llvm;

bool
AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const {
  if (IPAMode < Inlining)
    return false;

  if (!CXXMemberInliningMode) {
    static const char *ModeKey = "c++-inlining";
    std::string ModeStr = Config.lookup(ModeKey);

    CXXInlineableMemberKind &MutableMode =
      const_cast<CXXInlineableMemberKind &>(CXXMemberInliningMode);

    MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
      .Case("", CIMK_MemberFunctions)
      .Case("constructors", CIMK_Constructors)
      .Case("destructors", CIMK_Destructors)
      .Case("none", CIMK_None)
      .Case("methods", CIMK_MemberFunctions)
      .Default(CXXInlineableMemberKind());

    if (!MutableMode) {
      // FIXME: We should emit a warning here about an unknown inlining kind,
      // but the AnalyzerOptions doesn't have access to a diagnostic engine.
      MutableMode = CIMK_None;
    }
  }

  return CXXMemberInliningMode >= K;
}

bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal) const {
  // FIXME: We should emit a warning here if the value is something other than
  // "true", "false", or the empty string (meaning the default value),
  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
  return llvm::StringSwitch<bool>(Config.lookup(Name))
    .Case("true", true)
    .Case("false", false)
    .Default(DefaultVal);
}

bool AnalyzerOptions::includeTemporaryDtorsInCFG() const {
  if (!IncludeTemporaryDtorsInCFG.hasValue())
    const_cast<llvm::Optional<bool> &>(IncludeTemporaryDtorsInCFG) =
      getBooleanOption("cfg-temporary-dtors", /*Default=*/false);

  return *IncludeTemporaryDtorsInCFG;
}

bool AnalyzerOptions::mayInlineCXXStandardLibrary() const {
  if (!InlineCXXStandardLibrary.hasValue())
    const_cast<llvm::Optional<bool> &>(InlineCXXStandardLibrary) =
      getBooleanOption("c++-stdlib-inlining", /*Default=*/true);

  return *InlineCXXStandardLibrary;
}

bool AnalyzerOptions::mayInlineTemplateFunctions() const {
  if (!InlineTemplateFunctions.hasValue())
    const_cast<llvm::Optional<bool> &>(InlineTemplateFunctions) =
      getBooleanOption("c++-template-inlining", /*Default=*/true);

  return *InlineTemplateFunctions;
}

bool AnalyzerOptions::mayInlineObjCMethod() const {
  if (!ObjCInliningMode.hasValue())
    const_cast<llvm::Optional<bool> &>(ObjCInliningMode) =
      getBooleanOption("objc-inlining", /*Default=*/true);

  return *ObjCInliningMode;
}

int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) const {
  std::string OptStr = Config.lookup(Name);
  if (OptStr.empty())
    return DefaultVal;

  int Res = DefaultVal;
  assert(StringRef(OptStr).getAsInteger(10, Res) == false &&
         "analyzer-config option should be numeric.");

  return Res;
}

unsigned AnalyzerOptions::getAlwaysInlineSize() const {
  if (!AlwaysInlineSize.hasValue()) {
    unsigned DefaultSize = 3;
    const_cast<Optional<unsigned> &>(AlwaysInlineSize) =
      getOptionAsInteger("ipa-always-inline-size", DefaultSize);
  }

  return AlwaysInlineSize.getValue();
}

bool AnalyzerOptions::shouldSynthesizeBodies() const {
  return getBooleanOption("faux-bodies", true);
}
<|endoftext|>


<commit_before>#ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
#define STAN_IO_ARRAY_VAR_CONTEXT_HPP

#include <stan/io/var_context.hpp>
#include <boost/throw_exception.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <utility>

namespace stan {

namespace io {

/**
 * An array_var_context object represents a named arrays
 * with dimensions constructed from an array, a vector
 * of names, and a vector of all dimensions for each element.
 */
class array_var_context : public var_context {
 private:
  // Pairs
  template <typename T>
  using pair_
      = std::pair<std::string, std::pair<std::vector<T>, std::vector<size_t>>>;

  // Map holding reals
  using map_r_ = std::vector<pair_<double>>;
  map_r_ vars_r_;
  using map_i_ = std::vector<pair_<int>>;
  map_i_ vars_i_;
  // When search for variable name fails, return one these
  std::vector<double> const empty_vec_r_;
  std::vector<int> const empty_vec_i_;
  std::vector<size_t> const empty_vec_ui_;

  template <typename Str>
  auto find_var_r(Str&& name) const {
    return std::find_if(vars_r_.begin(), vars_r_.end(),
     [&](auto&& element){ return element.first == name;});
  }

  template <typename Str>
  auto find_var_i(Str&& name) const {
    return std::find_if(vars_i_.begin(), vars_i_.end(),
     [&](auto&& element){ return element.first == name;});
  }

  // Find method
  bool contains_r_only(const std::string& name) const {
    return find_var_r(name) != vars_r_.end();
  }

  /**
   * Check (1) if the vector size of dimensions is no smaller
   * than the name vector size; (2) if the size of the input
   * array is large enough for what is needed.
   *
   * @param names The names for each variable
   * @param array_size The total size of the vector holding the values we want
   * to access.
   * @param dims Vector holding the dimensions for each variable.
   * @return If the array size is equal to the number of dimensions,
   * a vector of the cumulative sum of the dimensions of each inner element of
   * dims. The return of this function is used in the add_* methods to get the
   * sequence of values For each variable.
   */

  template <typename T>
  std::vector<size_t> validate_dims(
      const std::vector<std::string>& names, const T array_size,
      const std::vector<std::vector<size_t>>& dims) {
    const size_t num_par = names.size();
    if (num_par > dims.size()) {
      std::stringstream msg;
      msg << "size of vector of dimensions (found " << dims.size() << ") "
          << "should be no smaller than number of parameters (found " << num_par
          << ").";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    std::vector<size_t> elem_dims_total(dims.size() + 1);
    elem_dims_total[0] = 0;
    int i = 0;
    for (i = 0; i < dims.size(); i++) {
      elem_dims_total[i + 1] = std::accumulate(dims[i].begin(), dims[i].end(),
                                               1, std::multiplies<T>());
      elem_dims_total[i + 1] += elem_dims_total[i];
    }
    if (elem_dims_total[i] > array_size) {
      std::stringstream msg;
      msg << "array is not long enough for all elements: " << array_size
          << " is found, but " << elem_dims_total[i] << " is needed.";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    return elem_dims_total;
  }

  /**
   * Adds a set of floating point variables to the floating point map.
   * @param names Names of each variable.
   * @param values The real values of variable in a contiguous
   * column major order container.
   * @param dims the dimensions for each variable.
   */
  void add_r(const std::vector<std::string>& names,
             const std::vector<double>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

  void add_r(const std::vector<std::string>& names,
             const Eigen::VectorXd& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    using val_d_t = decltype(values.data());
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

  /**
   * Adds a set of integer variables to the integer map.
   * @param names Names of each variable.
   * @param values The integer values of variable in a vector.
   * @param dims the dimensions for each variable.
   */
  void add_i(const std::vector<std::string>& names,
             const std::vector<int>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_i_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

 public:
  /**
   * Construct an array_var_context from only real value arrays.
   *
   * @param names_r  names for each element
   * @param values_r a vector of double values for all elements
   * @param dim_r   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Construct an array_var_context from only integer value arrays.
   *
   * @param names_i  names for each element
   * @param values_i a vector of integer values for all elements
   * @param dim_i   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
  }

  /**
   * Construct an array_var_context from arrays of both double
   * and integer separately
   *
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Return true if this dump contains the specified
   * variable name is defined. This method returns true
   * even if the values are all integers.
   *
   * @param name Variable name to test.
   * @return true if the variable exists.
   */
  bool contains_r(const std::string& name) const {
    return contains_r_only(name) || contains_i(name);
  }

  /**
   * Return true if this dump contains an integer
   * valued array with the specified name.
   *
   * @param name Variable name to test.
   * @return true if the variable name has an integer
   * array value.
   */
  bool contains_i(const std::string& name) const {
    return find_var_i(name) != vars_i_.end();
  }

  /**
   * Return the double values for the variable with the specified
   * name or null.
   *
   * @param name Name of variable.
   * @return Values of variable.
   *
   */
  std::vector<double> vals_r(const std::string& name) const {
    auto ret_val_r = find_var_r(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.first;
    } else {
      auto ret_val_i = find_var_i(name);
      if (ret_val_i != vars_i_.end()) {
        return {ret_val_i->second.first.begin(), ret_val_i->second.first.end()};
      }
    }
    return empty_vec_r_;
  }

  /**
   * Return the dimensions for the double variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_r(const std::string& name) const {
    auto ret_val_r = find_var_r(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.second;
    } else {
      auto ret_val_i = find_var_i(name);
      if (ret_val_i != vars_i_.end()) {
        return ret_val_i->second.second;
      }
    }
    return empty_vec_ui_;
  }

  /**
   * Return the integer values for the variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Values.
   */
  std::vector<int> vals_i(const std::string& name) const {
    auto ret_val_i = find_var_i(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.first;
    }
    return empty_vec_i_;
  }

  /**
   * Return the dimensions for the integer variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_i(const std::string& name) const {
    auto ret_val_i = find_var_i(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.second;
    }
    return empty_vec_ui_;
  }

  /**
   * Return a list of the names of the floating point variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_r(std::vector<std::string>& names) const {
    names.clear();
    for (const auto& vars_r_iter : vars_r_) {
      names.push_back(vars_r_iter.first);
    }
  }

  /**
   * Return a list of the names of the integer variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_i(std::vector<std::string>& names) const {
    names.clear();
    for (const auto& vars_i_iter : vars_r_) {
      names.push_back(vars_i_iter.first);
    }
  }

  /**
   * Remove variable from the object.
   *
   * @param name Name of the variable to remove.
   * @return If variable is removed returns true, else
   *   returns false.
   */
  bool remove(const std::string& name) {
    vars_i_.erase(find_var_i(name));
    vars_r_.erase(find_var_r(name));
    return true;
  }
};
}  // namespace io
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/stable/2017-11-14)<commit_after>#ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
#define STAN_IO_ARRAY_VAR_CONTEXT_HPP

#include <stan/io/var_context.hpp>
#include <boost/throw_exception.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <utility>

namespace stan {

namespace io {

/**
 * An array_var_context object represents a named arrays
 * with dimensions constructed from an array, a vector
 * of names, and a vector of all dimensions for each element.
 */
class array_var_context : public var_context {
 private:
  // Pairs
  template <typename T>
  using pair_
      = std::pair<std::string, std::pair<std::vector<T>, std::vector<size_t>>>;

  // Map holding reals
  using map_r_ = std::vector<pair_<double>>;
  map_r_ vars_r_;
  using map_i_ = std::vector<pair_<int>>;
  map_i_ vars_i_;
  // When search for variable name fails, return one these
  std::vector<double> const empty_vec_r_;
  std::vector<int> const empty_vec_i_;
  std::vector<size_t> const empty_vec_ui_;

  template <typename Str>
  auto find_var_r(Str&& name) const {
    return std::find_if(vars_r_.begin(), vars_r_.end(),
                        [&](auto&& element) { return element.first == name; });
  }

  template <typename Str>
  auto find_var_i(Str&& name) const {
    return std::find_if(vars_i_.begin(), vars_i_.end(),
                        [&](auto&& element) { return element.first == name; });
  }

  // Find method
  bool contains_r_only(const std::string& name) const {
    return find_var_r(name) != vars_r_.end();
  }

  /**
   * Check (1) if the vector size of dimensions is no smaller
   * than the name vector size; (2) if the size of the input
   * array is large enough for what is needed.
   *
   * @param names The names for each variable
   * @param array_size The total size of the vector holding the values we want
   * to access.
   * @param dims Vector holding the dimensions for each variable.
   * @return If the array size is equal to the number of dimensions,
   * a vector of the cumulative sum of the dimensions of each inner element of
   * dims. The return of this function is used in the add_* methods to get the
   * sequence of values For each variable.
   */

  template <typename T>
  std::vector<size_t> validate_dims(
      const std::vector<std::string>& names, const T array_size,
      const std::vector<std::vector<size_t>>& dims) {
    const size_t num_par = names.size();
    if (num_par > dims.size()) {
      std::stringstream msg;
      msg << "size of vector of dimensions (found " << dims.size() << ") "
          << "should be no smaller than number of parameters (found " << num_par
          << ").";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    std::vector<size_t> elem_dims_total(dims.size() + 1);
    elem_dims_total[0] = 0;
    int i = 0;
    for (i = 0; i < dims.size(); i++) {
      elem_dims_total[i + 1] = std::accumulate(dims[i].begin(), dims[i].end(),
                                               1, std::multiplies<T>());
      elem_dims_total[i + 1] += elem_dims_total[i];
    }
    if (elem_dims_total[i] > array_size) {
      std::stringstream msg;
      msg << "array is not long enough for all elements: " << array_size
          << " is found, but " << elem_dims_total[i] << " is needed.";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    return elem_dims_total;
  }

  /**
   * Adds a set of floating point variables to the floating point map.
   * @param names Names of each variable.
   * @param values The real values of variable in a contiguous
   * column major order container.
   * @param dims the dimensions for each variable.
   */
  void add_r(const std::vector<std::string>& names,
             const std::vector<double>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

  void add_r(const std::vector<std::string>& names,
             const Eigen::VectorXd& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    using val_d_t = decltype(values.data());
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

  /**
   * Adds a set of integer variables to the integer map.
   * @param names Names of each variable.
   * @param values The integer values of variable in a vector.
   * @param dims the dimensions for each variable.
   */
  void add_i(const std::vector<std::string>& names,
             const std::vector<int>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_i_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

 public:
  /**
   * Construct an array_var_context from only real value arrays.
   *
   * @param names_r  names for each element
   * @param values_r a vector of double values for all elements
   * @param dim_r   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Construct an array_var_context from only integer value arrays.
   *
   * @param names_i  names for each element
   * @param values_i a vector of integer values for all elements
   * @param dim_i   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
  }

  /**
   * Construct an array_var_context from arrays of both double
   * and integer separately
   *
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Return true if this dump contains the specified
   * variable name is defined. This method returns true
   * even if the values are all integers.
   *
   * @param name Variable name to test.
   * @return true if the variable exists.
   */
  bool contains_r(const std::string& name) const {
    return contains_r_only(name) || contains_i(name);
  }

  /**
   * Return true if this dump contains an integer
   * valued array with the specified name.
   *
   * @param name Variable name to test.
   * @return true if the variable name has an integer
   * array value.
   */
  bool contains_i(const std::string& name) const {
    return find_var_i(name) != vars_i_.end();
  }

  /**
   * Return the double values for the variable with the specified
   * name or null.
   *
   * @param name Name of variable.
   * @return Values of variable.
   *
   */
  std::vector<double> vals_r(const std::string& name) const {
    auto ret_val_r = find_var_r(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.first;
    } else {
      auto ret_val_i = find_var_i(name);
      if (ret_val_i != vars_i_.end()) {
        return {ret_val_i->second.first.begin(), ret_val_i->second.first.end()};
      }
    }
    return empty_vec_r_;
  }

  /**
   * Return the dimensions for the double variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_r(const std::string& name) const {
    auto ret_val_r = find_var_r(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.second;
    } else {
      auto ret_val_i = find_var_i(name);
      if (ret_val_i != vars_i_.end()) {
        return ret_val_i->second.second;
      }
    }
    return empty_vec_ui_;
  }

  /**
   * Return the integer values for the variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Values.
   */
  std::vector<int> vals_i(const std::string& name) const {
    auto ret_val_i = find_var_i(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.first;
    }
    return empty_vec_i_;
  }

  /**
   * Return the dimensions for the integer variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_i(const std::string& name) const {
    auto ret_val_i = find_var_i(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.second;
    }
    return empty_vec_ui_;
  }

  /**
   * Return a list of the names of the floating point variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_r(std::vector<std::string>& names) const {
    names.clear();
    for (const auto& vars_r_iter : vars_r_) {
      names.push_back(vars_r_iter.first);
    }
  }

  /**
   * Return a list of the names of the integer variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_i(std::vector<std::string>& names) const {
    names.clear();
    for (const auto& vars_i_iter : vars_r_) {
      names.push_back(vars_i_iter.first);
    }
  }

  /**
   * Remove variable from the object.
   *
   * @param name Name of the variable to remove.
   * @return If variable is removed returns true, else
   *   returns false.
   */
  bool remove(const std::string& name) {
    vars_i_.erase(find_var_i(name));
    vars_r_.erase(find_var_r(name));
    return true;
  }
};
}  // namespace io
}  // namespace stan
#endif
<|endoftext|>


<commit_before>
// Standard C++ includes
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <assert.h>
#include <float.h>
#include <math.h>
#include <vector>
#include <string>
#include <algorithm>
#include <map>

using namespace std;

// Public interface of the MySQL Connector/C++
#include <cppconn/mysql_public_iface.h>
#include "filtering.h"
#include "preprocessing.h"

using namespace std;

/**
* Usage example for Driver Manager, Connection, (simple) Statement, ResultSet
*/

int main(int argc, char** argv) {

	string productName = "Camera";
	stringstream sql;

	int clusterN;
	int conFeatureN;
	int catFeatureN;
	int boolFeatureN;
	int varNamesN;
	int range;
	int session_id;
	int repW;
	int clusterID = 0;

	string argu = argv[1];
	int ind, endit, startit, lengthit;
	string var;

	//productName
	var = "product_name";
	ind = argu.find(var, 0);
	endit = argu.find("\n", ind);
	startit = ind + var.length() + 2;
	lengthit = endit - startit;
	if (lengthit>0){
		productName = (argu.substr(startit, lengthit)).c_str();
	}
	else{
		cout<<"ERROR - Specify a productName"<<endl;
	}
	//session_id
	var = "session_id";
	ind = argu.find(var, 0);
	endit = argu.find("\n", ind);
	startit = ind + var.length() + 2;
	lengthit = endit - startit;
	if (lengthit>0){
		session_id = atoi((argu.substr(startit, lengthit)).c_str());
	}

	string tableName = productName;
	tableName.append("s");
	map<const string, int> productNames;
	productNames["camera"] = 1;
	productNames["printer"] = 2;

	switch(productNames[productName]){

		case 1:

					clusterN = 9;
					conFeatureN= 4;
					catFeatureN= 1;
					boolFeatureN= 0;
					varNamesN= 12;
					range= 2;
					repW = 9;
					break;

		case 2:
					clusterN = 9;
					conFeatureN= 4;
					catFeatureN= 1;
					boolFeatureN= 0;
					varNamesN= 12;
					range= 2;
					repW = 9;
					break;
		default:
					clusterN = 9;
					conFeatureN= 4;
					catFeatureN= 1;
					boolFeatureN= 0;
					varNamesN= 12;
					range= 2;
					repW = 9;
					break;
	}

	string* brands = new string [1] ;
	int* mergedClusterIDInput = new int[clusterN];
	bool smallNFlag =false;
	string* indicatorNames = new string[conFeatureN];
	int ** indicators = new int*[conFeatureN];
	double** conFeatureRange = new double* [conFeatureN];

	for (int f=0; f<conFeatureN; f++){
		conFeatureRange[f] = new double [2];
		indicators[f] = new int[repW];
		for (int i=0; i<repW; i++){
		indicators[f][i] = 0;
		}
	}
	ostringstream session_idStream;

	string *varNames = new string[varNamesN];
	string *catFeatureNames = new string [catFeatureN];
	string *conFeatureNames = new string[conFeatureN];
	double **filteredRange = new double* [conFeatureN];
	bool *conFilteredFeatures = new bool[conFeatureN];
	bool *catFilteredFeatures = new bool[catFeatureN];
	bool *boolFilteredFeatures = new bool[boolFeatureN];
	map<const string, string*> productFeatures;
   	for(int f=0; f<conFeatureN; f++){
		conFilteredFeatures[f] = 0;
		filteredRange[f] = new double [range];
	}

	for (int f=0; f<catFeatureN; f++){
	    catFilteredFeatures[f] = 0;
	}

    for (int f=0; f<boolFeatureN; f++){
		boolFilteredFeatures[f] = 0;
	}

	//cluster_id
	var = "cluster_id";
	ind = argu.find(var, 0);
	endit = argu.find("\n", ind);

	startit = ind + var.length() + 2;
	lengthit = endit - startit;

	if(lengthit>0){

		string valueString = argu.substr(startit, lengthit);
		int found = valueString.find("-");
		int mergedClusterN=0;
		while ( found != (int)string::npos){
			mergedClusterIDInput[mergedClusterN] = atoi((valueString.substr(found+1,1)).c_str());
			found = valueString.find("-", found+2, 1);
			mergedClusterN++;
		}
		if (mergedClusterN >0){
			clusterID = -1 * mergedClusterN;
		}
		if (found == (int)string::npos){
				clusterID = atoi((argu.substr(startit, lengthit)).c_str());
		}
	}

	parseInput(varNames, productNames, productName, argu, brands, catFilteredFeatures, conFilteredFeatures, boolFilteredFeatures, filteredRange,
				varNamesN, conFeatureNames, catFeatureNames, indicatorNames);

	string brand = "";

// Driver Manager

   	sql::mysql::MySQL_Driver *driver;

	sql::Connection	*con;
	sql::Statement	*stmt;

	sql::ResultSet	*res;
	sql::ResultSet	*res2;
		string line;
		string buf;
		vector<string> tokens;
		ifstream myfile;
		int i=0;
	   myfile.open("/optemo/site/config/database.yml");
	   if (myfile.is_open()){
		while (! myfile.eof()){
			getline (myfile,line);
			stringstream ss(line);
			while(ss>>buf){
				tokens.push_back(buf);
				i++;	}
		}
	    myfile.close();
       }
	   else{
			cout<<"Can't open file "<<myfile<<endl;
	   }

	string databaseString = tokens.at(findVec(tokens, "database:") + 1);
	string usernameString = tokens.at(findVec(tokens, "username:") + 1);
	string passwordString = tokens.at(findVec(tokens, "password:") + 1);
	string hostString = tokens.at(findVec(tokens, "host:") + 1);

	    #define PORT "3306"
	 	#define DB  "optemo_development"
		#define HOST hostString
		#define USER usernameString
	    #define PASS passwordString

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

			try {

				// Using the Driver to create a connection
				driver = sql::mysql::get_mysql_driver_instance();
				con = driver->connect(HOST, PORT, USER, PASS);
				stmt = con->createStatement();
				stmt->execute("USE "  DB);
				string command;
				int size;
				string out = "";

				bool reped = false;

			if (clusterID == 0){
				command = "SELECT id from ";
				command += tableName;
				command += ";";
 				res = stmt->executeQuery(command);
				size = res->rowsCount();
			}
			else{
				command = "SELECT id from ";
				command += productName;
				command += "_nodes where cluster_id=";
				ostringstream cid;
				cid<<clusterID;
				command += cid.str();
				command += ";";
				res = stmt->executeQuery(command);
				size = res->rowsCount();
			}
			int* productIDs = new int [size];
			int productN = filter2(filteredRange, brand, stmt, res, res2, productIDs, conFilteredFeatures, catFilteredFeatures, clusterID, clusterN, conFeatureN, conFeatureRange, productName, conFeatureNames);
			if (productN> 0){
				if (productN<=repW){
					repW = productN;
					smallNFlag = true;
				}

				int* reps = new int [repW];
				int* clusterIDs = new int[repW];
				int* clusterCounts = new int[repW];
				int* mergedClusterIDs;

				reped = getRep(reps, productIDs, productN, clusterIDs, clusterCounts, conFeatureN, repW, stmt, res, res2, clusterID, smallNFlag, mergedClusterIDs, mergedClusterIDInput, productName, conFeatureNames);

				if(reped){

					getIndicators(clusterIDs,repW, conFeatureN, indicators, stmt, res, mergedClusterIDs, productName, conFeatureNames);
				}

//Generating the output string
			//	repW = 9;

				out = generateOutput(indicatorNames, conFeatureN, productN, conFeatureRange, varNames, repW, reps, reped, clusterIDs, mergedClusterIDs, clusterCounts, indicators);
			}
			else{	//productN=0;
				out = "--- !map:HashWithIndifferentAccess \n";
				out.append("result_count: ");
				ostringstream resultCountStream;
				resultCountStream << productN;
				out.append(resultCountStream.str());
				out.append("\n");

			}
		cout<<out<<endl;

	// Clean up

 	delete stmt;
 	delete con;

 	} catch (sql::mysql::MySQL_DbcException *e) {

		delete e;
		return EXIT_FAILURE;

	} catch (sql::DbcException *e) {
		/* Exception is not caused by the MySQL Server */

		delete e;
		return EXIT_FAILURE;
	}

return 1; //EXIT_SUCCESS;
}<commit_msg>changed connect.cpp<commit_after>
// Standard C++ includes
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <assert.h>
#include <float.h>
#include <math.h>
#include <vector>
#include <string>
#include <algorithm>
#include <map>

using namespace std;

// Public interface of the MySQL Connector/C++
#include <cppconn/mysql_public_iface.h>
#include "filtering.h"
#include "preprocessing.h"

using namespace std;

/**
* Usage example for Driver Manager, Connection, (simple) Statement, ResultSet
*/

int main(int argc, char** argv) {

	string productName = "Camera";
	stringstream sql;

	int clusterN;
	int conFeatureN;
	int catFeatureN;
	int boolFeatureN;
	int varNamesN;
	int range;
	int session_id;
	int repW;
	int clusterID = 0;

	string argu = argv[1];
	int ind, endit, startit, lengthit;
	string var;

	//productName
	var = "product_name";
	ind = argu.find(var, 0);
	endit = argu.find("\n", ind);
	startit = ind + var.length() + 2;
	lengthit = endit - startit;
	if (lengthit>0){
		productName = (argu.substr(startit, lengthit)).c_str();
	}
	else{
		cout<<"ERROR - Specify a productName"<<endl;
	}
	//session_id
	var = "session_id";
	ind = argu.find(var, 0);
	endit = argu.find("\n", ind);
	startit = ind + var.length() + 2;
	lengthit = endit - startit;
	if (lengthit>0){
		session_id = atoi((argu.substr(startit, lengthit)).c_str());
	}

	string tableName = productName;
	tableName.append("s");
	map<const string, int> productNames;
	productNames["camera"] = 1;
	productNames["printer"] = 2;

	switch(productNames[productName]){

		case 1:
					//productName = "Camera";
					clusterN = 9;
					conFeatureN= 4;
					catFeatureN= 1;
					boolFeatureN= 0;
					varNamesN= 12;
					range= 2;
					repW = 9;
					break;

		case 2:
				//	productName = "Printer";
					clusterN = 9;
					conFeatureN= 4;
					catFeatureN= 1;
					boolFeatureN= 0;
					varNamesN= 12;
					range= 2;
					repW = 9;
					break;
		default:
					clusterN = 9;
					conFeatureN= 4;
					catFeatureN= 1;
					boolFeatureN= 0;
					varNamesN= 12;
					range= 2;
					repW = 9;
					break;
	}

	string* brands = new string [1] ;
	int* mergedClusterIDInput = new int[clusterN];
	bool smallNFlag =false;
	string* indicatorNames = new string[conFeatureN];
	int ** indicators = new int*[conFeatureN];
	double** conFeatureRange = new double* [conFeatureN];

	for (int f=0; f<conFeatureN; f++){
		conFeatureRange[f] = new double [2];
		indicators[f] = new int[repW];
		for (int i=0; i<repW; i++){
		indicators[f][i] = 0;
		}
	}
	ostringstream session_idStream;

	string *varNames = new string[varNamesN];
	string *catFeatureNames = new string [catFeatureN];
	string *conFeatureNames = new string[conFeatureN];
	double **filteredRange = new double* [conFeatureN];
	bool *conFilteredFeatures = new bool[conFeatureN];
	bool *catFilteredFeatures = new bool[catFeatureN];
	bool *boolFilteredFeatures = new bool[boolFeatureN];
	map<const string, string*> productFeatures;
   	for(int f=0; f<conFeatureN; f++){
		conFilteredFeatures[f] = 0;
		filteredRange[f] = new double [range];
	}

	for (int f=0; f<catFeatureN; f++){
	    catFilteredFeatures[f] = 0;
	}

    for (int f=0; f<boolFeatureN; f++){
		boolFilteredFeatures[f] = 0;
	}

	//cluster_id
	var = "cluster_id";
	ind = argu.find(var, 0);
	endit = argu.find("\n", ind);

	startit = ind + var.length() + 2;
	lengthit = endit - startit;

	if(lengthit>0){

		string valueString = argu.substr(startit, lengthit);
		int found = valueString.find("-");
		int mergedClusterN=0;
		while ( found != (int)string::npos){
			mergedClusterIDInput[mergedClusterN] = atoi((valueString.substr(found+1,1)).c_str());
			found = valueString.find("-", found+2, 1);
			mergedClusterN++;
		}
		if (mergedClusterN >0){
			clusterID = -1 * mergedClusterN;
		}
		if (found == (int)string::npos){
				clusterID = atoi((argu.substr(startit, lengthit)).c_str());
		}
	}

	parseInput(varNames, productNames, productName, argu, brands, catFilteredFeatures, conFilteredFeatures, boolFilteredFeatures, filteredRange,
				varNamesN, conFeatureNames, catFeatureNames, indicatorNames);

	string brand = "";

// Driver Manager

   	sql::mysql::MySQL_Driver *driver;

	sql::Connection	*con;
	sql::Statement	*stmt;

	sql::ResultSet	*res;
	sql::ResultSet	*res2;
		string line;
		string buf;
		vector<string> tokens;
		ifstream myfile;
		int i=0;
	   myfile.open("/optemo/site/config/database.yml");
	   if (myfile.is_open()){
		while (! myfile.eof()){
			getline (myfile,line);
			stringstream ss(line);
			while(ss>>buf){
				tokens.push_back(buf);
				i++;	}
		}
	    myfile.close();
       }
	   else{
			cout<<"Can't open file "<<myfile<<endl;
	   }

	string databaseString = tokens.at(findVec(tokens, "database:") + 1);
	string usernameString = tokens.at(findVec(tokens, "username:") + 1);
	string passwordString = tokens.at(findVec(tokens, "password:") + 1);
	string hostString = tokens.at(findVec(tokens, "host:") + 1);

	    #define PORT "3306"
	 	#define DB  "optemo_development"
		#define HOST hostString
		#define USER usernameString
	    #define PASS passwordString

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

			try {

				// Using the Driver to create a connection
				driver = sql::mysql::get_mysql_driver_instance();
				con = driver->connect(HOST, PORT, USER, PASS);
				stmt = con->createStatement();
				stmt->execute("USE "  DB);
				string command;
				int size;
				string out = "";

				bool reped = false;

			if (clusterID == 0){
				command = "SELECT id from ";
				command += tableName;
				command += ";";
 				res = stmt->executeQuery(command);
				size = res->rowsCount();
			}
			else{
				command = "SELECT id from ";
				command += productName;
				command += "_nodes where cluster_id=";
				ostringstream cid;
				cid<<clusterID;
				command += cid.str();
				command += ";";
				res = stmt->executeQuery(command);
				size = res->rowsCount();
			}
			int* productIDs = new int [size];
			int productN = filter2(filteredRange, brand, stmt, res, res2, productIDs, conFilteredFeatures, catFilteredFeatures, clusterID, clusterN, conFeatureN, conFeatureRange, productName, conFeatureNames);
			if (productN> 0){
				if (productN<=repW){
					repW = productN;
					smallNFlag = true;
				}

				int* reps = new int [repW];
				int* clusterIDs = new int[repW];
				int* clusterCounts = new int[repW];
				int* mergedClusterIDs;

				reped = getRep(reps, productIDs, productN, clusterIDs, clusterCounts, conFeatureN, repW, stmt, res, res2, clusterID, smallNFlag, mergedClusterIDs, mergedClusterIDInput, productName, conFeatureNames);

				if(reped){

					getIndicators(clusterIDs,repW, conFeatureN, indicators, stmt, res, mergedClusterIDs, productName, conFeatureNames);
				}

//Generating the output string
			//	repW = 9;

				out = generateOutput(indicatorNames, conFeatureN, productN, conFeatureRange, varNames, repW, reps, reped, clusterIDs, mergedClusterIDs, clusterCounts, indicators);
			}
			else{	//productN=0;
				out = "--- !map:HashWithIndifferentAccess \n";
				out.append("result_count: ");
				ostringstream resultCountStream;
				resultCountStream << productN;
				out.append(resultCountStream.str());
				out.append("\n");

			}
		cout<<out<<endl;

	// Clean up

 	delete stmt;
 	delete con;

 	} catch (sql::mysql::MySQL_DbcException *e) {

		delete e;
		return EXIT_FAILURE;

	} catch (sql::DbcException *e) {
		/* Exception is not caused by the MySQL Server */

		delete e;
		return EXIT_FAILURE;
	}

return 1; //EXIT_SUCCESS;
}<|endoftext|>