From ead034282893f6b959ba235a20afa214dc9ebb8b Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 16 Jun 2024 10:57:26 +0800 Subject: [PATCH] update: optimize utility functions --- src/core/all_cases/internal/basic_ranges.cc | 4 +-- src/core/all_cases/internal/constant.inl | 8 +++--- .../group/internal/constant/group_union.h | 2 +- src/core/short_code/internal/convert.cc | 12 ++++----- src/core/short_code/internal/offset/basic.h | 11 +++----- src/core/utils/utility.h | 27 ++++++++----------- 6 files changed, 28 insertions(+), 36 deletions(-) diff --git a/src/core/all_cases/internal/basic_ranges.cc b/src/core/all_cases/internal/basic_ranges.cc index 2d719e3..6aa079f 100644 --- a/src/core/all_cases/internal/basic_ranges.cc +++ b/src/core/all_cases/internal/basic_ranges.cc @@ -63,7 +63,7 @@ void BasicRanges::build() { } std::list points; // mark ordered interval - for (const auto offset : to_offset(BASIC_RANGES_NUM, 0)) { + for (const auto offset : BASIC_RANGES_OFFSET) { points.emplace_back(ranges.begin() + offset); } points.emplace_back(ranges.end()); @@ -117,7 +117,7 @@ void BasicRanges::build_async(Executor &&executor, Notifier &&callback) { } auto points = std::make_shared>(); // mark ordered interval - for (const auto offset : to_offset(BASIC_RANGES_NUM, 0)) { + for (const auto offset : BASIC_RANGES_OFFSET) { points->emplace_back(ranges.begin() + offset); } points->emplace_back(ranges.end()); diff --git a/src/core/all_cases/internal/constant.inl b/src/core/all_cases/internal/constant.inl index 2dc773f..3847fec 100644 --- a/src/core/all_cases/internal/constant.inl +++ b/src/core/all_cases/internal/constant.inl @@ -13,10 +13,10 @@ constexpr auto ALL_CASES_NUM = std::to_array({ 2942906, 2260392, 2942906, 0, }); -static_assert(ALL_CASES_NUM.size() == 16); - constexpr auto ALL_CASES_NUM_ = array_sum(ALL_CASES_NUM); +constexpr auto ALL_CASES_OFFSET = to_offset(ALL_CASES_NUM); + // ------------------------------------------------------------------------------------- // constexpr auto BASIC_RANGES_NUM = std::to_array({ @@ -48,10 +48,10 @@ constexpr auto BASIC_RANGES_NUM = std::to_array({ 1260 , 756 , 252 , }); -static_assert(BASIC_RANGES_NUM.size() == 203); - constexpr auto BASIC_RANGES_NUM_ = array_sum(BASIC_RANGES_NUM); +constexpr auto BASIC_RANGES_OFFSET = to_offset(BASIC_RANGES_NUM); + // ------------------------------------------------------------------------------------- // } // namespace klotski::cases diff --git a/src/core/group/internal/constant/group_union.h b/src/core/group/internal/constant/group_union.h index 9eff33b..fe40a76 100644 --- a/src/core/group/internal/constant/group_union.h +++ b/src/core/group/internal/constant/group_union.h @@ -23,7 +23,7 @@ constexpr auto GROUP_NUM = std::to_array({ 214, 6 , 18 , 54 , 2 , 44 , 40 , 124 , 84 , 70 , 18 , }); -constexpr auto GROUP_OFFSET = to_offset(GROUP_NUM, 0); +constexpr auto GROUP_OFFSET = to_offset(GROUP_NUM); /// The maximum Group size in each GroupUnion. constexpr auto MAX_GROUP_SIZE = std::to_array({ diff --git a/src/core/short_code/internal/convert.cc b/src/core/short_code/internal/convert.cc index e1a7256..01dbbac 100644 --- a/src/core/short_code/internal/convert.cc +++ b/src/core/short_code/internal/convert.cc @@ -59,8 +59,8 @@ uint32_t ShortCode::fast_encode(uint64_t common_code) { } uint64_t ShortCode::fast_decode(uint32_t short_code) { - auto offset = std::upper_bound(ALL_CASES_OFFSET, ALL_CASES_OFFSET + 16, short_code) - 1; - uint64_t head = offset - ALL_CASES_OFFSET; + auto offset = std::upper_bound(ALL_CASES_OFFSET.begin(), ALL_CASES_OFFSET.end(), short_code) - 1; + uint64_t head = offset - ALL_CASES_OFFSET.begin(); return (head << 32) | AllCases::instance().fetch()[head][short_code - *offset]; } @@ -90,11 +90,11 @@ uint32_t ShortCode::tiny_encode(uint64_t common_code) { } uint64_t ShortCode::tiny_decode(uint32_t short_code) { // short code --> common code - auto offset = std::upper_bound(ALL_CASES_OFFSET, ALL_CASES_OFFSET + 16, short_code) - 1; - auto head = offset - ALL_CASES_OFFSET; // head index - short_code -= *offset; + auto offset_ = std::upper_bound(ALL_CASES_OFFSET.begin(), ALL_CASES_OFFSET.end(), short_code) - 1; + auto head = offset_ - ALL_CASES_OFFSET.begin(); // head index + short_code -= *offset_; - offset = std::upper_bound(RANGE_PREFIX_OFFSET[head], RANGE_PREFIX_OFFSET[head] + 4096, short_code) - 1; + auto offset = std::upper_bound(RANGE_PREFIX_OFFSET[head], RANGE_PREFIX_OFFSET[head] + 4096, short_code) - 1; auto prefix = offset - RANGE_PREFIX_OFFSET[head]; // range prefix short_code -= *offset; diff --git a/src/core/short_code/internal/offset/basic.h b/src/core/short_code/internal/offset/basic.h index 4c6a4d6..fba769f 100644 --- a/src/core/short_code/internal/offset/basic.h +++ b/src/core/short_code/internal/offset/basic.h @@ -2,19 +2,16 @@ #include +#include "utils/utility.h" +#include "all_cases/all_cases.h" + namespace klotski::codec::offset { /// This is the head index, the offset [0, 29334498) in all cases is obtained /// according to the `head` (0 ~ 15). In other words, the short code range can /// be obtained according to the position of the 2x2 block. -// TODO: using std::array -constexpr uint32_t ALL_CASES_OFFSET[16] { - 0, 2942906, 5203298, 8146204, - 8146204, 10468254, 12345199, 14667249, - 14667249, 16989299, 18866244, 21188294, - 21188294, 24131200, 26391592, 29334498, -}; +constexpr auto ALL_CASES_OFFSET = to_offset(cases::ALL_CASES_NUM); /// This is the index for basic ranges, and its position (0 ~ 7311884) in all /// basic ranges is located according to the first 12-bit (0 ~ 4095) within the diff --git a/src/core/utils/utility.h b/src/core/utils/utility.h index c30cc2e..9f19b13 100644 --- a/src/core/utils/utility.h +++ b/src/core/utils/utility.h @@ -23,36 +23,31 @@ #define KLSK_ASSUME(expr) __builtin_assume(expr) /// Force function declaration to be inline. -#define KLSK_INLINE __attribute__((always_inline)) +#define KLSK_INLINE __attribute__ ((always_inline)) namespace klotski { -template -concept Addable = requires(T a, T b) { a + b; }; - -template +/// Calculate the sum of an array of integers. +template +requires std::is_integral_v consteval int array_sum(const std::array &arr) { return std::accumulate(arr.begin(), arr.end(), 0); } -template -consteval std::array to_offset(const std::array &arr, T base) { - - static_assert(N > 0); - +/// Calculate offset list of integer array with sizes. +template +requires std::is_integral_v +consteval std::array to_offset(const std::array &arr) { std::array offset; - - T val = base; - + static_assert(N > 0); offset[0] = 0; - for (int i = 0; i < N - 1; ++i) { + T val = 0; + for (int i = 0; i < N - 1; ++i) { // TODO: using `std::views::iota` val += arr[i]; offset[i + 1] = val; } - return offset; - } /// Flips the input u32 every two bits in low-high symmetry.