Browse Source

update: several improvements of group module

master
Dnomd343 2 weeks ago
parent
commit
a692b80578
  1. 23
      src/core/group/group.h
  2. 6
      src/core/group/internal/group.cc
  3. 16
      src/core/group/internal/group_cases.cc
  4. 10
      src/core/group/internal/group_cases.inl
  5. 10
      src/core/group/internal/group_union.cc
  6. 2
      src/core/group/internal/mirror.inl

23
src/core/group/group.h

@ -152,6 +152,7 @@
#include <mutex> #include <mutex>
#include "group/group_fwd.h"
#include "ranges/ranges_fwd.h" #include "ranges/ranges_fwd.h"
#include "raw_code/raw_code_fwd.h" #include "raw_code/raw_code_fwd.h"
#include "short_code/short_code_fwd.h" #include "short_code/short_code_fwd.h"
@ -160,9 +161,9 @@
#include "internal/constant/group.h" #include "internal/constant/group.h"
#include "internal/constant/group_union.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 { class GroupUnion {
public: 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. /// 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. /// 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. /// 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. /// 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: private:
// ------------------------------------------------------------------------------------- //
/// Whether fast mode is available. /// Whether fast mode is available.
static inline bool fast_ {false}; static inline bool fast_ {false};

6
src/core/group/internal/group.cc

@ -18,7 +18,9 @@ using klotski::mover::MaskMover;
using klotski::group::GROUP_DATA; using klotski::group::GROUP_DATA;
using klotski::group::PATTERN_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. /// Spawn all the unsorted codes of the current group.
static std::vector<RawCode> Group_extend_for_cases(RawCode raw_code, uint32_t reserve) { static std::vector<RawCode> Group_extend_for_cases(RawCode raw_code, uint32_t reserve) {
@ -46,6 +48,7 @@ static std::vector<RawCode> Group_extend_for_cases(RawCode raw_code, uint32_t re
return codes; return codes;
} }
// TODO: maybe we can perf with mirror cases
RangesUnion Group::cases() const { RangesUnion Group::cases() const {
// TODO: add white list for single-group unions // TODO: add white list for single-group unions
@ -117,6 +120,7 @@ static std::vector<RawCode> Group_extend_for_from_raw_code(RawCode raw_code) {
return codes; return codes;
} }
// TODO: maybe we can search new cases in `map_data`
Group Group::from_raw_code(const RawCode raw_code) { Group Group::from_raw_code(const RawCode raw_code) {
static auto map_data = build_map_data(); static auto map_data = build_map_data();

16
src/core/group/internal/group_cases.cc

@ -34,9 +34,8 @@ struct case_info_t {
static_assert(sizeof(case_info_t) == 4); static_assert(sizeof(case_info_t) == 4);
// TODO: we need multi-thread support (Executor) // TODO: benchmark of `phmap<Group>` structure
static std::vector<std::vector<RangesUnion>> *ru_data = nullptr; // group_offset + toward
static std::vector<std::vector<RangesUnion>> *ru_data = nullptr;
static std::vector<case_info_t> *rev_data = nullptr; static std::vector<case_info_t> *rev_data = nullptr;
std::vector<std::vector<RangesUnion>> build_ranges_unions() { std::vector<std::vector<RangesUnion>> build_ranges_unions() {
@ -45,6 +44,8 @@ std::vector<std::vector<RangesUnion>> build_ranges_unions() {
// TODO: add white list for single-group 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) { for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
auto group_union = GroupUnion::unsafe_create(type_id); auto group_union = GroupUnion::unsafe_create(type_id);
for (uint32_t pattern_id = 0; pattern_id < group_union.pattern_num(); ++pattern_id) { for (uint32_t pattern_id = 0; pattern_id < group_union.pattern_num(); ++pattern_id) {
@ -92,16 +93,23 @@ static std::vector<case_info_t> build_tmp_data() {
} }
void GroupCases::build() { 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_1 = build_ranges_unions();
static auto data_2 = build_tmp_data(); static auto data_2 = build_tmp_data();
ru_data = &data_1; ru_data = &data_1;
rev_data = &data_2; rev_data = &data_2;
// TODO: using std::mutex `busy_` KLSK_MEM_BARRIER;
fast_ = true; fast_ = true;
} }
void GroupCases::build_async(Executor &&executor, Notifier &&callback) { void GroupCases::build_async(Executor &&executor, Notifier &&callback) {
// TODO: real multi-thread build
executor([callback = std::move(callback)] { executor([callback = std::move(callback)] {
build(); build();
callback(); callback();

10
src/core/group/internal/group_cases.inl

@ -4,35 +4,35 @@ namespace klotski::group {
// TODO: maybe move `fast_obtain_*` into `.inl` file // 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_) { if (fast_) {
return fast_obtain_code(info); return fast_obtain_code(info);
} }
return tiny_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_) { if (fast_) {
return fast_obtain_group(short_code); return fast_obtain_group(short_code);
} }
return Group::from_short_code(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_) { if (fast_) {
return fast_obtain_group(common_code); return fast_obtain_group(common_code);
} }
return Group::from_common_code(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_) { if (fast_) {
return fast_obtain_info(short_code); return fast_obtain_info(short_code);
} }
return tiny_obtain_info(short_code.to_common_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_) { if (fast_) {
return fast_obtain_info(common_code); return fast_obtain_info(common_code);
} }

10
src/core/group/internal/group_union.cc

@ -17,11 +17,11 @@ RangesUnion GroupUnion::cases() const {
ranges.reverse(); ranges.reverse();
RangesUnion cases; RangesUnion cases;
const auto [s_a, s_b, s_c, s_d] = GROUP_UNION_CASES_NUM[type_id_]; const auto [na, nb, nc, nd] = GROUP_UNION_CASES_NUM[type_id_];
RANGE_RESERVE(0x0, s_a); RANGE_RESERVE(0x1, s_b); RANGE_RESERVE(0x2, s_a); RANGE_RESERVE(0x0, na); RANGE_RESERVE(0x1, nb); RANGE_RESERVE(0x2, na);
RANGE_RESERVE(0x4, s_c); RANGE_RESERVE(0x5, s_d); RANGE_RESERVE(0x6, s_c); RANGE_RESERVE(0x4, nc); RANGE_RESERVE(0x5, nd); RANGE_RESERVE(0x6, nc);
RANGE_RESERVE(0x8, s_c); RANGE_RESERVE(0x9, s_d); RANGE_RESERVE(0xA, s_c); RANGE_RESERVE(0x8, nc); RANGE_RESERVE(0x9, nd); RANGE_RESERVE(0xA, nc);
RANGE_RESERVE(0xC, s_a); RANGE_RESERVE(0xD, s_b); RANGE_RESERVE(0xE, s_a); RANGE_RESERVE(0xC, na); RANGE_RESERVE(0xD, nb); RANGE_RESERVE(0xE, na);
RANGE_DERIVE(0x0); RANGE_DERIVE(0x1); RANGE_DERIVE(0x2); RANGE_DERIVE(0x0); RANGE_DERIVE(0x1); RANGE_DERIVE(0x2);
RANGE_DERIVE(0x4); RANGE_DERIVE(0x5); RANGE_DERIVE(0x6); RANGE_DERIVE(0x4); RANGE_DERIVE(0x5); RANGE_DERIVE(0x6);

2
src/core/group/internal/mirror.inl

@ -1,5 +1,7 @@
#pragma once #pragma once
// TODO: class functions force inline
namespace klotski::group { namespace klotski::group {
constexpr auto Group::mirror_type() const -> MirrorType { constexpr auto Group::mirror_type() const -> MirrorType {

Loading…
Cancel
Save