#include "Sorter.hpp" #include "Profiling/Timer.hpp" #define BOOL_FMT "%s" #define BOOL_ARG(exp) (exp) ? "true" : "false" namespace sva { Sorter::Sorter(size_t size) : m_SortArray(size) { populate(size); spdlog::debug("Sorter: created -- size: %lld, is-sorted: " BOOL_FMT, size, BOOL_ARG(is_sorted())); } Sorter::SortResult Sorter::run(const sol::protected_function& sort_func) { SortResult res; timer_result tres; if (m_ActiveSortResult) spdlog::error("Sorter: A Sort already running..."); m_ActiveSortResult = &res; Timer timer(tres, timer.paused); spdlog::debug("Sorter: running function"); timer.set_state(timer.running); sol::function_result result = sort_func(); timer.set_state(timer.paused); if (!result.valid()) { spdlog::critical("Sol.Lua: Function result is invalid"); } if (m_ActiveSortResult) spdlog::error("Sorter: Something went wrong while running the test. There is no active result"); m_ActiveSortResult = nullptr; return res; } void Sorter::setup(sol::state& state) { state.open_libraries(sol::lib::coroutine, sol::lib::table); state.new_usertype("Sorter", "size", &Sorter::list_size, "swap", &Sorter::list_swap, "greater", &Sorter::list_greater, "less", &Sorter::list_less, "equal", &Sorter::list_equal ); } bool Sorter::list_greater(size_t a, size_t b) const { if (m_ActiveSortResult) m_ActiveSortResult->calls.nGreater++; return m_SortArray[a] > m_SortArray[b]; } bool Sorter::list_less(size_t a, size_t b) const { if (m_ActiveSortResult) m_ActiveSortResult->calls.nLesser++; return m_SortArray[a] < m_SortArray[b]; } bool Sorter::list_equal(size_t a, size_t b) const { if (m_ActiveSortResult) m_ActiveSortResult->calls.nEqual++; return m_SortArray[a] == m_SortArray[b]; } void Sorter::list_swap(size_t a, size_t b) { if (m_ActiveSortResult) m_ActiveSortResult->calls.nSwap++; // list[index1] ^= list[index2]; // list[index2] ^= list[index1]; // list[index1] ^= list[index2]; auto tmp = m_SortArray[a]; m_SortArray[a] = m_SortArray[b]; m_SortArray[b] = tmp; } size_t Sorter::list_size() const { if (m_ActiveSortResult) m_ActiveSortResult->calls.nSize++; return m_SortArray.size(); } bool Sorter::is_sorted() const { if (m_SortArray.size() <= 1) return true; for (size_t i = 1; i < m_SortArray.size(); i++) { if (m_SortArray[i - 1] > m_SortArray[i]) return false; } return true; } void Sorter::populate(size_t size) { std::random_device dev; std::mt19937_64 rng(dev()); std::uniform_int_distribution dist(0, SIZE_MAX); for (size_t i = 0; i < size; i++) { m_SortArray.at(i) = dist(rng); } } }