Browse Source

perf: codec source structure

legacy
Dnomd343 2 years ago
parent
commit
e65d8709f8
  1. 8
      src/klotski_core/common_code/common_code.cc
  2. 25
      src/klotski_core/common_code/common_code.h
  3. 40
      src/klotski_core/common_code/convert.cc
  4. 44
      src/klotski_core/common_code/serialize.cc
  5. 12
      src/klotski_core/raw_code/convert.cc
  6. 29
      src/klotski_core/raw_code/mirror.cc
  7. 3
      src/klotski_core/raw_code/raw_code.h
  8. 8
      src/klotski_core/short_code/convert.cc
  9. 27
      src/klotski_core/short_code/serialize.cc
  10. 10
      src/klotski_core/short_code/short_code.cc
  11. 3
      src/klotski_core/short_code/short_code.h

8
src/klotski_core/common_code/common_code.cc

@ -1,6 +1,8 @@
#include "common.h" #include "common.h"
#include "common_code.h" #include "common_code.h"
using klotski::CommonCode;
namespace std { namespace std {
template<> template<>
struct hash<klotski::CommonCode> { struct hash<klotski::CommonCode> {
@ -18,6 +20,10 @@ namespace std {
} }
namespace klotski { namespace klotski {
bool CommonCode::operator==(uint64_t common_code) const {
return this->code == common_code;
}
bool CommonCode::operator==(const CommonCode &common_code) const { bool CommonCode::operator==(const CommonCode &common_code) const {
return this->code == common_code.code; return this->code == common_code.code;
} }
@ -53,7 +59,7 @@ namespace klotski {
} }
} }
bool klotski::CommonCode::check(uint64_t common_code) { // whether common code is valid bool CommonCode::check(uint64_t common_code) { // whether common code is valid
/// M_1x1 M_1x2 M_2x1 M_2x2 /// M_1x1 M_1x2 M_2x1 M_2x2
/// 1 0 0 0 1 1 0 0 1 0 0 0 1 1 0 0 /// 1 0 0 0 1 1 0 0 1 0 0 0 1 1 0 0
/// 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 /// 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0

25
src/klotski_core/common_code/common_code.h

@ -59,8 +59,7 @@
#include "short_code.h" #include "short_code.h"
namespace klotski { namespace klotski {
// import for convert interface class RawCode; // import for convert interface
class RawCode;
class ShortCode; class ShortCode;
class CommonCodeException : public std::runtime_error { class CommonCodeException : public std::runtime_error {
@ -71,11 +70,19 @@ namespace klotski {
}; };
class CommonCode { class CommonCode {
uint64_t code;
CommonCode() = default; // unsafe initialize
static inline uint64_t string_decode(const std::string &common_code);
static inline std::string string_encode(uint64_t common_code, bool shorten);
public: public:
/// CommonCode validity check
bool valid() const; bool valid() const;
static bool check(uint64_t common_code); static bool check(uint64_t common_code);
/// Operators of CommonCode /// Operators of CommonCode
bool operator==(uint64_t common_code) const;
bool operator==(const CommonCode &common_code) const; bool operator==(const CommonCode &common_code) const;
constexpr explicit operator uint64_t() const { return code; } constexpr explicit operator uint64_t() const { return code; }
friend std::ostream& operator<<(std::ostream &out, const CommonCode &self); friend std::ostream& operator<<(std::ostream &out, const CommonCode &self);
@ -88,24 +95,28 @@ namespace klotski {
/// CommonCode constructors /// CommonCode constructors
explicit CommonCode(uint64_t common_code); explicit CommonCode(uint64_t common_code);
explicit CommonCode(RawCode &&raw_code);
explicit CommonCode(ShortCode &&short_code);
explicit CommonCode(std::string &&common_code);
explicit CommonCode(const RawCode &raw_code); explicit CommonCode(const RawCode &raw_code);
explicit CommonCode(const ShortCode &short_code); explicit CommonCode(const ShortCode &short_code);
explicit CommonCode(const std::string &common_code); explicit CommonCode(const std::string &common_code);
/// Rust-style initialization /// Static initialization
static CommonCode create(uint64_t common_code); static CommonCode create(uint64_t common_code);
static CommonCode unsafe_create(uint64_t common_code); static CommonCode unsafe_create(uint64_t common_code);
static CommonCode from_string(std::string &&common_code);
static CommonCode from_string(const std::string &common_code); static CommonCode from_string(const std::string &common_code);
static CommonCode from_raw_code(uint64_t raw_code); static CommonCode from_raw_code(uint64_t raw_code);
static CommonCode from_raw_code(RawCode &&raw_code);
static CommonCode from_raw_code(const RawCode &raw_code); static CommonCode from_raw_code(const RawCode &raw_code);
static CommonCode from_short_code(uint32_t short_code); static CommonCode from_short_code(uint32_t short_code);
static CommonCode from_short_code(ShortCode &&short_code);
static CommonCode from_short_code(std::string &&short_code);
static CommonCode from_short_code(const ShortCode &short_code); static CommonCode from_short_code(const ShortCode &short_code);
static CommonCode from_short_code(const std::string &short_code); static CommonCode from_short_code(const std::string &short_code);
private:
uint64_t code;
CommonCode() = default; // unsafe initialize
}; };
} }

40
src/klotski_core/common_code/convert.cc

@ -4,34 +4,62 @@ using klotski::RawCode;
using klotski::ShortCode; using klotski::ShortCode;
using klotski::CommonCode; using klotski::CommonCode;
/// CommonCode to RawCode /// -------------------------- CommonCode to RawCode --------------------------
RawCode CommonCode::to_raw_code() const { RawCode CommonCode::to_raw_code() const {
return RawCode(*this); // convert to raw code return RawCode(*this); // convert to raw code
} }
/// CommonCode to ShortCode /// ------------------------- CommonCode to ShortCode -------------------------
ShortCode CommonCode::to_short_code() const { ShortCode CommonCode::to_short_code() const {
return ShortCode(*this); // convert to short code return ShortCode(*this); // convert to short code
} }
/// RawCode to CommonCode /// -------------------------- RawCode to CommonCode --------------------------
CommonCode CommonCode::from_raw_code(uint64_t raw_code) { CommonCode CommonCode::from_raw_code(uint64_t raw_code) {
return RawCode(raw_code).to_common_code(); return RawCode(raw_code).to_common_code();
} }
CommonCode CommonCode::from_raw_code(RawCode &&raw_code) {
return raw_code.to_common_code();
}
CommonCode CommonCode::from_raw_code(const RawCode &raw_code) { CommonCode CommonCode::from_raw_code(const RawCode &raw_code) {
return raw_code.to_common_code(); return raw_code.to_common_code();
} }
CommonCode::CommonCode(RawCode &&raw_code) {
code = raw_code.to_common_code().code; // convert from raw code
}
CommonCode::CommonCode(const RawCode &raw_code) { CommonCode::CommonCode(const RawCode &raw_code) {
code = raw_code.to_common_code().code; // convert from raw code code = raw_code.to_common_code().code; // convert from raw code
} }
/// ShortCode to CommonCode /// ------------------------- ShortCode to CommonCode -------------------------
CommonCode::CommonCode(ShortCode &&short_code) {
code = short_code.to_common_code().code; // convert from short code
}
CommonCode::CommonCode(const ShortCode &short_code) {
code = short_code.to_common_code().code; // convert from short code
}
CommonCode CommonCode::from_short_code(uint32_t short_code) { CommonCode CommonCode::from_short_code(uint32_t short_code) {
return ShortCode(short_code).to_common_code(); return ShortCode(short_code).to_common_code();
} }
CommonCode CommonCode::from_short_code(ShortCode &&short_code) {
return short_code.to_common_code();
}
CommonCode CommonCode::from_short_code(std::string &&short_code) {
return ShortCode(std::forward<std::string>(short_code)).to_common_code();
}
CommonCode CommonCode::from_short_code(const ShortCode &short_code) { CommonCode CommonCode::from_short_code(const ShortCode &short_code) {
return short_code.to_common_code(); return short_code.to_common_code();
} }
@ -39,7 +67,3 @@ CommonCode CommonCode::from_short_code(const ShortCode &short_code) {
CommonCode CommonCode::from_short_code(const std::string &short_code) { CommonCode CommonCode::from_short_code(const std::string &short_code) {
return ShortCode(short_code).to_common_code(); return ShortCode(short_code).to_common_code();
} }
CommonCode::CommonCode(const ShortCode &short_code) {
code = short_code.to_common_code().code; // convert from short code
}

44
src/klotski_core/common_code/serialize.cc

@ -3,6 +3,32 @@
using klotski::CommonCode; using klotski::CommonCode;
using klotski::CommonCodeException; using klotski::CommonCodeException;
/// -------------------------- CommonCode to String ---------------------------
std::string CommonCode::to_string(bool shorten) const {
return string_encode(code, shorten);
}
/// -------------------------- String to CommonCode ---------------------------
CommonCode::CommonCode(std::string &&common_code) {
code = string_decode(common_code); // load from string
}
CommonCode::CommonCode(const std::string &common_code) {
code = string_decode(common_code); // load from string
}
CommonCode CommonCode::from_string(std::string &&common_code) {
return CommonCode(std::forward<std::string>(common_code));
}
CommonCode CommonCode::from_string(const std::string &common_code) {
return CommonCode(common_code);
}
/// ----------------------------- Basic Functions -----------------------------
inline uint8_t binary_count(uint32_t bin) { // get number of non-zero bits inline uint8_t binary_count(uint32_t bin) { // get number of non-zero bits
bin -= (bin >> 1) & 0x55'55'55'55; bin -= (bin >> 1) & 0x55'55'55'55;
bin = (bin & 0x33'33'33'33) + ((bin >> 2) & 0x33'33'33'33); bin = (bin & 0x33'33'33'33) + ((bin >> 2) & 0x33'33'33'33);
@ -18,28 +44,25 @@ inline uint8_t last_zero_num(uint32_t bin) { // get last zero number
return binary_count(bin >> 1); return binary_count(bin >> 1);
} }
CommonCode CommonCode::from_string(const std::string &common_code) { std::string CommonCode::string_encode(uint64_t common_code, bool shorten) { // convert uint64_t code to string
return CommonCode(common_code); // load from string
}
std::string CommonCode::to_string(bool shorten) const { // convert uint64_t code to string
char result[10]; // max length 9-bits char result[10]; // max length 9-bits
sprintf(result, "%09lX", code); sprintf(result, "%09lX", common_code);
if (shorten) { // remove `0` after common code if (shorten) { // remove `0` after common code
if ((uint32_t)code == 0x00'00'00'00) { // low 32-bits are zero if ((uint32_t)common_code == 0x00'00'00'00) { // low 32-bits are zero
result[1] = '\0'; // only keep first character result[1] = '\0'; // only keep first character
return result; return result;
} }
result[9 - last_zero_num(code) / 4] = '\0'; // truncate string result[9 - last_zero_num(common_code) / 4] = '\0'; // truncate string
} }
return result; // char* -> std::string return result; // char* -> std::string
} }
CommonCode::CommonCode(const std::string &common_code) { // convert from 1 ~ 9 bits string uint64_t CommonCode::string_decode(const std::string &common_code) { // convert from 1 ~ 9 bits string
/// check string length /// check string length
if (common_code.length() > 9 || common_code.empty()) { // check string length if (common_code.length() > 9 || common_code.empty()) { // check string length
throw CommonCodeException("common code should length 1 ~ 9"); throw CommonCodeException("common code should length 1 ~ 9");
} }
/// check every characters /// check every characters
uint64_t result = 0; uint64_t result = 0;
for (auto const &bit : common_code) { for (auto const &bit : common_code) {
@ -55,9 +78,10 @@ CommonCode::CommonCode(const std::string &common_code) { // convert from 1 ~ 9 b
} }
} }
result <<= (9 - common_code.length()) * 4; // low-bits fill with zero result <<= (9 - common_code.length()) * 4; // low-bits fill with zero
/// check whether common code is valid /// check whether common code is valid
if (!CommonCode::check(result)) { // check converted common code if (!CommonCode::check(result)) { // check converted common code
throw CommonCodeException("common code invalid"); throw CommonCodeException("common code invalid");
} }
code = result; return result;
} }

12
src/klotski_core/raw_code/convert.cc

@ -5,18 +5,20 @@ using klotski::RawCode;
using klotski::CommonCode; using klotski::CommonCode;
using klotski::RawCodeException; using klotski::RawCodeException;
/// RawCode to CommonCode /// -------------------------- RawCode to CommonCode --------------------------
CommonCode RawCode::to_common_code() const { CommonCode RawCode::to_common_code() const {
return CommonCode::unsafe_create(RawCode::compact(code)); return CommonCode::unsafe_create(RawCode::compact(code));
} }
/// CommonCode to RawCode /// -------------------------- CommonCode to RawCode --------------------------
RawCode::RawCode(CommonCode &&common_code) { RawCode::RawCode(CommonCode &&common_code) {
code = RawCode::extract(common_code.unwrap()); code = RawCode::extract(common_code.unwrap()); // convert from common code
} }
RawCode::RawCode(const CommonCode &common_code) { RawCode::RawCode(const CommonCode &common_code) {
code = RawCode::extract(common_code.unwrap()); code = RawCode::extract(common_code.unwrap()); // convert from common code
} }
RawCode RawCode::from_common_code(uint64_t common_code) { RawCode RawCode::from_common_code(uint64_t common_code) {
@ -39,6 +41,8 @@ RawCode RawCode::from_common_code(const std::string &common_code) {
return RawCode(CommonCode(common_code)); return RawCode(CommonCode(common_code));
} }
/// ----------------------------- Basic Functions -----------------------------
/// NOTE: ensure that input raw code is valid! /// NOTE: ensure that input raw code is valid!
uint64_t RawCode::compact(uint64_t raw_code) { // raw code --> common code uint64_t RawCode::compact(uint64_t raw_code) { // raw code --> common code
int unfilled = 16; int unfilled = 16;

29
src/klotski_core/raw_code/mirror.cc

@ -4,15 +4,11 @@ using klotski::RawCode;
/// Mirror convert functions /// Mirror convert functions
RawCode RawCode::to_vertical_mirror() const { RawCode RawCode::to_vertical_mirror() const {
return RawCode::unsafe_create(vertical_mirror(code));
// TODO: vertical mirror convert
} }
RawCode RawCode::to_horizontal_mirror() const { RawCode RawCode::to_horizontal_mirror() const {
return RawCode::unsafe_create(horizontal_mirror(code));
// TODO: horizontal mirror convert
} }
/// Mirror check functions /// Mirror check functions
@ -20,34 +16,55 @@ bool RawCode::is_vertical_mirror() const {
// TODO: vertical mirror check // TODO: vertical mirror check
return false;
} }
bool RawCode::is_horizontal_mirror() const { bool RawCode::is_horizontal_mirror() const {
// TODO: horizontal mirror check // TODO: horizontal mirror check
return false;
} }
bool RawCode::is_vertical_mirror(RawCode &&raw_code) const { bool RawCode::is_vertical_mirror(RawCode &&raw_code) const {
// TODO: vertical mirror check // TODO: vertical mirror check
return false;
} }
bool RawCode::is_vertical_mirror(const RawCode &raw_code) const { bool RawCode::is_vertical_mirror(const RawCode &raw_code) const {
// TODO: vertical mirror check // TODO: vertical mirror check
return false;
} }
bool RawCode::is_horizontal_mirror(RawCode &&raw_code) const { bool RawCode::is_horizontal_mirror(RawCode &&raw_code) const {
// TODO: horizontal mirror check // TODO: horizontal mirror check
return false;
} }
bool RawCode::is_horizontal_mirror(const RawCode &raw_code) const { bool RawCode::is_horizontal_mirror(const RawCode &raw_code) const {
// TODO: horizontal mirror check // TODO: horizontal mirror check
return false;
}
/// Basic mirror convert
uint64_t RawCode::vertical_mirror(uint64_t raw_code) {
// TODO: vertical mirror convert
return 0;
}
uint64_t RawCode::horizontal_mirror(uint64_t raw_code) {
// TODO: horizontal mirror convert
return 0;
} }

3
src/klotski_core/raw_code/raw_code.h

@ -60,6 +60,9 @@ namespace klotski {
static uint64_t compact(uint64_t raw_code); // raw code -> common code static uint64_t compact(uint64_t raw_code); // raw code -> common code
static uint64_t extract(uint64_t common_code); // common code -> raw code static uint64_t extract(uint64_t common_code); // common code -> raw code
static uint64_t vertical_mirror(uint64_t raw_code); // to vertical mirror
static uint64_t horizontal_mirror(uint64_t raw_code); // to horizontal mirror
public: public:
/// RawCode validity check /// RawCode validity check
bool valid() const; bool valid() const;

8
src/klotski_core/short_code/convert.cc

@ -9,7 +9,8 @@
using klotski::ShortCode; using klotski::ShortCode;
using klotski::CommonCode; using klotski::CommonCode;
/// ShortCode to CommonCode /// ------------------------- ShortCode to CommonCode -------------------------
CommonCode ShortCode::to_common_code() const { CommonCode ShortCode::to_common_code() const {
if (ShortCode::mode() == ShortCode::NORMAL) { if (ShortCode::mode() == ShortCode::NORMAL) {
return CommonCode::unsafe_create(tiny_decode(code)); // normal mode return CommonCode::unsafe_create(tiny_decode(code)); // normal mode
@ -17,7 +18,8 @@ CommonCode ShortCode::to_common_code() const {
return CommonCode::unsafe_create(fast_decode(code)); // fast mode return CommonCode::unsafe_create(fast_decode(code)); // fast mode
} }
/// CommonCode to ShortCode /// ------------------------- ShortCode to CommonCode -------------------------
ShortCode::ShortCode(CommonCode &&common_code) { ShortCode::ShortCode(CommonCode &&common_code) {
if (ShortCode::mode() == ShortCode::NORMAL) { if (ShortCode::mode() == ShortCode::NORMAL) {
code = tiny_encode(common_code.unwrap()); // normal mode code = tiny_encode(common_code.unwrap()); // normal mode
@ -54,6 +56,8 @@ ShortCode ShortCode::from_common_code(const std::string &common_code) {
return ShortCode(CommonCode(common_code)); return ShortCode(CommonCode(common_code));
} }
/// ----------------------------- Basic Functions -----------------------------
/// NOTE: ensure that input common code is valid! /// NOTE: ensure that input common code is valid!
uint32_t ShortCode::fast_encode(uint64_t common_code) { // common code --> short code uint32_t ShortCode::fast_encode(uint64_t common_code) { // common code --> short code
auto head = common_code >> 32; // head index auto head = common_code >> 32; // head index

27
src/klotski_core/short_code/serialize.cc

@ -4,19 +4,14 @@
using klotski::ShortCode; using klotski::ShortCode;
using klotski::ShortCodeException; using klotski::ShortCodeException;
/// ShortCode to String /// --------------------------- ShortCode to String ---------------------------
std::string ShortCode::to_string() const { // encode as 5-bits string std::string ShortCode::to_string() const { // encode as 5-bits string
uint32_t short_code = code; return string_encode(code);
char result[6]; // short code length 5
result[5] = '\0'; // string ending flag
for (int n = 0; n < 5; ++n) {
result[4 - n] = SHORT_CODE_TABLE[short_code & 0b11111]; // aka _ % 32
short_code >>= 5; // aka _ / 32
}
return result;
} }
/// String to ShortCode /// --------------------------- String to ShortCode ---------------------------
ShortCode::ShortCode(std::string &&short_code) { ShortCode::ShortCode(std::string &&short_code) {
code = string_decode(short_code); code = string_decode(short_code);
} }
@ -33,6 +28,18 @@ ShortCode ShortCode::from_string(const std::string &short_code) {
return ShortCode(short_code); return ShortCode(short_code);
} }
/// ----------------------------- Basic Functions -----------------------------
std::string klotski::ShortCode::string_encode(uint32_t short_code) { // encode as 5-bits string
char result[6]; // short code length 5
result[5] = '\0'; // string ending flag
for (int n = 0; n < 5; ++n) {
result[4 - n] = SHORT_CODE_TABLE[short_code & 0b11111]; // aka _ % 32
short_code >>= 5; // aka _ / 32
}
return result;
}
uint32_t ShortCode::string_decode(const std::string &short_code) { // 5-bits string decode uint32_t ShortCode::string_decode(const std::string &short_code) { // 5-bits string decode
if (short_code.length() != 5) { // check string length if (short_code.length() != 5) { // check string length
throw ShortCodeException("short code should length 5"); throw ShortCodeException("short code should length 5");

10
src/klotski_core/short_code/short_code.cc

@ -1,6 +1,11 @@
#include "all_cases.h" #include "all_cases.h"
#include "short_code.h" #include "short_code.h"
using klotski::ShortCode;
bool ShortCode::fast_mode_available = false;
bool ShortCode::normal_mode_available = false;
namespace std { namespace std {
template<> template<>
struct hash<klotski::ShortCode> { struct hash<klotski::ShortCode> {
@ -55,11 +60,6 @@ namespace klotski {
} }
} }
using klotski::ShortCode;
bool ShortCode::fast_mode_available = false;
bool ShortCode::normal_mode_available = false;
bool ShortCode::check(uint32_t short_code) { bool ShortCode::check(uint32_t short_code) {
return short_code < klotski::SHORT_CODE_LIMIT; // 0 ~ (SHORT_CODE_LIMIT - 1) return short_code < klotski::SHORT_CODE_LIMIT; // 0 ~ (SHORT_CODE_LIMIT - 1)
} }

3
src/klotski_core/short_code/short_code.h

@ -85,7 +85,8 @@ namespace klotski {
static uint64_t tiny_decode(uint32_t short_code); // short code -> common code static uint64_t tiny_decode(uint32_t short_code); // short code -> common code
static uint32_t tiny_encode(uint64_t common_code); // common code -> short code static uint32_t tiny_encode(uint64_t common_code); // common code -> short code
static uint32_t string_decode(const std::string &short_code); // string -> short code static inline std::string string_encode(uint32_t short_code); // short code -> string
static inline uint32_t string_decode(const std::string &short_code); // string -> short code
public: public:
/// ShortCode validity check /// ShortCode validity check

Loading…
Cancel
Save