2024-10-27 13:17:16 +00:00
|
|
|
#include "tape_config.h"
|
2024-10-28 02:23:42 +00:00
|
|
|
#include "tapelib/tape_util.h"
|
|
|
|
#include <chrono>
|
|
|
|
#include <cstddef>
|
|
|
|
#include <fstream>
|
2024-10-27 13:17:16 +00:00
|
|
|
#include <iostream>
|
2024-10-28 02:23:42 +00:00
|
|
|
#include <string>
|
|
|
|
|
|
|
|
size_t get_mem_peak() {
|
|
|
|
const static std::string mem_info_file = "/proc/self/status";
|
|
|
|
const static std::string mem_field = "VmPeak:";
|
|
|
|
std::ifstream status(mem_info_file);
|
|
|
|
size_t mem = 0;
|
|
|
|
std::string line;
|
|
|
|
while (std::getline(status, line)) {
|
|
|
|
if (line.find(mem_field) != std::string::npos) {
|
|
|
|
std::stringstream mem_line(line.substr(mem_field.size()));
|
|
|
|
mem_line >> mem;
|
|
|
|
return mem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mem;
|
|
|
|
}
|
2024-10-27 13:17:16 +00:00
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
2024-10-27 15:53:34 +00:00
|
|
|
AppSettings settings = parse_command_line(argc, argv);
|
|
|
|
if (settings.version) {
|
2024-10-27 13:17:16 +00:00
|
|
|
std::cout << VERSION_MSG << std::endl;
|
|
|
|
return 0;
|
|
|
|
}
|
2024-10-27 15:53:34 +00:00
|
|
|
if (settings.help) {
|
2024-10-27 13:17:16 +00:00
|
|
|
std::cerr << HELP_MSG << std::endl;
|
|
|
|
return 0;
|
|
|
|
}
|
2024-10-28 02:23:42 +00:00
|
|
|
if (!settings.config_file_path.empty() &&
|
|
|
|
!read_settings_from_file(settings)) {
|
|
|
|
return -1;
|
|
|
|
}
|
2024-10-27 15:53:34 +00:00
|
|
|
tape::FileTape input(settings.input_file_name, settings.ft_settings);
|
2024-10-28 02:23:42 +00:00
|
|
|
if (!input.is_open()) {
|
|
|
|
std::cerr << "Failed to create INPUT tape - file not found or "
|
|
|
|
"insufficient permissions"
|
|
|
|
<< std::endl;
|
|
|
|
return -1;
|
|
|
|
}
|
2024-10-27 15:53:34 +00:00
|
|
|
tape::FileTape output(input, settings.output_file_name,
|
|
|
|
settings.ft_settings);
|
2024-10-28 02:23:42 +00:00
|
|
|
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
|
2024-10-27 13:17:16 +00:00
|
|
|
tape::TempTapeFactory factory =
|
|
|
|
[&](size_t cells) -> std::unique_ptr<tape::Tape> {
|
|
|
|
return std::make_unique<tape::FileTape>(
|
2024-10-27 15:53:34 +00:00
|
|
|
tape::FileTape(cells, settings.ft_settings));
|
2024-10-27 13:17:16 +00:00
|
|
|
};
|
2024-10-28 02:23:42 +00:00
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
2024-10-27 15:53:34 +00:00
|
|
|
tape::external_sort(input, output, factory, settings.memory_limit);
|
2024-10-28 02:23:42 +00:00
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
|
|
auto duration = std::chrono::duration_cast<milliseconds>(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;
|
2024-10-27 13:17:16 +00:00
|
|
|
return 0;
|
|
|
|
}
|