Browse Source

feat: group cases build index with mutex

master
Dnomd343 1 year ago
parent
commit
011e65c636
  1. 24
      src/klotski_core/ffi/tmain.cc
  2. 7
      src/klotski_core/group/group.h
  3. 51
      src/klotski_core/group/group_info.cc

24
src/klotski_core/ffi/tmain.cc

@ -37,18 +37,20 @@ void tmain() {
// auto start = clock();
auto demo = []() {
// 1A9BF0C00 -> 169-1-7472
// 4FEA13400 -> 164-0-30833
std::cout << GroupCase::parse({169, 1, 7472}) << std::endl;
std::cout << GroupCase::parse({164, 0, 30833}) << std::endl;
auto i1 = GroupCase::encode(CommonCode(0x1A9BF0C00));
auto i2 = GroupCase::encode(CommonCode(0x4FEA13400));
std::cout << i1.type_id << "-" << i1.group_id << "-" << i1.group_index << std::endl;
std::cout << i2.type_id << "-" << i2.group_id << "-" << i2.group_index << std::endl;
};
demo();
GroupCase::speed_up();
// 1A9BF0C00 -> 169-1-7472
// 4FEA13400 -> 164-0-30833
std::cout << GroupCase::parse({169, 1, 7472}) << std::endl;
std::cout << GroupCase::parse({164, 0, 30833}) << std::endl;
auto i1 = GroupCase::encode(CommonCode(0x1A9BF0C00));
auto i2 = GroupCase::encode(CommonCode(0x4FEA13400));
std::cout << i1.type_id << "-" << i1.group_id << "-" << i1.group_index << std::endl;
std::cout << i2.type_id << "-" << i2.group_id << "-" << i2.group_index << std::endl;
demo();
// std::cerr << (clock() - start) * 1000 / CLOCKS_PER_SEC << "ms" << std::endl;

7
src/klotski_core/group/group.h

@ -57,6 +57,7 @@
/// type_id < 203 | group_id < 2653 | group_index < 964656
/// (8-bit ~ 256) | (12-bit ~ 4096) | (20-bit ~ 1048576)
#include <mutex>
#include <cstdint>
#include "raw_code.h"
#include "common_code.h"
@ -161,8 +162,10 @@ public:
};
private:
static std::vector<uint32_t> group_info;
static std::vector<ShortCodes> group_data[TYPE_ID_LIMIT];
static bool available_;
static std::mutex building_;
static std::vector<uint32_t> group_info_;
static std::vector<ShortCodes> group_data_[TYPE_ID_LIMIT];
static void build_index(GroupType group_type) noexcept;

51
src/klotski_core/group/group_info.cc

@ -7,8 +7,10 @@
namespace klotski {
std::vector<uint32_t> GroupCase::group_info(SHORT_CODE_LIMIT);
std::vector<ShortCodes> GroupCase::group_data[TYPE_ID_LIMIT];
std::mutex GroupCase::building_;
bool GroupCase::available_ = false;
std::vector<uint32_t> GroupCase::group_info_(SHORT_CODE_LIMIT);
std::vector<ShortCodes> GroupCase::group_data_[TYPE_ID_LIMIT];
/// --------------------------------------- Group Type ----------------------------------------
@ -39,8 +41,12 @@ uint32_t GroupType::max_size(const CommonCode &common_code) noexcept {
/// --------------------------------------- Group Case ----------------------------------------
CommonCode GroupCase::parse(const info_t &info) {
// return tiny_decode(info);
return fast_decode(info);
if (available_) {
std::cerr << "using fast mode" << std::endl;
return fast_decode(info);
}
std::cerr << "using tiny mode" << std::endl;
return tiny_decode(info);
}
GroupCase::info_t GroupCase::encode(const RawCode &raw_code) noexcept {
@ -48,8 +54,12 @@ GroupCase::info_t GroupCase::encode(const RawCode &raw_code) noexcept {
}
GroupCase::info_t GroupCase::encode(const CommonCode &common_code) noexcept {
// return tiny_encode(common_code);
return fast_encode(common_code);
if (available_) {
std::cerr << "using fast mode" << std::endl;
return fast_encode(common_code);
}
std::cerr << "using tiny mode" << std::endl;
return tiny_encode(common_code);
}
/// ------------------------------------ Group Case Codec -------------------------------------
@ -88,7 +98,7 @@ CommonCode GroupCase::fast_decode(const info_t &info) {
if (info.group_id >= TYPE_ID_GROUP_NUM[info.type_id]) {
throw std::invalid_argument("group id overflow");
}
auto &target_group = group_data[info.type_id][info.group_id];
auto &target_group = group_data_[info.type_id][info.group_id];
if (info.group_index >= target_group.size()) {
throw std::invalid_argument("group index overflow");
}
@ -96,7 +106,7 @@ CommonCode GroupCase::fast_decode(const info_t &info) {
}
GroupCase::info_t GroupCase::fast_encode(const CommonCode &common_code) noexcept {
auto info = group_info[common_code.to_short_code().unwrap()];
auto info = group_info_[common_code.to_short_code().unwrap()];
return {
.type_id = static_cast<uint16_t>(GroupType(common_code).unwrap()),
.group_id = static_cast<uint16_t>(info >> 20),
@ -107,22 +117,33 @@ GroupCase::info_t GroupCase::fast_encode(const CommonCode &common_code) noexcept
/// ------------------------------------ Group Case Index -------------------------------------
void GroupCase::speed_up() {
ShortCode::speed_up(ShortCode::FAST);
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
GroupCase::build_index(GroupType(type_id));
std::cerr << type_id << std::endl;
auto build_data = []() { // build group cases index
ShortCode::speed_up(ShortCode::FAST);
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
GroupCase::build_index(GroupType(type_id));
std::cerr << type_id << std::endl;
}
};
if (!available_) {
if (building_.try_lock()) { // mutex lock success
build_data(); // start build process
available_ = true;
} else {
building_.lock(); // blocking waiting
}
building_.unlock(); // release mutex
}
}
void GroupCase::build_index(GroupType group_type) noexcept {
group_data[group_type.unwrap()].resize(group_type.group_num());
group_data_[group_type.unwrap()].resize(group_type.group_num());
for (uint32_t group_id = 0; group_id < group_type.group_num(); ++group_id) {
auto cases = CommonCode::convert(Group(group_type, group_id).cases());
std::sort(cases.begin(), cases.end());
for (uint32_t group_index = 0; group_index < cases.size(); ++group_index) {
auto short_code = cases[group_index].to_short_code();
group_info[short_code.unwrap()] = (group_id << 20) | group_index;
group_data[group_type.unwrap()][group_id].emplace_back(short_code);
group_info_[short_code.unwrap()] = (group_id << 20) | group_index;
group_data_[group_type.unwrap()][group_id].emplace_back(short_code);
}
}
}

Loading…
Cancel
Save