<commit_before>#include <yal/yal.hpp>

#include <boost/filesystem.hpp>

#include <cstdio>
#include <cctype>
#include <cerrno>

#include <unordered_map>
#include <algorithm>

namespace yal {

/***************************************************************************/

logger::logger_session_manager_ptr logger::object;
std::once_flag logger::flag;

/***************************************************************************/

namespace detail {

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

struct session::impl {
	impl(const std::string &path, const std::string &name, std::size_t volume_size, std::size_t shift_after)
		:path(path)
		,name(name)
		,volume_size(volume_size)
		,shift_after(shift_after)
		,file(0)
		,toterm(false)
		,prefix()
		,level(yal::info)
		,writen_bytes(0)
		,volume_number(0)
	{
		boost::filesystem::directory_iterator fs_beg(path), fs_end;
		for ( ; fs_beg != fs_end; ++fs_beg ) {
			auto filename = fs_beg->path().filename().string();
			if ( filename == "." || filename == ".." || boost::filesystem::is_directory(*fs_beg) )
				continue;

			if ( filename.find(name+"-") == std::string::npos )
				continue;

			auto beg = std::find(filename.begin(), filename.end(), '-');
			if ( beg == filename.end() || beg+1 == filename.end() )
				continue;

			std::advance(beg, 1);

			if ( !std::isdigit(*beg) )
				continue;

			auto end = beg;
			for ( ; std::isdigit(*end); ++end)
				;

			const std::size_t num = std::stoul(std::string(beg, end)) + 1;
			if ( num > volume_number )
				volume_number = num;
		}

		create_volume();
	}

	~impl() {
		std::fclose(file);
	}

	static const char* date_str() {
		static const char *fmtstring = "%d.%m.%Y-%H.%M.%S";

		static char buf[32];
		std::time_t raw_time;
		std::tm* time;

		std::time(&raw_time);
		time = localtime(&raw_time);
		strftime(buf, sizeof(buf), fmtstring, time);

		return &buf[0];
	}

	std::string volume_fname() {
		std::string result;

		if ( volume_number > shift_after ) {
			shift_after = shift_after * 10 + 9;
		}

		char fmt[64] = {0};
		const int digits = std::log10(shift_after)+1;
		std::snprintf(fmt, sizeof(fmt), "%s%d%s", "%s/%s-%0", digits, "d-%s");

		std::string::const_iterator it = std::find(name.begin(), name.end(), '.');
		if ( it == name.end() ) {
			result = (
				boost::format(fmt)
					% path
					% name
					% volume_number
					% date_str()
			).str();
		} else {
			std::strcat(fmt, "%s");
			result = (
				boost::format(fmt)
					% path
					% std::string(name.begin(), it)
					% volume_number
					% date_str()
					% std::string(it, name.end())
			).str();
		}

		//std::cout << "shift_after:" << shift_after << ", digits:" << digits << ", fmt:" << fmt << ", name:" << result << std::endl;

		return result;
	}

	void create_volume() {
		const std::string &fname = volume_fname();
		file = std::fopen(fname.c_str(), "wb");
		if ( !file ) {
			int error = errno;
			throw std::runtime_error("yal: cannot create logfile \"" + fname + "\" with errno="+std::to_string(error));
		}
	}

	void set_buffer(std::size_t size) {
		std::setvbuf(file, 0, (size == 0 ? _IONBF : _IOFBF), size);
	}

	void to_term(bool ok, const std::string &pref) {
		toterm = ok;
		prefix = pref;
	}

	void set_level(const yal::level lvl) {
		level = lvl;
	}

	void write(const char *fileline, const char *func, const std::string &data, const yal::level lvl) {
		const char *levelstr = (
			lvl == yal::debug ? "debug  "
				:lvl == yal::error ? "error  "
					:lvl == yal::info ? "info   "
						:lvl == yal::warning ? "warning"
							: 0
		);
		if ( toterm ) {
			auto termlog = ((lvl == yal::info || lvl == yal::debug) ? stdout : stderr);
			if ( prefix.empty() ) {
				std::fprintf(termlog, "[%s][%s][%s][%s]: %s\n", date_str(), levelstr, fileline, func, data.c_str());
			} else {
				std::fprintf(termlog, "<%s>[%s][%s][%s][%s]: %s\n", prefix.c_str(), date_str(), levelstr, fileline, func, data.c_str());
			}
			std::fflush(termlog);
		}

		const int writen = std::fprintf(file, "[%s][%s][%s][%s]: %s\n", date_str(), levelstr, fileline, func, data.c_str());

		if ( writen < 0 ) {
			int error = errno;
			throw std::runtime_error("yal: cannot write to logfile with errno="+std::to_string(error));
		}

		writen_bytes += writen;
		if ( writen_bytes >= volume_size ) {
			writen_bytes = 0;

			std::fclose(file);

			volume_number += 1;
			create_volume();
		}
	}

	void flush() {
		if ( file )
			std::fflush(file);
	}

	const std::string			path;
	const std::string			name;
	const std::size_t			volume_size;
	std::size_t					shift_after;
	FILE							*file;
	bool							toterm;
	std::string					prefix;
	yal::level					level;
	std::size_t					writen_bytes;
	std::size_t					volume_number;
};

/***************************************************************************/

session::session(const std::string &path, const std::string &name, std::size_t volume_size, std::size_t shift_after)
	:pimpl(new impl(path, name, volume_size, shift_after))
{}

session::~session()
{ delete pimpl; }

const std::string &session::name() const { return pimpl->name; }

const char *session::date_str() { return session::impl::date_str(); }

/***************************************************************************/

void session::set_buffer(const std::size_t size) {
	pimpl->set_buffer(size);
}

void session::to_term(const bool ok, const std::string &pref) {
	pimpl->to_term(ok, pref);
}

void session::set_level(const level lvl) {
	pimpl->set_level(lvl);
}

level session::get_level() const { return pimpl->level; }

void session::write(const char *fileline, const char *func, const std::string &data, level lvl) {
	if ( data.empty() ) return;
	pimpl->write(fileline, func, data, lvl);
}

void session::flush() {
	pimpl->flush();
}

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

struct session_manager::impl {
	using session_weak_ptr = std::weak_ptr<session>;
	using sessions_map = std::unordered_map<std::string, session_weak_ptr>;

	impl()
		:mutex()
		,root_path(".")
		,sessions()
	{}

	template<typename Cont, typename F>
	static void iterate(Cont &cont, F func) {
		for ( auto it = cont.begin(), end = cont.end(); it != end; ) {
			if ( auto session = it->second.lock() ) {
				func(session);
				++it;
			} else {
				it = cont.erase(it);
			}
		}
	}

	std::mutex mutex;
	std::string root_path;
	sessions_map sessions;
}; // struct impl

/***************************************************************************/

session_manager::session_manager()
	:pimpl(new impl)
{}

session_manager::~session_manager() {
	flush();
	delete pimpl;
}

/***************************************************************************/

const std::string &session_manager::root_path() const {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	return pimpl->root_path;
}

void session_manager::root_path(const std::string &path) {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	if ( !boost::filesystem::exists(path) )
		boost::filesystem::create_directories(path);

	pimpl->root_path = path;
}

std::shared_ptr<session>
session_manager::create(const std::string &name, std::size_t volume_size, std::size_t shift_after) {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	if ( !name.empty() && name[0] == '/' )
		throw std::runtime_error("yal: session name cannot be a full path name");
	if ( !shift_after )
		throw std::runtime_error("yal: shift_after can be 1 or greater");

	impl::iterate(
		 pimpl->sessions
		,[&name](yal::session s) {
			if ( s->name() == name )
				throw std::runtime_error("yal: session \""+name+"\" already exists");
		}
	);

	const auto pos = name.find_last_of('/');
	if ( pos != std::string::npos ) {
		const std::string &path = pimpl->root_path+"/"+name.substr(0, pos);
		std::cout << "path:" << path << std::endl;
		if ( !boost::filesystem::exists(path) )
			boost::filesystem::create_directories(path);
	}

	yal::session session(new detail::session(pimpl->root_path, name, volume_size, shift_after));
	pimpl->sessions.insert({name, session});

	return session;
}

/***************************************************************************/

void session_manager::write(const char *fileline, const char *func, const std::string &data, level lvl) {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	impl::iterate(
		 pimpl->sessions
		,[fileline, func, &data, lvl](yal::session s) { s->write(fileline, func, data, lvl); }
	);
}

std::shared_ptr<session>
session_manager::get(const std::string &name) const {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	auto it = pimpl->sessions.find(name);
	if ( it == pimpl->sessions.end() )
		return std::shared_ptr<session>();

	if ( auto s = it->second.lock() ) {
		return s;
	} else {
		pimpl->sessions.erase(it);
		return std::shared_ptr<session>();
	}
}

/***************************************************************************/

void session_manager::flush() {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	impl::iterate(
		 pimpl->sessions
		,[](yal::session s) { s->flush(); }
	);
}

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

} // ns detail

logger::logger_session_manager_ptr logger::instance() {
	std::call_once(flag, &init);
	return object;
}

const std::string &logger::root_path() { return instance()->root_path(); }

session logger::create(const std::string &name, std::size_t volume_size, std::size_t shift_after) {
	return instance()->create(name, volume_size, shift_after);
}

yal::session logger::get(const std::string &name) {
	return instance()->get(name);
}

void logger::write(const char *fileline, const char *func, const std::string &data, level lvl) {
	instance()->write(fileline, func, data, lvl);
}

void logger::flush() { instance()->flush(); }

void logger::init() { object.reset(new logger_session_manager_ptr::element_type); }

void logger::root_path(const std::string &path) { instance()->root_path(path); }

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

} // ns yal
<commit_msg>Update yal.cpp<commit_after>#include <yal/yal.hpp>

#include <boost/filesystem.hpp>

#include <cstdio>
#include <cctype>
#include <cerrno>

#include <unordered_map>
#include <algorithm>

namespace yal {

/***************************************************************************/

logger::logger_session_manager_ptr logger::object;
std::once_flag logger::flag;

/***************************************************************************/

namespace detail {

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

struct session::impl {
	impl(const std::string &path, const std::string &name, std::size_t volume_size, std::size_t shift_after)
		:path(path)
		,name(name)
		,volume_size(volume_size)
		,shift_after(shift_after)
		,file(0)
		,toterm(false)
		,prefix()
		,level(yal::info)
		,writen_bytes(0)
		,volume_number(0)
	{
		boost::filesystem::directory_iterator fs_beg(path), fs_end;
		for ( ; fs_beg != fs_end; ++fs_beg ) {
			auto filename = fs_beg->path().filename().string();
			if ( filename == "." || filename == ".." || boost::filesystem::is_directory(*fs_beg) )
				continue;

			if ( filename.find(name+"-") == std::string::npos )
				continue;

			auto beg = std::find(filename.begin(), filename.end(), '-');
			if ( beg == filename.end() || beg+1 == filename.end() )
				continue;

			std::advance(beg, 1);

			if ( !std::isdigit(*beg) )
				continue;

			auto end = beg;
			for ( ; std::isdigit(*end); ++end)
				;

			const std::size_t num = std::stoul(std::string(beg, end)) + 1;
			if ( num > volume_number )
				volume_number = num;
		}

		create_volume();
	}

	~impl() {
		std::fclose(file);
	}

	static const char* date_str() {
		static const char *fmtstring = "%d.%m.%Y-%H.%M.%S";

		static char buf[32];
		std::time_t raw_time;
		std::tm* time;

		std::time(&raw_time);
		time = localtime(&raw_time);
		strftime(buf, sizeof(buf), fmtstring, time);

		return &buf[0];
	}

	std::string volume_fname() {
		std::string result;

		if ( volume_number > shift_after ) {
			shift_after = shift_after * 10 + 9;
		}

		char fmt[64] = {0};
		const int digits = std::log10(shift_after)+1;
		std::snprintf(fmt, sizeof(fmt), "%s%d%s", "%s/%s-%0", digits, "d-%s");

		std::string::const_iterator it = std::find(name.begin(), name.end(), '.');
		if ( it == name.end() ) {
			result = (
				boost::format(fmt)
					% path
					% name
					% volume_number
					% date_str()
			).str();
		} else {
			std::strcat(fmt, "%s");
			result = (
				boost::format(fmt)
					% path
					% std::string(name.begin(), it)
					% volume_number
					% date_str()
					% std::string(it, name.end())
			).str();
		}

		//std::cout << "shift_after:" << shift_after << ", digits:" << digits << ", fmt:" << fmt << ", name:" << result << std::endl;

		return result;
	}

	void create_volume() {
		const std::string &fname = volume_fname();
		file = std::fopen(fname.c_str(), "wb");
		if ( !file ) {
			int error = errno;
			throw std::runtime_error("yal: cannot create logfile \"" + fname + "\" with errno="+std::to_string(error));
		}
	}

	void set_buffer(std::size_t size) {
		std::setvbuf(file, 0, (size == 0 ? _IONBF : _IOFBF), size);
	}

	void to_term(bool ok, const std::string &pref) {
		toterm = ok;
		prefix = pref;
	}

	void set_level(const yal::level lvl) {
		level = lvl;
	}

	void write(const char *fileline, const char *func, const std::string &data, const yal::level lvl) {
		const char *levelstr = (
			lvl == yal::debug ? "debug  "
				:lvl == yal::error ? "error  "
					:lvl == yal::info ? "info   "
						:lvl == yal::warning ? "warning"
							: 0
		);
		if ( toterm ) {
			auto termlog = ((lvl == yal::info || lvl == yal::debug) ? stdout : stderr);
			if ( prefix.empty() ) {
				std::fprintf(termlog, "[%s][%s][%s][%s]: %s\n", date_str(), levelstr, fileline, func, data.c_str());
			} else {
				std::fprintf(termlog, "<%s>[%s][%s][%s][%s]: %s\n", prefix.c_str(), date_str(), levelstr, fileline, func, data.c_str());
			}
			std::fflush(termlog);
		}

		const int writen = std::fprintf(file, "[%s][%s][%s][%s]: %s\n", date_str(), levelstr, fileline, func, data.c_str());

		if ( writen < 0 ) {
			int error = errno;
			throw std::runtime_error("yal: cannot write to logfile with errno="+std::to_string(error));
		}

		writen_bytes += writen;
		if ( writen_bytes >= volume_size ) {
			writen_bytes = 0;

			std::fclose(file);

			volume_number += 1;
			create_volume();
		}
	}

	void flush() {
		if ( file )
			std::fflush(file);
	}

	const std::string			path;
	const std::string			name;
	const std::size_t			volume_size;
	std::size_t					shift_after;
	FILE							*file;
	bool							toterm;
	std::string					prefix;
	yal::level					level;
	std::size_t					writen_bytes;
	std::size_t					volume_number;
};

/***************************************************************************/

session::session(const std::string &path, const std::string &name, std::size_t volume_size, std::size_t shift_after)
	:pimpl(new impl(path, name, volume_size, shift_after))
{}

session::~session()
{ delete pimpl; }

const std::string &session::name() const { return pimpl->name; }

const char *session::date_str() { return session::impl::date_str(); }

/***************************************************************************/

void session::set_buffer(const std::size_t size) {
	pimpl->set_buffer(size);
}

void session::to_term(const bool ok, const std::string &pref) {
	pimpl->to_term(ok, pref);
}

void session::set_level(const level lvl) {
	pimpl->set_level(lvl);
}

level session::get_level() const { return pimpl->level; }

void session::write(const char *fileline, const char *func, const std::string &data, level lvl) {
	if ( data.empty() ) return;
	pimpl->write(fileline, func, data, lvl);
}

void session::flush() {
	pimpl->flush();
}

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

struct session_manager::impl {
	using session_weak_ptr = std::weak_ptr<session>;
	using sessions_map = std::unordered_map<std::string, session_weak_ptr>;

	impl()
		:mutex()
		,root_path(".")
		,sessions()
	{}

	template<typename Cont, typename F>
	static void iterate(Cont &cont, F func) {
		for ( auto it = cont.begin(), end = cont.end(); it != end; ) {
			if ( auto session = it->second.lock() ) {
				func(session);
				++it;
			} else {
				it = cont.erase(it);
			}
		}
	}

	std::mutex mutex;
	std::string root_path;
	sessions_map sessions;
}; // struct impl

/***************************************************************************/

session_manager::session_manager()
	:pimpl(new impl)
{}

session_manager::~session_manager() {
	flush();
	delete pimpl;
}

/***************************************************************************/

const std::string &session_manager::root_path() const {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	return pimpl->root_path;
}

void session_manager::root_path(const std::string &path) {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	if ( !boost::filesystem::exists(path) )
		boost::filesystem::create_directories(path);

	pimpl->root_path = path;
}

std::shared_ptr<session>
session_manager::create(const std::string &name, std::size_t volume_size, std::size_t shift_after) {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	if ( !name.empty() && name[0] == '/' )
		throw std::runtime_error("yal: session name cannot be a full path name");
	if ( !shift_after )
		throw std::runtime_error("yal: shift_after can be 1 or greater");

	impl::iterate(
		 pimpl->sessions
		,[&name](yal::session s) {
			if ( s->name() == name )
				throw std::runtime_error("yal: session \""+name+"\" already exists");
		}
	);

	const auto pos = name.find_last_of('/');
	if ( pos != std::string::npos ) {
		const std::string &path = pimpl->root_path+"/"+name.substr(0, pos);
		//std::cout << "path:" << path << std::endl;
		if ( !boost::filesystem::exists(path) )
			boost::filesystem::create_directories(path);
	}

	yal::session session(new detail::session(pimpl->root_path, name, volume_size, shift_after));
	pimpl->sessions.insert({name, session});

	return session;
}

/***************************************************************************/

void session_manager::write(const char *fileline, const char *func, const std::string &data, level lvl) {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	impl::iterate(
		 pimpl->sessions
		,[fileline, func, &data, lvl](yal::session s) { s->write(fileline, func, data, lvl); }
	);
}

std::shared_ptr<session>
session_manager::get(const std::string &name) const {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	auto it = pimpl->sessions.find(name);
	if ( it == pimpl->sessions.end() )
		return std::shared_ptr<session>();

	if ( auto s = it->second.lock() ) {
		return s;
	} else {
		pimpl->sessions.erase(it);
		return std::shared_ptr<session>();
	}
}

/***************************************************************************/

void session_manager::flush() {
	std::lock_guard<std::mutex> lock(pimpl->mutex);

	impl::iterate(
		 pimpl->sessions
		,[](yal::session s) { s->flush(); }
	);
}

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

} // ns detail

logger::logger_session_manager_ptr logger::instance() {
	std::call_once(flag, &init);
	return object;
}

const std::string &logger::root_path() { return instance()->root_path(); }

session logger::create(const std::string &name, std::size_t volume_size, std::size_t shift_after) {
	return instance()->create(name, volume_size, shift_after);
}

yal::session logger::get(const std::string &name) {
	return instance()->get(name);
}

void logger::write(const char *fileline, const char *func, const std::string &data, level lvl) {
	instance()->write(fileline, func, data, lvl);
}

void logger::flush() { instance()->flush(); }

void logger::init() { object.reset(new logger_session_manager_ptr::element_type); }

void logger::root_path(const std::string &path) { instance()->root_path(path); }

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

} // ns yal
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Cloudius Systems
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/test/unit_test.hpp>
#include <core/distributed.hh>
#include <core/app-template.hh>
#include <core/sstring.hh>
#include <random>
#include "perf_sstable.hh"

using namespace sstables;

static unsigned iterations = 30;
static unsigned parallelism = 1;

future<> test_write(distributed<test_env>& dt) {
    return dt.invoke_on_all([] (test_env &t) {
        t.fill_memtable();
    }).then([&dt] {
        return time_runs(iterations, parallelism, dt, &test_env::flush_memtable);
    });
}

future<> test_index_read(distributed<test_env>& dt) {
    return time_runs(iterations, parallelism, dt, &test_env::read_all_indexes);
}

future<> test_sequential_read(distributed<test_env>& dt) {
    return time_runs(iterations, parallelism, dt, &test_env::read_sequential_partitions);
}

enum class test_modes {
    sequential_read,
    index_read,
    write,
    index_write,
};

static std::unordered_map<sstring, test_modes> test_mode = {
    {"sequential_read", test_modes::sequential_read },
    {"index_read", test_modes::index_read },
    {"write", test_modes::write },
    {"index_write", test_modes::index_write },
};

int main(int argc, char** argv) {
    namespace bpo = boost::program_options;
    app_template app;
    app.add_options()
        ("parallelism", bpo::value<unsigned>()->default_value(1), "number parallel requests")
        ("iterations", bpo::value<unsigned>()->default_value(30), "number of iterations")
        ("partitions", bpo::value<unsigned>()->default_value(5000000), "number of partitions")
        ("buffer_size", bpo::value<unsigned>()->default_value(64), "sstable buffer size, in KB")
        ("key_size", bpo::value<unsigned>()->default_value(128), "size of partition key")
        ("num_columns", bpo::value<unsigned>()->default_value(5), "number of columns per row")
        ("column_size", bpo::value<unsigned>()->default_value(64), "size in bytes for each column")
        ("mode", bpo::value<sstring>()->default_value("index_write"), "one of: random_read, sequential_read, index_read, write, index_write (default)")
        ("testdir", bpo::value<sstring>()->default_value("/var/lib/cassandra/perf-tests"), "directory in which to store the sstables");

    return app.run_deprecated(argc, argv, [&app] {
        auto test = make_lw_shared<distributed<test_env>>();

        auto cfg = test_env::conf();
        iterations = app.configuration()["iterations"].as<unsigned>();
        parallelism = app.configuration()["parallelism"].as<unsigned>();
        cfg.partitions = app.configuration()["partitions"].as<unsigned>();
        cfg.key_size = app.configuration()["key_size"].as<unsigned>();
        cfg.buffer_size = app.configuration()["buffer_size"].as<unsigned>() << 10;
        sstring dir = app.configuration()["testdir"].as<sstring>();
        cfg.dir = dir;
        auto mode = test_mode[app.configuration()["mode"].as<sstring>()];
        if ((mode == test_modes::index_read) || (mode == test_modes::index_write)) {
            cfg.num_columns = 0;
            cfg.column_size = 0;
        } else {
            cfg.num_columns = app.configuration()["num_columns"].as<unsigned>();
            cfg.column_size = app.configuration()["column_size"].as<unsigned>();
        }
        return test->start(std::move(cfg)).then([mode, dir, test] {
            engine().at_exit([test] { return test->stop(); });
            if ((mode == test_modes::index_read) ||
               (mode == test_modes::sequential_read)) {
                return test->invoke_on_all([] (test_env &t) {
                    return t.load_sstables(iterations);
                }).then_wrapped([] (future<> f) {
                    try {
                        f.get();
                    } catch (...) {
                        std::cerr << "An error occurred when trying to load test sstables. Did you run write mode yet?" << std::endl;
                        throw;
                    }
                });
            } else if ((mode == test_modes::index_write) || (mode == test_modes::write)) {
                return test_setup::create_empty_test_dir(dir);
            } else {
                throw std::invalid_argument("Invalid mode");
            }
        }).then([test, mode] {
            if (mode == test_modes::index_read) {
                return test_index_read(*test).then([test] {});
            } else if (mode == test_modes::sequential_read) {
                return test_sequential_read(*test).then([test] {});
            } else if ((mode == test_modes::index_write) || (mode == test_modes::write)) {
                return test_write(*test).then([test] {});
            } else {
                throw std::invalid_argument("Invalid mode");
            }
        }).then([] {
            return engine().exit(0);
        }).or_terminate();
    });
}
<commit_msg>perf_sstable: use current scylla default directory<commit_after>/*
 * Copyright 2015 Cloudius Systems
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/test/unit_test.hpp>
#include <core/distributed.hh>
#include <core/app-template.hh>
#include <core/sstring.hh>
#include <random>
#include "perf_sstable.hh"

using namespace sstables;

static unsigned iterations = 30;
static unsigned parallelism = 1;

future<> test_write(distributed<test_env>& dt) {
    return dt.invoke_on_all([] (test_env &t) {
        t.fill_memtable();
    }).then([&dt] {
        return time_runs(iterations, parallelism, dt, &test_env::flush_memtable);
    });
}

future<> test_index_read(distributed<test_env>& dt) {
    return time_runs(iterations, parallelism, dt, &test_env::read_all_indexes);
}

future<> test_sequential_read(distributed<test_env>& dt) {
    return time_runs(iterations, parallelism, dt, &test_env::read_sequential_partitions);
}

enum class test_modes {
    sequential_read,
    index_read,
    write,
    index_write,
};

static std::unordered_map<sstring, test_modes> test_mode = {
    {"sequential_read", test_modes::sequential_read },
    {"index_read", test_modes::index_read },
    {"write", test_modes::write },
    {"index_write", test_modes::index_write },
};

int main(int argc, char** argv) {
    namespace bpo = boost::program_options;
    app_template app;
    app.add_options()
        ("parallelism", bpo::value<unsigned>()->default_value(1), "number parallel requests")
        ("iterations", bpo::value<unsigned>()->default_value(30), "number of iterations")
        ("partitions", bpo::value<unsigned>()->default_value(5000000), "number of partitions")
        ("buffer_size", bpo::value<unsigned>()->default_value(64), "sstable buffer size, in KB")
        ("key_size", bpo::value<unsigned>()->default_value(128), "size of partition key")
        ("num_columns", bpo::value<unsigned>()->default_value(5), "number of columns per row")
        ("column_size", bpo::value<unsigned>()->default_value(64), "size in bytes for each column")
        ("mode", bpo::value<sstring>()->default_value("index_write"), "one of: random_read, sequential_read, index_read, write, index_write (default)")
        ("testdir", bpo::value<sstring>()->default_value("/var/lib/scylla/perf-tests"), "directory in which to store the sstables");

    return app.run_deprecated(argc, argv, [&app] {
        auto test = make_lw_shared<distributed<test_env>>();

        auto cfg = test_env::conf();
        iterations = app.configuration()["iterations"].as<unsigned>();
        parallelism = app.configuration()["parallelism"].as<unsigned>();
        cfg.partitions = app.configuration()["partitions"].as<unsigned>();
        cfg.key_size = app.configuration()["key_size"].as<unsigned>();
        cfg.buffer_size = app.configuration()["buffer_size"].as<unsigned>() << 10;
        sstring dir = app.configuration()["testdir"].as<sstring>();
        cfg.dir = dir;
        auto mode = test_mode[app.configuration()["mode"].as<sstring>()];
        if ((mode == test_modes::index_read) || (mode == test_modes::index_write)) {
            cfg.num_columns = 0;
            cfg.column_size = 0;
        } else {
            cfg.num_columns = app.configuration()["num_columns"].as<unsigned>();
            cfg.column_size = app.configuration()["column_size"].as<unsigned>();
        }
        return test->start(std::move(cfg)).then([mode, dir, test] {
            engine().at_exit([test] { return test->stop(); });
            if ((mode == test_modes::index_read) ||
               (mode == test_modes::sequential_read)) {
                return test->invoke_on_all([] (test_env &t) {
                    return t.load_sstables(iterations);
                }).then_wrapped([] (future<> f) {
                    try {
                        f.get();
                    } catch (...) {
                        std::cerr << "An error occurred when trying to load test sstables. Did you run write mode yet?" << std::endl;
                        throw;
                    }
                });
            } else if ((mode == test_modes::index_write) || (mode == test_modes::write)) {
                return test_setup::create_empty_test_dir(dir);
            } else {
                throw std::invalid_argument("Invalid mode");
            }
        }).then([test, mode] {
            if (mode == test_modes::index_read) {
                return test_index_read(*test).then([test] {});
            } else if (mode == test_modes::sequential_read) {
                return test_sequential_read(*test).then([test] {});
            } else if ((mode == test_modes::index_write) || (mode == test_modes::write)) {
                return test_write(*test).then([test] {});
            } else {
                throw std::invalid_argument("Invalid mode");
            }
        }).then([] {
            return engine().exit(0);
        }).or_terminate();
    });
}
<|endoftext|>


<commit_before>#include "log.h"

void Log(const char* format, ...)
{
    char msg[1024] = "";
    va_list vl;
    va_start(vl, format);
    _vsnprintf(msg, sizeof(msg) / sizeof(char), format, vl);
#ifdef _DEBUG
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, msg);
#endif
    va_end(format);
    UNICODE_STRING FileName;
    OBJECT_ATTRIBUTES objAttr;
    RtlInitUnicodeString(&FileName, L"\\DosDevices\\C:\\TitanHide.log");
    InitializeObjectAttributes(&objAttr, &FileName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    if(KeGetCurrentIrql() != PASSIVE_LEVEL)
    {
#ifdef _DEBUG
        DbgPrint("[TITANHIDE] KeGetCurrentIrql != PASSIVE_LEVEL!\n");
#endif
        return;
    }
    HANDLE handle;
    IO_STATUS_BLOCK ioStatusBlock;
    NTSTATUS ntstatus = ZwCreateFile(&handle,
                                     FILE_APPEND_DATA,
                                     &objAttr, &ioStatusBlock, NULL,
                                     FILE_ATTRIBUTE_NORMAL,
                                     FILE_SHARE_WRITE | FILE_SHARE_READ,
                                     FILE_OPEN_IF,
                                     FILE_SYNCHRONOUS_IO_NONALERT,
                                     NULL, 0);
    if(NT_SUCCESS(ntstatus))
    {
        size_t cb;
        ntstatus = RtlStringCbLengthA(msg, sizeof(msg), &cb);
        if(NT_SUCCESS(ntstatus))
            ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock, msg, (ULONG)cb, NULL, NULL);
        ZwClose(handle);
    }
}
<commit_msg>Null-terminate result of _vsnprintf in Log()<commit_after>#include "log.h"

void Log(const char* format, ...)
{
    char msg[1024] = "";
    va_list vl;
    va_start(vl, format);
    const int n = _vsnprintf(msg, sizeof(msg) / sizeof(char), format, vl);
    msg[n] = '\0';
    va_end(vl);
#ifdef _DEBUG
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, msg);
#endif
    va_end(format);
    UNICODE_STRING FileName;
    OBJECT_ATTRIBUTES objAttr;
    RtlInitUnicodeString(&FileName, L"\\DosDevices\\C:\\TitanHide.log");
    InitializeObjectAttributes(&objAttr, &FileName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    if(KeGetCurrentIrql() != PASSIVE_LEVEL)
    {
#ifdef _DEBUG
        DbgPrint("[TITANHIDE] KeGetCurrentIrql != PASSIVE_LEVEL!\n");
#endif
        return;
    }
    HANDLE handle;
    IO_STATUS_BLOCK ioStatusBlock;
    NTSTATUS ntstatus = ZwCreateFile(&handle,
                                     FILE_APPEND_DATA,
                                     &objAttr, &ioStatusBlock, NULL,
                                     FILE_ATTRIBUTE_NORMAL,
                                     FILE_SHARE_WRITE | FILE_SHARE_READ,
                                     FILE_OPEN_IF,
                                     FILE_SYNCHRONOUS_IO_NONALERT,
                                     NULL, 0);
    if(NT_SUCCESS(ntstatus))
    {
        size_t cb;
        ntstatus = RtlStringCbLengthA(msg, sizeof(msg), &cb);
        if(NT_SUCCESS(ntstatus))
            ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock, msg, (ULONG)cb, NULL, NULL);
        ZwClose(handle);
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <ctime>
#include <fstream>
#include <string>
#include <limits>

#include "../include/Game.h"
#include "../include/Common.h"
#include "../include/Console.h"

#include "../include/PlayerTypes/PlayerTypes.h"
#include "../include/EnemyTypes/EnemyTypes.h"

using namespace std;
using namespace Common;

// To avoid conflict with numeric_limits<streamsize>::max used in Game::GetChoice()
#ifdef max
#undef max
#endif

#define SKIP_TURN -2

void Game::MainMenu(){
    // Main menu. Loops until you start
    // a game or quit.
	    for (int choice=-1; choice!=0;){
        choice = GetChoice(MenuType::eMain);
        switch(choice){
			case 1:
           		StartGame();
				break;
			case 2:
				HowToPlay();
				break;
			case 0:
				break;
        }
    }
}

string Game::InitializePlayerName() {
	ClearScreen();
	string name;
	cout << "What is your name?"
		<< endl << endl
		<< "> ";

  cin.ignore();
	getline(cin,name); // Change to full name
	return name;
}

char Game::InitializePlayerGender() {
    char gender;
    do {
        ClearScreen();
        cout << "What is your gender (M or F)?"
            << endl << endl
            << "> ";

        cin >> gender;
        gender = toupper(gender);
    } while (gender != 'M' && gender != 'F');

    return gender;
}

int Game::InitializePlayerClass() {
	// Initializes the player's class through user choice.
	int player_class = 0;
	player_class = GetChoice(MenuType::ePlayerClass);
	SetPlayerClass(player_class);
	return player_class;
}

void Game::SetPlayerClass(int player_class) {
	// Sets the Player class according to player code given.
	switch (player_class) {
	case 1:
		// Player's class is a warrior.
		_Player = new Warrior;
		break;
	case 2:
		// Player's class is a rogue.
		_Player = new Rogue;
		break;
	case 3:
		// Player's class is a healer.
		_Player = new Healer;
		break;
	case 4:
		// Player's class is a debugger.
		// Used to easily defeat enemies. Only for development purposes.
		_Player = new Debugger;
		break;
	case 5:
		// You are Saitama.
		// Do I have to explain??
		_Player = new Saitama;
		break;
	default:
		// If input does not equal any of the cases, the default class is a warrior.
		_Player = new Warrior;
		break;
	}
}

void Game::SetPlayerData(){
	/* Data initialized in order of:
	* class code
	* name
	* level
	* experience
	* health
	* arrows
	* bombs
	* potions
	* whetstones
	* weaponstrength
	* coins
	*/

	ifstream ReadData;
	ReadData.open("data.txt");

	// Runs if user has never played the game before or data is not found.
	if (!ReadData) {
		ReadData.close();
		ofstream WriteData;
		WriteData.open("data.txt");

		WriteData << InitializePlayerClass() << endl
			<< InitializePlayerName() << endl
            << InitializePlayerGender() << endl
			<< 1 << endl
			<< 0 << endl
			<< 100 << endl
			<< 10 << endl
			<< 1 << endl
			<< 1 << endl
			<< 1 << endl
			<< 100 << endl
			<< 0;
		WriteData.close();
	}

	else {
		// Initializes player type from class code given in data.txt
		int player_class;
		ReadData >> player_class;
		SetPlayerClass(player_class);
		ReadData.close();
	}
}

void Game::SetEnemy(){
    // Generates a random integer to determine class of the enemy.
    // The abstract class Enemy is morphed with one of its child classes.

    EnemyType selector = EnemyType(rand()%etNumEnemyTypes);
    switch(selector){
	case: etSlimeball:
	// Enemy is a slimeball.
	_Enemy = new Slimeball;
            break;
        case etCrab:
            // Enemy is a crab.
            _Enemy = new Crab;
            break;
        case etGiantCrab:
            // Enemy is a giant crab.
            _Enemy = new GiantCrab;
            break;
        case etSquid:
            // Enemy is a squid.
            _Enemy = new Squid;
            break;
        case etGiantSquid:
            // Enemy is a giant squid.
            _Enemy = new GiantSquid;
            break;
		case etLich:
			// Enemy is a Lich
			_Enemy = new Lich;
			break;
		case etMurloc:
			//Enemy is a Murloc
			_Enemy = new Murloc;
			break;
		case etPutnafer:
			// Enemy is a Putnafer
			_Enemy = new Putnafer;
			break;
        case etZombie:
            // Enemy is a Zombie
            _Enemy = new Zombie;
            break;
		case etVampire:
			// Enemy is a Vampire
			_Enemy = new Vampire;
			break;
		case etWerewolf:
			// Enemy is a Werewolf
			_Enemy = new Werewolf;
			break;
		case etGoblin:
			// Enemy is a Goblin
			_Enemy = new Goblin;
			break;
		case etGargoyle:
			// Enemy is a Goblin
			_Enemy = new Gargoyle;
			break;
		case etCerberus:
			// Enemy is a Cerberus
			_Enemy = new Cerberus;
			break;
		case etSkeleton:
			// Enemy is a Rat
			_Enemy = new Skeleton;
			break;
		case etSmallRat:
			// Enemy is a Small Rat
			_Enemy = new SmallRat;
			break;
        default:
            // If the above cases do not match the selector for any reason,
            // the enemy defaults on the crab class.
            _Enemy = new Crab;
            break;
    }
    // Simply prints that the enemy's class was encountered.
	cout << _Enemy->GetIntro() << endl;
	Sleep(SLEEP_MS);
	ColourPrint(_Enemy->GetName(), Console::DarkGrey);
    cout << " encountered!" << endl << endl;
    Sleep(SLEEP_MS);
}

bool Game::PlayAgain(){
    // Returns a bool value to determine if the player wants to play again.

    char choice;
    cout << "Keep going? (y/n)" << endl << endl;
    choice = (char)input();
    // Returns true if the player says yes (Y, y, 1).
    if (choice == 'y' || choice == 'Y' || choice == '1') return true;
    // Returns false otherwise, regardless of choice=='n'.
    return false;
}

void Game::Intermission(){
    // Saves game in case player unexpectedly quits (uses X instead of
    // in-game quit.
    _Player->SaveGame();

    // Loops until the player starts another battle or they quit (IsPlaying=false).
    for (int choice=0; IsPlaying;){
        ClearScreen();
        cout << "*--------- Intermission ----------* " << endl << endl;

	_Player->DisplayInventory();
        cout << "1) Start battle" << endl;
        cout << "2) Store" << endl;
        cout << "3) Gamble" << endl;
	cout << "4) Use Item" << endl;
        cout << "0) Quit" << endl << endl;

        choice = input();

        switch(choice){
        case 1:
            // Returns to StartGame()'s loop, calling Battle().
            return;
        case 2:
            // Goes to the store where the player can buy items.
            /// Currently in working progress.
            _Store.StoreFront(_Player);
            break;
        case 3:
            // Goes to the gambling arena.
            // _Player is passed in to add items won to the player inventory.
            _Gambling.Gamble(_Player);
            break;
	case 4:
	    _Player->UseItem();
	    _Player->SaveGame();
	    break;
        case 0:
            // Breaks the loop in StartGame(), going back to MainMenu().
            IsPlaying=false;
	    break;
        }
    }
}

void Game::StartGame(){
    // Starts the game by initializing values for a new game.

    // Seeds the random number generator for pseudo-random numbers.
    srand((unsigned int)time(NULL));
    IsPlaying=true;

    // SetPlayerData() initializes the variables in this end.
    ClearScreen();
    SetPlayerData();

	// This initializes the variables on the Player end.
    ClearScreen();
    _Player->SetPlayerData();

    // Loops while the game is still playing.
    // Alternates between battles and intermission (gambling, store, et)
    while(IsPlaying){
		Intermission();
		if (!IsPlaying)
			break;
		Battle();
    }

    // Saves the player's data to an external file before quitting.
    _Player->SaveGame();
}

void Game::Battle(){
    ClearScreen();
    // Uses random integers to determine class of the enemy.
    SetEnemy();

    // Loops the actual battle while playing.
    while(IsPlaying){
        ClearScreen();
        // Displays the name and health bar of the player and enemy.
        // The Enemy* argument is to display the enemy's
        // name. Explained more in _Player->DisplayHealthBar().
        _Player->DisplayHUD(_Enemy);
        _Enemy->DisplayHUD();

		int damagePlayer = _Player->Action();
        // Player's turn to attack Enemy or choose other action.

		if (damagePlayer != SKIP_TURN){
			_Enemy->TakeDamage(damagePlayer);
			// Pauses console and ignores user input for SLEEP_MS milliseconds.
        		Sleep(SLEEP_MS);
		}

        // Leaves battle if player chooses to.
        if (!IsPlaying){
            IsPlaying = true;
            return;
        }

        // Executes when the enemy's health is 0 or below.
        if (_Enemy->IsDead()){
            // Adds drops to player's inventory from defeated enemy.
            _Player->AddToInventory(_Enemy->GetDrops());
            // Adds points to player's experience.
            _Player->AddExperience(_Enemy->ReturnExperience());
			// Replenishes player's health for the next round.
			_Player->ReplenishHealth();

			// If player wants to battle again, it breaks the loop and uses tail recursion to play again.
            if (PlayAgain()) break;
            // Returns to StartGame()'s loop, and executes Intermission().
            return;
        }

        // Enemy's turn to attack player.
		if (damagePlayer != SKIP_TURN)
			_Player->TakeDamage(_Enemy->Action());
        Sleep(SLEEP_MS);

        // Executes when player's health is 0 or below.
        if (_Player->IsDead()){
            // Player loses the amount of experience points gained when you defeat the enemy.
            _Player->LoseExperience(_Enemy->ReturnExperience());
			// Replenishes player's health for the next round.
			_Player->ReplenishHealth();

			if (PlayAgain()) break;
            return;
        }
    }
    Battle();
}

void Game::HowToPlay() {

	GetChoice(MenuType::eHowToPlay);
}

int Game::GetChoice(MenuType menuType)
{
	DisplayMenu(menuType);
	int choice = -1;
	while (!(cin >> choice)) {
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		cout << "Invalid input.  Please try again.";
		Sleep(SLEEP_MS);
		DisplayMenu(menuType);
	}
	return choice;
}

void Game::DisplayMenu(MenuType menuType)
{
	ClearScreen();
	switch (menuType)
	{
	case Game::eMain:
		cout << "========== TURN-BASED FIGHTING GAME ==========" << endl << endl
			<< "1) Start Game" << endl
			<< "2) How to play" << endl
			<< "0) Exit" << endl << endl << "> ";
		break;
	case Game::ePlayerClass:
		cout << endl
			<< "Which class do you want to play as?" << endl
			<< "1) Warrior (high damage, low healing capabilities)" << endl
			<< "2) Rogue (moderate damage, moderate healing capabilities)" << endl
			<< "3) Healer (low damage, high healing capabilities)" << endl
			<< "4) Debugger (INFINITE DAMAGE!!!!)" << endl
			<< "5) Saitama (self-explanatory)" << endl
			<< endl << endl
			<< "> ";
		break;
	case Game::eHowToPlay:
		cout << "============== HOW TO PLAY ==============" << endl << endl
			<< "Turn is a turn-based RPG game." << endl
			<< "Create your character and start playing." << endl
			<< "For playing you have to choose what to do by typing" << endl
			<< "the corresponding number." << endl
			<< "You can perform actions and use items." << endl << endl
			<< "-- Actions --" << endl
			<< "Attack: Regular attack" << endl
			<< "Risk Attack: Attack deals more damage, but with a chance of missing" << endl
			<< "Heal: Restore an amount of your HP" << endl
			<< "Flee: Run away from battle" << endl << endl
			<< "-- Items --" << endl
			<< "Bombs: Deals 50HP to your opponent with no chance of missing" << endl
			<< "Arrows: Deals 10-15HP to your opponent with no chance of missing" << endl
			<< "Potion: Replenishes your HP to 100" << endl
			<< "Whetstone: Restores your weapon's sharpness." << endl << endl
			<< "Good luck and have fun!" << endl << endl
			<< "0) Quit" << endl << endl << "> ";
		break;
	default:
		break;
	}
}
<commit_msg>Update Game.cpp<commit_after>#include <iostream>
#include <ctime>
#include <fstream>
#include <string>
#include <limits>

#include "../include/Game.h"
#include "../include/Common.h"
#include "../include/Console.h"

#include "../include/PlayerTypes/PlayerTypes.h"
#include "../include/EnemyTypes/EnemyTypes.h"

using namespace std;
using namespace Common;

// To avoid conflict with numeric_limits<streamsize>::max used in Game::GetChoice()
#ifdef max
#undef max
#endif

#define SKIP_TURN -2

void Game::MainMenu(){
    // Main menu. Loops until you start
    // a game or quit.
	    for (int choice=-1; choice!=0;){
        choice = GetChoice(MenuType::eMain);
        switch(choice){
			case 1:
           		StartGame();
				break;
			case 2:
				HowToPlay();
				break;
			case 0:
				break;
        }
    }
}

string Game::InitializePlayerName() {
	ClearScreen();
	string name;
	cout << "What is your name?"
		<< endl << endl
		<< "> ";

  cin.ignore();
	getline(cin,name); // Change to full name
	return name;
}

char Game::InitializePlayerGender() {
    char gender;
    do {
        ClearScreen();
        cout << "What is your gender (M or F)?"
            << endl << endl
            << "> ";

        cin >> gender;
        gender = toupper(gender);
    } while (gender != 'M' && gender != 'F');

    return gender;
}

int Game::InitializePlayerClass() {
	// Initializes the player's class through user choice.
	int player_class = 0;
	player_class = GetChoice(MenuType::ePlayerClass);
	SetPlayerClass(player_class);
	return player_class;
}

void Game::SetPlayerClass(int player_class) {
	// Sets the Player class according to player code given.
	switch (player_class) {
	case 1:
		// Player's class is a warrior.
		_Player = new Warrior;
		break;
	case 2:
		// Player's class is a rogue.
		_Player = new Rogue;
		break;
	case 3:
		// Player's class is a healer.
		_Player = new Healer;
		break;
	case 4:
		// Player's class is a debugger.
		// Used to easily defeat enemies. Only for development purposes.
		_Player = new Debugger;
		break;
	case 5:
		// You are Saitama.
		// Do I have to explain??
		_Player = new Saitama;
		break;
	default:
		// If input does not equal any of the cases, the default class is a warrior.
		_Player = new Warrior;
		break;
	}
}

void Game::SetPlayerData(){
	/* Data initialized in order of:
	* class code
	* name
	* level
	* experience
	* health
	* arrows
	* bombs
	* potions
	* whetstones
	* weaponstrength
	* coins
	*/

	ifstream ReadData;
	ReadData.open("data.txt");

	// Runs if user has never played the game before or data is not found.
	if (!ReadData) {
		ReadData.close();
		ofstream WriteData;
		WriteData.open("data.txt");

		WriteData << InitializePlayerClass() << endl
			<< InitializePlayerName() << endl
            << InitializePlayerGender() << endl
			<< 1 << endl
			<< 0 << endl
			<< 100 << endl
			<< 10 << endl
			<< 1 << endl
			<< 1 << endl
			<< 1 << endl
			<< 100 << endl
			<< 0;
		WriteData.close();
	}

	else {
		// Initializes player type from class code given in data.txt
		int player_class;
		ReadData >> player_class;
		SetPlayerClass(player_class);
		ReadData.close();
	}
}

void Game::SetEnemy(){
    // Generates a random integer to determine class of the enemy.
    // The abstract class Enemy is morphed with one of its child classes.

    EnemyType selector = EnemyType(rand()%etNumEnemyTypes);
    switch(selector){
	case etSlimeball:
	// Enemy is a slimeball.
	_Enemy = new Slimeball;
            break;
        case etCrab:
            // Enemy is a crab.
            _Enemy = new Crab;
            break;
        case etGiantCrab:
            // Enemy is a giant crab.
            _Enemy = new GiantCrab;
            break;
        case etSquid:
            // Enemy is a squid.
            _Enemy = new Squid;
            break;
        case etGiantSquid:
            // Enemy is a giant squid.
            _Enemy = new GiantSquid;
            break;
		case etLich:
			// Enemy is a Lich
			_Enemy = new Lich;
			break;
		case etMurloc:
			//Enemy is a Murloc
			_Enemy = new Murloc;
			break;
		case etPutnafer:
			// Enemy is a Putnafer
			_Enemy = new Putnafer;
			break;
        case etZombie:
            // Enemy is a Zombie
            _Enemy = new Zombie;
            break;
		case etVampire:
			// Enemy is a Vampire
			_Enemy = new Vampire;
			break;
		case etWerewolf:
			// Enemy is a Werewolf
			_Enemy = new Werewolf;
			break;
		case etGoblin:
			// Enemy is a Goblin
			_Enemy = new Goblin;
			break;
		case etGargoyle:
			// Enemy is a Goblin
			_Enemy = new Gargoyle;
			break;
		case etCerberus:
			// Enemy is a Cerberus
			_Enemy = new Cerberus;
			break;
		case etSkeleton:
			// Enemy is a Rat
			_Enemy = new Skeleton;
			break;
		case etSmallRat:
			// Enemy is a Small Rat
			_Enemy = new SmallRat;
			break;
        default:
            // If the above cases do not match the selector for any reason,
            // the enemy defaults on the crab class.
            _Enemy = new Crab;
            break;
    }
    // Simply prints that the enemy's class was encountered.
	cout << _Enemy->GetIntro() << endl;
	Sleep(SLEEP_MS);
	ColourPrint(_Enemy->GetName(), Console::DarkGrey);
    cout << " encountered!" << endl << endl;
    Sleep(SLEEP_MS);
}

bool Game::PlayAgain(){
    // Returns a bool value to determine if the player wants to play again.

    char choice;
    cout << "Keep going? (y/n)" << endl << endl;
    choice = (char)input();
    // Returns true if the player says yes (Y, y, 1).
    if (choice == 'y' || choice == 'Y' || choice == '1') return true;
    // Returns false otherwise, regardless of choice=='n'.
    return false;
}

void Game::Intermission(){
    // Saves game in case player unexpectedly quits (uses X instead of
    // in-game quit.
    _Player->SaveGame();

    // Loops until the player starts another battle or they quit (IsPlaying=false).
    for (int choice=0; IsPlaying;){
        ClearScreen();
        cout << "*--------- Intermission ----------* " << endl << endl;

	_Player->DisplayInventory();
        cout << "1) Start battle" << endl;
        cout << "2) Store" << endl;
        cout << "3) Gamble" << endl;
	cout << "4) Use Item" << endl;
        cout << "0) Quit" << endl << endl;

        choice = input();

        switch(choice){
        case 1:
            // Returns to StartGame()'s loop, calling Battle().
            return;
        case 2:
            // Goes to the store where the player can buy items.
            /// Currently in working progress.
            _Store.StoreFront(_Player);
            break;
        case 3:
            // Goes to the gambling arena.
            // _Player is passed in to add items won to the player inventory.
            _Gambling.Gamble(_Player);
            break;
	case 4:
	    _Player->UseItem();
	    _Player->SaveGame();
	    break;
        case 0:
            // Breaks the loop in StartGame(), going back to MainMenu().
            IsPlaying=false;
	    break;
        }
    }
}

void Game::StartGame(){
    // Starts the game by initializing values for a new game.

    // Seeds the random number generator for pseudo-random numbers.
    srand((unsigned int)time(NULL));
    IsPlaying=true;

    // SetPlayerData() initializes the variables in this end.
    ClearScreen();
    SetPlayerData();

	// This initializes the variables on the Player end.
    ClearScreen();
    _Player->SetPlayerData();

    // Loops while the game is still playing.
    // Alternates between battles and intermission (gambling, store, et)
    while(IsPlaying){
		Intermission();
		if (!IsPlaying)
			break;
		Battle();
    }

    // Saves the player's data to an external file before quitting.
    _Player->SaveGame();
}

void Game::Battle(){
    ClearScreen();
    // Uses random integers to determine class of the enemy.
    SetEnemy();

    // Loops the actual battle while playing.
    while(IsPlaying){
        ClearScreen();
        // Displays the name and health bar of the player and enemy.
        // The Enemy* argument is to display the enemy's
        // name. Explained more in _Player->DisplayHealthBar().
        _Player->DisplayHUD(_Enemy);
        _Enemy->DisplayHUD();

		int damagePlayer = _Player->Action();
        // Player's turn to attack Enemy or choose other action.

		if (damagePlayer != SKIP_TURN){
			_Enemy->TakeDamage(damagePlayer);
			// Pauses console and ignores user input for SLEEP_MS milliseconds.
        		Sleep(SLEEP_MS);
		}

        // Leaves battle if player chooses to.
        if (!IsPlaying){
            IsPlaying = true;
            return;
        }

        // Executes when the enemy's health is 0 or below.
        if (_Enemy->IsDead()){
            // Adds drops to player's inventory from defeated enemy.
            _Player->AddToInventory(_Enemy->GetDrops());
            // Adds points to player's experience.
            _Player->AddExperience(_Enemy->ReturnExperience());
			// Replenishes player's health for the next round.
			_Player->ReplenishHealth();

			// If player wants to battle again, it breaks the loop and uses tail recursion to play again.
            if (PlayAgain()) break;
            // Returns to StartGame()'s loop, and executes Intermission().
            return;
        }

        // Enemy's turn to attack player.
		if (damagePlayer != SKIP_TURN)
			_Player->TakeDamage(_Enemy->Action());
        Sleep(SLEEP_MS);

        // Executes when player's health is 0 or below.
        if (_Player->IsDead()){
            // Player loses the amount of experience points gained when you defeat the enemy.
            _Player->LoseExperience(_Enemy->ReturnExperience());
			// Replenishes player's health for the next round.
			_Player->ReplenishHealth();

			if (PlayAgain()) break;
            return;
        }
    }
    Battle();
}

void Game::HowToPlay() {

	GetChoice(MenuType::eHowToPlay);
}

int Game::GetChoice(MenuType menuType)
{
	DisplayMenu(menuType);
	int choice = -1;
	while (!(cin >> choice)) {
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		cout << "Invalid input.  Please try again.";
		Sleep(SLEEP_MS);
		DisplayMenu(menuType);
	}
	return choice;
}

void Game::DisplayMenu(MenuType menuType)
{
	ClearScreen();
	switch (menuType)
	{
	case Game::eMain:
		cout << "========== TURN-BASED FIGHTING GAME ==========" << endl << endl
			<< "1) Start Game" << endl
			<< "2) How to play" << endl
			<< "0) Exit" << endl << endl << "> ";
		break;
	case Game::ePlayerClass:
		cout << endl
			<< "Which class do you want to play as?" << endl
			<< "1) Warrior (high damage, low healing capabilities)" << endl
			<< "2) Rogue (moderate damage, moderate healing capabilities)" << endl
			<< "3) Healer (low damage, high healing capabilities)" << endl
			<< "4) Debugger (INFINITE DAMAGE!!!!)" << endl
			<< "5) Saitama (self-explanatory)" << endl
			<< endl << endl
			<< "> ";
		break;
	case Game::eHowToPlay:
		cout << "============== HOW TO PLAY ==============" << endl << endl
			<< "Turn is a turn-based RPG game." << endl
			<< "Create your character and start playing." << endl
			<< "For playing you have to choose what to do by typing" << endl
			<< "the corresponding number." << endl
			<< "You can perform actions and use items." << endl << endl
			<< "-- Actions --" << endl
			<< "Attack: Regular attack" << endl
			<< "Risk Attack: Attack deals more damage, but with a chance of missing" << endl
			<< "Heal: Restore an amount of your HP" << endl
			<< "Flee: Run away from battle" << endl << endl
			<< "-- Items --" << endl
			<< "Bombs: Deals 50HP to your opponent with no chance of missing" << endl
			<< "Arrows: Deals 10-15HP to your opponent with no chance of missing" << endl
			<< "Potion: Replenishes your HP to 100" << endl
			<< "Whetstone: Restores your weapon's sharpness." << endl << endl
			<< "Good luck and have fun!" << endl << endl
			<< "0) Quit" << endl << endl << "> ";
		break;
	default:
		break;
	}
}
<|endoftext|>


<commit_before>#include <set>
#include <iostream>
#include <fstream>
#include <istream>
#include <sys/stat.h>
#include <cstdlib>
#include <string.h>

#include <cliopt.h>
#include <cliargs.h>
#include <spcre.h>

#include <string>

using namespace std;

static bool is_quiet;
static bool is_preserve;

string fileToString(const char *fname) {
ifstream in(fname);
return string(istreambuf_iterator<char>(in),
istreambuf_iterator<char>());
}

char * find_unused_filename(const char *startingname) {
  char *str = (char *) calloc(1, strlen(startingname) + 128);
  sprintf(str, "%s.orig", startingname);
  if (!does_file_exist_quiet(str))
    return str;
  int i;
  for (i = 2; ; i += 1) {
    sprintf(str, "%s.orig-%d", startingname, i);
    if (!is_path_file(str))
      return str;
  }
}

string pre_backsub(string origstr, string filename)
{
  int curoffset = 0;
  int len = origstr.size();
  string res;
  const char *cs = origstr.c_str();
  while (curoffset < len) {
    int slashind = origstr.find('\\', curoffset);
    if (slashind != string::npos) {
      res.append(cs + curoffset, slashind - curoffset);
      if (slashind + 1 < len) {
        char c = cs[slashind+1];
        if (c == 'f' )
          res.append(filename);
        else
          res.append(cs + slashind, 2); // preserve other markers
      }
      curoffset = slashind + 2;
    }
    else {
      res.append(cs + curoffset, len - curoffset);
      break;
    }
  }
  return res;
}

void process_file(SPCRE s, string repstr, string fname)
{
  string orig = fileToString(fname.c_str());
  string xformed = s.gsub(orig, repstr);
  if (orig == xformed)
    return;
  else {
    if (!is_quiet)
      cerr << "(  changed) " << fname << endl;
    string templ = fname + string("mXXXXXX");
    char *tmpfn = strdup(templ.c_str());
    ofstream outf(tmpfn);
    outf.write(xformed.c_str(), xformed.size());
    if (outf.bad()) {
      cerr << "Error, could not write file " << xformed << endl;
      cerr << "Aborting due to short write." << endl;
      exit(1);
    }
    outf.close();
    if (outf.bad()) {
      cerr << "Error, could not close file " << xformed << endl;
      cerr << "Aborting due to failed close." << endl;
      exit(1);
    }
    chmod(tmpfn, get_path_mode(fname.c_str()));
    const char *destfilename = fname.c_str();
    if (is_preserve) {
      char *origdest = find_unused_filename(destfilename);
      cout << "(preserved: " << destfilename << " => " << origdest << ")"<<endl;
      rename(destfilename, origdest);
      free(origdest);
    }
    rename(tmpfn, destfilename);
    free(tmpfn);
  }
}

string cplusplusbasename(string inpstring)
{
  char *dup = strdup(inpstring.c_str());
  string result;
  int lastIndex = inpstring.find_last_of("/\\");
  if (lastIndex == std::string::npos)
    result = inpstring;
  else
    result = inpstring.substr(lastIndex + 1);
  free(dup);
  return result;
}

void rename_file_maybe(SPCRE s, string repstr, string fname)
{
  string orig = fname;
  string xformed = s.gsub(orig, repstr);
  if (orig == xformed)
    return;
  if (cplusplusbasename(orig) == cplusplusbasename(xformed))
    return;
  if (!is_quiet)
    cerr << "(renaming f) " << orig << " => " << xformed << endl;
  int rc = s.options.renamer->rename(orig.c_str(), xformed.c_str(), is_preserve);
  if (rc)
    cerr << "Error renaming " << orig << " to " << xformed << endl;
}

void rename_dir_maybe(SPCRE s, string repstr, string fname)
{
  string orig = fname;
  string xformed = s.gsub(orig, repstr);
  if (orig == xformed)
    return;
  if (cplusplusbasename(orig) == cplusplusbasename(xformed))
    return;
  if (!is_quiet)
    cerr << "(renaming d) " << orig << " => " << xformed << endl;
  int rc = s.options.renamer->rename(orig.c_str(), xformed.c_str(), is_preserve);
  if (rc)
    cerr << "Error renaming " << orig << " to " << xformed << endl;
}

int main(int argc, const char **argv)
{
  TargetList tl;
  CliArgs ca(argv);
  deque<string>::iterator i;

  is_quiet = ca.options.is_quiet;
  is_preserve = ca.options.do_preserve;

  tl = ca.make_target_list();

  if (ca.options.do_contents) {
    for (i = tl.files.begin(); i != tl.files.end(); i++) {
      string cur = (*i);
      SPCRE s(pre_backsub(ca.searchpat, cur), ca.options);
      process_file(s, pre_backsub(ca.repstr, cur), cur);
    }
  }

  SPCRE s(ca.searchpat, ca.options);

  if (ca.options.do_filenames) {
    for (i = tl.files.begin(); i != tl.files.end(); i++) {
      string cur = (*i);
      rename_file_maybe(s, ca.repstr, cur);
    }
  }

  if (ca.options.do_directorynames) {
    for (i = tl.dirs.begin(); i != tl.dirs.end(); i++) {
      string cur = (*i);
      rename_dir_maybe(s, ca.repstr, cur);
    }
  }

  return 0;
}
<commit_msg>ADD: one can use '\n/\r' in a replacement-string<commit_after>#include <set>
#include <iostream>
#include <fstream>
#include <istream>
#include <sys/stat.h>
#include <cstdlib>
#include <string.h>

#include <cliopt.h>
#include <cliargs.h>
#include <spcre.h>

#include <string>

using namespace std;

static bool is_quiet;
static bool is_preserve;

string fileToString(const char *fname) {
  ifstream in(fname);
  return string(istreambuf_iterator<char>(in),
                istreambuf_iterator<char>());
}

char * find_unused_filename(const char *startingname) {
  char *str = (char *) calloc(1, strlen(startingname) + 128);
  sprintf(str, "%s.orig", startingname);
  if (!does_file_exist_quiet(str))
    return str;
  int i;
  for (i = 2; ; i += 1) {
    sprintf(str, "%s.orig-%d", startingname, i);
    if (!is_path_file(str))
      return str;
  }
}

string pre_backsub(string origstr, string filename)
{
  int curoffset = 0;
  int len = origstr.size();
  string res;
  const char *cs = origstr.c_str();
  while (curoffset < len) {
    int slashind = origstr.find('\\', curoffset);
    if (slashind != string::npos) {
      res.append(cs + curoffset, slashind - curoffset);
      if (slashind + 1 < len) {
        char c = cs[slashind+1];
        if (c == 'f' )
          res.append(filename);
        else if (c == 'n')
          res.append("\n");
        else if (c == 'r')
          res.append("\r");
        else
          res.append(cs + slashind, 2); // preserve other markers
      }
      curoffset = slashind + 2;
    }
    else {
      res.append(cs + curoffset, len - curoffset);
      break;
    }
  }
  return res;
}

void process_file(SPCRE s, string repstr, string fname)
{
  string orig = fileToString(fname.c_str());
  string xformed = s.gsub(orig, repstr);
  if (orig == xformed)
    return;
  else {
    if (!is_quiet)
      cerr << "(  changed) " << fname << endl;
    string templ = fname + string("mXXXXXX");
    char *tmpfn = strdup(templ.c_str());
    ofstream outf(tmpfn);
    outf.write(xformed.c_str(), xformed.size());
    if (outf.bad()) {
      cerr << "Error, could not write file " << xformed << endl;
      cerr << "Aborting due to short write." << endl;
      exit(1);
    }
    outf.close();
    if (outf.bad()) {
      cerr << "Error, could not close file " << xformed << endl;
      cerr << "Aborting due to failed close." << endl;
      exit(1);
    }
    chmod(tmpfn, get_path_mode(fname.c_str()));
    const char *destfilename = fname.c_str();
    if (is_preserve) {
      char *origdest = find_unused_filename(destfilename);
      cout << "(preserved: " << destfilename << " => " << origdest << ")"<<endl;
      rename(destfilename, origdest);
      free(origdest);
    }
    rename(tmpfn, destfilename);
    free(tmpfn);
  }
}

string cplusplusbasename(string inpstring)
{
  char *dup = strdup(inpstring.c_str());
  string result;
  int lastIndex = inpstring.find_last_of("/\\");
  if (lastIndex == std::string::npos)
    result = inpstring;
  else
    result = inpstring.substr(lastIndex + 1);
  free(dup);
  return result;
}

void rename_file_maybe(SPCRE s, string repstr, string fname)
{
  string orig = fname;
  string xformed = s.gsub(orig, repstr);
  if (orig == xformed)
    return;
  if (cplusplusbasename(orig) == cplusplusbasename(xformed))
    return;
  if (!is_quiet)
    cerr << "(renaming f) " << orig << " => " << xformed << endl;
  int rc = s.options.renamer->rename(orig.c_str(), xformed.c_str(), is_preserve);
  if (rc)
    cerr << "Error renaming " << orig << " to " << xformed << endl;
}

void rename_dir_maybe(SPCRE s, string repstr, string fname)
{
  string orig = fname;
  string xformed = s.gsub(orig, repstr);
  if (orig == xformed)
    return;
  if (cplusplusbasename(orig) == cplusplusbasename(xformed))
    return;
  if (!is_quiet)
    cerr << "(renaming d) " << orig << " => " << xformed << endl;
  int rc = s.options.renamer->rename(orig.c_str(), xformed.c_str(), is_preserve);
  if (rc)
    cerr << "Error renaming " << orig << " to " << xformed << endl;
}

int main(int argc, const char **argv)
{
  TargetList tl;
  CliArgs ca(argv);
  deque<string>::iterator i;

  is_quiet = ca.options.is_quiet;
  is_preserve = ca.options.do_preserve;

  tl = ca.make_target_list();

  if (ca.options.do_contents) {
    for (i = tl.files.begin(); i != tl.files.end(); i++) {
      string cur = (*i);
      SPCRE s(pre_backsub(ca.searchpat, cur), ca.options);
      process_file(s, pre_backsub(ca.repstr, cur), cur);
    }
  }

  SPCRE s(ca.searchpat, ca.options);

  if (ca.options.do_filenames) {
    for (i = tl.files.begin(); i != tl.files.end(); i++) {
      string cur = (*i);
      rename_file_maybe(s, ca.repstr, cur);
    }
  }

  if (ca.options.do_directorynames) {
    for (i = tl.dirs.begin(); i != tl.dirs.end(); i++) {
      string cur = (*i);
      rename_dir_maybe(s, ca.repstr, cur);
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>
#include <q/execution_context.hpp>
#include <q/blocking_dispatcher.hpp>
#include <q/threadpool.hpp>
#include <q/promise.hpp>

#include <gtest/gtest.h>

#include "q-test.hpp"

TEST( ThreadPool, PerformTasks )
{
	qtest::spy spy;

	auto bd = q::make_execution_context<
		q::blocking_dispatcher, q::direct_scheduler
	>( "test" );
	auto tp = q::threadpool::construct( "test", bd->queue( ) );

	auto task = EXPECT_CALL_WRAPPER( spy )(
		[ tp, &spy ]( )
		{
			auto task = EXPECT_CALL_WRAPPER( spy )(
				[ tp ]( )
				{
					;
				}
			);

			tp->add_task( task );
		}
	);

	tp->add_task( task );

	tp->terminate( q::termination::linger )
	.finally( [ bd ]( )
	{
		bd->dispatcher( )->terminate( q::termination::linger );
	} );

	bd->dispatcher( )->start( );
	tp->await_termination( );
	bd->dispatcher( )->await_termination( );
}
<commit_msg>Updated threadpool test to its new API<commit_after>
#include <q/execution_context.hpp>
#include <q/blocking_dispatcher.hpp>
#include <q/threadpool.hpp>
#include <q/promise.hpp>

#include <gtest/gtest.h>

#include <queue>

#include "q-test.hpp"

TEST( ThreadPool, PerformTasks )
{
	qtest::spy spy;

	auto bd = q::make_execution_context<
		q::blocking_dispatcher, q::direct_scheduler
	>( "test" );
	auto tp = q::threadpool::construct( "test", bd->queue( ) );

	auto tasks = q::make_shared< q::queue >( 0 );

	tp->set_task_fetcher( [ tasks ]( )
	{
		return tasks->pop( );
	} );

	auto task = EXPECT_CALL_WRAPPER( spy )(
		[ tasks, tp, &spy ]( )
		{
			auto task = EXPECT_CALL_WRAPPER( spy )(
				[ tp ]( )
				{
					;
				}
			);

			tasks->push( task );
			tp->notify( );
		}
	);

	tasks->push( task );
	tp->notify( );

	tp->terminate( q::termination::linger )
	.finally( [ bd ]( )
	{
		bd->dispatcher( )->terminate( q::termination::linger );
	} );

	bd->dispatcher( )->start( );
	tp->await_termination( );
	bd->dispatcher( )->await_termination( );
}
<|endoftext|>


<commit_before>#include "xcint.hpp"

static struct alias_data aliases_array[XC_MAX_ALIASES] =
{
  {"null","No functional",{{"slaterx",0.0}} },
  {"lda","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"blyp","Becke exchange and LYP correlation",{{"beckex",1.0},{"lypc",1.0}} },
  {"pbe","PBE exchange and correlation",{{"pbex",1.0},{"pbec",1.0}} },
  {"bp86","Becke-Perdew 1986",{{"beckex",1.0},{"p86c",1.0}} },
  {"kt1","Keal-Tozer 2",{{"slaterx",1.},{"ktx",-0.006},{"vwn5c",1.}} },
  {"kt2","Keal-Tozer 2",{{"slaterx",1.07173},{"ktx",-0.006},{"vwn5c",0.576727}} },
  {"kt3","Keal-Tozer 3",{{"slaterx",1.092},{"ktx",-0.004},{"optxcorr",-0.925452},{"lypc",0.864409}} },
  {"ldaerf","Short-range exchange and correlation LDA functional",{{"ldaerfx",1.0},{"ldaerfc",1.0}}},
  // Hybrid Functionals
  {"pbe0","Perdew-Burke-Ernzerhof",{{"pbex",0.75},{"pbec",1.0},{"exx",0.25}} },
  {"b3lyp","Becke-3-paramater-LYP (VWN5 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"lypc",0.81},{"vwn5c",0.19},{"exx",0.20}} },
  {"m06","M06", {{"m06c",1.0},{"m06x",1.0}} },
  {"m06-2x","M06 2X", {{"m06x2c",1.0},{"m06x2x",1.0}} },
  {"m06L","M06 L", {{"m06lc",1.0},{"m06lx",1.0}} },
  {"b3lyp-g","Becke-3-paramater-LYP (VWN3 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"lypc",0.81},{"vwn3c",0.19},{"exx",0.20}} },
  {"b3p86","Becke-3-paramater-LYP (VWN5 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"p86corrc",0.81},{"vwn5c",1.0},{"exx",0.20}} },
  {"b3p86-g","Becke-3-paramater-LYP (VWN3 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"p86corrc",0.81},{"vwn3c",1.0},{"exx",0.20}} },
  {"bpw91","Becke 88 exchange+PW91",{{"beckex",1.0},{"pw91c",1.0}} },
  {"b97","B97 exchange and correlation", {{"b97x",1.0},{"b97c",1.0},{"exx",0.1943}} },
  {"b97-1","B97-1 exchange and correlation", {{"b97_1x",1.0},{"b97_1c",1.0},{"exx",0.21}} },
  {"b97_2","B97-2 exchange and correlation", {{"b97_2x",1.0},{"b97_2c",1.0},{"exx",0.21}} },
  // Some of these are there to match the names used in Dalton
  {"vwn","VWN5 correlation",{{"vwn5c",1.0}}},
  {"vwn3","VWN5 correlation",{{"vwn3c",1.0}}},
  {"svwn","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"svwn5","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"svwn3","Slater exchange and VWN3 correlation",{{"slaterx",1.0},{"vwn3c",1.0}} },
  {"becke","Becke exchange",{{"beckecorrx",1.0}}},
  {"slater","Slater exchange",{{"slaterx",1.0}}},
};

// TODO: OLYP

struct alias_data *xcint_aliases = aliases_array;
<commit_msg>Added alaias B88X for ADMM<commit_after>#include "xcint.hpp"

static struct alias_data aliases_array[XC_MAX_ALIASES] =
{
  {"null","No functional",{{"slaterx",0.0}} },
  {"lda","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"blyp","Becke exchange and LYP correlation",{{"beckex",1.0},{"lypc",1.0}} },
  {"pbe","PBE exchange and correlation",{{"pbex",1.0},{"pbec",1.0}} },
  {"bp86","Becke-Perdew 1986",{{"beckex",1.0},{"p86c",1.0}} },
  {"kt1","Keal-Tozer 2",{{"slaterx",1.},{"ktx",-0.006},{"vwn5c",1.}} },
  {"kt2","Keal-Tozer 2",{{"slaterx",1.07173},{"ktx",-0.006},{"vwn5c",0.576727}} },
  {"kt3","Keal-Tozer 3",{{"slaterx",1.092},{"ktx",-0.004},{"optxcorr",-0.925452},{"lypc",0.864409}} },
  {"ldaerf","Short-range exchange and correlation LDA functional",{{"ldaerfx",1.0},{"ldaerfc",1.0}}},
  // Hybrid Functionals
  {"pbe0","Perdew-Burke-Ernzerhof",{{"pbex",0.75},{"pbec",1.0},{"exx",0.25}} },
  {"b3lyp","Becke-3-paramater-LYP (VWN5 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"lypc",0.81},{"vwn5c",0.19},{"exx",0.20}} },
  {"m06","M06", {{"m06c",1.0},{"m06x",1.0}} },
  {"m06-2x","M06 2X", {{"m06x2c",1.0},{"m06x2x",1.0}} },
  {"m06L","M06 L", {{"m06lc",1.0},{"m06lx",1.0}} },
  {"b3lyp-g","Becke-3-paramater-LYP (VWN3 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"lypc",0.81},{"vwn3c",0.19},{"exx",0.20}} },
  {"b3p86","Becke-3-paramater-LYP (VWN5 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"p86corrc",0.81},{"vwn5c",1.0},{"exx",0.20}} },
  {"b3p86-g","Becke-3-paramater-LYP (VWN3 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"p86corrc",0.81},{"vwn3c",1.0},{"exx",0.20}} },
  {"bpw91","Becke 88 exchange+PW91",{{"beckex",1.0},{"pw91c",1.0}} },
  {"b97","B97 exchange and correlation", {{"b97x",1.0},{"b97c",1.0},{"exx",0.1943}} },
  {"b97-1","B97-1 exchange and correlation", {{"b97_1x",1.0},{"b97_1c",1.0},{"exx",0.21}} },
  {"b97_2","B97-2 exchange and correlation", {{"b97_2x",1.0},{"b97_2c",1.0},{"exx",0.21}} },
  // Some of these are there to match the names used in Dalton
  {"vwn","VWN5 correlation",{{"vwn5c",1.0}}},
  {"vwn3","VWN5 correlation",{{"vwn3c",1.0}}},
  {"svwn","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"svwn5","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"svwn3","Slater exchange and VWN3 correlation",{{"slaterx",1.0},{"vwn3c",1.0}} },
  {"becke","Becke exchange",{{"beckecorrx",1.0}}},
  {"slater","Slater exchange",{{"slaterx",1.0}}},
  // ADMM exchange funtional corrections
  {"B88X","Becke exchange",{{"beckecorrx",1.0}}},
};

// TODO: OLYP

struct alias_data *xcint_aliases = aliases_array;
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include <Utils/String.h>

TEST(Utils_String, Split) {
    std::string str1 = "text with   words";
    std::string str2 = "other text";

    std::vector<std::string> result1 = Util::String::split(str1, ' ', true);
    std::vector<std::string> result2 = Util::String::split(str1, ' ', false);
    std::vector<std::string> result3 = Util::String::split(str2, 't', true);
    std::vector<std::string> result4 = Util::String::split(str2, 't', false);

    ASSERT_EQ(3, result1.size());
    ASSERT_EQ(5, result2.size());
    ASSERT_EQ(3, result3.size());
    ASSERT_EQ(3, result4.size());

    ASSERT_EQ("text",  result1[0]);
    ASSERT_EQ("with",  result1[1]);
    ASSERT_EQ("words", result1[2]);

    ASSERT_EQ("text",  result2[0]);
    ASSERT_EQ("with",  result2[1]);
    ASSERT_EQ("",      result2[2]);
    ASSERT_EQ("",      result2[3]);
    ASSERT_EQ("words", result2[4]);

    ASSERT_EQ("o",    result3[0]);
    ASSERT_EQ("her ", result3[1]);
    ASSERT_EQ("ex",   result3[2]);

    ASSERT_EQ("o",    result4[0]);
    ASSERT_EQ("her ", result4[1]);
    ASSERT_EQ("ex",   result4[2]);
}

TEST(Utils_String, Trim) {
    std::string templateString = "trimmed template";

    std::string str1 = " " + templateString + "  ";
    std::string str2 = "    " + templateString + "\t";
    std::string str3 = "\t\t\n" + templateString + " \t ";

    ASSERT_EQ(templateString, Util::String::trim(str1));
    ASSERT_EQ(templateString, Util::String::trim(str2));
    ASSERT_EQ(templateString, Util::String::trim(str3));
}

TEST(Utils_String, Trim_Left) {
    std::string templateString = "trimmed template";

    std::string str1 = " " + templateString;
    std::string str2 = "    " + templateString;
    std::string str3 = "  \t \t   \n " + templateString;

    ASSERT_EQ(templateString, Util::String::ltrim(str1));
    ASSERT_EQ(templateString, Util::String::ltrim(str2));
    ASSERT_EQ(templateString, Util::String::ltrim(str3));
}

TEST(Utils_String, Trim_Right) {
    std::string templateString = "trimmed template";

    std::string str1 = templateString + "  ";
    std::string str2 = templateString + " \t   ";
    std::string str3 = templateString + " \t \n\n  \n";

    ASSERT_EQ(templateString, Util::String::rtrim(str1));
    ASSERT_EQ(templateString, Util::String::rtrim(str2));
    ASSERT_EQ(templateString, Util::String::rtrim(str3));
}

TEST(Utils_String, Starts_With) {
    std::string str1 = "hello world";
    std::string str2 = "lorem ipsum dolor sit omet";
    std::string str3 = " some text ";

    ASSERT_TRUE(Util::String::startsWith(str1, "hello"));
    ASSERT_TRUE(Util::String::startsWith(str2, "lorem ipsum"));
    ASSERT_TRUE(Util::String::startsWith(str3, " som"));
    ASSERT_TRUE(Util::String::startsWith(str3, str3));
    ASSERT_FALSE(Util::String::startsWith(str1, " " + str1));
    ASSERT_FALSE(Util::String::startsWith(str2, "omet"));
}

TEST(Utils_String, Ends_With) {
    std::string str1 = "hello world";
    std::string str2 = "lorem ipsum dolor sit omet";
    std::string str3 = " some text ";

    ASSERT_TRUE(Util::String::endsWith(str1, " world"));
    ASSERT_TRUE(Util::String::endsWith(str2, "sit omet"));
    ASSERT_TRUE(Util::String::endsWith(str3, "text "));
    ASSERT_TRUE(Util::String::endsWith(str2, str2));
    ASSERT_FALSE(Util::String::endsWith(str1, str1 + " "));
    ASSERT_FALSE(Util::String::endsWith(str2, "lorem "));
}
<commit_msg>Fixed typo.<commit_after>#include <gtest/gtest.h>

#include <Utils/String.h>

TEST(Utils_String, Split) {
    std::string str1 = "text with   words";
    std::string str2 = "other text";

    std::vector<std::string> result1 = Util::String::split(str1, ' ', true);
    std::vector<std::string> result2 = Util::String::split(str1, ' ', false);
    std::vector<std::string> result3 = Util::String::split(str2, 't', true);
    std::vector<std::string> result4 = Util::String::split(str2, 't', false);

    ASSERT_EQ(3, result1.size());
    ASSERT_EQ(5, result2.size());
    ASSERT_EQ(3, result3.size());
    ASSERT_EQ(3, result4.size());

    ASSERT_EQ("text",  result1[0]);
    ASSERT_EQ("with",  result1[1]);
    ASSERT_EQ("words", result1[2]);

    ASSERT_EQ("text",  result2[0]);
    ASSERT_EQ("with",  result2[1]);
    ASSERT_EQ("",      result2[2]);
    ASSERT_EQ("",      result2[3]);
    ASSERT_EQ("words", result2[4]);

    ASSERT_EQ("o",    result3[0]);
    ASSERT_EQ("her ", result3[1]);
    ASSERT_EQ("ex",   result3[2]);

    ASSERT_EQ("o",    result4[0]);
    ASSERT_EQ("her ", result4[1]);
    ASSERT_EQ("ex",   result4[2]);
}

TEST(Utils_String, Trim) {
    std::string templateString = "trimmed template";

    std::string str1 = " " + templateString + "  ";
    std::string str2 = "    " + templateString + "\t";
    std::string str3 = "\t\t\n" + templateString + " \t ";

    ASSERT_EQ(templateString, Util::String::trim(str1));
    ASSERT_EQ(templateString, Util::String::trim(str2));
    ASSERT_EQ(templateString, Util::String::trim(str3));
}

TEST(Utils_String, Trim_Left) {
    std::string templateString = "trimmed template";

    std::string str1 = " " + templateString;
    std::string str2 = "    " + templateString;
    std::string str3 = "  \t \t   \n " + templateString;

    ASSERT_EQ(templateString, Util::String::ltrim(str1));
    ASSERT_EQ(templateString, Util::String::ltrim(str2));
    ASSERT_EQ(templateString, Util::String::ltrim(str3));
}

TEST(Utils_String, Trim_Right) {
    std::string templateString = "trimmed template";

    std::string str1 = templateString + "  ";
    std::string str2 = templateString + " \t   ";
    std::string str3 = templateString + " \t \n\n  \n";

    ASSERT_EQ(templateString, Util::String::rtrim(str1));
    ASSERT_EQ(templateString, Util::String::rtrim(str2));
    ASSERT_EQ(templateString, Util::String::rtrim(str3));
}

TEST(Utils_String, Starts_With) {
    std::string str1 = "hello world";
    std::string str2 = "lorem ipsum dolor sit amet";
    std::string str3 = " some text ";

    ASSERT_TRUE(Util::String::startsWith(str1, "hello"));
    ASSERT_TRUE(Util::String::startsWith(str2, "lorem ipsum"));
    ASSERT_TRUE(Util::String::startsWith(str3, " som"));
    ASSERT_TRUE(Util::String::startsWith(str3, str3));
    ASSERT_FALSE(Util::String::startsWith(str1, " " + str1));
    ASSERT_FALSE(Util::String::startsWith(str2, "amet"));
}

TEST(Utils_String, Ends_With) {
    std::string str1 = "hello world";
    std::string str2 = "lorem ipsum dolor sit amet";
    std::string str3 = " some text ";

    ASSERT_TRUE(Util::String::endsWith(str1, " world"));
    ASSERT_TRUE(Util::String::endsWith(str2, "sit amet"));
    ASSERT_TRUE(Util::String::endsWith(str3, "text "));
    ASSERT_TRUE(Util::String::endsWith(str2, str2));
    ASSERT_FALSE(Util::String::endsWith(str1, str1 + " "));
    ASSERT_FALSE(Util::String::endsWith(str2, "lorem "));
}
<|endoftext|>