diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 51d599a..50268c9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -37,7 +37,7 @@ set(KLOTSKI_CORE_SRC add_library(klotski_core STATIC ${KLOTSKI_CORE_SRC}) target_compile_options(klotski_core PRIVATE -fno-rtti -fno-exceptions) # option for `-fvisibility=hidden` target_include_directories(klotski_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(klotski_core PRIVATE absl::flat_hash_map) +target_link_libraries(klotski_core PRIVATE absl::flat_hash_map phmap) add_library(klotski::core ALIAS klotski_core) # TODO: just for dev testing diff --git a/src/core/fast_cal/internal/demo.cc b/src/core/fast_cal/internal/demo.cc index 528f97f..8f20020 100644 --- a/src/core/fast_cal/internal/demo.cc +++ b/src/core/fast_cal/internal/demo.cc @@ -4,7 +4,15 @@ #include -#include +//#include + +//#include +//#define PHMAP_USE_ABSL_HASH + +//#include +//#include +//#include +#include #include "mover/mover.h" #include "group/group.h" @@ -23,46 +31,91 @@ struct data_t { // TODO: try wrapper as custom `std::queue` +template +class MyQueue { +public: + explicit MyQueue(size_t reserve) { +// vec_.reserve(reserve); + vec_.resize(reserve); + } + + void emplace_back(T item) { +// vec_.emplace_back(item); + vec_[iter_] = item; + ++iter_; + } + + T front() { + return vec_[offset_]; + } + + void pop() { + ++offset_; + } + + bool empty() { + return offset_ == iter_; + } + +private: + size_t iter_ {0}; + size_t offset_ {0}; + std::vector vec_ {}; +}; + class FCDemo { public: - explicit FCDemo(RawCode raw_code) { + explicit FCDemo(RawCode raw_code) : codes_(GroupUnion::from_raw_code(raw_code).max_group_size()) { auto reserve = GroupUnion::from_raw_code(raw_code).max_group_size(); - codes_.reserve(reserve); +// codes_.reserve(reserve); cases_.reserve(reserve); - codes_.emplace_back(raw_code); + codes_.emplace_back(raw_code.unwrap()); cases_.emplace(raw_code, data_t {0, 0}); // without mask } RawCode DoCal() { -// bool stop_flag = false; uint64_t result = 0; auto core = MaskMover([this, &result](uint64_t code, uint64_t mask) { if (const auto match = cases_.find(code); match != cases_.end()) { match->second.mask |= mask; // update mask +// match.value().mask |= mask; // update mask return; } cases_.emplace(code, data_t { .mask = mask, - .back = codes_[offset_].unwrap(), + .back = codes_.front(), +// .back = codes_[offset_].unwrap(), }); - codes_.emplace_back(RawCode::unsafe_create(code)); + codes_.emplace_back(code); if (((code >> 39) & 0b111) == 0b100) { -// stop_flag = true; result = code; } }); - while (offset_ != codes_.size()) { - auto curr = codes_[offset_].unwrap(); + while (!codes_.empty()) { + auto curr = codes_.front(); core.next_cases(curr, cases_.find(curr)->second.mask); - ++offset_; + codes_.pop(); if (result != 0) { - break; + return RawCode::unsafe_create(result); } + } + return RawCode::unsafe_create(0); + +// while (offset_ != codes_.size()) { +// auto curr = codes_[offset_].unwrap(); +// core.next_cases(curr, cases_.find(curr)->second.mask); +// ++offset_; +// +// if (result != 0) { +// break; +// } +// } + // std::vector path; // auto code = result; // while (true) { @@ -78,89 +131,20 @@ public: // } // std::cout << path.size() << std::endl; - return codes_[offset_]; +// return codes_[offset_]; } private: - uint64_t offset_ {0}; - std::vector codes_; - absl::flat_hash_map cases_; // +// uint64_t offset_ {0}; + MyQueue codes_; +// absl::flat_hash_map cases_; // +// robin_hood::unordered_map cases_; +// ankerl::unordered_dense::map cases_; +// tsl::robin_map cases_; + phmap::flat_hash_map cases_; }; RawCode FastCal_demo(RawCode raw_code) { - FCDemo fc {raw_code}; return fc.DoCal(); - -// std::queue cache; - std::vector codes; - absl::flat_hash_map cases; // - auto reserve = GroupUnion::from_raw_code(raw_code).max_group_size(); - codes.reserve(reserve); - cases.reserve(reserve); - - uint64_t offset = 0; - bool stop_flag = false; - auto core = MaskMover([&codes, &cases, &offset, &stop_flag](uint64_t code, uint64_t mask) { - if (const auto match = cases.find(code); match != cases.end()) { - match->second.mask |= mask; // update mask - return; - } - cases.emplace(code, data_t { - .mask = mask, - .back = codes[offset].unwrap(), -// .back = cache.front().unwrap(), - }); - codes.emplace_back(RawCode::unsafe_create(code)); -// cache.emplace(RawCode::unsafe_create(code)); - if (((code >> 39) & 0b111) == 0b100) { - stop_flag = true; - } - }); - - codes.emplace_back(raw_code); -// cache.emplace(raw_code); - cases.emplace(raw_code, data_t {0, 0}); // without mask - - while (offset != codes.size()) { - auto curr = codes[offset].unwrap(); - core.next_cases(curr, cases.find(curr)->second.mask); - ++offset; - - if (stop_flag) { - break; - } - - } - -// while (!cache.empty()) { -// if (((cache.front().unwrap() >> 39) & 0b111) == 0b100) { -// break; -// } -// uint64_t curr = cache.front().unwrap(); -// core.next_cases(curr, cases.find(curr)->second.mask); -// cache.pop(); -// if (stop_flag) { -// break; -// } -// } - -// std::vector path; -// auto code = cache.front().unwrap(); -// while (true) { -// if (code == 0) { -// break; -// } -// path.emplace_back(RawCode::unsafe_create(code)); -// code = cases.find(code)->second.back; -// } -// std::reverse(path.begin(), path.end()); -// for (auto step : path) { -// std::cout << step << std::endl; -// } -// std::cout << path.size() << std::endl; - - return codes[offset]; -// return cache.front(); - }