From 3030f9bd98a2d8564e33e575007ef9fa58dc92de Mon Sep 17 00:00:00 2001 From: bronku Date: Mon, 17 Nov 2025 19:39:10 +0100 Subject: [PATCH] final? --- include/config.hpp | 16 ++++++++++------ include/merge_sorter.hpp | 8 ++++---- makefile | 4 ++-- src/config.cpp | 19 ++++++++----------- src/main.cpp | 13 ++++++++----- src/merge_sorter.cpp | 23 ++++++++++++++++++----- 6 files changed, 50 insertions(+), 33 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index f0a6ae4..400425b 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -4,14 +4,18 @@ class Configuration { public: + // I/O settings std::string input_file = "1.in"; std::string output_file = "1.out"; - std::string tmp_dir = "build/run"; - bool generate_data = false; - bool evaluate_file = false; - int N = 100000; // number of records in a file - int n = 101; // number of buffers - int b = 10; // blocking factor + std::string tmp_directory = "run"; + + // Algorithm settings + size_t buffer_rows = 101; + size_t buffer_cols = 10; + + // Additional modes + size_t generate_data = 0; + bool read_file = false; Configuration(int argc, char** argv); }; diff --git a/include/merge_sorter.hpp b/include/merge_sorter.hpp index 2d93a41..361eeda 100644 --- a/include/merge_sorter.hpp +++ b/include/merge_sorter.hpp @@ -21,9 +21,9 @@ private: public: MergeSorter(size_t buffer_rows, size_t buffer_cols, const std::string& tmp_dir); - bool sort_file(const std::string& input_file, const std::string& output_file); + void sort_file(const std::string& input_file, const std::string& output_file); - size_t disk_reads() const; - size_t disk_writes() const; - size_t phases() const; + size_t disk_reads(); + size_t disk_writes(); + size_t phases(); }; diff --git a/makefile b/makefile index 238d77c..f97d0e8 100644 --- a/makefile +++ b/makefile @@ -24,10 +24,10 @@ generate: build/run/1.in # actually should depend on build/main and build/run, but that will trigger it every recompile, and i don't need that build/run/1.in: - $(TARGET) -g -o build/run/1.in + $(TARGET) -g 100000 -o build/run/1.in run: $(TARGET) build/run/1.in - $(TARGET) -i build/run/1.in -d build/run/tmp + $(TARGET) -i build/run/1.in -d build/run/tmp -o build/run/1.out run_alt: $(TARGET) build/run/1.in $(TARGET) -i build/run/1.in -d build/run/tmp -n 11 -b 100 diff --git a/src/config.cpp b/src/config.cpp index 861edc8..3fea682 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -6,13 +6,13 @@ Configuration::Configuration(int argc, char** argv) { if (argc <= 1) { std::cerr << "Please specify input arguments\n"; - std::cerr << "Usage: " << argv[0] << " [-g] [-e] [-N count] [-i input] [-o output] [-d dir] [-n buffers] [-b block_size]\n"; + std::cerr << "Usage: " << argv[0] << " [-g count] [-e] [-i input] [-o output] [-d dir] [-n buffers] [-b block_size]\n"; throw std::invalid_argument("No input arguments"); } bool input_set = false; int opt; - while ((opt = getopt(argc, argv, "i:d:o:geN:n:b:")) != -1) { + while ((opt = getopt(argc, argv, "i:d:o:g:en:b:")) != -1) { switch (opt) { case 'i': input_file = optarg; @@ -22,22 +22,19 @@ Configuration::Configuration(int argc, char** argv) output_file = optarg; break; case 'd': - tmp_dir = optarg; + tmp_directory = optarg; break; case 'g': - generate_data = true; + generate_data = std::stoi(optarg); break; case 'e': - evaluate_file = true; - break; - case 'N': - N = std::stoi(optarg); + read_file = true; break; case 'n': - n = std::stoi(optarg); + buffer_rows = std::stoi(optarg); break; case 'b': - b = std::stoi(optarg); + buffer_cols = std::stoi(optarg); break; case '?': throw std::invalid_argument("Invalid command line argument"); @@ -49,7 +46,7 @@ Configuration::Configuration(int argc, char** argv) if (generate_data && input_set) { throw std::invalid_argument("Cannot specify both -g and -i options"); } - if (generate_data && evaluate_file) { + if (generate_data && read_file) { throw std::invalid_argument("Cannot specify both -g and -e options"); } } diff --git a/src/main.cpp b/src/main.cpp index 2c0d955..3ea7eee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,13 +21,13 @@ void generate_file(int N, const std::string& filename) void read_and_evaluate(std::string filename) { FileReader input(filename); - while (true) { + for (size_t i = 0;; i++) { auto rec = input.read(); if (!rec.has_value()) { return; } - std::cout << "[Evaluate: " << rec.value().evaluate() << "] " << rec.value() << "\n"; + std::cout << "record " << i << " [value: " << rec.value().evaluate() << "] " << rec.value() << "\n"; } } @@ -36,15 +36,18 @@ int main(int argc, char** argv) Configuration opts(argc, argv); if (opts.generate_data) { - generate_file(opts.N, opts.output_file); + generate_file(opts.generate_data, opts.output_file); return 0; } - if (opts.evaluate_file) { + if (opts.read_file) { read_and_evaluate(opts.input_file); return 0; } - MergeSorter sorter(opts.b, opts.n, opts.tmp_dir); + MergeSorter sorter(opts.buffer_cols, opts.buffer_rows, opts.tmp_directory); sorter.sort_file(opts.input_file, opts.output_file); + std::cout << "total reads: " << sorter.disk_reads() << '\n' + << "total writes: " << sorter.disk_writes() << '\n' + << "phases: " << sorter.phases() << "\n"; } diff --git a/src/merge_sorter.cpp b/src/merge_sorter.cpp index 0a657ea..f9189f2 100644 --- a/src/merge_sorter.cpp +++ b/src/merge_sorter.cpp @@ -138,7 +138,7 @@ MergeSorter::MergeSorter(size_t buffer_rows, size_t buffer_cols, const std::stri } } -bool MergeSorter::sort_file(const std::string& input_file, const std::string& output_file) +void MergeSorter::sort_file(const std::string& input_file, const std::string& output_file) { std::string current_dir = tmp_dir_ + "/pass0/run_"; std::string next_dir = tmp_dir_ + "/pass1/run_"; @@ -146,16 +146,29 @@ bool MergeSorter::sort_file(const std::string& input_file, const std::string& ou run_count = create_initial_runs(input_file, current_dir); phases_++; - std::cout << "created inital runs, disk reads: " << disk_reads_ << ", disk writes: " << disk_writes_ << '\n'; while (run_count > 1) { run_count = merge_pass(current_dir, next_dir, run_count); - std::cout << "completed merge pass " << phases_ << ", disk reads: " << disk_reads_ << ", disk writes: " << disk_writes_ << '\n'; phases_++; current_dir = next_dir; next_dir = tmp_dir_ + "/pass" + std::to_string(phases_) + "/run_"; } - std::cout << output_file << '\n'; - return true; + std::string final_run = current_dir + "0.dat"; + std::filesystem::rename(final_run, output_file); +} + +size_t MergeSorter::disk_reads() +{ + return disk_reads_; +} + +size_t MergeSorter::disk_writes() +{ + return disk_writes_; +} + +size_t MergeSorter::phases() +{ + return phases_; }