From 5c221e7dda734bd3bcd631d8e781b8c2f42d9291 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 2 Mar 2025 15:17:42 +0800 Subject: [PATCH] update: split build process by type_id --- src/core/group/internal/group_cases.cc | 423 ++++++++++++++++--------- 1 file changed, 282 insertions(+), 141 deletions(-) diff --git a/src/core/group/internal/group_cases.cc b/src/core/group/internal/group_cases.cc index 7b8c96a..a02d915 100644 --- a/src/core/group/internal/group_cases.cc +++ b/src/core/group/internal/group_cases.cc @@ -87,183 +87,334 @@ KLSK_NOINLINE static void extend(const RawCode seed, const size_t reserve, MF ad for (const auto code : mirrors) { release(code); } } -KLSK_NOINLINE static void extend_full_pattern(RawCode seed, size_t size, RangesUnion &a) { - const auto mirror_func = [](const RawCode code, auto spawn) { - const auto m_vrt = code.to_vertical_mirror(); - spawn(m_vrt); - if (const auto m_hor = code.to_horizontal_mirror(); m_hor != code) { - spawn(m_hor); - spawn(m_vrt.to_horizontal_mirror()); - } - }; +// KLSK_NOINLINE static void extend_full_pattern(RawCode seed, size_t size, RangesUnion &a) { +// const auto mirror_func = [](const RawCode code, auto spawn) { +// const auto m_vrt = code.to_vertical_mirror(); +// spawn(m_vrt); +// if (const auto m_hor = code.to_horizontal_mirror(); m_hor != code) { +// spawn(m_hor); +// spawn(m_vrt.to_horizontal_mirror()); +// } +// }; +// +// extend(seed, size, mirror_func, [&a](const RawCode raw_code) { +// const auto code = raw_code.to_common_code().unwrap(); +// a.ranges(code >> 32).emplace_back(static_cast(code)); +// }); +// +// for (auto head : RangesUnion::Heads) { +// std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); +// } +// +// } + +// KLSK_NOINLINE static void extend_hor_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &c) { +// const auto mirror_func = [](const RawCode code, auto spawn) { +// if (const auto m_hor = code.to_horizontal_mirror(); m_hor != code) { +// spawn(m_hor); +// } +// }; +// extend(seed, size, mirror_func, [&a, &c](const RawCode raw_code) { +// const auto code = raw_code.to_common_code().unwrap(); +// a.ranges(code >> 32).emplace_back(static_cast(code)); +// +// const auto code_ = raw_code.to_vertical_mirror().to_common_code().unwrap(); +// c.ranges(code_ >> 32).emplace_back(static_cast(code_)); +// }); +// +// for (auto head : RangesUnion::Heads) { +// std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); +// std::stable_sort(c.ranges(head).begin(), c.ranges(head).end()); +// } +// +// } + +// KLSK_NOINLINE static void extend_cen_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &b) { +// const auto mirror_func = [](const RawCode code, auto spawn) { +// spawn(code.to_diagonal_mirror()); +// }; +// extend(seed, size, mirror_func, [&a, &b](const RawCode raw_code) { +// const auto code = raw_code.to_common_code().unwrap(); +// a.ranges(code >> 32).emplace_back(static_cast(code)); +// +// const auto code_ = raw_code.to_horizontal_mirror().to_common_code().unwrap(); +// b.ranges(code_ >> 32).emplace_back(static_cast(code_)); +// }); +// +// for (auto head : RangesUnion::Heads) { +// std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); +// std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); +// } +// } + +// KLSK_NOINLINE static void extend_ver_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &b) { +// const auto mirror_func = [](const RawCode code, auto spawn) { +// spawn(code.to_vertical_mirror()); +// }; +// extend(seed, size, mirror_func, [&a, &b](const RawCode raw_code) { +// const auto code = raw_code.to_common_code().unwrap(); +// a.ranges(code >> 32).emplace_back(static_cast(code)); +// +// const auto code_ = raw_code.to_horizontal_mirror().to_common_code().unwrap(); +// b.ranges(code_ >> 32).emplace_back(static_cast(code_)); +// }); +// +// for (auto head : RangesUnion::Heads) { +// std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); +// std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); +// } +// } + +// KLSK_NOINLINE static void extend_ord_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &b, RangesUnion &c, RangesUnion &d) { +// extend(seed, size, NO_MIRROR, [&a, &b, &c, &d](const RawCode raw_code) { +// const auto code = raw_code.to_common_code().unwrap(); +// a.ranges(code >> 32).emplace_back(static_cast(code)); +// +// const auto code_1 = raw_code.to_horizontal_mirror().to_common_code().unwrap(); +// b.ranges(code_1 >> 32).emplace_back(static_cast(code_1)); +// +// const auto code_2 = raw_code.to_vertical_mirror().to_common_code().unwrap(); +// c.ranges(code_2 >> 32).emplace_back(static_cast(code_2)); +// +// const auto code_3 = raw_code.to_diagonal_mirror().to_common_code().unwrap(); +// d.ranges(code_3 >> 32).emplace_back(static_cast(code_3)); +// }); +// +// for (auto head : RangesUnion::Heads) { +// std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); +// std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); +// std::stable_sort(c.ranges(head).begin(), c.ranges(head).end()); +// std::stable_sort(d.ranges(head).begin(), d.ranges(head).end()); +// } +// } + +template +// static void extend_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &b, RangesUnion &c, RangesUnion &d) { +static void extend_pattern(RawCode seed, size_t size, RangesUnion *kk) { + + RangesUnion &a = kk[0]; + RangesUnion &b = kk[1]; + RangesUnion &c = kk[2]; + RangesUnion &d = kk[3]; + + if constexpr(TYPE == Group::MirrorType::Full) { + + const auto mirror_func = [](const RawCode code, auto spawn) { + const auto m_vrt = code.to_vertical_mirror(); + spawn(m_vrt); + if (const auto m_hor = code.to_horizontal_mirror(); m_hor != code) { + spawn(m_hor); + spawn(m_vrt.to_horizontal_mirror()); + } + }; - extend(seed, size, mirror_func, [&a](const RawCode raw_code) { - const auto code = raw_code.to_common_code().unwrap(); - a.ranges(code >> 32).emplace_back(static_cast(code)); - }); + // RangesUnion &a = kk[0]; + extend(seed, size, mirror_func, [&a](const RawCode raw_code) { + const auto code = raw_code.to_common_code().unwrap(); + a.ranges(code >> 32).emplace_back(static_cast(code)); + }); + + // for (auto head : RangesUnion::Heads) { + // std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); + // } - for (auto head : RangesUnion::Heads) { - std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); } -} + if constexpr(TYPE == Group::MirrorType::Horizontal) { -KLSK_NOINLINE static void extend_hor_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &c) { - const auto mirror_func = [](const RawCode code, auto spawn) { - if (const auto m_hor = code.to_horizontal_mirror(); m_hor != code) { - spawn(m_hor); - } - }; - extend(seed, size, mirror_func, [&a, &c](const RawCode raw_code) { - const auto code = raw_code.to_common_code().unwrap(); - a.ranges(code >> 32).emplace_back(static_cast(code)); + const auto mirror_func = [](const RawCode code, auto spawn) { + if (const auto m_hor = code.to_horizontal_mirror(); m_hor != code) { + spawn(m_hor); + } + }; - const auto code_ = raw_code.to_vertical_mirror().to_common_code().unwrap(); - c.ranges(code_ >> 32).emplace_back(static_cast(code_)); - }); + // RangesUnion &a = kk[0]; + // RangesUnion &c = kk[2]; + extend(seed, size, mirror_func, [&a, &c](const RawCode raw_code) { + const auto code = raw_code.to_common_code().unwrap(); + a.ranges(code >> 32).emplace_back(static_cast(code)); + + const auto code_ = raw_code.to_vertical_mirror().to_common_code().unwrap(); + c.ranges(code_ >> 32).emplace_back(static_cast(code_)); + }); + + // for (auto head : RangesUnion::Heads) { + // std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); + // std::stable_sort(c.ranges(head).begin(), c.ranges(head).end()); + // } - for (auto head : RangesUnion::Heads) { - std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); - std::stable_sort(c.ranges(head).begin(), c.ranges(head).end()); } -} + if constexpr(TYPE == Group::MirrorType::Centro) { -KLSK_NOINLINE static void extend_cen_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &b) { - const auto mirror_func = [](const RawCode code, auto spawn) { - spawn(code.to_diagonal_mirror()); - }; - extend(seed, size, mirror_func, [&a, &b](const RawCode raw_code) { - const auto code = raw_code.to_common_code().unwrap(); - a.ranges(code >> 32).emplace_back(static_cast(code)); + const auto mirror_func = [](const RawCode code, auto spawn) { + spawn(code.to_diagonal_mirror()); + }; + // RangesUnion &a = kk[0]; + // RangesUnion &b = kk[1]; + extend(seed, size, mirror_func, [&a, &b](const RawCode raw_code) { + const auto code = raw_code.to_common_code().unwrap(); + a.ranges(code >> 32).emplace_back(static_cast(code)); - const auto code_ = raw_code.to_horizontal_mirror().to_common_code().unwrap(); - b.ranges(code_ >> 32).emplace_back(static_cast(code_)); - }); + const auto code_ = raw_code.to_horizontal_mirror().to_common_code().unwrap(); + b.ranges(code_ >> 32).emplace_back(static_cast(code_)); + }); + + // for (auto head : RangesUnion::Heads) { + // std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); + // std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); + // } - for (auto head : RangesUnion::Heads) { - std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); - std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); } -} -KLSK_NOINLINE static void extend_ver_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &b) { - const auto mirror_func = [](const RawCode code, auto spawn) { - spawn(code.to_vertical_mirror()); - }; - extend(seed, size, mirror_func, [&a, &b](const RawCode raw_code) { - const auto code = raw_code.to_common_code().unwrap(); - a.ranges(code >> 32).emplace_back(static_cast(code)); + if constexpr(TYPE == Group::MirrorType::Vertical) { - const auto code_ = raw_code.to_horizontal_mirror().to_common_code().unwrap(); - b.ranges(code_ >> 32).emplace_back(static_cast(code_)); - }); + const auto mirror_func = [](const RawCode code, auto spawn) { + spawn(code.to_vertical_mirror()); + }; + // RangesUnion &a = kk[0]; + // RangesUnion &b = kk[1]; + extend(seed, size, mirror_func, [&a, &b](const RawCode raw_code) { + const auto code = raw_code.to_common_code().unwrap(); + a.ranges(code >> 32).emplace_back(static_cast(code)); + + const auto code_ = raw_code.to_horizontal_mirror().to_common_code().unwrap(); + b.ranges(code_ >> 32).emplace_back(static_cast(code_)); + }); + + // for (auto head : RangesUnion::Heads) { + // std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); + // std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); + // } - for (auto head : RangesUnion::Heads) { - std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); - std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); } -} -KLSK_NOINLINE static void extend_ord_pattern(RawCode seed, size_t size, RangesUnion &a, RangesUnion &b, RangesUnion &c, RangesUnion &d) { - extend(seed, size, NO_MIRROR, [&a, &b, &c, &d](const RawCode raw_code) { - const auto code = raw_code.to_common_code().unwrap(); - a.ranges(code >> 32).emplace_back(static_cast(code)); + if constexpr(TYPE == Group::MirrorType::Ordinary) { - const auto code_1 = raw_code.to_horizontal_mirror().to_common_code().unwrap(); - b.ranges(code_1 >> 32).emplace_back(static_cast(code_1)); + // RangesUnion &a = kk[0]; + // RangesUnion &b = kk[1]; + // RangesUnion &c = kk[2]; + // RangesUnion &d = kk[3]; + extend(seed, size, NO_MIRROR, [&a, &b, &c, &d](const RawCode raw_code) { + const auto code = raw_code.to_common_code().unwrap(); + a.ranges(code >> 32).emplace_back(static_cast(code)); - const auto code_2 = raw_code.to_vertical_mirror().to_common_code().unwrap(); - c.ranges(code_2 >> 32).emplace_back(static_cast(code_2)); + const auto code_1 = raw_code.to_horizontal_mirror().to_common_code().unwrap(); + b.ranges(code_1 >> 32).emplace_back(static_cast(code_1)); + + const auto code_2 = raw_code.to_vertical_mirror().to_common_code().unwrap(); + c.ranges(code_2 >> 32).emplace_back(static_cast(code_2)); + + const auto code_3 = raw_code.to_diagonal_mirror().to_common_code().unwrap(); + d.ranges(code_3 >> 32).emplace_back(static_cast(code_3)); + }); + + // for (auto head : RangesUnion::Heads) { + // std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); + // std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); + // std::stable_sort(c.ranges(head).begin(), c.ranges(head).end()); + // std::stable_sort(d.ranges(head).begin(), d.ranges(head).end()); + // } + + } - const auto code_3 = raw_code.to_diagonal_mirror().to_common_code().unwrap(); - d.ranges(code_3 >> 32).emplace_back(static_cast(code_3)); - }); for (auto head : RangesUnion::Heads) { std::stable_sort(a.ranges(head).begin(), a.ranges(head).end()); - std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); - std::stable_sort(c.ranges(head).begin(), c.ranges(head).end()); - std::stable_sort(d.ranges(head).begin(), d.ranges(head).end()); + + if constexpr(TYPE == Group::MirrorType::Centro || TYPE == Group::MirrorType::Vertical || TYPE == Group::MirrorType::Ordinary) { + std::stable_sort(b.ranges(head).begin(), b.ranges(head).end()); + } + + if constexpr(TYPE == Group::MirrorType::Horizontal || TYPE == Group::MirrorType::Ordinary) { + std::stable_sort(c.ranges(head).begin(), c.ranges(head).end()); + } + + if constexpr(TYPE == Group::MirrorType::Ordinary) { + std::stable_sort(d.ranges(head).begin(), d.ranges(head).end()); + } } + } -std::array build_ru_array() { - std::array data; - for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { - auto group_union = GroupUnion::unsafe_create(type_id); +static void build_ru_arr(uint8_t type_id, std::array &data) { + auto group_union = GroupUnion::unsafe_create(type_id); - if (group_union.group_num() == 1) { // only single group + if (group_union.group_num() == 1) { // only single group + data[PATTERN_OFFSET[type_id] * 4] = group_union.cases(); + return; + } - // std::println("type_id = {}", type_id); + uint32_t pattern_id_begin = 0; + if ((PATTERN_DATA[PATTERN_OFFSET[type_id]] & 0b111) == 0) { // first pattern is `x` + pattern_id_begin = 1; + } - data[PATTERN_OFFSET[type_id] * 4] = group_union.cases(); - continue; - } + for (uint32_t pattern_id = pattern_id_begin; pattern_id < group_union.pattern_num(); ++pattern_id) { - uint32_t pattern_id_begin = 0; - if ((PATTERN_DATA[PATTERN_OFFSET[type_id]] & 0b111) == 0) { // first pattern is `x` - pattern_id_begin = 1; - } + const auto flat_id = PATTERN_OFFSET[type_id] + pattern_id; + const auto mirror_type = static_cast(PATTERN_DATA[flat_id] & 0b111); - for (uint32_t pattern_id = pattern_id_begin; pattern_id < group_union.pattern_num(); ++pattern_id) { - // std::vector groups; - // for (auto group : group_union.groups()) { - // if (group.pattern_id() == pattern_id) { - // groups.emplace_back(group); - // } - // } - // - // auto flat_id = PATTERN_OFFSET[type_id] + pattern_id; - // for (auto group : groups) { - // data[flat_id * 4 + (int)group.toward()] = Group_cases(group); - // } - - const auto flat_id = PATTERN_OFFSET[type_id] + pattern_id; - const auto mirror_type = static_cast(PATTERN_DATA[flat_id] & 0b111); - - const auto seed_val = PATTERN_DATA[flat_id] >> 23; - auto seed = CommonCode::unsafe_create(seed_val).to_raw_code(); - const auto size = (PATTERN_DATA[flat_id] >> 3) & 0xFFFFF; - - if (mirror_type == Group::MirrorType::Full) { - extend_full_pattern(seed, size, data[flat_id * 4]); - } else if (mirror_type == Group::MirrorType::Horizontal) { - extend_hor_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 2]); - } else if (mirror_type == Group::MirrorType::Centro) { - extend_cen_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1]); - } else if (mirror_type == Group::MirrorType::Vertical) { - extend_ver_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1]); - } else if (mirror_type == Group::MirrorType::Ordinary) { - extend_ord_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1], data[flat_id * 4 + 2], data[flat_id * 4 + 3]); - } + const auto seed_val = PATTERN_DATA[flat_id] >> 23; + auto seed = CommonCode::unsafe_create(seed_val).to_raw_code(); + const auto size = (PATTERN_DATA[flat_id] >> 3) & 0xFFFFF; - } + if (mirror_type == Group::MirrorType::Full) { + // extend_full_pattern(seed, size, data[flat_id * 4]); + // extend_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1], data[flat_id * 4 + 2], data[flat_id * 4 + 3]); + extend_pattern(seed, size, &data[flat_id * 4]); - if (pattern_id_begin == 1) { // first pattern is `x` + } else if (mirror_type == Group::MirrorType::Horizontal) { + // extend_hor_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 2]); + // extend_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1], data[flat_id * 4 + 2], data[flat_id * 4 + 3]); + extend_pattern(seed, size, &data[flat_id * 4]); - RangesUnion others; + } else if (mirror_type == Group::MirrorType::Centro) { + // extend_cen_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1]); + // extend_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1], data[flat_id * 4 + 2], data[flat_id * 4 + 3]); + extend_pattern(seed, size, &data[flat_id * 4]); - size_t index_begin = (PATTERN_OFFSET[type_id] + 1) * 4; - size_t index_end = (PATTERN_OFFSET[type_id] + group_union.pattern_num()) * 4; + } else if (mirror_type == Group::MirrorType::Vertical) { + // extend_ver_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1]); + // extend_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1], data[flat_id * 4 + 2], data[flat_id * 4 + 3]); + extend_pattern(seed, size, &data[flat_id * 4]); - for (size_t index = index_begin; index < index_end; ++index) { - others += data[index]; - } + } else if (mirror_type == Group::MirrorType::Ordinary) { + // extend_ord_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1], data[flat_id * 4 + 2], data[flat_id * 4 + 3]); + // extend_pattern(seed, size, data[flat_id * 4], data[flat_id * 4 + 1], data[flat_id * 4 + 2], data[flat_id * 4 + 3]); + extend_pattern(seed, size, &data[flat_id * 4]); - for (auto head : RangesUnion::Heads) { - std::stable_sort(others.ranges(head).begin(), others.ranges(head).end()); - } + } + + } + + if (pattern_id_begin == 1) { // first pattern is `x` + RangesUnion others; - data[PATTERN_OFFSET[type_id] * 4] = group_union.cases_without(others); + size_t index_begin = (PATTERN_OFFSET[type_id] + 1) * 4; + size_t index_end = (PATTERN_OFFSET[type_id] + group_union.pattern_num()) * 4; + for (size_t index = index_begin; index < index_end; ++index) { + others += data[index]; } + for (auto head : RangesUnion::Heads) { + std::stable_sort(others.ranges(head).begin(), others.ranges(head).end()); + } + + data[PATTERN_OFFSET[type_id] * 4] = group_union.cases_without(others); } +} + +std::array build_ru_array() { + std::array data; + for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { + build_ru_arr(type_id, data); + } - // verify + /// verify // for (uint8_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { // const auto group_union = GroupUnion::unsafe_create(type_id); // for (const auto group : group_union.groups()) { @@ -278,7 +429,6 @@ std::array build_ru_array() { // } // } - return data; } @@ -340,18 +490,9 @@ CommonCode GroupCases::fast_obtain_code(CaseInfo info) { auto flat_id = PATTERN_OFFSET[info.group().type_id()] + info.group().pattern_id(); - // auto &cases = (*ru_data)[flat_id][(int)info.group().toward()]; // TODO: make offset table for perf - - // auto &cases = (*ru_data_flat)[flat_id * 4 + (int)info.group().toward()]; - - // auto &cases = (*ru_data_map)[info.group()]; - - // auto &cases = (*ru_data_array)[flat_id][(int)info.group().toward()]; auto &cases = (*ru_data_array)[flat_id * 4 + (int)info.group().toward()]; - // auto &cases = (*ru_data_vector)[flat_id][(int)info.group().toward()]; - uint64_t head = 0; auto case_id = info.case_id();