void try_sort_chunk() { std::shared_ptr<chunk_to_sort > chunk=chunks.pop(); if(chunk) { sort_chunk(chunk); } }
void sort(const SortParameters& parameters) { std::uint32_t chunk_no = split_into_chunks(parameters.input_filename, parameters.chunk_size); const std::uint32_t initial_chunks_count = chunk_no; std::cout << "Split into " << initial_chunks_count << " chunks." << std::endl; ThreadPool pool(parameters.threads_count); std::vector<std::future<bool>> schedule; // Add tasks for sorting initial chunks for (std::uint32_t i = 0; i < initial_chunks_count; ++i) { schedule.emplace_back(pool.enqueue( [i, ¶meters]() { sort_chunk(get_chunk_filename(i), parameters.chunk_size); std::cout << "Chunk #" << i << " sorted" << std::endl; return true; } )); } // Add tasks for merging chunks for (std::uint32_t i = 0; i * (parameters.no_of_ways_for_merging - 1) + 1 < initial_chunks_count; ++i) { schedule.emplace_back(pool.enqueue( [i, chunk_no, &schedule, ¶meters]() mutable { std::cout << "Merging ["; std::vector<std::string> chunk_filenames; for (std::uint32_t delta = 0; delta < parameters.no_of_ways_for_merging; ++delta) { std::uint32_t needed_chunk_no = parameters.no_of_ways_for_merging * i + delta; if (needed_chunk_no + 1 < schedule.size()) { schedule[needed_chunk_no].wait(); chunk_filenames.emplace_back(get_chunk_filename(needed_chunk_no)); std::cout << needed_chunk_no << " "; } } std::cout << "] into " << chunk_no << std::endl; merge_sorted_chunks(chunk_filenames, get_chunk_filename(chunk_no)); delete_files(chunk_filenames); return true; } )); ++chunk_no; } schedule.back().get(); if (std::rename(get_chunk_filename(chunk_no - 1).c_str(), parameters.output_filename.c_str()) != 0) { throw std::runtime_error("Cannot rename last chunk into output file"); } }