From 011e65c636fea8fd7e28a4368f4756c511f9900a Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Mon, 1 May 2023 16:16:52 +0800 Subject: [PATCH] feat: group cases build index with mutex --- src/klotski_core/ffi/tmain.cc | 24 +++++++------ src/klotski_core/group/group.h | 7 ++-- src/klotski_core/group/group_info.cc | 51 ++++++++++++++++++++-------- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/klotski_core/ffi/tmain.cc b/src/klotski_core/ffi/tmain.cc index 61d77b2..2883098 100644 --- a/src/klotski_core/ffi/tmain.cc +++ b/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; diff --git a/src/klotski_core/group/group.h b/src/klotski_core/group/group.h index 2185deb..50f63a1 100644 --- a/src/klotski_core/group/group.h +++ b/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 #include #include "raw_code.h" #include "common_code.h" @@ -161,8 +162,10 @@ public: }; private: - static std::vector group_info; - static std::vector group_data[TYPE_ID_LIMIT]; + static bool available_; + static std::mutex building_; + static std::vector group_info_; + static std::vector group_data_[TYPE_ID_LIMIT]; static void build_index(GroupType group_type) noexcept; diff --git a/src/klotski_core/group/group_info.cc b/src/klotski_core/group/group_info.cc index 6823df6..a0f1423 100644 --- a/src/klotski_core/group/group_info.cc +++ b/src/klotski_core/group/group_info.cc @@ -7,8 +7,10 @@ namespace klotski { -std::vector GroupCase::group_info(SHORT_CODE_LIMIT); -std::vector GroupCase::group_data[TYPE_ID_LIMIT]; +std::mutex GroupCase::building_; +bool GroupCase::available_ = false; +std::vector GroupCase::group_info_(SHORT_CODE_LIMIT); +std::vector 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(GroupType(common_code).unwrap()), .group_id = static_cast(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); } } }