#include "tape_config.h" #include "tapelib/filetape.h" #include "tapelib/tape.h" #include "tapelib/tape_util.h" #include #include #include #include #include #include using std::string; using std::chrono::high_resolution_clock; using std::chrono::milliseconds; using namespace tape; size_t get_mem_peak() { const static string mem_info_file = "/proc/self/status"; const static string mem_field = "VmPeak:"; std::ifstream status(mem_info_file); size_t mem = 0; string line; while (std::getline(status, line)) { if (line.find(mem_field) != string::npos) { std::stringstream mem_line(line.substr(mem_field.size())); mem_line >> mem; return mem; } } return mem; } // if we assume N as INPUT tape size, we can calucalte the optimal memory-limit // by using this formula: // X = sqrt(8000*N) // where X is the optimal memory-limit value int main(int argc, char *argv[]) { AppSettings settings = parse_command_line(argc, argv); if (settings.version) { std::cout << VERSION_MSG << std::endl; return 0; } if (settings.help) { std::cerr << HELP_MSG << std::endl; return 0; } if (!settings.config_file_path.empty() && !read_settings_from_file(settings)) { return -1; } FileTape input(settings.input_file_name, settings.ft_settings); if (!input.is_open()) { std::cerr << "Failed to create INPUT tape - file not found or " "insufficient permissions" << std::endl; return -1; } FileTape output(input, settings.output_file_name, settings.ft_settings); if (!output.is_open()) { std::cerr << "Failed to create OUTPUT tape - insufficient permissions" << std::endl; return -1; } // tmp tape factory that captures settings.ft_settings from local scope TempTapeFactory factory = [&](size_t cells) -> std::unique_ptr { return std::make_unique( FileTape(cells, settings.ft_settings)); }; auto start = high_resolution_clock::now(); external_sort(input, output, factory, settings.memory_limit); auto end = high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start); std::cout << "Successfully sorted " << settings.input_file_name << " into " << settings.output_file_name << std::endl; std::cout << "The operation took " << duration.count() << " ms to complete and peaked at " << get_mem_peak() << " KiB of virtual memory usage" << std::endl; return 0; }