yadro-task/bin/ftsort/ftsort.cpp

80 lines
2.7 KiB
C++
Raw Permalink Normal View History

#include "tape_config.h"
#include "tapelib/filetape.h"
#include "tapelib/tape.h"
#include "tapelib/tape_util.h"
#include <chrono>
#include <cstddef>
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
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[]) {
2024-10-27 15:53:34 +00:00
AppSettings settings = parse_command_line(argc, argv);
if (settings.version) {
std::cout << VERSION_MSG << std::endl;
return 0;
}
2024-10-27 15:53:34 +00:00
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<Tape> {
return std::make_unique<FileTape>(
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<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;
return 0;
}