diff --git a/src/all_cases/basic_ranges.cc b/src/all_cases/basic_ranges.cc index 525390d..edf7f01 100644 --- a/src/all_cases/basic_ranges.cc +++ b/src/all_cases/basic_ranges.cc @@ -7,13 +7,11 @@ std::mutex BasicRanges::building; bool BasicRanges::available = false; std::vector BasicRanges::data; -inline uint32_t binary_count(uint32_t bin) { // get number of non-zero bits - bin -= (bin >> 1) & 0x55555555; - bin = (bin & 0x33333333) + ((bin >> 2) & 0x33333333); - bin = ((bin >> 4) + bin) & 0x0F0F0F0F; - bin += bin >> 8; - bin += bin >> 16; - return bin & 0b111111; +const std::vector* BasicRanges::fetch() { // get basic ranges content + if (status() != AVAILABLE) { + BasicRanges::build(); // basic ranges initialize + } + return &BasicRanges::data; // return const ptr } BasicRanges::Status BasicRanges::status() { // get basic ranges status @@ -27,13 +25,6 @@ BasicRanges::Status BasicRanges::status() { // get basic ranges status return NO_INIT; } -const std::vector* BasicRanges::fetch() { // get basic ranges content - if (status() != AVAILABLE) { - BasicRanges::build(); // basic ranges initialize - } - return &BasicRanges::data; // return const ptr -} - void BasicRanges::build() { // ensure that basic ranges available if (!BasicRanges::available) { if (BasicRanges::building.try_lock()) { // mutex lock success @@ -46,59 +37,12 @@ void BasicRanges::build() { // ensure that basic ranges available } } -#include - -void BasicRanges::sort_data(std::vector &flags, std::vector &raw) { - struct heap_node { - uint32_t value; - int index; - int limit; - }; - - struct compare { - bool operator() (heap_node n1, heap_node n2) { - return n1.value > n2.value; - } - }; - std::priority_queue, compare> min_heap; - - for (auto i = 0; i < flags.size() - 1; ++i) { - min_heap.push({ - .value = raw[flags[i]], - .index = flags[i], - .limit = flags[i + 1] - 1, - }); - } - - while (!min_heap.empty()) { - auto current = min_heap.top(); - min_heap.pop(); - data.emplace_back(current.value); - if (current.index != current.limit) { - min_heap.push({ - .value = raw[current.index + 1], - .index = current.index + 1, - .limit = current.limit, - }); - } - } -} - void BasicRanges::build_data() { // build basic ranges BasicRanges::data.reserve(BASIC_RANGES_SIZE); // memory pre-allocated - - std::vector raw_data; - raw_data.reserve(BASIC_RANGES_SIZE); - - std::vector start_points; - for (int n = 0; n <= 7; ++n) { // number of 1x2 and 2x1 block -> 0 ~ 7 for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) { // number of 2x1 block -> 0 ~ n for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) { // number of 1x1 block -> 0 ~ (14 - 2n) - - start_points.emplace_back(raw_data.size()); - - generate(raw_data, generate_t { // generate target ranges + generate(generate_t { // generate target ranges .n1 = 16 - n * 2 - n_1x1, /// space -> 00 .n2 = n - n_2x1, /// 1x2 -> 01 .n3 = n_2x1, /// 2x1 -> 10 @@ -107,47 +51,36 @@ void BasicRanges::build_data() { // build basic ranges } } } - - start_points.emplace_back(raw_data.size()); - -// std::sort(BasicRanges::data.begin(), BasicRanges::data.end()); // sort basic ranges - - BasicRanges::sort_data(start_points, raw_data); - - std::cout << "size: " << BasicRanges::data.size() << std::endl; - -// std::sort(raw_data.begin(), raw_data.end()); -// std::cout << raw_data.size() << std::endl; - -// for (auto &range : BasicRanges::data) { -// range = Common::range_reverse(range); // basic ranges reverse -// } + std::sort(BasicRanges::data.begin(), BasicRanges::data.end()); // sort basic ranges + for (auto &range : BasicRanges::data) { + range = Common::range_reverse(range); // basic ranges reverse + } } -void BasicRanges::generate(std::vector &release, generate_t info) { // generate specific basic ranges - constexpr uint32_t MASK_01 = (uint32_t)0b01 << 30; - constexpr uint32_t MASK_10 = (uint32_t)0b10 << 30; - constexpr uint32_t MASK_11 = (uint32_t)0b11 << 30; +void BasicRanges::generate(generate_t info) { // generate specific basic ranges + constexpr auto MASK_01 = (uint32_t)0b01 << 30; + constexpr auto MASK_10 = (uint32_t)0b10 << 30; + constexpr auto MASK_11 = (uint32_t)0b11 << 30; /// n4 n3 n2 n1 /// 00000000 00000000 00000000 00000000 (32-bits) struct build_t { - uint32_t nx; + uint32_t nx; // (n4, n3, n2, n1) uint32_t prefix; - int offset; + int offset; // prefix length }; std::queue cache; - cache.emplace(build_t { + cache.emplace(build_t { // setup info .nx = static_cast(info.n1 | info.n2 << 8 | info.n3 << 16 | info.n4 << 24), .prefix = 0x00000000, .offset = 0, }); - while (!cache.empty()) { // queue without elements + while (!cache.empty()) { // queue without elements -> work complete auto current = cache.front(); if (!current.nx) { // both n1, n2, n3, n4 -> 0 - release.emplace_back(current.prefix); // release prefix as basic range + BasicRanges::data.emplace_back(current.prefix); // release prefix as basic range cache.pop(); continue; // skip search } diff --git a/src/all_cases/basic_ranges.h b/src/all_cases/basic_ranges.h index 7e90093..b874e98 100644 --- a/src/all_cases/basic_ranges.h +++ b/src/all_cases/basic_ranges.h @@ -30,6 +30,5 @@ private: static std::vector data; static void build_data(); - static void sort_data(std::vector &flags, std::vector &raw); - static void generate(std::vector &release, generate_t info); + static void generate(generate_t info); }; diff --git a/src/common_code/common_code.cc b/src/common_code/common_code.cc index 6cef632..2df92e5 100644 --- a/src/common_code/common_code.cc +++ b/src/common_code/common_code.cc @@ -2,6 +2,15 @@ #include "common.h" #include "common_code.h" +inline uint32_t binary_count(uint32_t bin) { // get number of non-zero bits + bin -= (bin >> 1) & 0x55555555; + bin = (bin & 0x33333333) + ((bin >> 2) & 0x33333333); + bin = ((bin >> 4) + bin) & 0x0F0F0F0F; + bin += bin >> 8; + bin += bin >> 16; + return bin & 0b111111; +} + /// WARN: bin should not be zero inline uint32_t last_zero_num(uint32_t bin) { // get last zero number bin ^= (bin - 1); diff --git a/src/main.cc b/src/main.cc index 23ccc10..56ac321 100644 --- a/src/main.cc +++ b/src/main.cc @@ -244,6 +244,10 @@ int main() { // load_ranges(); BasicRanges::build(); +// std::cout << "size: " << BasicRanges::fetch()->size() << std::endl; + for (const auto &range : *BasicRanges::fetch()) { + printf("%08X\n", range); + } std::cerr << (clock() - start_time) * 1000 / CLOCKS_PER_SEC << "ms" << std::endl; // std::cerr << (clock() - start_time) * 1000000 / CLOCKS_PER_SEC << "us" << std::endl;