|
@ -50,18 +50,10 @@ static uint32_t check_range(uint32_t head, uint32_t range) noexcept { |
|
|
return 0; // pass check
|
|
|
return 0; // pass check
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
std::mutex ShortCode::busy_ {}; |
|
|
|
|
|
|
|
|
|
|
|
// ShortCode::Stage ShortCode::stage_ = Stage::UNINIT;
|
|
|
|
|
|
|
|
|
|
|
|
// const klotski::cases::RangesUnion *ShortCode::cases_ = &AllCases::instance().fetch();
|
|
|
|
|
|
const klotski::cases::RangesUnion *ShortCode::cases_ = nullptr; |
|
|
|
|
|
|
|
|
|
|
|
const klotski::cases::Ranges *ShortCode::ranges_ = nullptr; |
|
|
|
|
|
|
|
|
|
|
|
uint32_t ShortCode::fast_encode(uint64_t common_code) { |
|
|
uint32_t ShortCode::fast_encode(uint64_t common_code) { |
|
|
auto head = common_code >> 32; |
|
|
auto head = common_code >> 32; |
|
|
auto &ranges = AllCases::instance().fetch()[head]; // match available ranges
|
|
|
auto &ranges = (*cases_)[head]; // match available ranges
|
|
|
|
|
|
// TODO: try to narrow the scope by prefix
|
|
|
auto target = std::lower_bound(ranges.begin(), ranges.end(), (uint32_t)common_code); |
|
|
auto target = std::lower_bound(ranges.begin(), ranges.end(), (uint32_t)common_code); |
|
|
return ALL_CASES_OFFSET[head] + (target - ranges.begin()); |
|
|
return ALL_CASES_OFFSET[head] + (target - ranges.begin()); |
|
|
} |
|
|
} |
|
@ -79,19 +71,22 @@ uint32_t ShortCode::tiny_encode(uint64_t common_code) { |
|
|
|
|
|
|
|
|
uint32_t offset = 0; |
|
|
uint32_t offset = 0; |
|
|
auto index = RANGES_GLOBAL_OFFSET[prefix]; |
|
|
auto index = RANGES_GLOBAL_OFFSET[prefix]; |
|
|
const auto &basic_ranges = BasicRanges::instance().fetch(); |
|
|
|
|
|
|
|
|
ranges_ = &cases::BasicRanges::instance().fetch(); |
|
|
|
|
|
const auto &ranges = *ranges_; |
|
|
|
|
|
|
|
|
auto target = (uint32_t)common_code; // target range
|
|
|
auto target = (uint32_t)common_code; // target range
|
|
|
for (; index < basic_ranges.size(); ++index) { |
|
|
for (; index < ranges.size(); ++index) { |
|
|
auto broken_offset = check_range(head, range_reverse(basic_ranges[index])); |
|
|
auto broken_offset = check_range(head, range_reverse(ranges[index])); |
|
|
if (!broken_offset) { // valid case
|
|
|
if (!broken_offset) { // valid case
|
|
|
if (basic_ranges[index] == target) { |
|
|
if (ranges[index] == target) { |
|
|
break; // found target range
|
|
|
break; // found target range
|
|
|
} |
|
|
} |
|
|
++offset; // record sub offset
|
|
|
++offset; // record sub offset
|
|
|
} else { |
|
|
} else { |
|
|
auto delta = (uint32_t)1 << (32 - broken_offset * 2); // delta to next possible range
|
|
|
auto delta = (uint32_t)1 << (32 - broken_offset * 2); // delta to next possible range
|
|
|
auto next_min = (basic_ranges[index] & ~(delta - 1)) + delta; |
|
|
auto next_min = (ranges[index] & ~(delta - 1)) + delta; |
|
|
while (basic_ranges[++index] < next_min); // located next range
|
|
|
while (ranges[++index] < next_min); // located next range
|
|
|
--index; |
|
|
--index; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -99,13 +94,6 @@ 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
|
|
|
// speed_up(false);
|
|
|
|
|
|
|
|
|
|
|
|
// std::lock_guard guard {busy_};
|
|
|
|
|
|
|
|
|
|
|
|
ranges_ = &cases::BasicRanges::instance().fetch(); |
|
|
|
|
|
// stage_ = Stage::TINY;
|
|
|
|
|
|
|
|
|
|
|
|
auto offset_ = std::upper_bound(ALL_CASES_OFFSET.begin(), ALL_CASES_OFFSET.end(), 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.begin(); // head index
|
|
|
auto head = offset_ - ALL_CASES_OFFSET.begin(); // head index
|
|
|
short_code -= *offset_; |
|
|
short_code -= *offset_; |
|
@ -116,11 +104,9 @@ uint64_t ShortCode::tiny_decode(uint32_t short_code) { // short code --> common |
|
|
|
|
|
|
|
|
/// search for target range
|
|
|
/// search for target range
|
|
|
auto index = RANGES_GLOBAL_OFFSET[prefix]; |
|
|
auto index = RANGES_GLOBAL_OFFSET[prefix]; |
|
|
// auto basic_ranges = ranges_;
|
|
|
|
|
|
// const auto &basic_ranges = BasicRanges::instance().fetch();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ranges_ = &cases::BasicRanges::instance().fetch(); |
|
|
const auto &ranges = *ranges_; |
|
|
const auto &ranges = *ranges_; |
|
|
// const auto &ranges = BasicRanges::instance().fetch();
|
|
|
|
|
|
|
|
|
|
|
|
for (; index < ranges.size(); ++index) { // traverse basic ranges
|
|
|
for (; index < ranges.size(); ++index) { // traverse basic ranges
|
|
|
auto broken_offset = check_range(head, range_reverse(ranges[index])); |
|
|
auto broken_offset = check_range(head, range_reverse(ranges[index])); |
|
|