Browse Source

update: release lambda as template

master
Dnomd343 1 week ago
parent
commit
74b35e30ba
  1. 158
      src/core/group/internal/group.cc

158
src/core/group/internal/group.cc

@ -51,10 +51,6 @@ KLSK_NOINLINE static RangesUnion group_extend(RawCode seed, const size_t reserve
core.next_cases(curr, cases.find(curr)->second); core.next_cases(curr, cases.find(curr)->second);
} }
// std::cout << std::format("[{}, {}, {}]\n", codes.size(), mirrors.size(), cases.size());
// std::cout << std::format("{:.5f}\n", static_cast<double>(codes.size()) / reserve);
RangesUnion result {}; RangesUnion result {};
// TODO: how to reserve // TODO: how to reserve
for (auto raw_code : codes) { for (auto raw_code : codes) {
@ -88,9 +84,6 @@ static RangesUnion extend_type_ver(RawCode seed, size_t reserve) {
static RangesUnion extend_type_diag(RawCode seed, size_t reserve) { static RangesUnion extend_type_diag(RawCode seed, size_t reserve) {
return group_extend(seed, reserve, [](const RawCode code, auto callback) { return group_extend(seed, reserve, [](const RawCode code, auto callback) {
// if (const auto mirror = code.to_diagonal_mirror(); mirror != code) {
// callback(mirror);
// }
callback(code.to_diagonal_mirror()); callback(code.to_diagonal_mirror());
}); });
} }
@ -106,123 +99,102 @@ static RangesUnion extend_type_x(RawCode seed, size_t reserve) {
}); });
} }
KLSK_NOINLINE static void spawn_full_pattern(RawCode seed, const size_t reserve, RangesUnion &output) { template <typename MFunc, typename RFunc>
KLSK_NOINLINE static void spawn_pattern(RawCode seed, const size_t reserve, MFunc add_mirror, RFunc release) {
std::vector<RawCode> codes; std::vector<RawCode> codes;
std::vector<RawCode> mirrors;
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint> phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve); codes.reserve(reserve);
mirrors.reserve(reserve); // TODO: cal max size-coff
cases.reserve(static_cast<size_t>(reserve * 1.56)); cases.reserve(static_cast<size_t>(reserve * 1.56));
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t hint) { auto core = MaskMover([&codes, &cases, &mirrors, add_mirror](RawCode code, uint64_t hint) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) { if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) {
iter->second |= hint; // update hint iter->second |= hint; // update hint
return; return;
} }
codes.emplace_back(code); codes.emplace_back(code);
add_mirror(code, [&cases, &mirrors](RawCode mirror) {
cases.emplace(mirror, 0);
mirrors.emplace_back(mirror);
});
}); });
uint64_t offset = 0; uint64_t offset = 0;
codes.emplace_back(seed); codes.emplace_back(seed);
cases.emplace(seed, 0); // without hint cases.emplace(seed, 0); // without hint
add_mirror(seed, [&mirrors, &cases](RawCode mirror) {
cases.emplace(mirror, 0);
mirrors.emplace_back(mirror);
});
while (offset != codes.size()) { while (offset != codes.size()) {
const auto curr = codes[offset++]; const auto curr = codes[offset++];
core.next_cases(curr, cases.find(curr)->second); core.next_cases(curr, cases.find(curr)->second);
} }
for (auto raw_code : codes) { for (const auto code : codes) {
const auto code = raw_code.to_common_code().unwrap(); release(code);
output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
} }
for (const auto code : mirrors) {
release(code);
} }
KLSK_NOINLINE static void spawn_hor_pattern(RawCode seed, const size_t reserve, RangesUnion &output) {
std::vector<RawCode> codes;
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve);
cases.reserve(static_cast<size_t>(reserve * 1.56));
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t hint) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) {
iter->second |= hint; // update hint
return;
} }
codes.emplace_back(code);
});
uint64_t offset = 0; KLSK_NOINLINE static void spawn_full_pattern(RawCode seed, const size_t reserve, RangesUnion &output) {
codes.emplace_back(seed); spawn_pattern(seed, reserve, [](const RawCode code, auto callback) {
cases.emplace(seed, 0); // without hint // const auto mirror_1 = code.to_vertical_mirror();
while (offset != codes.size()) { // callback(mirror_1);
const auto curr = codes[offset++]; // if (const auto mirror_2 = code.to_horizontal_mirror(); mirror_2 != code) {
core.next_cases(curr, cases.find(curr)->second); // callback(mirror_2);
// callback(mirror_1.to_horizontal_mirror());
// }
}, [&output](RawCode raw_code) {
const auto code = raw_code.to_common_code().unwrap();
output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
});
} }
for (auto raw_code : codes) { KLSK_NOINLINE static void spawn_hor_pattern(RawCode seed, const size_t reserve, RangesUnion &output) {
spawn_pattern(seed, reserve, [](const RawCode code, auto callback) {
// if (const auto mirror = code.to_horizontal_mirror(); mirror != code) {
// callback(mirror);
// }
}, [&output](RawCode raw_code) {
const auto code = raw_code.to_common_code().unwrap(); const auto code = raw_code.to_common_code().unwrap();
output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code)); output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
const auto code_ = raw_code.to_vertical_mirror().to_common_code().unwrap(); const auto code_ = raw_code.to_vertical_mirror().to_common_code().unwrap();
output.ranges(code_ >> 32).emplace_back(static_cast<uint32_t>(code_)); output.ranges(code_ >> 32).emplace_back(static_cast<uint32_t>(code_));
}
}
KLSK_NOINLINE static void spawn_ver_pattern(RawCode seed, const size_t reserve, RangesUnion &output) {
std::vector<RawCode> codes;
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve);
cases.reserve(static_cast<size_t>(reserve * 1.56));
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t hint) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) {
iter->second |= hint; // update hint
return;
}
codes.emplace_back(code);
}); });
uint64_t offset = 0;
codes.emplace_back(seed);
cases.emplace(seed, 0); // without hint
while (offset != codes.size()) {
const auto curr = codes[offset++];
core.next_cases(curr, cases.find(curr)->second);
} }
for (auto raw_code : codes) { KLSK_NOINLINE static void spawn_ver_pattern(RawCode seed, const size_t reserve, RangesUnion &output) {
spawn_pattern(seed, reserve, [](const RawCode code, auto callback) {
// callback(code.to_vertical_mirror());
}, [&output](RawCode raw_code) {
const auto code = raw_code.to_common_code().unwrap(); const auto code = raw_code.to_common_code().unwrap();
output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code)); output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
const auto code_ = raw_code.to_horizontal_mirror().to_common_code().unwrap(); const auto code_ = raw_code.to_horizontal_mirror().to_common_code().unwrap();
output.ranges(code_ >> 32).emplace_back(static_cast<uint32_t>(code_)); output.ranges(code_ >> 32).emplace_back(static_cast<uint32_t>(code_));
} });
} }
KLSK_NOINLINE static void spawn_ord_pattern(RawCode seed, const size_t reserve, RangesUnion &output) { KLSK_NOINLINE static void spawn_ord_pattern(RawCode seed, const size_t reserve, RangesUnion &output) {
std::vector<RawCode> codes; spawn_pattern(seed, reserve, [](RawCode, auto) {}, [&output](RawCode raw_code) {
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve);
cases.reserve(static_cast<size_t>(reserve * 1.56));
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t hint) { // auto add_case = [&output](RawCode r_code) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) { // const auto code = r_code.to_common_code().unwrap();
iter->second |= hint; // update hint // output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
return; // };
} //
codes.emplace_back(code); // add_case(raw_code);
}); // add_case(raw_code.to_vertical_mirror());
// add_case(raw_code.to_horizontal_mirror());
uint64_t offset = 0; // add_case(raw_code.to_diagonal_mirror());
codes.emplace_back(seed);
cases.emplace(seed, 0); // without hint
while (offset != codes.size()) {
const auto curr = codes[offset++];
core.next_cases(curr, cases.find(curr)->second);
}
for (auto raw_code : codes) {
const auto code = raw_code.to_common_code().unwrap(); const auto code = raw_code.to_common_code().unwrap();
output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code)); output.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
@ -234,17 +206,10 @@ KLSK_NOINLINE static void spawn_ord_pattern(RawCode seed, const size_t reserve,
const auto code_3 = raw_code.to_diagonal_mirror().to_common_code().unwrap(); const auto code_3 = raw_code.to_diagonal_mirror().to_common_code().unwrap();
output.ranges(code_3 >> 32).emplace_back(static_cast<uint32_t>(code_3)); output.ranges(code_3 >> 32).emplace_back(static_cast<uint32_t>(code_3));
} });
} }
KLSK_NOINLINE static RangesUnion extend_pro(uint8_t type_id) { KLSK_NOINLINE static RangesUnion extend_pro(uint8_t type_id) {
// auto groups = GroupUnion::unsafe_create(type_id).groups();
// RangesUnion others {};
// for (size_t index = 1; index < groups.size(); ++index) {
// others += groups[index].cases();
// }
RangesUnion others {}; RangesUnion others {};
auto gu = GroupUnion::unsafe_create(type_id); auto gu = GroupUnion::unsafe_create(type_id);
for (int pattern_id = 1; pattern_id < gu.pattern_num(); ++pattern_id) { for (int pattern_id = 1; pattern_id < gu.pattern_num(); ++pattern_id) {
@ -260,9 +225,7 @@ KLSK_NOINLINE static RangesUnion extend_pro(uint8_t type_id) {
spawn_hor_pattern(seed, size, others); spawn_hor_pattern(seed, size, others);
} else if (mirror_type == Group::MirrorType::Vertical) { } else if (mirror_type == Group::MirrorType::Vertical) {
spawn_ver_pattern(seed, size, others); spawn_ver_pattern(seed, size, others);
} else if (mirror_type == Group::MirrorType::Centro) { } else if (mirror_type == Group::MirrorType::Ordinary) {
// std::abort();
} else {
spawn_ord_pattern(seed, size, others); spawn_ord_pattern(seed, size, others);
} }
} }
@ -270,29 +233,16 @@ KLSK_NOINLINE static RangesUnion extend_pro(uint8_t type_id) {
for (auto head : RangesUnion::Heads) { for (auto head : RangesUnion::Heads) {
std::stable_sort(others.ranges(head).begin(), others.ranges(head).end()); std::stable_sort(others.ranges(head).begin(), others.ranges(head).end());
} }
// return others;
// auto all = GroupUnion::unsafe_create(type_id).cases();
//
// RangesUnion result {};
// for (auto head : RangesUnion::Heads) {
// std::set_difference(all.ranges(head).begin(), all.ranges(head).end(),
// others.ranges(head).begin(), others.ranges(head).end(),
// std::back_inserter(result.ranges(head)));
// }
// return result;
return GroupUnion::unsafe_create(type_id).cases_without(others); return GroupUnion::unsafe_create(type_id).cases_without(others);
} }
RangesUnion Group::cases() const { RangesUnion Group::cases() const {
if (const auto gu = GroupUnion::unsafe_create(type_id_); gu.group_num() == 1) { if (const auto gu = GroupUnion::unsafe_create(type_id_); gu.group_num() == 1) {
// std::cout << "[]" << std::endl;
return gu.cases(); return gu.cases();
} }
// if (type_id_ == 89 && pattern_id_ == 0) { // for group `89-0x`
// return extend_pro(89);
// }
if (pattern_id_ == 0 && mirror_type() == MirrorType::Full) { // TODO: black-list filter if (pattern_id_ == 0 && mirror_type() == MirrorType::Full) { // TODO: black-list filter
return extend_pro(type_id_); return extend_pro(type_id_);
// return GroupUnion::unsafe_create(type_id_).cases(); // return GroupUnion::unsafe_create(type_id_).cases();

Loading…
Cancel
Save