Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bindings/python_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,6 @@ PYBIND11_MODULE(_py_capio_cl, m) {
});

m.def("serialize", &capiocl::serializer::Serializer::dump, py::arg("engine"),
py::arg("filename"), py::arg("version") = capiocl::CAPIO_CL_VERSION::V1);
py::arg("filename"), py::arg("compress") = false,
py::arg("version") = capiocl::CAPIO_CL_VERSION::V1);
}
25 changes: 22 additions & 3 deletions capiocl/serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ class SerializerException final : public std::exception {
/// @brief Dump the current loaded CAPIO-CL configuration from class Engine to a CAPIO-CL
/// configuration file.
class Serializer final {
/**
* Check whether a CAPIO-CL entry has a parent entry for which the same rules applies, and tell
* whether this entry can be omitted by using rule inheritance.
* @param compress
* @param path
* @param engine
* @return
*/
static bool entryCanBeCompressed(bool compress, const std::filesystem::path &path,
const engine::Engine &engine);

/**
* Sort path entries from longest to shortest
* @param paths
*/
static void sortPathsByDecreasingLength(std::vector<std::string> &paths);

/// @brief Available serializers for CAPIO-CL
struct available_serializers {
Expand All @@ -37,21 +53,23 @@ class Serializer final {
*
* @param engine instance of Engine to dump
* @param filename path of output file
* @param compress Compress the serialized output
* @throws SerializerException
*/
static void serialize_v1(const engine::Engine &engine,
const std::filesystem::path &filename);
const std::filesystem::path &filename, bool compress = false);

/**
* @brief Dump the current configuration loaded into an instance of Engine to a CAPIO-CL
* VERSION 1.1 configuration file.
*
* @param engine instance of Engine to dump
* @param filename path of output file
* @param compress Compress the serialized output
* @throws SerializerException
*/
static void serialize_v1_1(const engine::Engine &engine,
const std::filesystem::path &filename);
const std::filesystem::path &filename, bool compress = false);
};

public:
Expand All @@ -61,10 +79,11 @@ class Serializer final {
*
* @param engine instance of Engine to dump
* @param filename path of output file
* @param compress Compress directories entries when possible
* @param version Version of CAPIO-CL used to generate configuration files.
*/
static void dump(const engine::Engine &engine, const std::filesystem::path &filename,
const std::string &version = CAPIO_CL_VERSION::V1);
bool compress = false, const std::string &version = CAPIO_CL_VERSION::V1);
};
} // namespace capiocl::serializer
#endif // CAPIO_CL_SERIALIZER_H
38 changes: 35 additions & 3 deletions src/Serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

void capiocl::serializer::Serializer::dump(const engine::Engine &engine,
const std::filesystem::path &filename,
const std::string &version) {
const bool compress, const std::string &version) {
if (version == CAPIO_CL_VERSION::V1) {
printer::print(printer::CLI_LEVEL_INFO, "Serializing engine with V1 specification");
available_serializers::serialize_v1(engine, filename);
available_serializers::serialize_v1(engine, filename, compress);
} else if (version == CAPIO_CL_VERSION::V1_1) {
printer::print(printer::CLI_LEVEL_INFO, "Serializing engine with V1.1 specification");
available_serializers::serialize_v1_1(engine, filename);
available_serializers::serialize_v1_1(engine, filename, compress);
} else {
const auto message = "No serializer available for CAPIO-CL version: " + version;
throw SerializerException(message);
Expand All @@ -25,4 +25,36 @@ void capiocl::serializer::Serializer::dump(const engine::Engine &engine,
capiocl::serializer::SerializerException::SerializerException(const std::string &msg)
: message(msg) {
printer::print(printer::CLI_LEVEL_ERROR, msg);
}

bool capiocl::serializer::Serializer::entryCanBeCompressed(const bool compress,
const std::filesystem::path &path,
const engine::Engine &engine) {

if (!compress) {
return false;
}

if (engine.isDirectory(path)) {
return false;
}

const auto parent_path = path.parent_path();

if (!engine.contains(parent_path)) {
return false;
}

return engine.getCommitRule(path) == engine.getCommitRule(parent_path) &&
engine.getFireRule(path) == engine.getFireRule(parent_path);
}


void capiocl::serializer::Serializer::sortPathsByDecreasingLength(std::vector<std::string> &paths) {
std::sort(paths.begin(), paths.end(), [](const std::string &a, const std::string &b) {
if (a.length() != b.length()) {
return a.length() > b.length();
}
return a > b;
});
}
38 changes: 34 additions & 4 deletions src/serializers/v1.1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
#include "capiocl/serializer.h"

void capiocl::serializer::Serializer::available_serializers::serialize_v1_1(
const engine::Engine &engine, const std::filesystem::path &filename) {
const engine::Engine &engine, const std::filesystem::path &filename, const bool compress) {

if (compress) {
printer::print(printer::CLI_LEVEL_WARNING,
"Using configuration compression to directories!");
}

jsoncons::json doc;
doc["version"] = 1.1;
doc["name"] = engine.getWorkflowName();
Expand All @@ -24,7 +30,22 @@ void capiocl::serializer::Serializer::available_serializers::serialize_v1_1(
jsoncons::json storage = jsoncons::json::object();
jsoncons::json io_graph = jsoncons::json::array();

for (const auto &[path, entry] : files) {
std::vector<std::string> keys;
keys.reserve(files.size());
for (const auto &[k, v] : files) {
keys.push_back(k);
}

sortPathsByDecreasingLength(keys);

for (const auto &path : keys) {
const auto entry = files.at(path);

if (entryCanBeCompressed(compress, path, engine)) {
printer::print(printer::CLI_LEVEL_WARNING, "Compressing entry " + path);
continue;
}

if (entry.permanent) {
permanent.push_back(path);
}
Expand All @@ -41,13 +62,22 @@ void capiocl::serializer::Serializer::available_serializers::serialize_v1_1(
}
}

for (const auto &[app_name, outputs] : app_outputs) {
for (auto &[app_name, outputs] : app_outputs) {
jsoncons::json app = jsoncons::json::object();
jsoncons::json streaming = jsoncons::json::array();
std::vector<std::string> filtered_outputs;

sortPathsByDecreasingLength(outputs);

for (const auto &path : outputs) {
const auto &entry = files.at(path);

if (entryCanBeCompressed(compress, path, engine)) {
continue;
}

filtered_outputs.push_back(path);

jsoncons::json streaming_item = jsoncons::json::object();
std::string committed = entry.commit_rule;
const char *name_kind = entry.is_file ? "name" : "dirname";
Expand Down Expand Up @@ -87,7 +117,7 @@ void capiocl::serializer::Serializer::available_serializers::serialize_v1_1(

app["name"] = app_name;
app["input_stream"] = app_inputs[app_name];
app["output_stream"] = outputs;
app["output_stream"] = filtered_outputs;
app["streaming"] = streaming;

io_graph.push_back(app);
Expand Down
38 changes: 34 additions & 4 deletions src/serializers/v1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
#include "capiocl/serializer.h"

void capiocl::serializer::Serializer::available_serializers::serialize_v1(
const engine::Engine &engine, const std::filesystem::path &filename) {
const engine::Engine &engine, const std::filesystem::path &filename, const bool compress) {

if (compress) {
printer::print(printer::CLI_LEVEL_WARNING,
"Using configuration compression to directories!");
}

jsoncons::json doc;
doc["name"] = engine.getWorkflowName();

Expand All @@ -23,7 +29,22 @@ void capiocl::serializer::Serializer::available_serializers::serialize_v1(
jsoncons::json storage = jsoncons::json::object();
jsoncons::json io_graph = jsoncons::json::array();

for (const auto &[path, entry] : files) {
std::vector<std::string> keys;
keys.reserve(files.size());
for (const auto &[k, v] : files) {
keys.push_back(k);
}

sortPathsByDecreasingLength(keys);

for (const auto &path : keys) {
const auto entry = files.at(path);

if (entryCanBeCompressed(compress, path, engine)) {
printer::print(printer::CLI_LEVEL_WARNING, "Compressing entry " + path);
continue;
}

if (entry.permanent) {
permanent.push_back(path);
}
Expand All @@ -40,13 +61,22 @@ void capiocl::serializer::Serializer::available_serializers::serialize_v1(
}
}

for (const auto &[app_name, outputs] : app_outputs) {
for (auto &[app_name, outputs] : app_outputs) {
jsoncons::json app = jsoncons::json::object();
jsoncons::json streaming = jsoncons::json::array();
std::vector<std::string> filtered_outputs;

sortPathsByDecreasingLength(outputs);

for (const auto &path : outputs) {
const auto &entry = files.at(path);

if (entryCanBeCompressed(compress, path, engine)) {
continue;
}

filtered_outputs.push_back(path);

jsoncons::json streaming_item = jsoncons::json::object();
std::string committed = entry.commit_rule;
const char *name_kind = entry.is_file ? "name" : "dirname";
Expand Down Expand Up @@ -86,7 +116,7 @@ void capiocl::serializer::Serializer::available_serializers::serialize_v1(

app["name"] = app_name;
app["input_stream"] = app_inputs[app_name];
app["output_stream"] = outputs;
app["output_stream"] = filtered_outputs;
app["streaming"] = streaming;

io_graph.push_back(app);
Expand Down
5 changes: 3 additions & 2 deletions tests/cpp/test_exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ TEST(EXCEPTION_SUITE_NAME, testFailedserializeVersion) {
const std::filesystem::path source = "/tmp/capio_cl_jsons/V" + version + "/test24.json";
auto engine = capiocl::parser::Parser::parse(source, "/tmp");

EXPECT_THROW(capiocl::serializer::Serializer::dump(*engine, "test.json", "1234.5678"),
capiocl::serializer::SerializerException);
EXPECT_THROW(
capiocl::serializer::Serializer::dump(*engine, "test.json", false, "1234.5678"),
capiocl::serializer::SerializerException);
}
}

Expand Down
8 changes: 4 additions & 4 deletions tests/cpp/test_serialize_deserialize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ TEST(SERIALIZE_DESERIALIZE_SUITE_NAME, testSerializeParseCAPIOCLV1) {

engine.print();

capiocl::serializer::Serializer::dump(engine, path, _cl_version);
capiocl::serializer::Serializer::dump(engine, path, false, _cl_version);

std::filesystem::path resolve = "";
auto new_engine = capiocl::parser::Parser::parse(path, resolve);
Expand Down Expand Up @@ -74,7 +74,7 @@ TEST(SERIALIZE_DESERIALIZE_SUITE_NAME, testSerializeParseCAPIOCLV1NcloseNfiles)
engine.addProducer(file_1_name, producer_name);
engine.addConsumer(file_1_name, consumer_name);

capiocl::serializer::Serializer::dump(engine, path, _cl_version);
capiocl::serializer::Serializer::dump(engine, path, false, _cl_version);

std::filesystem::path resolve = "";
auto new_engine = capiocl::parser::Parser::parse(path, resolve);
Expand Down Expand Up @@ -110,7 +110,7 @@ TEST(SERIALIZE_DESERIALIZE_SUITE_NAME, testSerializeParseCAPIOCLV1FileDeps) {
engine.setFileDeps(file_3_name, {file_1_name, file_2_name});

engine.print();
capiocl::serializer::Serializer::dump(engine, path, _cl_version);
capiocl::serializer::Serializer::dump(engine, path, false, _cl_version);

std::filesystem::path resolve = "";
auto new_engine = capiocl::parser::Parser::parse(path, resolve);
Expand Down Expand Up @@ -139,7 +139,7 @@ TEST(SERIALIZE_DESERIALIZE_SUITE_NAME, testSerializeCommitOnCloseCountNoCommitRu
engine.setCommitedCloseNumber(file_1_name, 10);

engine.print();
capiocl::serializer::Serializer::dump(engine, path, _cl_version);
capiocl::serializer::Serializer::dump(engine, path, false, _cl_version);

std::filesystem::path resolve = "";
auto new_engine = capiocl::parser::Parser::parse(path, resolve);
Expand Down
Loading