sortiva/src/Sorter.cpp
2024-12-28 01:51:07 +01:00

118 lines
2.7 KiB
C++

#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>("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<std::mt19937_64::result_type> dist(0, SIZE_MAX);
for (size_t i = 0; i < size; i++)
{
m_SortArray.at(i) = dist(rng);
}
}
}