Browse Source

perf: ShortCode module

legacy
Dnomd343 2 years ago
parent
commit
ec21c73e54
  1. 25
      klotski/main.cc
  2. 110
      klotski/short_code.cc
  3. 27
      klotski/short_code.h

25
klotski/main.cc

@ -18,37 +18,16 @@ int main() {
// std::cout << temp.size() << std::endl; // std::cout << temp.size() << std::endl;
// } // }
// auto s = ShortCode();
// auto s = ShortCode(ShortCode::Mode::NORMAL);
// auto s = ShortCode(ShortCode::Mode::FAST);
// s.speed_up(ShortCode::Mode::FAST);
// std::cout << s.all_cases_list.size() << std::endl;
// std::cout << s.all_cases_dict.size() << std::endl;
// printf("%d\n", s.fast_encode(0x6EC0F8800));
// printf("%09lX\n", s.fast_decode(14323231));
// s.speed_up(ShortCode::Mode::NORMAL);
// std::cout << s.basic_ranges.size() << std::endl;
// auto s = ShortCode();
// s.speed_up(ShortCode::Mode::NORMAL); // enter normal mode first
//
// printf("%d\n", s.tiny_encode(0x6EC0F8800));
// printf("%09lX\n", s.tiny_decode(14323231));
auto s = ShortCode(); auto s = ShortCode();
// auto s = ShortCode(ShortCode::Mode::NORMAL); // auto s = ShortCode(ShortCode::Mode::NORMAL);
// auto s = ShortCode(ShortCode::Mode::FAST); // auto s = ShortCode(ShortCode::Mode::FAST);
// std::cout << "start" << std::endl; // s.speed_up(ShortCode::Mode::NORMAL);
// std::cout << s.zip_short_code(0x6EC0F8800) << std::endl; s.speed_up(ShortCode::Mode::FAST);
// std::cout << "complete" << std::endl;
printf("%d\n", s.zip_short_code(0x6EC0F8800)); printf("%d\n", s.zip_short_code(0x6EC0F8800));
printf("%09lX\n", s.unzip_short_code(14323231)); printf("%09lX\n", s.unzip_short_code(14323231));
// printf("%09lX\n", s.unzip_short_code(87654321));
return 0; return 0;
} }

110
klotski/short_code.cc

@ -46,49 +46,46 @@ void ShortCode::build_mappings() { // build fast search mappings
} }
} }
uint64_t ShortCode::fast_decode(uint32_t short_code) { // short_code --fast--> common_code enum ShortCode::Mode ShortCode::check_mode() { // ensure speed up enabled and return current mode
// TODO: ensure input short_code < SHORT_CODE_LIMIT if (!all_cases_list.empty()) {
return all_cases_list[short_code]; return ShortCode::Mode::FAST; // fast mode already enabled
} }
if (!basic_ranges.empty()) {
uint32_t ShortCode::fast_encode(uint64_t common_code) { // common_code --fast--> short_code return ShortCode::Mode::NORMAL; // normal mode already enabled
// TODO: ensure input common_code valid
return all_cases_dict[common_code];
} }
speed_up(ShortCode::Mode::NORMAL); // class without initialized -> enter normal mode
// TODO: load basic ranges before tiny_decode return ShortCode::Mode::NORMAL; // use normal mode
// TODO: ensure input short_code < SHORT_CODE_LIMIT
uint64_t ShortCode::tiny_decode(uint32_t short_code) { // short_code --low-mem--> common_code
uint32_t head = 0, prefix = 0;
for (; head < 16; ++head) {
if (short_code < ALL_CASES_INDEX[head]) { // match head
break;
} }
short_code -= ALL_CASES_INDEX[head]; // short code approximate
uint32_t ShortCode::zip_short_code(uint64_t common_code) { // common_code --zip--> short_code
if (!CommonCode::check(common_code)) {
throw std::runtime_error("invalid common code");
} }
for (; prefix < 256; ++prefix) { switch (check_mode()) {
if (short_code < RANGE_PREFIX_INDEX[head][prefix]) { // match range prefix case ShortCode::Mode::NORMAL:
break; return tiny_encode(common_code);
case ShortCode::Mode::FAST:
return all_cases_dict[common_code];
default:
throw std::runtime_error("unknown error");
} }
short_code -= RANGE_PREFIX_INDEX[head][prefix]; // short code approximate
} }
uint32_t range; uint64_t ShortCode::unzip_short_code(uint32_t short_code) { // short_code --unzip--> common_code
for (int index = 0; index < BASIC_RANGES_INDEX[prefix]; ++index) { // traverse basic ranges if (!ShortCode::check(short_code)) {
range = basic_ranges[index + BASIC_RANGES_OFFSET[prefix]]; throw std::runtime_error("invalid short code");
if (Common::check_case(head, range)) { // search for valid cases
if (short_code == 0) {
break; // found target range
}
--short_code; // short code approximate
} }
switch (check_mode()) {
case ShortCode::Mode::NORMAL:
return tiny_decode(short_code);
case ShortCode::Mode::FAST:
return all_cases_list[short_code];
default:
throw std::runtime_error("unknown error");
} }
return (uint64_t)head << 32 | Common::range_reverse(range); // release common code
} }
// TODO: ensure input common_code valid uint32_t ShortCode::tiny_encode(uint64_t common_code) { // common_code --low-memory--> short_code
// TODO: load basic ranges before tiny_encode
uint32_t ShortCode::tiny_encode(uint64_t common_code) {
uint32_t offset = 0; uint32_t offset = 0;
uint32_t head = common_code >> 32; // common code head uint32_t head = common_code >> 32; // common code head
uint32_t prefix = (common_code >> 24) & 0xFF; // common code range prefix uint32_t prefix = (common_code >> 24) & 0xFF; // common code range prefix
@ -106,41 +103,30 @@ uint32_t ShortCode::tiny_encode(uint64_t common_code) {
return ALL_CASES_OFFSET[head] + RANGE_PREFIX_OFFSET[head][prefix] + offset; return ALL_CASES_OFFSET[head] + RANGE_PREFIX_OFFSET[head][prefix] + offset;
} }
uint32_t ShortCode::zip_short_code(uint64_t common_code) { // common_code --zip--> short_code uint64_t ShortCode::tiny_decode(uint32_t short_code) { // short_code --low-memory--> common_code
if (!CommonCode::check(common_code)) { uint32_t head = 0, prefix = 0;
throw std::runtime_error("invalid common code"); for (; head < 16; ++head) {
} if (short_code < ALL_CASES_INDEX[head]) { // match head
switch (check_mode()) { break;
case ShortCode::Mode::NORMAL:
return tiny_encode(common_code);
case ShortCode::Mode::FAST:
return fast_encode(common_code);
default:
throw std::runtime_error("unknown error");
}
} }
short_code -= ALL_CASES_INDEX[head]; // short code approximate
uint64_t ShortCode::unzip_short_code(uint32_t short_code) { // short_code --unzip--> common_code
if (!check(short_code)) {
throw std::runtime_error("invalid short code");
} }
switch (check_mode()) { for (; prefix < 256; ++prefix) {
case ShortCode::Mode::NORMAL: if (short_code < RANGE_PREFIX_INDEX[head][prefix]) { // match range prefix
return tiny_decode(short_code); break;
case ShortCode::Mode::FAST:
return fast_decode(short_code);
default:
throw std::runtime_error("unknown error");
} }
short_code -= RANGE_PREFIX_INDEX[head][prefix]; // short code approximate
} }
enum ShortCode::Mode ShortCode::check_mode() { // ensure speed up enabled and return current mode uint32_t range;
if (!all_cases_list.empty()) { for (int index = 0; index < BASIC_RANGES_INDEX[prefix]; ++index) { // traverse basic ranges
return ShortCode::Mode::FAST; // fast mode already enabled range = basic_ranges[index + BASIC_RANGES_OFFSET[prefix]];
if (Common::check_case(head, range)) { // search for valid cases
if (short_code == 0) {
break; // found target range
} }
if (!basic_ranges.empty()) { --short_code; // short code approximate
return ShortCode::Mode::NORMAL; // normal mode already enabled
} }
speed_up(ShortCode::Mode::NORMAL); // class without initialized -> enter normal mode }
return ShortCode::Mode::NORMAL; // use normal mode return (uint64_t)head << 32 | Common::range_reverse(range); // release common code
} }

27
klotski/short_code.h

@ -6,38 +6,25 @@
class ShortCode { class ShortCode {
public: public:
enum Mode {NORMAL, FAST}; enum Mode {NORMAL, FAST};
std::vector<uint32_t> basic_ranges;
std::vector<uint64_t> all_cases_list; // short_code -> common_code
std::unordered_map<uint64_t, uint32_t> all_cases_dict; // common_code -> short_code
ShortCode() = default; ShortCode() = default;
void speed_up(enum Mode mode); void speed_up(enum Mode mode);
explicit ShortCode(enum Mode mode); explicit ShortCode(enum Mode mode);
static bool check(uint32_t short_code);
uint32_t zip_short_code(uint64_t common_code); uint32_t zip_short_code(uint64_t common_code);
uint64_t unzip_short_code(uint32_t short_code); uint64_t unzip_short_code(uint32_t short_code);
enum Mode check_mode();
static bool check(uint32_t short_code);
private: private:
// std::vector<uint64_t> all_cases_list; // short_code -> common_code
// std::unordered_map<uint64_t, uint32_t> all_cases_dict; // common_code -> short_code
static const uint32_t SHORT_CODE_LIMIT = 29334498; static const uint32_t SHORT_CODE_LIMIT = 29334498;
uint64_t fast_decode(uint32_t short_code); std::vector<uint32_t> basic_ranges;
uint32_t fast_encode(uint64_t common_code); std::vector<uint64_t> all_cases_list; // short_code -> common_code
std::unordered_map<uint64_t, uint32_t> all_cases_dict; // common_code -> short_code
uint64_t tiny_decode(uint32_t short_code);
uint32_t tiny_encode(uint64_t common_code);
void build_mappings(); void build_mappings();
enum Mode check_mode();
void build_base_ranges(); void build_base_ranges();
uint64_t tiny_decode(uint32_t short_code);
uint32_t tiny_encode(uint64_t common_code);
}; };

Loading…
Cancel
Save