1 #ifndef UTOPIA_DATAIO_DATA_MANAGER_HH
2 #define UTOPIA_DATAIO_DATA_MANAGER_HH
9 #include <unordered_map>
13 #include "../../core/logging.hh"
14 #include "../../core/type_traits.hh"
15 #include "../cfg_utils.hh"
68 template <
class TaskType,
71 class ExecutionProcessType >
129 template <
class Traits >
137 using Task =
typename Traits::Task;
149 using TaskMap = std::unordered_map< std::string, std::shared_ptr< Task > >;
156 std::unordered_map< std::string, std::shared_ptr< Decider > >;
160 std::map< std::string, std::shared_ptr< Decider > >;
164 std::unordered_map< std::string, std::shared_ptr< Trigger > >;
168 std::map< std::string, std::shared_ptr< Trigger > >;
172 std::unordered_map< std::string, std::vector< std::string > >;
178 std::shared_ptr< spdlog::logger >
_log;
215 template <
typename ObjMap,
typename KnownObjectsMap >
219 _log->debug(
"Setting up name -> object map from config node ...");
224 throw std::invalid_argument(
"Received a zombie node for the setup "
225 "of DataManager objects!");
227 else if (not cfg.IsMap())
229 throw std::invalid_argument(
"Expected a mapping for DataManager "
230 "object setup, got:\n" +
236 _log->debug(
"Configuring DataManager objects ... (container size: {})",
237 known_objects.size());
249 for (
const auto& node_pair : cfg)
254 const auto cfg_name = node_pair.first.as< std::string >();
255 const auto& obj_cfg = node_pair.second;
257 const auto type_name = get_as< std::string >(
"type", obj_cfg);
259 _log->debug(
"Attempting to build {} of type {} from config",
263 if (known_objects.find(type_name) == known_objects.end())
265 throw std::invalid_argument(
"Error for node " + cfg_name +
266 ": No 'type' node given");
272 _log->debug(
" ... using given arguments from config ...");
274 known_objects[type_name]();
275 map[cfg_name]->set_from_cfg(obj_cfg[
"args"]);
282 _log->debug(
"... constructing {} of type {} without "
283 "config args because no node 'args' is "
284 "given for it in the config.",
288 map[cfg_name] = known_objects[type_name]();
312 throw std::invalid_argument(
313 "Error: data_manager config node needs to contain a node "
314 "'tasks' which it apparently is missing ");
316 if (not task_cfg.IsMap())
318 throw std::invalid_argument(
"Expected a mapping for DataManager "
319 "task filtering, got:\n" +
323 for (
const auto& node_pair : task_cfg)
328 const auto cfg_name = node_pair.first.as< std::string >();
329 const auto& obj_cfg = node_pair.second;
331 _log->debug(
"Investigating task {} and checking if it is active ",
334 if (get_as< bool >(
"active", obj_cfg))
337 _log->debug(
"Task '{}' was marked as active; will be kept.",
340 if (tasks.find(cfg_name) == tasks.end())
342 throw std::invalid_argument(
343 "Error, no task supplied to the datamanager is named " +
348 map[cfg_name] = tasks[cfg_name];
354 _log->debug(
"Task '{}' was marked as not active; skipping.",
378 template <
typename DTMap >
382 std::string lookup_key)
389 _log->debug(
"Building task to {} associations from given config ...",
395 for (
const auto& node_pair : task_cfg)
398 const auto task_name = node_pair.first.as< std::string >();
399 const auto& task_cfg = node_pair.second;
402 const auto active = get_as< bool >(
"active", task_cfg,
true);
407 _log->debug(
"Task '{}' was marked as not active; skipping.",
414 const auto dt_to_associate_to =
415 get_as< std::string >(lookup_key, task_cfg);
418 if (dt_map.find(dt_to_associate_to) == dt_map.end())
420 this->_log->info(
" Error for decider/trigger: {}",
422 throw std::invalid_argument(
423 "Error when trying to associate tasks to deciders or "
425 "Name in config does not match the name of a "
426 "decider/trigger known to the datamanager");
431 map[dt_to_associate_to].push_back(task_name);
433 _log->debug(
"Associating task '{}' to {} '{}'.",
455 template <
class Model,
typename... Args >
460 *
this, std::forward< Model >(model), std::forward< Args >(args)...);
506 return _decider_task_map;
517 return _trigger_task_map;
525 const std::shared_ptr< spdlog::logger >&
603 std::unordered_map< std::string,
604 std::function< std::shared_ptr< Decider >() > >
606 std::unordered_map< std::string,
607 std::function< std::shared_ptr< Trigger >() > >
611 _log(spdlog::get(
"data_mngr")),
612 _tasks(_filter_tasks_from_config(cfg[
"tasks"], tasks)),
613 _deciders(_setup_from_config<
DeciderMap >(cfg[
"deciders"], deciders)),
614 _triggers(_setup_from_config<
TriggerMap >(cfg[
"triggers"], triggers)),
617 _associate_from_config(cfg[
"tasks"], _deciders,
"decider")),
619 _associate_from_config(cfg[
"tasks"], _triggers,
"trigger")),
620 _execution_process(execproc)
647 std::map< std::string, std::string > decider_task_assocs = {},
648 std::map< std::string, std::string > trigger_task_assocs = {}) :
650 _log(spdlog::get(
"data_mngr")),
651 _tasks(TaskMap(tasks.begin(), tasks.end())),
652 _deciders(DeciderMap(deciders.begin(), deciders.end())),
653 _triggers(TriggerMap(triggers.begin(), triggers.end())),
655 _decider_task_map(_DMUtils::build_task_association_map< AssocsMap >(
656 tasks, deciders, decider_task_assocs)),
657 _trigger_task_map(_DMUtils::build_task_association_map< AssocsMap >(
658 tasks, triggers, trigger_task_assocs)),
659 _execution_process(execproc)
661 _log->info(
"DataManager setup with {} task(s), {} decider(s), and "
664 _decider_task_map.size(),
665 _trigger_task_map.size());
715 template <
typename Model >
Manage different tasks of writing out data from a source in a uniform yet flexible way....
Definition: data_manager.hh:131
ObjMap _setup_from_config(const Config &cfg, KnownObjectsMap &&known_objects)
Definition: data_manager.hh:217
std::unordered_map< std::string, std::shared_ptr< Decider > > DeciderMap
Map of decider names to decider functions.
Definition: data_manager.hh:156
typename Traits::Task Task
Task type, as defined in the traits.
Definition: data_manager.hh:137
DataManager()=default
Construct a new Data Manager object.
DeciderMap & get_deciders()
Get the container of decider objects.
Definition: data_manager.hh:471
virtual ~DataManager()=default
Destroy the Data Manager object.
DataManager & operator=(const DataManager &other)=default
Copy assignment.
DataManager(DataManager &&other)=default
Construct a new Data Manager object.
TaskMap _filter_tasks_from_config(const Config &task_cfg, TaskMap &tasks)
Check which tasks supplied to the datamanager are active and shall be retained, using the config node...
Definition: data_manager.hh:305
typename Traits::Trigger Trigger
Trigger type, as defined in the traits.
Definition: data_manager.hh:143
void operator()(Model &&model, Args &&... args)
Invoke the execution process.
Definition: data_manager.hh:457
void swap(DataManager &other)
Exchange the state of the caller with the argument 'other'.
Definition: data_manager.hh:676
std::map< std::string, std::shared_ptr< Task > > OrderedTaskMap
Same as TaskMap, but using std::map such that ordering is preserved.
Definition: data_manager.hh:152
ExecutionProcess _execution_process
Callable which tells how to utilize triggers, deciders, tasks to write data.
Definition: data_manager.hh:211
AssocsMap & get_decider_task_map()
Get the decider task map object.
Definition: data_manager.hh:504
AssocsMap _trigger_task_map
Mapping from trigger names to containers of names of tasks that use those triggers.
Definition: data_manager.hh:205
std::map< std::string, std::shared_ptr< Decider > > OrderedDeciderMap
Same as DeciderMap, but using std::map such that ordering is preserved.
Definition: data_manager.hh:160
DataManager(const DataManager &other)=default
Construct a new Data Manager object.
DataManager & operator=(DataManager &&other)=default
Move assignment.
TriggerMap & get_triggers()
Get the container of trigger objects.
Definition: data_manager.hh:493
DataManager(const Config &cfg, TaskMap tasks, std::unordered_map< std::string, std::function< std::shared_ptr< Decider >() > > deciders, std::unordered_map< std::string, std::function< std::shared_ptr< Trigger >() > > triggers, ExecutionProcess execproc)
Construct DataManager using a config node.
Definition: data_manager.hh:600
TaskMap & get_tasks()
Get the container of task objects.
Definition: data_manager.hh:482
typename Traits::ExecutionProcess ExecutionProcess
Execution process type, as defined in the traits.
Definition: data_manager.hh:146
TaskMap _tasks
Stores (name, task) pairs in an unordered map.
Definition: data_manager.hh:183
std::shared_ptr< spdlog::logger > _log
Used to inform about progress of DataManager operations.
Definition: data_manager.hh:178
std::unordered_map< std::string, std::vector< std::string > > AssocsMap
Map of decider/task names to a collection of task names.
Definition: data_manager.hh:172
AssocsMap _associate_from_config(const Config &task_cfg, DTMap &&dt_map, std::string lookup_key)
Given a configuration, builds an association map.
Definition: data_manager.hh:380
std::unordered_map< std::string, std::shared_ptr< Task > > TaskMap
Map of task names to shared pointers of Tasks; supporting polymorphism.
Definition: data_manager.hh:149
const std::shared_ptr< spdlog::logger > & get_logger() const
Get the logger used in this DataManager.
Definition: data_manager.hh:526
AssocsMap _decider_task_map
Mapping from deciders names to containers of names of tasks that use those deciders.
Definition: data_manager.hh:199
typename Traits::Decider Decider
Decider type, as defined in the traits.
Definition: data_manager.hh:140
DataManager(OrderedTaskMap tasks, OrderedDeciderMap deciders, OrderedTriggerMap triggers, ExecutionProcess execproc, std::map< std::string, std::string > decider_task_assocs={}, std::map< std::string, std::string > trigger_task_assocs={})
Construct DataManager without config node from passed mappings only. If the last two arguments are no...
Definition: data_manager.hh:643
AssocsMap & get_trigger_task_map()
Get the trigger task map object.
Definition: data_manager.hh:515
TriggerMap _triggers
Stores (name, triggerfunction) pairs in an unordered map.
Definition: data_manager.hh:193
DeciderMap _deciders
Stores (name, deciderfunction) pairs in an unordered map.
Definition: data_manager.hh:188
std::unordered_map< std::string, std::shared_ptr< Trigger > > TriggerMap
Map of trigger names to trigger functions.
Definition: data_manager.hh:164
std::map< std::string, std::shared_ptr< Trigger > > OrderedTriggerMap
Same as TriggerMap, but using std::map such that ordering is preserved.
Definition: data_manager.hh:168
Base class interface for Models using the CRT Pattern.
Definition: model.hh:112
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
std::string to_string(const Config &node)
Given a config node, returns a string representation of it.
Definition: cfg_utils.hh:110
Decider< Model > Trigger
Definition: defaults.hh:439
void swap(WriteTask< BGB, DW, DB, AWG, AWD > &lhs, WriteTask< BGB, DW, DB, AWG, AWD > &rhs)
Swaps the state of lhs and rhs.
Definition: write_task.hh:240
Definition: metaprogramming.hh:43
Type traits for the DataManager This allows to specify custom types for the DataManager....
Definition: data_manager.hh:73
ExecutionProcessType ExecutionProcess
Definition: data_manager.hh:77
TaskType Task
Definition: data_manager.hh:74
DeciderType Decider
Definition: data_manager.hh:75
TriggerType Trigger
Definition: data_manager.hh:76
Common interface for all deciders (and triggers, for that matter). Every decider/Trigger must inherit...
Definition: defaults.hh:166
Functor representing what is considered the most widely used execution process for writing data.
Definition: defaults.hh:84