Browse Source

feat: support obtain group info

legacy
Dnomd343 2 months ago
parent
commit
b9428ea74d
  1. 2
      src/core/CMakeLists.txt
  2. 87
      src/core/group/group.h
  3. 126
      src/core/group/internal/group_cases.cc
  4. 126
      src/core/group/internal/group_cases_legacy.cc
  5. 40
      src/core/group/internal/group_cases_pro.cc
  6. 13
      src/core/main.cc

2
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

87
src/core/group/group.h

@ -260,7 +260,7 @@ private:
/// Spawn all the unsorted codes of the current group.
std::vector<codec::RawCode> 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

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

@ -1,126 +0,0 @@
#include <iostream>
#include <algorithm>
#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<tmp_t> *rev_data = nullptr;
static std::vector<RangesUnion> *ru_data = nullptr;
std::vector<RangesUnion> build_ranges_unions() {
std::vector<RangesUnion> 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<tmp_t> build_tmp_data() {
std::vector<tmp_t> 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 {};
}

126
src/core/group/internal/group_cases_legacy.cc

@ -0,0 +1,126 @@
#include <iostream>
#include <algorithm>
#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<tmp_t> *rev_data = nullptr;
static std::vector<RangesUnion> *ru_data = nullptr;
static std::vector<RangesUnion> build_ranges_unions() {
std::vector<RangesUnion> 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<tmp_t> build_tmp_data() {
std::vector<tmp_t> 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 {};
//}

40
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<case_info_t> 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<uint64_t, Group> 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<CommonCode> 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);
}

13
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);

Loading…
Cancel
Save