diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a45be71..6f30ee5 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -26,8 +26,7 @@ set(KLOTSKI_CORE_SRC group/internal/group_union.cc group/internal/extend.cc group/internal/group.cc - group/internal/group_cases_legacy.cc - group/internal/group_cases_pro.cc + group/internal/group_cases.cc ranges/internal/spawn.cc ranges/internal/ranges.cc diff --git a/src/core/group/group.h b/src/core/group/group.h index ea27de1..bf15f0c 100644 --- a/src/core/group/group.h +++ b/src/core/group/group.h @@ -76,9 +76,6 @@ constexpr uint32_t TYPE_ID_LIMIT = 203; constexpr uint32_t ALL_GROUP_NUM = 25422; constexpr uint32_t ALL_PATTERN_NUM = 6577; -typedef std::vector RawCodes; -typedef std::vector CommonCodes; - class Group; class GroupUnion { @@ -189,6 +186,10 @@ public: /// Get the original pattern id. [[nodiscard]] constexpr uint32_t pattern_id() const; + // TODO: add toward char interface + + // TODO: add stream output for debug + // ------------------------------------------------------------------------------------- // /// Create Group without any check. @@ -262,31 +263,18 @@ std::vector Group_extend(codec::RawCode raw_code, uint32_t reser class GroupCases { public: + // ------------------------------------------------------------------------------------- // + struct CaseInfo { Group group; uint32_t case_id; - }; - static codec::CommonCode obtain_code(CaseInfo info) { - if (fast_) { - return fast_obtain_code(info); - } - return tiny_obtain_code(info); - } + // TODO: add create interface - static CaseInfo obtain_info(codec::CommonCode common_code) { - if (fast_) { - return fast_obtain_info(common_code); - } - return tiny_obtain_info(common_code); - } - - static Group obtain_group(codec::CommonCode common_code) { - if (fast_) { - return fast_obtain_group(common_code); - } - return tiny_obtain_group(common_code); - } +#ifndef KLSK_NDEBUG + friend std::ostream& operator<<(std::ostream &out, CaseInfo self); +#endif + }; // ------------------------------------------------------------------------------------- // @@ -298,96 +286,57 @@ public: // ------------------------------------------------------------------------------------- // - static inline bool fast_ {false}; - - static inline std::mutex busy_ {}; + /// Get the CommonCode from CaseInfo. + static codec::CommonCode obtain_code(CaseInfo info); - static codec::CommonCode fast_obtain_code(CaseInfo info); - - static CaseInfo fast_obtain_info(codec::ShortCode short_code); - static CaseInfo fast_obtain_info(codec::CommonCode common_code); + /// Get the Group which ShortCode is located. + static Group obtain_group(codec::ShortCode short_code); - static Group fast_obtain_group(codec::ShortCode short_code); - static Group fast_obtain_group(codec::CommonCode common_code); + /// Get the Group which CommonCode is located. + static Group obtain_group(codec::CommonCode common_code); - static Group tiny_obtain_group(codec::CommonCode common_code); + /// Get the CaseInfo corresponding to the ShortCode. + static CaseInfo obtain_info(codec::ShortCode short_code); - static codec::CommonCode tiny_obtain_code(CaseInfo info); - - static CaseInfo tiny_obtain_info(codec::CommonCode common_code); -}; - -//class GroupCases { -//public: - // TODO: rename as Info and changed as class -// class Info { -// public: -// uint16_t type_id; -// uint16_t group_id; -// uint32_t case_id; - -#ifndef KLSK_NDEBUG -// friend std::ostream& operator<<(std::ostream &out, Info self) { -// out << std::format("{}-{}-{}", self.type_id, self.group_id, self.case_id); -// return out; -// } -#endif - -// // TODO: keep info_t valid (convert without check) -// }; + /// Get the CaseInfo corresponding to the CommonCode. + static CaseInfo obtain_info(codec::CommonCode common_code); // ------------------------------------------------------------------------------------- // - /// Execute the build process. -// static void build(); +private: + static inline bool fast_ {false}; - /// Execute the build process without blocking. -// static void build_async(Executor &&executor, Notifier &&callback); + static inline std::mutex busy_ {}; // ------------------------------------------------------------------------------------- // - /// Parse CommonCode from group info. - // codec::CommonCode parse(Info info); - - /// Get group info from RawCode. - // Info get_info(codec::RawCode raw_code); - - /// Get group info from short code. - // Info get_info(codec::ShortCode short_code); - - /// Get group info from common code. - // Info get_info(codec::CommonCode common_code); - - // ------------------------------------------------------------------------------------- // + /// Quickly obtain CommonCode from CaseInfo. + static codec::CommonCode fast_obtain_code(CaseInfo info); -//private: -// bool available_ = false; -// std::mutex building_ {}; -// -// KLSK_INSTANCE(GroupCases) + /// Obtain CommonCode from CaseInfo without cache. + static codec::CommonCode tiny_obtain_code(CaseInfo info); -//public: // ------------------------------------------------------------------------------------- // - /// Parse group info into CommonCode. -// static codec::CommonCode tiny_parse(Info info); + /// Quickly obtain Group from ShortCode. + static Group fast_obtain_group(codec::ShortCode short_code); - /// Obtain group info from CommonCode. -// static Info tiny_obtain(codec::CommonCode common_code); + /// Quickly obtain Group from CommonCode. + static Group fast_obtain_group(codec::CommonCode common_code); // ------------------------------------------------------------------------------------- // - /// Quickly parse group info into CommonCode. -// static codec::CommonCode fast_parse(Info info); + /// Quickly obtain CaseInfo from ShortCode. + static CaseInfo fast_obtain_info(codec::ShortCode short_code); - /// Quickly obtain group info from ShortCode. -// static Info fast_obtain(codec::ShortCode short_code); + /// Quickly obtain CaseInfo from CommonCode. + static CaseInfo fast_obtain_info(codec::CommonCode common_code); - /// Quickly obtain group info from CommonCode. -// static Info fast_obtain(codec::CommonCode common_code); + /// Obtain CaseInfo from CommonCode without cache. + static CaseInfo tiny_obtain_info(codec::CommonCode common_code); // ------------------------------------------------------------------------------------- // -//}; +}; } // namespace klotski::cases diff --git a/src/core/group/internal/group_cases_pro.cc b/src/core/group/internal/group_cases.cc similarity index 98% rename from src/core/group/internal/group_cases_pro.cc rename to src/core/group/internal/group_cases.cc index 7527995..ae6b7c2 100644 --- a/src/core/group/internal/group_cases_pro.cc +++ b/src/core/group/internal/group_cases.cc @@ -218,7 +218,3 @@ GroupCases::CaseInfo GroupCases::tiny_obtain_info(CommonCode common_code) { .case_id = (uint32_t)case_id, }; } - -Group GroupCases::tiny_obtain_group(codec::CommonCode common_code) { - return Group::from_common_code(common_code); -} diff --git a/src/core/group/internal/group_cases.inl b/src/core/group/internal/group_cases.inl index 124ff80..bb8aa6c 100644 --- a/src/core/group/internal/group_cases.inl +++ b/src/core/group/internal/group_cases.inl @@ -2,4 +2,39 @@ namespace klotski::cases { +inline codec::CommonCode GroupCases::obtain_code(CaseInfo info) { + if (fast_) { + return fast_obtain_code(info); + } + return tiny_obtain_code(info); +} + +inline GroupCases::CaseInfo GroupCases::obtain_info(codec::CommonCode common_code) { + if (fast_) { + return fast_obtain_info(common_code); + } + return tiny_obtain_info(common_code); +} + +inline Group GroupCases::obtain_group(codec::CommonCode common_code) { + if (fast_) { + return fast_obtain_group(common_code); + } + return Group::from_common_code(common_code); +} + +inline Group GroupCases::obtain_group(codec::ShortCode short_code) { + if (fast_) { + return fast_obtain_group(short_code); + } + return Group::from_short_code(short_code); +} + +inline GroupCases::CaseInfo GroupCases::obtain_info(codec::ShortCode short_code) { + if (fast_) { + return fast_obtain_info(short_code); + } + return tiny_obtain_info(short_code.to_common_code()); +} + } // namespace klotski::cases diff --git a/src/core/group/internal/group_cases_legacy.cc b/src/core/group/internal/group_cases_legacy.cc deleted file mode 100644 index b3c8392..0000000 --- a/src/core/group/internal/group_cases_legacy.cc +++ /dev/null @@ -1,126 +0,0 @@ -#include -#include - -#include "group/group.h" - -using klotski::codec::ShortCode; -using klotski::codec::CommonCode; - -//using klotski::cases::GroupCases; -using klotski::cases::GroupUnion; -using klotski::cases::RangesUnion; - -using klotski::cases::ALL_GROUP_NUM; -using klotski::cases::TYPE_ID_LIMIT; -using klotski::cases::ALL_CASES_NUM_; - -struct tmp_t { - uint32_t group_id : 12; - uint32_t case_id : 20; -}; - -static_assert(sizeof(tmp_t) == 4); - -// TODO: we need multi-thread support (Executor) - -static std::vector *rev_data = nullptr; -static std::vector *ru_data = nullptr; - -static std::vector build_ranges_unions() { - std::vector unions; - unions.reserve(ALL_GROUP_NUM); - - // TODO: add white list for single-group unions - - for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { - auto group_union = GroupUnion::unsafe_create(type_id); -// for (auto group : group_union.groups()) { -// unions.emplace_back(group.cases()); -// } - } - return unions; -} - -static std::vector build_tmp_data() { - std::vector data; - data.resize(ALL_CASES_NUM_); - ShortCode::speed_up(true); - - for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { - auto group_union = GroupUnion::unsafe_create(type_id); -// for (auto group : group_union.groups()) { -// uint32_t group_id = group.group_id(); -// -// auto codes = group.cases().codes(); -// for (uint32_t case_id = 0; case_id < codes.size(); ++case_id) { -// auto short_code = codes[case_id].to_short_code(); -// -// data[short_code.unwrap()] = tmp_t { -// .group_id = group_id, -// .case_id = case_id, -// }; -// } -// } - } - return data; -} - -//void GroupCases::build() { -// static auto data_1 = build_ranges_unions(); -// static auto data_2 = build_tmp_data(); -// ru_data = &data_1; -// rev_data = &data_2; -//} - -//CommonCode GroupCases::fast_parse(Info info) { -// -// auto flat_id = GROUP_OFFSET[info.type_id] + info.group_id; -// -// auto &cases = (*ru_data)[flat_id]; -// // TODO: make offset table for perf -// -// uint64_t head = 0; -// -// for (;;) { -// if (info.case_id >= cases[head].size()) { -// info.case_id -= cases[head].size(); -// ++head; -// } else { -// break; -// } -// } -// -// auto range = cases[head][info.case_id]; -// return CommonCode::unsafe_create(head << 32 | range); -//} - -//GroupCases::Info GroupCases::fast_obtain(codec::ShortCode short_code) { -// -// uint16_t type_id = GroupUnion::from_short_code(short_code).unwrap(); // NOTE: need to convert as CommonCode -// uint16_t group_id = (*rev_data)[short_code.unwrap()].group_id; -// auto case_id = (*rev_data)[short_code.unwrap()].case_id; -// -// return Info { -// .type_id = type_id, -// .group_id = group_id, -// .case_id = case_id, -// }; -//} - -//GroupCases::Info GroupCases::fast_obtain(codec::CommonCode common_code) { -// return fast_obtain(common_code.to_short_code()); -//} -// -//void GroupCases::build_async(klotski::Executor &&executor, klotski::Notifier &&callback) { -// -//} -// -//klotski::codec::CommonCode GroupCases::tiny_parse(klotski::cases::GroupCases::Info info) { -// // TODO: tiny parse process -// return CommonCode::unsafe_create(0); -//} -// -//GroupCases::Info GroupCases::tiny_obtain(codec::CommonCode common_code) { -// // TODO: tiny obtain process -// return Info {}; -//} diff --git a/src/core/main.cc b/src/core/main.cc index 63ab96c..84ccbda 100644 --- a/src/core/main.cc +++ b/src/core/main.cc @@ -64,19 +64,27 @@ int main() { // std::cout << group.pattern_id() << std::endl; // std::cout << (int)group.toward() << std::endl; - auto kk = GroupCases::obtain_info(CommonCode::unsafe_create(0x1A9BF0C00)); - std::cout << std::format("{}-{}-{}-{}\n", kk.group.type_id(), kk.group.pattern_id(), (int)kk.group.toward(), kk.case_id); - - auto code_1 = GroupCases::obtain_code(kk); + auto info_1 = GroupCases::obtain_info(CommonCode::unsafe_create(0x1A9BF0C00)); + std::cout << std::format("{}-{}-{}-{}\n", info_1.group.type_id(), info_1.group.pattern_id(), (int)info_1.group.toward(), info_1.case_id); + auto code_1 = GroupCases::obtain_code(info_1); std::cout << code_1 << std::endl; + auto info_2 = GroupCases::obtain_info(CommonCode::unsafe_create(0x1A9BF0C00).to_short_code()); + std::cout << std::format("{}-{}-{}-{}\n", info_2.group.type_id(), info_2.group.pattern_id(), (int)info_2.group.toward(), info_2.case_id); + auto code_2 = GroupCases::obtain_code(info_2); + std::cout << code_2 << std::endl; + GroupCases::build(); - auto pp = GroupCases::obtain_info(CommonCode::unsafe_create(0x1A9BF0C00)); - std::cout << std::format("{}-{}-{}-{}\n", pp.group.type_id(), pp.group.pattern_id(), (int)pp.group.toward(), pp.case_id); + auto info_3 = GroupCases::obtain_info(CommonCode::unsafe_create(0x1A9BF0C00)); + std::cout << std::format("{}-{}-{}-{}\n", info_3.group.type_id(), info_3.group.pattern_id(), (int)info_3.group.toward(), info_3.case_id); + auto code_3 = GroupCases::obtain_code(info_3); + std::cout << code_3 << std::endl; - auto code_2 = GroupCases::obtain_code(pp); - std::cout << code_2 << std::endl; + auto info_4 = GroupCases::obtain_info(CommonCode::unsafe_create(0x1A9BF0C00).to_short_code()); + std::cout << std::format("{}-{}-{}-{}\n", info_4.group.type_id(), info_4.group.pattern_id(), (int)info_4.group.toward(), info_4.case_id); + auto code_4 = GroupCases::obtain_code(info_4); + std::cout << code_4 << std::endl; // const auto common_code = CommonCode::unsafe_create(0x1A9BF0C00); // const auto group = Group::from_common_code(common_code);