Browse Source

update: optimize utility functions

master
Dnomd343 3 weeks 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. 27
      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
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<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.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,
});
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

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 ,
});
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.
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) {
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;

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

@ -2,19 +2,16 @@
#include <cstdint>
#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

27
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 <typename T>
concept Addable = requires(T a, T b) { a + b; };
template <Addable T, size_t N>
/// Calculate the sum of an array of integers.
template <typename T, size_t N>
requires std::is_integral_v<T>
consteval int array_sum(const std::array<T, N> &arr) {
return std::accumulate(arr.begin(), arr.end(), 0);
}
template <Addable T, size_t N>
consteval std::array<T, N> to_offset(const std::array<T, N> &arr, T base) {
static_assert(N > 0);
/// Calculate offset list of integer array with sizes.
template <typename T, size_t N>
requires std::is_integral_v<T>
consteval std::array<T, N> to_offset(const std::array<T, N> &arr) {
std::array<T, N> 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.

Loading…
Cancel
Save