Browse Source

update: optimize utility functions

legacy
Dnomd343 6 months ago
parent
commit
ead0342828
  1. 4
      src/core/all_cases/internal/basic_ranges.cc
  2. 8
      src/core/all_cases/internal/constant.inl
  3. 2
      src/core/group/internal/constant/group_union.h
  4. 12
      src/core/short_code/internal/convert.cc
  5. 11
      src/core/short_code/internal/offset/basic.h
  6. 25
      src/core/utils/utility.h

4
src/core/all_cases/internal/basic_ranges.cc

@ -63,7 +63,7 @@ void BasicRanges::build() {
} }
std::list<RangesIter> points; // mark ordered interval std::list<RangesIter> 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.begin() + offset);
} }
points.emplace_back(ranges.end()); points.emplace_back(ranges.end());
@ -117,7 +117,7 @@ void BasicRanges::build_async(Executor &&executor, Notifier &&callback) {
} }
auto points = std::make_shared<std::list<RangesIter>>(); // mark ordered interval auto points = std::make_shared<std::list<RangesIter>>(); // 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.begin() + offset);
} }
points->emplace_back(ranges.end()); points->emplace_back(ranges.end());

8
src/core/all_cases/internal/constant.inl

@ -13,10 +13,10 @@ constexpr auto ALL_CASES_NUM = std::to_array({
2942906, 2260392, 2942906, 0, 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_NUM_ = array_sum(ALL_CASES_NUM);
constexpr auto ALL_CASES_OFFSET = to_offset(ALL_CASES_NUM);
// ------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------- //
constexpr auto BASIC_RANGES_NUM = std::to_array({ constexpr auto BASIC_RANGES_NUM = std::to_array({
@ -48,10 +48,10 @@ constexpr auto BASIC_RANGES_NUM = std::to_array({
1260 , 756 , 252 , 1260 , 756 , 252 ,
}); });
static_assert(BASIC_RANGES_NUM.size() == 203);
constexpr auto BASIC_RANGES_NUM_ = array_sum(BASIC_RANGES_NUM); constexpr auto BASIC_RANGES_NUM_ = array_sum(BASIC_RANGES_NUM);
constexpr auto BASIC_RANGES_OFFSET = to_offset(BASIC_RANGES_NUM);
// ------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------- //
} // namespace klotski::cases } // namespace klotski::cases

2
src/core/group/internal/constant/group_union.h

@ -23,7 +23,7 @@ constexpr auto GROUP_NUM = std::to_array<uint16_t>({
214, 6 , 18 , 54 , 2 , 44 , 40 , 124 , 84 , 70 , 18 , 214, 6 , 18 , 54 , 2 , 44 , 40 , 124 , 84 , 70 , 18 ,
}); });
constexpr auto GROUP_OFFSET = to_offset<uint16_t, 203>(GROUP_NUM, 0); constexpr auto GROUP_OFFSET = to_offset<uint16_t, 203>(GROUP_NUM);
/// The maximum Group size in each GroupUnion. /// The maximum Group size in each GroupUnion.
constexpr auto MAX_GROUP_SIZE = std::to_array<uint32_t>({ constexpr auto MAX_GROUP_SIZE = std::to_array<uint32_t>({

12
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) { uint64_t ShortCode::fast_decode(uint32_t short_code) {
auto offset = std::upper_bound(ALL_CASES_OFFSET, ALL_CASES_OFFSET + 16, short_code) - 1; auto offset = std::upper_bound(ALL_CASES_OFFSET.begin(), ALL_CASES_OFFSET.end(), short_code) - 1;
uint64_t head = offset - ALL_CASES_OFFSET; uint64_t head = offset - ALL_CASES_OFFSET.begin();
return (head << 32) | AllCases::instance().fetch()[head][short_code - *offset]; 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 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 offset_ = std::upper_bound(ALL_CASES_OFFSET.begin(), ALL_CASES_OFFSET.end(), short_code) - 1;
auto head = offset - ALL_CASES_OFFSET; // head index auto head = offset_ - ALL_CASES_OFFSET.begin(); // head index
short_code -= *offset; 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 auto prefix = offset - RANGE_PREFIX_OFFSET[head]; // range prefix
short_code -= *offset; short_code -= *offset;

11
src/core/short_code/internal/offset/basic.h

@ -2,19 +2,16 @@
#include <cstdint> #include <cstdint>
#include "utils/utility.h"
#include "all_cases/all_cases.h"
namespace klotski::codec::offset { namespace klotski::codec::offset {
/// This is the head index, the offset [0, 29334498) in all cases is obtained /// 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 /// according to the `head` (0 ~ 15). In other words, the short code range can
/// be obtained according to the position of the 2x2 block. /// be obtained according to the position of the 2x2 block.
// TODO: using std::array constexpr auto ALL_CASES_OFFSET = to_offset(cases::ALL_CASES_NUM);
constexpr uint32_t ALL_CASES_OFFSET[16] {
0, 2942906, 5203298, 8146204,
8146204, 10468254, 12345199, 14667249,
14667249, 16989299, 18866244, 21188294,
21188294, 24131200, 26391592, 29334498,
};
/// This is the index for basic ranges, and its position (0 ~ 7311884) in all /// 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 /// basic ranges is located according to the first 12-bit (0 ~ 4095) within the

25
src/core/utils/utility.h

@ -27,32 +27,27 @@
namespace klotski { namespace klotski {
template <typename T> /// Calculate the sum of an array of integers.
concept Addable = requires(T a, T b) { a + b; }; template <typename T, size_t N>
requires std::is_integral_v<T>
template <Addable T, size_t N>
consteval int array_sum(const std::array<T, N> &arr) { consteval int array_sum(const std::array<T, N> &arr) {
return std::accumulate(arr.begin(), arr.end(), 0); return std::accumulate(arr.begin(), arr.end(), 0);
} }
template <Addable T, size_t N> /// Calculate offset list of integer array with sizes.
consteval std::array<T, N> to_offset(const std::array<T, N> &arr, T base) { template <typename T, size_t N>
requires std::is_integral_v<T>
static_assert(N > 0); consteval std::array<T, N> to_offset(const std::array<T, N> &arr) {
std::array<T, N> offset; std::array<T, N> offset;
static_assert(N > 0);
T val = base;
offset[0] = 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]; val += arr[i];
offset[i + 1] = val; offset[i + 1] = val;
} }
return offset; return offset;
} }
/// Flips the input u32 every two bits in low-high symmetry. /// Flips the input u32 every two bits in low-high symmetry.

Loading…
Cancel
Save