Skip to content

Commit

Permalink
[FEATURE] Add config::read_from and config::write_to.
Browse files Browse the repository at this point in the history
  • Loading branch information
smehringer committed Aug 23, 2023
1 parent 7817dc2 commit 8817a76
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/hibf/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <cstddef> // for size_t
#include <filesystem> // for path
#include <functional> // for function
#include <iosfwd> // for ostream
#include <iterator> // for insert_iterator

#include <hibf/contrib/robin_hood.hpp> // for unordered_flat_set
Expand Down Expand Up @@ -82,6 +83,9 @@ struct config
// bool compressed{false};
//!\}

void read_from(std::istream & stream);
void write_to(std::ostream & stream) const;

private:
friend class cereal::access;

Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set (HIBF_SOURCE_FILES
hierarchical_interleaved_bloom_filter.cpp
config.cpp
detail/layout/simple_binning.cpp
detail/layout/execute.cpp
detail/layout/compute_fpr_correction.cpp
Expand Down
60 changes: 60 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// ---------------------------------------------------------------------------------------------------
// Copyright (c) 2006-2023, Knut Reinert & Freie Universität Berlin
// Copyright (c) 2016-2023, Knut Reinert & MPI für molekulare Genetik
// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
// shipped with this file and also available at: https://github.com/seqan/hibf/blob/main/LICENSE.md
// ---------------------------------------------------------------------------------------------------

#include <cassert>
#include <charconv>
#include <iostream>

#include <hibf/config.hpp>
#include <hibf/detail/prefixes.hpp>

#include <cereal/archives/json.hpp>

namespace hibf
{

void config::read_from(std::istream & stream)
{
std::string line;
std::stringstream config_str;

while (std::getline(stream, line) && line != prefix::meta_hibf_config_start)
;

assert(line == prefix::meta_hibf_config_start);

// TODO ##CONFIG: as prefix
while (std::getline(stream, line) && line != prefix::meta_hibf_config_end)
{
assert(line.size() >= 2);
assert(std::string_view{line}.substr(0, 1) == hibf::prefix::meta_header);
config_str << line.substr(1); // remove hibf::prefix::meta_header
}

assert(line == prefix::meta_hibf_config_end);

cereal::JSONInputArchive iarchive(config_str);
iarchive(*this);
}

void config::write_to(std::ostream & stream) const
{
// write json file to temprorary string stream with cereal
std::stringstream config_stream{};
cereal::JSONOutputArchive output(config_stream); // stream to cout
output(cereal::make_nvp("hibf_config", *this));

// write config
stream << prefix::meta_hibf_config_start << '\n';
std::string line;
while (std::getline(config_stream, line, '\n'))
stream << prefix::meta_header << line << '\n';
stream << prefix::meta_header << "}\n" // last closing bracket isn't written by loop above
<< prefix::meta_hibf_config_end << '\n';
}

} // namespace hibf
1 change: 1 addition & 0 deletions test/unit/hibf/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectories ()

hibf_test (config_test.cpp)
hibf_test (hierarchical_interleaved_bloom_filter_test.cpp)
hibf_test (interleaved_bloom_filter_test.cpp)
130 changes: 130 additions & 0 deletions test/unit/hibf/config_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include <gtest/gtest.h> // for Test, TestInfo, EXPECT_EQ, Message, TEST, TestPartResult

#include <cstddef> // for size_t
#include <sstream> // for operator<<, char_traits, basic_ostream, basic_stringstream, strings...
#include <string> // for allocator, string
#include <string_view> // for operator<<
#include <vector> // for vector

#include <hibf/config.hpp> // for config

TEST(config_test, write_to)
{
std::stringstream ss{};

hibf::config configuration;

configuration.number_of_user_bins = 123456789;
configuration.number_of_hash_functions = 4;
configuration.maximum_false_positive_rate = 0.0001;
configuration.threads = 31;
configuration.sketch_bits = 8;
configuration.tmax = 128;
configuration.alpha = 1.0;
configuration.max_rearrangement_ratio = 0.333;
configuration.disable_estimate_union = true;
configuration.disable_rearrangement = false;
configuration.disable_cutoffs = false;

configuration.write_to(ss);

std::string const expected_file{"@HIBF_CONFIG\n"
"@{\n"
"@ \"hibf_config\": {\n"
"@ \"version\": 1,\n"
"@ \"number_of_user_bins\": 123456789,\n"
"@ \"number_of_hash_functions\": 4,\n"
"@ \"maximum_false_positive_rate\": 0.0001,\n"
"@ \"threads\": 31,\n"
"@ \"sketch_bits\": 8,\n"
"@ \"tmax\": 128,\n"
"@ \"alpha\": 1.0,\n"
"@ \"max_rearrangement_ratio\": 0.333,\n"
"@ \"disable_estimate_union\": true,\n"
"@ \"disable_rearrangement\": false,\n"
"@ \"disable_cutoffs\": false\n"
"@ }\n"
"@}\n"
"@HIBF_CONFIG_END\n"};

EXPECT_EQ(ss.str(), expected_file);
}

TEST(config_test, read_from)
{
std::stringstream ss{"@HIBF_CONFIG\n"
"@{\n"
"@ \"hibf_config\": {\n"
"@ \"version\": 1,\n"
"@ \"number_of_user_bins\": 123456789,\n"
"@ \"number_of_hash_functions\": 4,\n"
"@ \"maximum_false_positive_rate\": 0.0001,\n"
"@ \"threads\": 31,\n"
"@ \"sketch_bits\": 8,\n"
"@ \"tmax\": 128,\n"
"@ \"alpha\": 1.0,\n"
"@ \"max_rearrangement_ratio\": 0.333,\n"
"@ \"disable_estimate_union\": true,\n"
"@ \"disable_rearrangement\": false,\n"
"@ \"disable_cutoffs\": false\n"
"@ }\n"
"@}\n"
"@HIBF_CONFIG_END\n"};

hibf::config configuration;
configuration.read_from(ss);

EXPECT_EQ(configuration.number_of_user_bins, 123456789);
EXPECT_EQ(configuration.number_of_hash_functions, 4);
EXPECT_EQ(configuration.maximum_false_positive_rate, 0.0001);
EXPECT_EQ(configuration.threads, 31);
EXPECT_EQ(configuration.sketch_bits, 8);
EXPECT_EQ(configuration.tmax, 128);
EXPECT_EQ(configuration.alpha, 1.0);
EXPECT_EQ(configuration.max_rearrangement_ratio, 0.333);
EXPECT_EQ(configuration.disable_estimate_union, true);
EXPECT_EQ(configuration.disable_rearrangement, false);
EXPECT_EQ(configuration.disable_cutoffs, false);
}

TEST(config_test, read_from_with_more_meta)
{
std::stringstream ss{"@blah some chopper stuff\n"
"@blah some chopper stuff\n"
"@blah some chopper stuff\n"
"@blah some chopper stuff\n"
"@blah some chopper stuff\n"
"@HIBF_CONFIG\n"
"@{\n"
"@ \"hibf_config\": {\n"
"@ \"version\": 1,\n"
"@ \"number_of_user_bins\": 123456789,\n"
"@ \"number_of_hash_functions\": 4,\n"
"@ \"maximum_false_positive_rate\": 0.0001,\n"
"@ \"threads\": 31,\n"
"@ \"sketch_bits\": 8,\n"
"@ \"tmax\": 128,\n"
"@ \"alpha\": 1.0,\n"
"@ \"max_rearrangement_ratio\": 0.333,\n"
"@ \"disable_estimate_union\": true,\n"
"@ \"disable_rearrangement\": false,\n"
"@ \"disable_cutoffs\": false\n"
"@ }\n"
"@}\n"
"@HIBF_CONFIG_END\n"};

hibf::config configuration;
configuration.read_from(ss);

EXPECT_EQ(configuration.number_of_user_bins, 123456789);
EXPECT_EQ(configuration.number_of_hash_functions, 4);
EXPECT_EQ(configuration.maximum_false_positive_rate, 0.0001);
EXPECT_EQ(configuration.threads, 31);
EXPECT_EQ(configuration.sketch_bits, 8);
EXPECT_EQ(configuration.tmax, 128);
EXPECT_EQ(configuration.alpha, 1.0);
EXPECT_EQ(configuration.max_rearrangement_ratio, 0.333);
EXPECT_EQ(configuration.disable_estimate_union, true);
EXPECT_EQ(configuration.disable_rearrangement, false);
EXPECT_EQ(configuration.disable_cutoffs, false);
}

0 comments on commit 8817a76

Please sign in to comment.