diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 3a5a030..a45be71 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -26,7 +26,7 @@ set(KLOTSKI_CORE_SRC group/internal/group_union.cc group/internal/extend.cc group/internal/group.cc - group/internal/group_cases.cc + group/internal/group_cases_legacy.cc group/internal/group_cases_pro.cc ranges/internal/spawn.cc diff --git a/src/core/group/group.h b/src/core/group/group.h index d451680..ea27de1 100644 --- a/src/core/group/group.h +++ b/src/core/group/group.h @@ -260,7 +260,7 @@ private: /// Spawn all the unsorted codes of the current group. std::vector Group_extend(codec::RawCode raw_code, uint32_t reserve = 0); -class GroupCasesPro { +class GroupCases { public: struct CaseInfo { Group group; @@ -274,52 +274,75 @@ public: return tiny_obtain_code(info); } - CaseInfo obtain_info(codec::CommonCode common_code); + 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); + } + + // ------------------------------------------------------------------------------------- // + + /// Execute the build process. + static void build(); + + /// Execute the build process without blocking. + static void build_async(Executor &&executor, Notifier &&callback); - // TODO: allow cal Group directly -> `obtain_group` + // ------------------------------------------------------------------------------------- // static inline bool fast_ {false}; static inline std::mutex busy_ {}; - static void build(); - 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); + static Group fast_obtain_group(codec::ShortCode short_code); + static Group fast_obtain_group(codec::CommonCode common_code); + + static Group tiny_obtain_group(codec::CommonCode common_code); + static codec::CommonCode tiny_obtain_code(CaseInfo info); static CaseInfo tiny_obtain_info(codec::CommonCode common_code); }; -class GroupCases { -public: +//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; +// 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; - } +// 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) - }; +// // TODO: keep info_t valid (convert without check) +// }; // ------------------------------------------------------------------------------------- // /// Execute the build process. - static void build(); +// static void build(); /// Execute the build process without blocking. - static void build_async(Executor &&executor, Notifier &&callback); +// static void build_async(Executor &&executor, Notifier &&callback); // ------------------------------------------------------------------------------------- // @@ -337,34 +360,34 @@ public: // ------------------------------------------------------------------------------------- // -private: - bool available_ = false; - std::mutex building_ {}; - - KLSK_INSTANCE(GroupCases) +//private: +// bool available_ = false; +// std::mutex building_ {}; +// +// KLSK_INSTANCE(GroupCases) -public: +//public: // ------------------------------------------------------------------------------------- // /// Parse group info into CommonCode. - static codec::CommonCode tiny_parse(Info info); +// static codec::CommonCode tiny_parse(Info info); /// Obtain group info from CommonCode. - static Info tiny_obtain(codec::CommonCode common_code); +// static Info tiny_obtain(codec::CommonCode common_code); // ------------------------------------------------------------------------------------- // /// Quickly parse group info into CommonCode. - static codec::CommonCode fast_parse(Info info); +// static codec::CommonCode fast_parse(Info info); /// Quickly obtain group info from ShortCode. - static Info fast_obtain(codec::ShortCode short_code); +// static Info fast_obtain(codec::ShortCode short_code); /// Quickly obtain group info from CommonCode. - static Info fast_obtain(codec::CommonCode common_code); +// static Info fast_obtain(codec::CommonCode common_code); // ------------------------------------------------------------------------------------- // -}; +//}; } // namespace klotski::cases diff --git a/src/core/group/internal/group_cases.cc b/src/core/group/internal/group_cases.cc deleted file mode 100644 index 99688f8..0000000 --- a/src/core/group/internal/group_cases.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; - -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/group/internal/group_cases_legacy.cc b/src/core/group/internal/group_cases_legacy.cc new file mode 100644 index 0000000..b3c8392 --- /dev/null +++ b/src/core/group/internal/group_cases_legacy.cc @@ -0,0 +1,126 @@ +#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/group/internal/group_cases_pro.cc b/src/core/group/internal/group_cases_pro.cc index 0a29294..7527995 100644 --- a/src/core/group/internal/group_cases_pro.cc +++ b/src/core/group/internal/group_cases_pro.cc @@ -8,9 +8,9 @@ using klotski::codec::ShortCode; using klotski::codec::CommonCode; using klotski::cases::Group; +using klotski::cases::GroupCases; using klotski::cases::GroupUnion; using klotski::cases::RangesUnion; -using klotski::cases::GroupCasesPro; using klotski::cases::ALL_GROUP_NUM; using klotski::cases::TYPE_ID_LIMIT; @@ -83,7 +83,7 @@ static std::vector build_tmp_data() { return data; } -void GroupCasesPro::build() { +void GroupCases::build() { static auto data_1 = build_ranges_unions(); static auto data_2 = build_tmp_data(); ru_data = &data_1; @@ -93,7 +93,14 @@ void GroupCasesPro::build() { fast_ = true; } -CommonCode GroupCasesPro::fast_obtain_code(CaseInfo info) { +void GroupCases::build_async(Executor &&executor, Notifier &&callback) { + executor([callback = std::move(callback)] { + build(); + callback(); + }); +} + +CommonCode GroupCases::fast_obtain_code(CaseInfo info) { auto flat_id = PATTERN_OFFSET[info.group.type_id()] + info.group.pattern_id(); @@ -115,7 +122,7 @@ CommonCode GroupCasesPro::fast_obtain_code(CaseInfo info) { return CommonCode::unsafe_create(head << 32 | range); } -GroupCasesPro::CaseInfo GroupCasesPro::fast_obtain_info(ShortCode short_code) { +GroupCases::CaseInfo GroupCases::fast_obtain_info(ShortCode short_code) { uint16_t type_id = GroupUnion::from_short_code(short_code).unwrap(); // NOTE: need to convert as CommonCode uint16_t pattern_id = (*rev_data)[short_code.unwrap()].pattern_id; uint16_t toward_id = (*rev_data)[short_code.unwrap()].toward_id; @@ -127,7 +134,7 @@ GroupCasesPro::CaseInfo GroupCasesPro::fast_obtain_info(ShortCode short_code) { }; } -GroupCasesPro::CaseInfo GroupCasesPro::fast_obtain_info(CommonCode common_code) { +GroupCases::CaseInfo GroupCases::fast_obtain_info(CommonCode common_code) { auto short_code = common_code.to_short_code(); uint16_t type_id = GroupUnion::from_common_code(common_code).unwrap(); uint16_t pattern_id = (*rev_data)[short_code.unwrap()].pattern_id; @@ -140,7 +147,22 @@ GroupCasesPro::CaseInfo GroupCasesPro::fast_obtain_info(CommonCode common_code) }; } -CommonCode GroupCasesPro::tiny_obtain_code(CaseInfo info) { +Group GroupCases::fast_obtain_group(codec::ShortCode short_code) { + uint16_t type_id = GroupUnion::from_short_code(short_code).unwrap(); + uint16_t pattern_id = (*rev_data)[short_code.unwrap()].pattern_id; + uint16_t toward_id = (*rev_data)[short_code.unwrap()].toward_id; + return Group::unsafe_create(type_id, pattern_id, (Group::Toward)toward_id); +} + +Group GroupCases::fast_obtain_group(codec::CommonCode common_code) { + auto short_code = common_code.to_short_code(); + uint16_t type_id = GroupUnion::from_common_code(common_code).unwrap(); + uint16_t pattern_id = (*rev_data)[short_code.unwrap()].pattern_id; + uint16_t toward_id = (*rev_data)[short_code.unwrap()].toward_id; + return Group::unsafe_create(type_id, pattern_id, (Group::Toward)toward_id); +} + +CommonCode GroupCases::tiny_obtain_code(CaseInfo info) { auto cases = info.group.cases(); uint64_t head = 0; @@ -173,7 +195,7 @@ static std::unordered_map build_map_data() { return data; } -GroupCasesPro::CaseInfo GroupCasesPro::tiny_obtain_info(CommonCode common_code) { +GroupCases::CaseInfo GroupCases::tiny_obtain_info(CommonCode common_code) { auto raw_codes = Group_extend(common_code.to_raw_code()); std::vector common_codes; common_codes.reserve(raw_codes.size()); @@ -196,3 +218,7 @@ GroupCasesPro::CaseInfo GroupCasesPro::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/main.cc b/src/core/main.cc index c2776bf..63ab96c 100644 --- a/src/core/main.cc +++ b/src/core/main.cc @@ -29,7 +29,6 @@ using klotski::cases::GroupUnion; using klotski::cases::Group; using klotski::cases::GroupCases; using klotski::cases::GroupUnion; -using klotski::cases::GroupCasesPro; using klotski::cases::TYPE_ID_LIMIT; using klotski::cases::ALL_CASES_NUM_; @@ -65,18 +64,18 @@ int main() { // std::cout << group.pattern_id() << std::endl; // std::cout << (int)group.toward() << std::endl; - GroupCasesPro::build(); - - auto kk = GroupCasesPro::fast_obtain_info(CommonCode::unsafe_create(0x1A9BF0C00)); + 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 = GroupCasesPro::fast_obtain_code(kk); + auto code_1 = GroupCases::obtain_code(kk); std::cout << code_1 << std::endl; - auto pp = GroupCasesPro::tiny_obtain_info(CommonCode::unsafe_create(0x1A9BF0C00)); + 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 code_2 = GroupCasesPro::tiny_obtain_code(pp); + auto code_2 = GroupCases::obtain_code(pp); std::cout << code_2 << std::endl; // const auto common_code = CommonCode::unsafe_create(0x1A9BF0C00);