Browse Source

update: async builder of AllCases

master
Dnomd343 1 month ago
parent
commit
10d1533062
  1. 36
      src/core/all_cases/internal/all_cases.cc

36
src/core/all_cases/internal/all_cases.cc

@ -1,7 +1,3 @@
#include <future>
#include "utils/utility.h"
#include "ranges/ranges.h"
#include "all_cases/all_cases.h"
using klotski::range_reverse;
@ -10,9 +6,11 @@ using klotski::cases::AllCases;
using klotski::cases::BasicRanges;
using klotski::cases::ALL_CASES_NUM;
typedef std::array<int, 12> Heads;
/// Generate all possible klotski heads.
static consteval std::array<int, 12> heads() {
std::array<int, 12> heads {};
static consteval Heads get_heads() {
Heads heads {};
for (int i = 0, head = 0; head < 15; ++head) {
if (head % 4 != 3) {
heads[i++] = head;
@ -60,7 +58,6 @@ static void build_cases(const std::vector<uint32_t> &ranges,
if (offset > 14) {
continue;
}
// !! <- broken
// ( xx xx xx ) xx xx xx ... [range]
// +1 00 00 00 ... (delta)
@ -83,7 +80,6 @@ void AllCases::build() {
if (available_) {
return; // reduce consumption of mutex
}
std::lock_guard guard {building_};
if (available_) {
return; // data is already available
@ -94,7 +90,7 @@ void AllCases::build() {
for (auto &x : reversed) {
x = range_reverse(x);
}
for (const auto head : heads()) {
for (const auto head : get_heads()) {
build_cases(ranges, reversed, get_cases()[head], head);
}
available_ = true;
@ -105,7 +101,6 @@ void AllCases::build_async(Executor &&executor, Notifier &&callback) {
callback();
return; // reduce consumption of mutex
}
building_.lock();
if (available_) {
building_.unlock();
@ -113,21 +108,22 @@ void AllCases::build_async(Executor &&executor, Notifier &&callback) {
return; // data is already available
}
const auto counter = std::make_shared<std::atomic<int>>(0);
const auto all_done = std::make_shared<Notifier>(std::move(callback));
const auto reversed = std::make_shared<std::vector<uint32_t>>(BasicRanges::instance().fetch());
auto &ranges = BasicRanges::instance().fetch();
auto reversed = std::make_shared<std::vector<uint32_t>>(ranges);
for (auto &x : *reversed) {
x = range_reverse(x);
}
for (const auto head : heads()) {
executor([=, this] {
Worker worker {executor};
for (const auto head : get_heads()) {
worker.post([head, reversed] {
build_cases(BasicRanges::instance().fetch(), *reversed, get_cases()[head], head);
if (counter->fetch_add(1) == heads().size() - 1) { // all tasks done
available_ = true;
building_.unlock(); // release building mutex
all_done->operator()(); // trigger callback
}
});
}
worker.then([this, callback = std::move(callback)] {
available_ = true;
building_.unlock();
callback();
});
}

Loading…
Cancel
Save