Skip to content

Commit

Permalink
Improvements for the ConfigManager, part 1 (ad-freiburg#1054)
Browse files Browse the repository at this point in the history
`ConfigManager::addOption` now returns a reference to the created option. This makes working with this option much simpler in comparison to the previous interface, where we had to explicitly (and redundantly and error-prone) request the option by its key.
  • Loading branch information
schlegan authored Aug 17, 2023
1 parent d8039e1 commit 6753cb9
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 224 deletions.
20 changes: 10 additions & 10 deletions benchmark/BenchmarkExamples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "util/ConfigManager/ConfigOption.h"
#include "util/Random.h"

using namespace std::string_literals;

namespace ad_benchmark {
/*
A typical problem in benchmarking is that the result of a computation is
Expand Down Expand Up @@ -49,19 +51,17 @@ class ConfigOptions : public BenchmarkInterface {
ConfigOptions() {
ad_utility::ConfigManager& manager = getConfigManager();

manager.createConfigOption<std::string>("date", "The current date.",
&dateString_, "22.3.2023");
manager.addOption("date", "The current date.", &dateString_, "22.3.2023"s);

manager.createConfigOption<int>("numSigns", "The number of street signs.",
&numberOfStreetSigns_, 10);
manager.addOption("numSigns", "The number of street signs.",
&numberOfStreetSigns_, 10);

manager.createConfigOption<std::vector<bool>>(
"CoinFlipTry", "The number of succesful coin flips.", &wonOnTryX_,
std::vector{false, false, false, false, false});
manager.addOption("CoinFlipTry", "The number of succesful coin flips.",
&wonOnTryX_, {false, false, false, false, false});

manager.createConfigOption<float>({"Accounts", "Personal", "Steve"},
"Steves saving account balance.",
&balanceOnStevesSavingAccount_, -41.9);
manager.addOption({"Accounts"s, "Personal"s, "Steve"s},
"Steves saving account balance.",
&balanceOnStevesSavingAccount_, -41.9f);
}
};

Expand Down
2 changes: 1 addition & 1 deletion benchmark/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Defining the configuration options and passing values to them.
### Adding options
Adding configuration options is done by adding configuration option to the private member variable `manager_`, accessible via a getter, by using the function `ConfigManager::createConfigOption`. That is best done in the constructor of your class.
Adding configuration options is done by adding configuration option to the private member variable `manager_`, accessible via a getter, by using the function `ConfigManager::addOption`. That is best done in the constructor of your class.
In our system a configuration option is described by a handful of characteristics:
Expand Down
59 changes: 34 additions & 25 deletions src/util/ConfigManager/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
#include <absl/strings/str_cat.h>
#include <antlr4-runtime.h>

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <ranges>
#include <regex>
#include <sstream>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>

#include "util/Algorithm.h"
#include "util/ConfigManager/ConfigExceptions.h"
Expand All @@ -30,6 +34,25 @@
#include "util/json.h"

namespace ad_utility {
static auto configurationOptionsImpl(auto& configurationOptions) {
return std::views::transform(configurationOptions, [](auto& pair) {
// Make sure, that there is no null pointer.
AD_CORRECTNESS_CHECK(pair.second);

// Return a dereferenced reference.
return std::tie(pair.first, *pair.second);
});
}

// ____________________________________________________________________________
auto ConfigManager::configurationOptions() {
return configurationOptionsImpl(configurationOptions_);
}

// ____________________________________________________________________________
auto ConfigManager::configurationOptions() const {
return configurationOptionsImpl(configurationOptions_);
}

// ____________________________________________________________________________
std::string ConfigManager::createJsonPointerString(
Expand Down Expand Up @@ -103,22 +126,8 @@ void ConfigManager::addConfigOption(

// Add the configuration option.
configurationOptions_.insert(
{createJsonPointerString(pathToOption), std::move(option)});
}

// ____________________________________________________________________________
const ConfigOption& ConfigManager::getConfigurationOptionByNestedKeys(
const std::vector<std::string>& keys) const {
// If there is an config option with that described location, then this should
// point to the configuration option.
const std::string ptr{createJsonPointerString(keys)};

if (configurationOptions_.contains(ptr)) {
return configurationOptions_.at(ptr);
} else {
throw NoConfigOptionFoundException(vectorOfKeysForJsonToString(keys),
printConfigurationDoc(true));
}
{createJsonPointerString(pathToOption),
std::make_unique<ConfigOption>(std::move(option))});
}

// ____________________________________________________________________________
Expand Down Expand Up @@ -217,7 +226,7 @@ void ConfigManager::parseConfig(const nlohmann::json& j) {
an exception, if a configuration option was given a value of the wrong type,
or if it HAD to be set, but wasn't.
*/
for (auto& [key, option] : configurationOptions_) {
for (auto&& [key, option] : configurationOptions()) {
// Set the option, if possible, with the pointer to the position of the
// current configuration in json.
if (const nlohmann::json::json_pointer configurationOptionJsonPosition{key};
Expand All @@ -229,8 +238,8 @@ void ConfigManager::parseConfig(const nlohmann::json& j) {

/*
If the option hasn't set the variable, that it's internal variable pointer
points to, that means, it doesn't have a default value, and needs to be set
by the user at runtime, but wasn't.
points to, that means, it doesn't have a default value, and needs to be
set by the user at runtime, but wasn't.
*/
if (!option.wasSet()) {
throw ConfigOptionWasntSetException(key);
Expand Down Expand Up @@ -258,7 +267,7 @@ std::string ConfigManager::printConfigurationDoc(
- The default value of the configuration option.
- An example value, of the correct type.
*/
for (const auto& [path, option] : configurationOptions_) {
for (const auto& [path, option] : configurationOptions()) {
// Pointer to the position of this option in
// `configuratioOptionsVisualization`.
const nlohmann::json::json_pointer jsonOptionPointer{path};
Expand All @@ -281,13 +290,13 @@ std::string ConfigManager::printConfigurationDoc(

// List the configuration options themselves.
const std::string& listOfConfigurationOptions = ad_utility::lazyStrJoin(
std::views::transform(configurationOptions_,
std::views::transform(configurationOptions(),
[](const auto& pair) {
// Add the location of the option and the option
// itself.
return absl::StrCat(
"Location : ", pair.first, "\n",
static_cast<std::string>(pair.second));
"Location : ", std::get<0>(pair), "\n",
static_cast<std::string>(std::get<1>(pair)));
}),
"\n\n");

Expand Down Expand Up @@ -320,8 +329,8 @@ std::string
ConfigManager::getListOfNotChangedConfigOptionsWithDefaultValuesAsString()
const {
// For only looking at the configuration options in our map.
auto onlyConfigurationOptionsView = std::views::transform(
configurationOptions_, [](const auto& pair) { return pair.second; });
auto onlyConfigurationOptionsView =
std::views::values(configurationOptions());

// Returns true, if the `ConfigOption` has a default value and wasn't set at
// runtime.
Expand Down
Loading

0 comments on commit 6753cb9

Please sign in to comment.