Browse Source

perf: codec source structure

master
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_code.h"
using klotski::CommonCode;
namespace std {
template<>
struct hash<klotski::CommonCode> {
@ -18,6 +20,10 @@ namespace std {
}
namespace klotski {
bool CommonCode::operator==(uint64_t common_code) const {
return this->code == common_code;
}
bool CommonCode::operator==(const CommonCode &common_code) const {
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
/// 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

25
src/klotski_core/common_code/common_code.h

@ -59,8 +59,7 @@
#include "short_code.h"
namespace klotski {
// import for convert interface
class RawCode;
class RawCode; // import for convert interface
class ShortCode;
class CommonCodeException : public std::runtime_error {
@ -71,11 +70,19 @@ namespace klotski {
};
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:
/// CommonCode validity check
bool valid() const;
static bool check(uint64_t common_code);
/// Operators of CommonCode
bool operator==(uint64_t common_code) const;
bool operator==(const CommonCode &common_code) const;
constexpr explicit operator uint64_t() const { return code; }
friend std::ostream& operator<<(std::ostream &out, const CommonCode &self);
@ -88,24 +95,28 @@ namespace klotski {
/// CommonCode constructors
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 ShortCode &short_code);
explicit CommonCode(const std::string &common_code);
/// Rust-style initialization
/// Static initialization
static CommonCode 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_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_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 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::CommonCode;
/// CommonCode to RawCode
/// -------------------------- CommonCode to RawCode --------------------------
RawCode CommonCode::to_raw_code() const {
return RawCode(*this); // convert to raw code
}
/// CommonCode to ShortCode
/// ------------------------- CommonCode to ShortCode -------------------------
ShortCode CommonCode::to_short_code() const {
return ShortCode(*this); // convert to short code
}
/// RawCode to CommonCode
/// -------------------------- RawCode to CommonCode --------------------------
CommonCode CommonCode::from_raw_code(uint64_t raw_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) {
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) {
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) {
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) {
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) {
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::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
bin -= (bin >> 1) & 0x55'55'55'55;
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);
}
CommonCode CommonCode::from_string(const std::string &common_code) {
return CommonCode(common_code); // load from string
}
std::string CommonCode::to_string(bool shorten) const { // convert uint64_t code to string
std::string CommonCode::string_encode(uint64_t common_code, bool shorten) { // convert uint64_t code to string
char result[10]; // max length 9-bits
sprintf(result, "%09lX", code);
sprintf(result, "%09lX", 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
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
}
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
if (common_code.length() > 9 || common_code.empty()) { // check string length
throw CommonCodeException("common code should length 1 ~ 9");
}
/// check every characters
uint64_t result = 0;
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
/// check whether common code is valid
if (!CommonCode::check(result)) { // check converted common code
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::RawCodeException;
/// RawCode to CommonCode
/// -------------------------- RawCode to CommonCode --------------------------
CommonCode RawCode::to_common_code() const {
return CommonCode::unsafe_create(RawCode::compact(code));
}
/// CommonCode to RawCode
/// -------------------------- CommonCode to RawCode --------------------------
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) {
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) {
@ -39,6 +41,8 @@ RawCode RawCode::from_common_code(const std::string &common_code) {
return RawCode(CommonCode(common_code));
}
/// ----------------------------- Basic Functions -----------------------------
/// NOTE: ensure that input raw code is valid!
uint64_t RawCode::compact(uint64_t raw_code) { // raw code --> common code
int unfilled = 16;

29
src/klotski_core/raw_code/mirror.cc

@ -4,15 +4,11 @@ using klotski::RawCode;
/// Mirror convert functions
RawCode RawCode::to_vertical_mirror() const {
// TODO: vertical mirror convert
return RawCode::unsafe_create(vertical_mirror(code));
}
RawCode RawCode::to_horizontal_mirror() const {
// TODO: horizontal mirror convert
return RawCode::unsafe_create(horizontal_mirror(code));
}
/// Mirror check functions
@ -20,34 +16,55 @@ bool RawCode::is_vertical_mirror() const {
// TODO: vertical mirror check
return false;
}
bool RawCode::is_horizontal_mirror() const {
// TODO: horizontal mirror check
return false;
}
bool RawCode::is_vertical_mirror(RawCode &&raw_code) const {
// TODO: vertical mirror check
return false;
}
bool RawCode::is_vertical_mirror(const RawCode &raw_code) const {
// TODO: vertical mirror check
return false;
}
bool RawCode::is_horizontal_mirror(RawCode &&raw_code) const {
// TODO: horizontal mirror check
return false;
}
bool RawCode::is_horizontal_mirror(const RawCode &raw_code) const {
// 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 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:
/// RawCode validity check
bool valid() const;

8
src/klotski_core/short_code/convert.cc

@ -9,7 +9,8 @@
using klotski::ShortCode;
using klotski::CommonCode;
/// ShortCode to CommonCode
/// ------------------------- ShortCode to CommonCode -------------------------
CommonCode ShortCode::to_common_code() const {
if (ShortCode::mode() == ShortCode::NORMAL) {
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
}
/// CommonCode to ShortCode
/// ------------------------- ShortCode to CommonCode -------------------------
ShortCode::ShortCode(CommonCode &&common_code) {
if (ShortCode::mode() == ShortCode::NORMAL) {
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));
}
/// ----------------------------- Basic Functions -----------------------------
/// NOTE: ensure that input common code is valid!
uint32_t ShortCode::fast_encode(uint64_t common_code) { // common code --> short code
auto head = common_code >> 32; // head index

27
src/klotski_core/short_code/serialize.cc

@ -4,19 +4,14 @@
using klotski::ShortCode;
using klotski::ShortCodeException;
/// ShortCode to String
/// --------------------------- ShortCode to String ---------------------------
std::string ShortCode::to_string() const { // encode as 5-bits string
uint32_t short_code = 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;
return string_encode(code);
}
/// String to ShortCode
/// --------------------------- String to ShortCode ---------------------------
ShortCode::ShortCode(std::string &&short_code) {
code = string_decode(short_code);
}
@ -33,6 +28,18 @@ ShortCode ShortCode::from_string(const std::string &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
if (short_code.length() != 5) { // check string length
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 "short_code.h"
using klotski::ShortCode;
bool ShortCode::fast_mode_available = false;
bool ShortCode::normal_mode_available = false;
namespace std {
template<>
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) {
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 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:
/// ShortCode validity check

Loading…
Cancel
Save