Browse Source

feat: ShortCode init and to_string trait

legacy
Dnomd343 2 years ago
parent
commit
768bd281f6
  1. 5
      klotski/short_code.h
  2. 31
      src/main.cc
  3. 2
      src/short_code/CMakeLists.txt
  4. 52
      src/short_code/data_loader.cc
  5. 60
      src/short_code/short_code.cc
  6. 14
      src/short_code/short_code.h

5
klotski/short_code.h

@ -28,6 +28,7 @@ const char SHORT_CODE_TABLE_REV[42] = {
class ShortCode { class ShortCode {
public: public:
// ok
enum Mode {NORMAL, FAST}; enum Mode {NORMAL, FAST};
ShortCode() = default; ShortCode() = default;
@ -42,15 +43,19 @@ public:
static uint32_t code_from_string(const std::string &short_code); static uint32_t code_from_string(const std::string &short_code);
private: private:
// ok
static const uint32_t SHORT_CODE_LIMIT = 29334498; static const uint32_t SHORT_CODE_LIMIT = 29334498;
// ok
std::vector<uint32_t> basic_ranges; std::vector<uint32_t> basic_ranges;
std::vector<uint64_t> all_cases_list; // short_code -> 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 std::unordered_map<uint64_t, uint32_t> all_cases_dict; // common_code -> short_code
// ok
void build_mappings(); void build_mappings();
enum Mode check_mode(); enum Mode check_mode();
void build_base_ranges(); void build_base_ranges();
uint64_t tiny_decode(uint32_t short_code); uint64_t tiny_decode(uint32_t short_code);
uint32_t tiny_encode(uint64_t common_code); uint32_t tiny_encode(uint64_t common_code);
}; };

31
src/main.cc

@ -63,23 +63,22 @@ int main() {
// std::cout << BasicRanges::fetch() << std::endl; // std::cout << BasicRanges::fetch() << std::endl;
std::cout << CommonCode::check(0x123456789) << std::endl; // std::cout << CommonCode::check(0x123456789) << std::endl;
std::cout << CommonCode::check(0x4FEA13400) << std::endl; // std::cout << CommonCode::check(0x4FEA13400) << std::endl;
//
printf("%09lX\n", CommonCode("1A9bF0c0").unwrap()); // printf("%09lX\n", CommonCode("1A9bF0c0").unwrap());
std::cout << CommonCode(0x1A9BF0C00).to_string() << std::endl; // std::cout << CommonCode(0x1A9BF0C00).to_string() << std::endl;
std::cout << CommonCode(0x1A9BF0C00).to_string(true) << std::endl; // std::cout << CommonCode(0x1A9BF0C00).to_string(true) << std::endl;
//
auto c = CommonCode("4Fea13400"); // auto c = CommonCode("4Fea13400");
std::cout << c.to_string(true) << std::endl; // std::cout << c.to_string(true) << std::endl;
std::cout << c.to_string() << std::endl; // std::cout << c.to_string() << std::endl;
printf("%09lX\n", c.unwrap()); // printf("%09lX\n", c.unwrap());
// std::cout << ShortCode::check_mode() << std::endl; // std::cout << ShortCode::check_mode() << std::endl;
//
// std::cout << "start NORMAL speed up" << std::endl; // std::cout << "start NORMAL speed up" << std::endl;
//// ShortCode::speed_up(ShortCode::NORMAL);
// std::thread t1(ShortCode::speed_up, ShortCode::NORMAL); // std::thread t1(ShortCode::speed_up, ShortCode::NORMAL);
// std::thread t2(ShortCode::speed_up, ShortCode::NORMAL); // std::thread t2(ShortCode::speed_up, ShortCode::NORMAL);
// t1.join(); // t1.join();
@ -89,7 +88,6 @@ int main() {
// std::cout << ShortCode::check_mode() << std::endl; // std::cout << ShortCode::check_mode() << std::endl;
// //
// std::cout << "start FAST speed up" << std::endl; // std::cout << "start FAST speed up" << std::endl;
//// ShortCode::speed_up(ShortCode::FAST);
// std::thread t3(ShortCode::speed_up, ShortCode::FAST); // std::thread t3(ShortCode::speed_up, ShortCode::FAST);
// std::thread t4(ShortCode::speed_up, ShortCode::FAST); // std::thread t4(ShortCode::speed_up, ShortCode::FAST);
// t3.join(); // t3.join();
@ -98,5 +96,10 @@ int main() {
// //
// std::cout << ShortCode::check_mode() << std::endl; // std::cout << ShortCode::check_mode() << std::endl;
auto s = ShortCode(14323231);
std::cout << s.unwrap() << std::endl;
std::cout << s.to_string() << std::endl;
return 0; return 0;
} }

2
src/short_code/CMakeLists.txt

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.0)
add_library(short_code short_code.cc) add_library(short_code data_loader.cc short_code.cc)
target_link_libraries(short_code all_cases) target_link_libraries(short_code all_cases)

52
src/short_code/data_loader.cc

@ -0,0 +1,52 @@
#include "all_cases.h"
#include "short_code.h"
#include "basic_ranges.h"
std::mutex ShortCode::map_building;
bool ShortCode::fast_mode_available = false;
bool ShortCode::normal_mode_available = false;
std::vector<uint64_t> ShortCode::all_cases_list;
std::unordered_map<uint64_t, uint32_t> ShortCode::all_cases_dict;
void ShortCode::speed_up(ShortCode::Mode mode) {
if (fast_mode_available) {
return; // fast mode already available
}
if (mode == ShortCode::FAST) { // build fast mode data
build_mappings();
} else if (mode == ShortCode::NORMAL && !normal_mode_available) { // build normal mode data
BasicRanges::build(); // blocking function
normal_mode_available = true;
}
}
ShortCode::Mode ShortCode::check_mode() { // ensure speed up enabled and return current mode
if (fast_mode_available) {
return ShortCode::FAST; // fast mode already enabled
}
if (normal_mode_available) {
return ShortCode::NORMAL; // normal mode already enabled
}
speed_up(ShortCode::Mode::NORMAL); // without initialized -> enter normal mode
return ShortCode::Mode::NORMAL; // use normal mode
}
/// ensure that fast_mode_available == false
void ShortCode::build_mappings() { // build fast search mappings
if (map_building.try_lock()) { // lock success -> start building
for (int head = 0; head < 16; ++head) {
uint64_t prefix = (uint64_t)head << 32;
for (const auto &range : (*AllCases::fetch())[head]) { // blocking function
all_cases_list.emplace_back(prefix | range); // short_code -> common_code
}
}
for (int index = 0; index < all_cases_list.size(); ++index) {
all_cases_dict[all_cases_list[index]] = index; // common_code -> short_code
}
fast_mode_available = true; // set available flag
} else { // another thread building
map_building.lock(); // blocking waiting
}
map_building.unlock();
}

60
src/short_code/short_code.cc

@ -1,51 +1,27 @@
#include "all_cases.h"
#include "short_code.h" #include "short_code.h"
#include "basic_ranges.h"
std::mutex ShortCode::map_building; uint32_t ShortCode::unwrap() const {
bool ShortCode::fast_mode_available = false; return code; // get raw uint32_t code
bool ShortCode::normal_mode_available = false;
std::vector<uint64_t> ShortCode::all_cases_list;
std::unordered_map<uint64_t, uint32_t> ShortCode::all_cases_dict;
void ShortCode::speed_up(ShortCode::Mode mode) {
if (fast_mode_available) {
return; // fast mode already available
}
if (mode == ShortCode::FAST) { // build fast mode data
build_mappings();
} else if (mode == ShortCode::NORMAL && !normal_mode_available) { // build normal mode data
BasicRanges::build(); // blocking function
normal_mode_available = true;
}
} }
ShortCode::Mode ShortCode::check_mode() { // ensure speed up enabled and return current mode bool ShortCode::check(uint32_t short_code) {
if (fast_mode_available) { return short_code < ShortCode::SHORT_CODE_LIMIT; // 0 ~ (SHORT_CODE_LIMIT - 1)
return ShortCode::FAST; // fast mode already enabled
}
if (normal_mode_available) {
return ShortCode::NORMAL; // normal mode already enabled
}
speed_up(ShortCode::Mode::NORMAL); // without initialized -> enter normal mode
return ShortCode::Mode::NORMAL; // use normal mode
} }
/// ensure that fast_mode_available = false ShortCode::ShortCode(uint32_t short_code) {
void ShortCode::build_mappings() { // build fast search mappings if (!ShortCode::check(short_code)) { // check input short code
if (map_building.try_lock()) { // lock success -> start building throw std::invalid_argument("invalid short code");
for (int head = 0; head < 16; ++head) {
uint64_t prefix = (uint64_t)head << 32;
for (const auto &range : (*AllCases::fetch())[head]) { // blocking function
all_cases_list.emplace_back(prefix | range); // short_code -> common_code
}
} }
for (int index = 0; index < all_cases_list.size(); ++index) { code = short_code;
all_cases_dict[all_cases_list[index]] = index; // common_code -> short_code
} }
fast_mode_available = true; // set available flag
} else { // another thread building #include <iostream>
map_building.lock(); // blocking waiting
} std::string ShortCode::to_string() const {
map_building.unlock();
// this->code ==> std::string
std::cout << "short code: " << code << std::endl;
return "";
} }

14
src/short_code/short_code.h

@ -13,10 +13,24 @@ public:
static enum Mode check_mode(); static enum Mode check_mode();
static void speed_up(enum Mode mode); static void speed_up(enum Mode mode);
static bool check(uint32_t short_code);
uint32_t unwrap() const;
std::string to_string() const;
explicit ShortCode(uint32_t short_code);
// explicit CommonCode(const std::string &common_code_str);
private: private:
uint32_t code;
static std::mutex map_building; static std::mutex map_building;
static bool fast_mode_available; static bool fast_mode_available;
static bool normal_mode_available; static bool normal_mode_available;
static const uint32_t SHORT_CODE_LIMIT = 29334498;
static std::vector<uint64_t> all_cases_list; // short_code -> common_code static std::vector<uint64_t> all_cases_list; // short_code -> common_code
static std::unordered_map<uint64_t, uint32_t> all_cases_dict; // common_code -> short_code static std::unordered_map<uint64_t, uint32_t> all_cases_dict; // common_code -> short_code

Loading…
Cancel
Save