Added using directives to avoid excessive namespaecs
Added explicit include directories to each file, even if an already included header defined them Removed using directives from header files
This commit is contained in:
parent
f8bfc78cad
commit
ad976a5a9e
10 changed files with 121 additions and 83 deletions
|
@ -1,19 +1,27 @@
|
||||||
#include "tape_config.h"
|
#include "tape_config.h"
|
||||||
|
#include "tapelib/filetape.h"
|
||||||
|
#include "tapelib/tape.h"
|
||||||
#include "tapelib/tape_util.h"
|
#include "tapelib/tape_util.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::chrono::high_resolution_clock;
|
||||||
|
using std::chrono::milliseconds;
|
||||||
|
using namespace tape;
|
||||||
|
|
||||||
size_t get_mem_peak() {
|
size_t get_mem_peak() {
|
||||||
const static std::string mem_info_file = "/proc/self/status";
|
const static string mem_info_file = "/proc/self/status";
|
||||||
const static std::string mem_field = "VmPeak:";
|
const static string mem_field = "VmPeak:";
|
||||||
std::ifstream status(mem_info_file);
|
std::ifstream status(mem_info_file);
|
||||||
size_t mem = 0;
|
size_t mem = 0;
|
||||||
std::string line;
|
string line;
|
||||||
while (std::getline(status, line)) {
|
while (std::getline(status, line)) {
|
||||||
if (line.find(mem_field) != std::string::npos) {
|
if (line.find(mem_field) != string::npos) {
|
||||||
std::stringstream mem_line(line.substr(mem_field.size()));
|
std::stringstream mem_line(line.substr(mem_field.size()));
|
||||||
mem_line >> mem;
|
mem_line >> mem;
|
||||||
return mem;
|
return mem;
|
||||||
|
@ -36,29 +44,27 @@ int main(int argc, char *argv[]) {
|
||||||
!read_settings_from_file(settings)) {
|
!read_settings_from_file(settings)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tape::FileTape input(settings.input_file_name, settings.ft_settings);
|
FileTape input(settings.input_file_name, settings.ft_settings);
|
||||||
if (!input.is_open()) {
|
if (!input.is_open()) {
|
||||||
std::cerr << "Failed to create INPUT tape - file not found or "
|
std::cerr << "Failed to create INPUT tape - file not found or "
|
||||||
"insufficient permissions"
|
"insufficient permissions"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tape::FileTape output(input, settings.output_file_name,
|
FileTape output(input, settings.output_file_name, settings.ft_settings);
|
||||||
settings.ft_settings);
|
|
||||||
if (!output.is_open()) {
|
if (!output.is_open()) {
|
||||||
std::cerr << "Failed to create OUTPUT tape - insufficient permissions"
|
std::cerr << "Failed to create OUTPUT tape - insufficient permissions"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// tmp tape factory that captures settings.ft_settings from local scope
|
// tmp tape factory that captures settings.ft_settings from local scope
|
||||||
tape::TempTapeFactory factory =
|
TempTapeFactory factory = [&](size_t cells) -> std::unique_ptr<Tape> {
|
||||||
[&](size_t cells) -> std::unique_ptr<tape::Tape> {
|
return std::make_unique<FileTape>(
|
||||||
return std::make_unique<tape::FileTape>(
|
FileTape(cells, settings.ft_settings));
|
||||||
tape::FileTape(cells, settings.ft_settings));
|
|
||||||
};
|
};
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
tape::external_sort(input, output, factory, settings.memory_limit);
|
external_sort(input, output, factory, settings.memory_limit);
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
auto end = high_resolution_clock::now();
|
||||||
auto duration = std::chrono::duration_cast<milliseconds>(end - start);
|
auto duration = std::chrono::duration_cast<milliseconds>(end - start);
|
||||||
std::cout << "Successfully sorted " << settings.input_file_name << " into "
|
std::cout << "Successfully sorted " << settings.input_file_name << " into "
|
||||||
<< settings.output_file_name << std::endl;
|
<< settings.output_file_name << std::endl;
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
#include "tape_config.h"
|
#include "tape_config.h"
|
||||||
|
#include "tapelib/filetape.h"
|
||||||
#include <bits/getopt_core.h>
|
#include <bits/getopt_core.h>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstddef>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::chrono::milliseconds;
|
||||||
|
|
||||||
const static struct std::vector<option> CMD_OPTS{
|
const static struct std::vector<option> CMD_OPTS{
|
||||||
{.name = "write-delay",
|
{.name = "write-delay",
|
||||||
|
@ -32,9 +39,9 @@ const static struct std::vector<option> CMD_OPTS{
|
||||||
{.name = "help", .has_arg = no_argument, .flag = nullptr, .val = 'h'},
|
{.name = "help", .has_arg = no_argument, .flag = nullptr, .val = 'h'},
|
||||||
{.name = nullptr, .has_arg = no_argument, .flag = nullptr, .val = 0}};
|
{.name = nullptr, .has_arg = no_argument, .flag = nullptr, .val = 0}};
|
||||||
|
|
||||||
std::chrono::milliseconds parse_delay(const std::string &input) {
|
milliseconds parse_delay(const string &input) {
|
||||||
int delay_ms = std::stoi(input);
|
int delay_ms = std::stoi(input);
|
||||||
return std::chrono::milliseconds(delay_ms);
|
return milliseconds(delay_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppSettings parse_command_line(int argc, char **argv) {
|
AppSettings parse_command_line(int argc, char **argv) {
|
||||||
|
@ -105,15 +112,15 @@ bool read_settings_from_file(AppSettings &settings) {
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string line;
|
string line;
|
||||||
size_t line_number = 1;
|
size_t line_number = 1;
|
||||||
while (std::getline(config, line)) {
|
while (std::getline(config, line)) {
|
||||||
size_t delim_index = line.find(CFG_DELIMETER);
|
size_t delim_index = line.find(CFG_DELIMETER);
|
||||||
if (delim_index >= line.size()) {
|
if (delim_index >= line.size()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::string key = line.substr(0, delim_index);
|
string key = line.substr(0, delim_index);
|
||||||
std::string value = line.substr(delim_index + 1);
|
string value = line.substr(delim_index + 1);
|
||||||
try {
|
try {
|
||||||
if (key == "write-delay") {
|
if (key == "write-delay") {
|
||||||
settings.ft_settings.write_delay = parse_delay(value);
|
settings.ft_settings.write_delay = parse_delay(value);
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define TAPE_CONFIG_H
|
#define TAPE_CONFIG_H
|
||||||
|
|
||||||
#include "tapelib/filetape.h"
|
#include "tapelib/filetape.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// stringizing opearator to convert macro into string literal
|
// stringizing opearator to convert macro into string literal
|
||||||
#define xstr(s) str(s)
|
#define xstr(s) str(s)
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
|
|
||||||
#include "tape.h"
|
#include "tape.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using std::chrono::milliseconds;
|
|
||||||
|
|
||||||
namespace tape {
|
namespace tape {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,17 +16,17 @@ namespace tape {
|
||||||
* such as read dealy, write delay etc.
|
* such as read dealy, write delay etc.
|
||||||
*/
|
*/
|
||||||
struct FileTapeSettings {
|
struct FileTapeSettings {
|
||||||
milliseconds read_delay;
|
std::chrono::milliseconds read_delay;
|
||||||
milliseconds write_delay;
|
std::chrono::milliseconds write_delay;
|
||||||
milliseconds seek_forward_delay;
|
std::chrono::milliseconds seek_forward_delay;
|
||||||
milliseconds seek_backwards_delay;
|
std::chrono::milliseconds seek_backwards_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
const static struct FileTapeSettings FT_DEFAULT_SETTINGS =
|
const static struct FileTapeSettings FT_DEFAULT_SETTINGS =
|
||||||
FileTapeSettings{.read_delay = milliseconds(0),
|
FileTapeSettings{.read_delay = std::chrono::milliseconds(0),
|
||||||
.write_delay = milliseconds(0),
|
.write_delay = std::chrono::milliseconds(0),
|
||||||
.seek_forward_delay = milliseconds(0),
|
.seek_forward_delay = std::chrono::milliseconds(0),
|
||||||
.seek_backwards_delay = milliseconds(0)};
|
.seek_backwards_delay = std::chrono::milliseconds(0)};
|
||||||
|
|
||||||
const static char FT_DELIMETER = '\n';
|
const static char FT_DELIMETER = '\n';
|
||||||
|
|
||||||
|
|
|
@ -8,21 +8,19 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
|
|
||||||
namespace tape {
|
namespace tape {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lambda, which takes the amount of cells a tape should have and returns
|
* Lambda, which takes the amount of cells a tape should have and returns
|
||||||
* a unique pointer to a temporary Tape with the specified amount of cells
|
* a unique pointer to a temporary Tape with the specified amount of cells
|
||||||
*/
|
*/
|
||||||
using TempTapeFactory = std::function<unique_ptr<Tape>(size_t)>;
|
using TempTapeFactory = std::function<std::unique_ptr<Tape>(size_t)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TempTapeFactory that creates a new temporary FileTape
|
* TempTapeFactory that creates a new temporary FileTape
|
||||||
*/
|
*/
|
||||||
const static inline TempTapeFactory FILETAPE_FACTORY =
|
const static inline TempTapeFactory FILETAPE_FACTORY =
|
||||||
[](size_t cells) -> unique_ptr<Tape> {
|
[](size_t cells) -> std::unique_ptr<Tape> {
|
||||||
return std::make_unique<FileTape>(FileTape(cells));
|
return std::make_unique<FileTape>(FileTape(cells));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,43 @@
|
||||||
#include "tapelib/filetape.h"
|
#include "tapelib/filetape.h"
|
||||||
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using std::fstream;
|
using std::fstream;
|
||||||
|
using std::setfill;
|
||||||
|
using std::setw;
|
||||||
|
using std::string;
|
||||||
|
using std::to_string;
|
||||||
|
using std::this_thread::sleep_for;
|
||||||
using tape::FileTape;
|
using tape::FileTape;
|
||||||
|
|
||||||
std::string generate_tmp_file_name() {
|
std::string generate_tmp_file_name() {
|
||||||
std::array<char, L_tmpnam> tmp_file_name{};
|
std::array<char, L_tmpnam> tmp_file_name{};
|
||||||
// tmpnam is unsafe, but its cross-platform
|
|
||||||
std::tmpnam(tmp_file_name.data());
|
std::tmpnam(tmp_file_name.data());
|
||||||
return tmp_file_name.data();
|
return tmp_file_name.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTape::FileTape(const std::string file_name, const FileTapeSettings settings)
|
FileTape::FileTape(const string file_name, const FileTapeSettings settings)
|
||||||
: settings(settings), file_name(file_name) {
|
: settings(settings), file_name(file_name) {
|
||||||
this->file = fstream(file_name);
|
this->file = fstream(file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTape::FileTape(const size_t cells, const std::string file_name,
|
FileTape::FileTape(const size_t cells, const string file_name,
|
||||||
const FileTapeSettings settings)
|
const FileTapeSettings settings)
|
||||||
: FileTape(file_name, settings) {
|
: FileTape(file_name, settings) {
|
||||||
this->file =
|
this->file =
|
||||||
fstream(this->file_name, fstream::in | fstream::out | fstream::trunc);
|
fstream(this->file_name, fstream::in | fstream::out | fstream::trunc);
|
||||||
this->file << std::setfill('0') << std::setw(tape::FT_CELL_SIZE) << '0';
|
this->file << setfill('0') << setw(FT_CELL_SIZE) << '0';
|
||||||
for (size_t i = 1; i < cells; i++) {
|
for (size_t i = 1; i < cells; i++) {
|
||||||
this->file << FT_DELIMETER << std::setfill('0')
|
this->file << FT_DELIMETER << setfill('0') << setw(FT_CELL_SIZE) << '0';
|
||||||
<< std::setw(FT_CELL_SIZE) << '0';
|
|
||||||
}
|
}
|
||||||
this->file.seekg(0, fstream::beg);
|
this->file.seekg(0, fstream::beg);
|
||||||
}
|
}
|
||||||
|
@ -40,22 +47,21 @@ FileTape::FileTape(const size_t cells, const FileTapeSettings settings)
|
||||||
this->tmp = true;
|
this->tmp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTape::FileTape(FileTape &same_size_as, const std::string file_name,
|
FileTape::FileTape(FileTape &same_size_as, const string file_name,
|
||||||
const FileTapeSettings settings)
|
const FileTapeSettings settings)
|
||||||
: settings(settings), file_name(file_name) {
|
: settings(settings), file_name(file_name) {
|
||||||
this->file =
|
this->file =
|
||||||
fstream(this->file_name, fstream::in | fstream::out | fstream::trunc);
|
fstream(this->file_name, fstream::in | fstream::out | fstream::trunc);
|
||||||
this->file << std::setfill('0') << std::setw(tape::FT_CELL_SIZE) << '0';
|
this->file << setfill('0') << setw(tape::FT_CELL_SIZE) << '0';
|
||||||
while (same_size_as.seek_forward()) {
|
while (same_size_as.seek_forward()) {
|
||||||
file << tape::FT_DELIMETER << std::setfill('0')
|
file << FT_DELIMETER << setfill('0') << setw(FT_CELL_SIZE) << '0';
|
||||||
<< std::setw(tape::FT_CELL_SIZE) << '0';
|
|
||||||
}
|
}
|
||||||
this->file.seekg(0, fstream::beg);
|
this->file.seekg(0, fstream::beg);
|
||||||
same_size_as.file.seekg(0, fstream::beg);
|
same_size_as.file.seekg(0, fstream::beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTape::FileTape(FileTape &same_size_as, const FileTapeSettings settings)
|
FileTape::FileTape(FileTape &same_size_as, const FileTapeSettings settings)
|
||||||
: tape::FileTape(same_size_as, generate_tmp_file_name(), settings) {
|
: FileTape(same_size_as, generate_tmp_file_name(), settings) {
|
||||||
this->tmp = true;
|
this->tmp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,17 +74,16 @@ FileTape::FileTape(const std::vector<uint32_t> &data,
|
||||||
if (data.empty()) {
|
if (data.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->file << std::setfill('0') << std::setw(FT_CELL_SIZE)
|
this->file << setfill('0') << setw(FT_CELL_SIZE) << to_string(data[0]);
|
||||||
<< std::to_string(data[0]);
|
|
||||||
for (size_t i = 1; i < data.size(); i++) {
|
for (size_t i = 1; i < data.size(); i++) {
|
||||||
this->file << FT_DELIMETER << std::setfill('0')
|
this->file << FT_DELIMETER << setfill('0') << setw(FT_CELL_SIZE)
|
||||||
<< std::setw(FT_CELL_SIZE) << std::to_string(data[i]);
|
<< to_string(data[i]);
|
||||||
}
|
}
|
||||||
this->file.seekg(0, fstream::beg);
|
this->file.seekg(0, fstream::beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileTape::seek_backwards() {
|
bool FileTape::seek_backwards() {
|
||||||
std::this_thread::sleep_for(this->settings.seek_backwards_delay);
|
sleep_for(this->settings.seek_backwards_delay);
|
||||||
if (this->file.tellg() == 0) {
|
if (this->file.tellg() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +92,7 @@ bool FileTape::seek_backwards() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileTape::seek_forward() {
|
bool FileTape::seek_forward() {
|
||||||
std::this_thread::sleep_for(this->settings.seek_forward_delay);
|
sleep_for(this->settings.seek_forward_delay);
|
||||||
this->file.seekg(FT_SEEK_OFFSET, fstream::cur);
|
this->file.seekg(FT_SEEK_OFFSET, fstream::cur);
|
||||||
this->file.peek(); // peek to check if eof is reached
|
this->file.peek(); // peek to check if eof is reached
|
||||||
if (this->file.eof()) {
|
if (this->file.eof()) {
|
||||||
|
@ -99,7 +104,7 @@ bool FileTape::seek_forward() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FileTape::read() {
|
uint32_t FileTape::read() {
|
||||||
std::this_thread::sleep_for(this->settings.read_delay);
|
sleep_for(this->settings.read_delay);
|
||||||
uint32_t data = 0;
|
uint32_t data = 0;
|
||||||
this->file >> data;
|
this->file >> data;
|
||||||
if (this->file.eof()) {
|
if (this->file.eof()) {
|
||||||
|
@ -112,10 +117,9 @@ uint32_t FileTape::read() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileTape::write(const uint32_t data) {
|
void FileTape::write(const uint32_t data) {
|
||||||
std::this_thread::sleep_for(this->settings.write_delay);
|
sleep_for(this->settings.write_delay);
|
||||||
std::stringstream cell;
|
std::stringstream cell;
|
||||||
cell << std::setfill('0') << std::setw(FT_CELL_SIZE)
|
cell << setfill('0') << setw(FT_CELL_SIZE) << to_string(data);
|
||||||
<< std::to_string(data);
|
|
||||||
this->file.write(cell.str().data(), FT_CELL_SIZE);
|
this->file.write(cell.str().data(), FT_CELL_SIZE);
|
||||||
this->file.seekg(-FT_SEEK_OFFSET + 1, fstream::cur);
|
this->file.seekg(-FT_SEEK_OFFSET + 1, fstream::cur);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
#include "tapelib/tape_util.h"
|
#include "tapelib/tape_util.h"
|
||||||
|
#include "tapelib/tape.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
|
#include "tapelib/filetape.h"
|
||||||
|
#include "tapelib/tape.h"
|
||||||
#include "tapelib/tape_util.h"
|
#include "tapelib/tape_util.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
const static std::vector<uint32_t> TEST_DATA = {123, 26, 87, 266, 111, 234,
|
using std::vector;
|
||||||
|
using namespace tape;
|
||||||
|
|
||||||
|
const static vector<uint32_t> TEST_DATA = {123, 26, 87, 266, 111, 234,
|
||||||
6, 63, 28, 1, 90, 33};
|
6, 63, 28, 1, 90, 33};
|
||||||
const static std::vector<uint32_t> TEST_DATA_SORTED = {
|
const static vector<uint32_t> TEST_DATA_SORTED = {1, 6, 26, 28, 33, 63,
|
||||||
1, 6, 26, 28, 33, 63, 87, 90, 111, 123, 234, 266};
|
87, 90, 111, 123, 234, 266};
|
||||||
|
|
||||||
std::vector<uint32_t> read_from_tape_backwards(tape::Tape &tape) {
|
vector<uint32_t> read_from_tape_backwards(Tape &tape) {
|
||||||
std::vector<uint32_t> data;
|
vector<uint32_t> data;
|
||||||
do {
|
do {
|
||||||
data.push_back(tape.read());
|
data.push_back(tape.read());
|
||||||
} while (tape.seek_backwards());
|
} while (tape.seek_backwards());
|
||||||
|
@ -16,40 +23,39 @@ std::vector<uint32_t> read_from_tape_backwards(tape::Tape &tape) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOLINTBEGIN(*-magic-numbers)
|
// NOLINTBEGIN
|
||||||
TEST_CASE("Sorting FileTape with external sort", "[sort]") {
|
TEST_CASE("Sorting FileTape with external sort", "[sort]") {
|
||||||
tape::FileTape input(TEST_DATA);
|
FileTape input(TEST_DATA);
|
||||||
tape::FileTape output(input);
|
FileTape output(input);
|
||||||
|
|
||||||
SECTION("Sorting with no limitations") {
|
SECTION("Sorting with no limitations") {
|
||||||
tape::external_sort(input, output, tape::FILETAPE_FACTORY);
|
external_sort(input, output, FILETAPE_FACTORY);
|
||||||
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Sorting with 4 elements in memory limit") {
|
SECTION("Sorting with 4 elements in memory limit") {
|
||||||
tape::external_sort(input, output, tape::FILETAPE_FACTORY, 4);
|
external_sort(input, output, FILETAPE_FACTORY, 4);
|
||||||
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Sorting with 9 elements in memory limit") {
|
SECTION("Sorting with 9 elements in memory limit") {
|
||||||
tape::external_sort(input, output, tape::FILETAPE_FACTORY, 9);
|
external_sort(input, output, FILETAPE_FACTORY, 9);
|
||||||
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Sorting with vector size elements in memory limit") {
|
SECTION("Sorting with vector size elements in memory limit") {
|
||||||
tape::external_sort(input, output, tape::FILETAPE_FACTORY,
|
external_sort(input, output, FILETAPE_FACTORY, TEST_DATA.size());
|
||||||
TEST_DATA.size());
|
|
||||||
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Sorting with 1000 elements in memory limit") {
|
SECTION("Sorting with 1000 elements in memory limit") {
|
||||||
tape::external_sort(input, output, tape::FILETAPE_FACTORY, 1000);
|
external_sort(input, output, FILETAPE_FACTORY, 1000);
|
||||||
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Sorting with 1 elements in memory limit") {
|
SECTION("Sorting with 1 elements in memory limit") {
|
||||||
tape::external_sort(input, output, tape::FILETAPE_FACTORY, 1);
|
external_sort(input, output, FILETAPE_FACTORY, 1);
|
||||||
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
REQUIRE(read_from_tape_backwards(output) == TEST_DATA_SORTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NOLINTEND(*-magic-numbers)
|
// NOLINTEND
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
#include "tapelib/filetape.h"
|
#include "tapelib/filetape.h"
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
const static std::vector<uint32_t> TEST_DATA = {1, 12345, 0, 2222222222,
|
using std::vector;
|
||||||
4294967295};
|
using namespace tape;
|
||||||
|
|
||||||
// NOLINTBEGIN(readability-function-cognitive-complexity)
|
const static vector<uint32_t> TEST_DATA = {1, 12345, 0, 2222222222, 4294967295};
|
||||||
|
|
||||||
|
// NOLINTBEGIN
|
||||||
TEST_CASE("Reading data from a FileTape", "[filetape]") {
|
TEST_CASE("Reading data from a FileTape", "[filetape]") {
|
||||||
tape::FileTape tape(TEST_DATA);
|
FileTape tape(TEST_DATA);
|
||||||
|
|
||||||
SECTION("Read all data sequentially") {
|
SECTION("Read all data sequentially") {
|
||||||
REQUIRE(tape.read() == TEST_DATA[0]);
|
REQUIRE(tape.read() == TEST_DATA[0]);
|
||||||
|
@ -38,7 +41,7 @@ TEST_CASE("Reading data from a FileTape", "[filetape]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Seeking forward and backwards", "[filetape]") {
|
TEST_CASE("Seeking forward and backwards", "[filetape]") {
|
||||||
tape::FileTape tape(TEST_DATA);
|
FileTape tape(TEST_DATA);
|
||||||
|
|
||||||
SECTION("Rewinding at the beginning of a file tape") {
|
SECTION("Rewinding at the beginning of a file tape") {
|
||||||
REQUIRE(tape.seek_backwards() == false);
|
REQUIRE(tape.seek_backwards() == false);
|
||||||
|
@ -67,7 +70,7 @@ TEST_CASE("Seeking forward and backwards", "[filetape]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Writing to a file tape", "[filetape]") {
|
TEST_CASE("Writing to a file tape", "[filetape]") {
|
||||||
tape::FileTape tape(3);
|
FileTape tape(3);
|
||||||
|
|
||||||
tape.write(0);
|
tape.write(0);
|
||||||
REQUIRE(tape.read() == 0);
|
REQUIRE(tape.read() == 0);
|
||||||
|
@ -83,4 +86,4 @@ TEST_CASE("Writing to a file tape", "[filetape]") {
|
||||||
tape.write(4);
|
tape.write(4);
|
||||||
REQUIRE(tape.read() == 4);
|
REQUIRE(tape.read() == 4);
|
||||||
}
|
}
|
||||||
// NOLINTEND(readability-function-cognitive-complexity)
|
// NOLINTEND
|
||||||
|
|
|
@ -6,6 +6,12 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
using std::setfill;
|
||||||
|
using std::setw;
|
||||||
|
using std::string;
|
||||||
|
using std::to_string;
|
||||||
|
using namespace tape;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate big input data sets for external sort testing.
|
* Generate big input data sets for external sort testing.
|
||||||
* Takes 2 positional arguments - first one is the ouput file name,
|
* Takes 2 positional arguments - first one is the ouput file name,
|
||||||
|
@ -17,7 +23,7 @@ int main(int argc, char *argv[]) {
|
||||||
std::cerr << "Not enough arguments" << std::endl;
|
std::cerr << "Not enough arguments" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
std::string out_name = argv[1]; // NOLINT
|
string out_name = argv[1]; // NOLINT
|
||||||
size_t cells = std::stoi(argv[2]); // NOLINT
|
size_t cells = std::stoi(argv[2]); // NOLINT
|
||||||
std::ofstream out(out_name);
|
std::ofstream out(out_name);
|
||||||
if (!out.is_open()) {
|
if (!out.is_open()) {
|
||||||
|
@ -25,11 +31,10 @@ int main(int argc, char *argv[]) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
srand(time(nullptr));
|
srand(time(nullptr));
|
||||||
out << std::setfill('0') << std::setw(tape::FT_CELL_SIZE)
|
out << setfill('0') << setw(tape::FT_CELL_SIZE) << to_string(rand());
|
||||||
<< std::to_string(rand());
|
|
||||||
for (size_t i = 1; i < cells; i++) {
|
for (size_t i = 1; i < cells; i++) {
|
||||||
out << tape::FT_DELIMETER << std::setfill('0')
|
out << FT_DELIMETER << setfill('0') << setw(tape::FT_CELL_SIZE)
|
||||||
<< std::setw(tape::FT_CELL_SIZE) << std::to_string(rand());
|
<< to_string(rand());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue