diff --git a/src/core/group/group.h b/src/core/group/group.h index 761d2ff..e3139b8 100644 --- a/src/core/group/group.h +++ b/src/core/group/group.h @@ -152,6 +152,7 @@ #include +#include "group/group_fwd.h" #include "ranges/ranges_fwd.h" #include "raw_code/raw_code_fwd.h" #include "short_code/short_code_fwd.h" @@ -160,9 +161,9 @@ #include "internal/constant/group.h" #include "internal/constant/group_union.h" -namespace klotski::group { +// TODO: using `uint_fast8_t` is no needed (just using `uint8_t`) -class Group; +namespace klotski::group { class GroupUnion { public: @@ -458,28 +459,28 @@ public: // ------------------------------------------------------------------------------------- // + /// Get the CommonCode from CaseInfo. + static KLSK_INLINE codec::CommonCode obtain_code(CaseInfo info); + + // ------------------------------------------------------------------------------------- // + /// Get the Group which ShortCode is located. - static Group obtain_group(codec::ShortCode short_code); + static KLSK_INLINE Group obtain_group(codec::ShortCode short_code); /// Get the Group which CommonCode is located. - static Group obtain_group(codec::CommonCode common_code); + static KLSK_INLINE Group obtain_group(codec::CommonCode common_code); // ------------------------------------------------------------------------------------- // - /// Get the CommonCode from CaseInfo. - static codec::CommonCode obtain_code(CaseInfo info); - /// Get the CaseInfo corresponding to the ShortCode. - static CaseInfo obtain_info(codec::ShortCode short_code); + static KLSK_INLINE CaseInfo obtain_info(codec::ShortCode short_code); /// Get the CaseInfo corresponding to the CommonCode. - static CaseInfo obtain_info(codec::CommonCode common_code); + static KLSK_INLINE CaseInfo obtain_info(codec::CommonCode common_code); // ------------------------------------------------------------------------------------- // private: - // ------------------------------------------------------------------------------------- // - /// Whether fast mode is available. static inline bool fast_ {false}; diff --git a/src/core/group/internal/group.cc b/src/core/group/internal/group.cc index 53ebe89..f0aa4e7 100644 --- a/src/core/group/internal/group.cc +++ b/src/core/group/internal/group.cc @@ -18,7 +18,9 @@ using klotski::mover::MaskMover; using klotski::group::GROUP_DATA; using klotski::group::PATTERN_DATA; -// TODO: maybe we can perf with mirror cases +// NOTE: This code implements two time-consuming functions: +// 1. Calculate all cases included in Group based on type_id/pattern_id/toward. +// 2. Calculate the Group information it belongs to based on RawCode. /// Spawn all the unsorted codes of the current group. static std::vector Group_extend_for_cases(RawCode raw_code, uint32_t reserve) { @@ -46,6 +48,7 @@ static std::vector Group_extend_for_cases(RawCode raw_code, uint32_t re return codes; } +// TODO: maybe we can perf with mirror cases RangesUnion Group::cases() const { // TODO: add white list for single-group unions @@ -117,6 +120,7 @@ static std::vector Group_extend_for_from_raw_code(RawCode raw_code) { return codes; } +// TODO: maybe we can search new cases in `map_data` Group Group::from_raw_code(const RawCode raw_code) { static auto map_data = build_map_data(); diff --git a/src/core/group/internal/group_cases.cc b/src/core/group/internal/group_cases.cc index e937e8d..5488f08 100644 --- a/src/core/group/internal/group_cases.cc +++ b/src/core/group/internal/group_cases.cc @@ -34,9 +34,8 @@ struct case_info_t { static_assert(sizeof(case_info_t) == 4); -// TODO: we need multi-thread support (Executor) - -static std::vector> *ru_data = nullptr; +// TODO: benchmark of `phmap` structure +static std::vector> *ru_data = nullptr; // group_offset + toward static std::vector *rev_data = nullptr; std::vector> build_ranges_unions() { @@ -45,6 +44,8 @@ std::vector> build_ranges_unions() { // TODO: add white list for single-group unions + // TODO: helper with mirror + for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { auto group_union = GroupUnion::unsafe_create(type_id); for (uint32_t pattern_id = 0; pattern_id < group_union.pattern_num(); ++pattern_id) { @@ -92,16 +93,23 @@ static std::vector build_tmp_data() { } void GroupCases::build() { + if (fast_) { + return; + } + std::lock_guard guard {busy_}; + + // TODO: make `data` as class member static auto data_1 = build_ranges_unions(); static auto data_2 = build_tmp_data(); ru_data = &data_1; rev_data = &data_2; - // TODO: using std::mutex `busy_` + KLSK_MEM_BARRIER; fast_ = true; } void GroupCases::build_async(Executor &&executor, Notifier &&callback) { + // TODO: real multi-thread build executor([callback = std::move(callback)] { build(); callback(); diff --git a/src/core/group/internal/group_cases.inl b/src/core/group/internal/group_cases.inl index a4c75a8..f329463 100644 --- a/src/core/group/internal/group_cases.inl +++ b/src/core/group/internal/group_cases.inl @@ -4,35 +4,35 @@ namespace klotski::group { // TODO: maybe move `fast_obtain_*` into `.inl` file -inline codec::CommonCode GroupCases::obtain_code(const CaseInfo info) { +KLSK_INLINE_H codec::CommonCode GroupCases::obtain_code(const CaseInfo info) { if (fast_) { return fast_obtain_code(info); } return tiny_obtain_code(info); } -inline Group GroupCases::obtain_group(const codec::ShortCode short_code) { +KLSK_INLINE_H Group GroupCases::obtain_group(const codec::ShortCode short_code) { if (fast_) { return fast_obtain_group(short_code); } return Group::from_short_code(short_code); } -inline Group GroupCases::obtain_group(const codec::CommonCode common_code) { +KLSK_INLINE_H Group GroupCases::obtain_group(const codec::CommonCode common_code) { if (fast_) { return fast_obtain_group(common_code); } return Group::from_common_code(common_code); } -inline CaseInfo GroupCases::obtain_info(const codec::ShortCode short_code) { +KLSK_INLINE_H CaseInfo GroupCases::obtain_info(const codec::ShortCode short_code) { if (fast_) { return fast_obtain_info(short_code); } return tiny_obtain_info(short_code.to_common_code()); } -inline CaseInfo GroupCases::obtain_info(const codec::CommonCode common_code) { +KLSK_INLINE_H CaseInfo GroupCases::obtain_info(const codec::CommonCode common_code) { if (fast_) { return fast_obtain_info(common_code); } diff --git a/src/core/group/internal/group_union.cc b/src/core/group/internal/group_union.cc index ca96411..87b0b93 100644 --- a/src/core/group/internal/group_union.cc +++ b/src/core/group/internal/group_union.cc @@ -17,11 +17,11 @@ RangesUnion GroupUnion::cases() const { ranges.reverse(); RangesUnion cases; - const auto [s_a, s_b, s_c, s_d] = GROUP_UNION_CASES_NUM[type_id_]; - RANGE_RESERVE(0x0, s_a); RANGE_RESERVE(0x1, s_b); RANGE_RESERVE(0x2, s_a); - RANGE_RESERVE(0x4, s_c); RANGE_RESERVE(0x5, s_d); RANGE_RESERVE(0x6, s_c); - RANGE_RESERVE(0x8, s_c); RANGE_RESERVE(0x9, s_d); RANGE_RESERVE(0xA, s_c); - RANGE_RESERVE(0xC, s_a); RANGE_RESERVE(0xD, s_b); RANGE_RESERVE(0xE, s_a); + const auto [na, nb, nc, nd] = GROUP_UNION_CASES_NUM[type_id_]; + RANGE_RESERVE(0x0, na); RANGE_RESERVE(0x1, nb); RANGE_RESERVE(0x2, na); + RANGE_RESERVE(0x4, nc); RANGE_RESERVE(0x5, nd); RANGE_RESERVE(0x6, nc); + RANGE_RESERVE(0x8, nc); RANGE_RESERVE(0x9, nd); RANGE_RESERVE(0xA, nc); + RANGE_RESERVE(0xC, na); RANGE_RESERVE(0xD, nb); RANGE_RESERVE(0xE, na); RANGE_DERIVE(0x0); RANGE_DERIVE(0x1); RANGE_DERIVE(0x2); RANGE_DERIVE(0x4); RANGE_DERIVE(0x5); RANGE_DERIVE(0x6); diff --git a/src/core/group/internal/mirror.inl b/src/core/group/internal/mirror.inl index 569a7b9..4b528f9 100644 --- a/src/core/group/internal/mirror.inl +++ b/src/core/group/internal/mirror.inl @@ -1,5 +1,7 @@ #pragma once +// TODO: class functions force inline + namespace klotski::group { constexpr auto Group::mirror_type() const -> MirrorType {