Skip to content

Commit 8074bbb

Browse files
committed
docs
1 parent 3a90b19 commit 8074bbb

19 files changed

Lines changed: 422 additions & 202 deletions

Framework/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ add_library(O2QualityControl
137137
src/KafkaPoller.cxx
138138
src/FlagHelpers.cxx
139139
src/ObjectMetadataHelpers.cxx
140-
src/DataAdapters.cxx
140+
src/QCInputsAdapters.cxx
141+
src/QCInputsFactory.cxx
141142
)
142143

143144
target_include_directories(
@@ -291,7 +292,7 @@ add_executable(o2-qc-test-core
291292
test/testKafkaTests.cxx
292293
test/testFlagHelpers.cxx
293294
test/testQualitiesToFlagCollectionConverter.cxx
294-
test/testData.cxx
295+
test/testQCInputs.cxx
295296
)
296297
set_property(TARGET o2-qc-test-core
297298
PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests)

Framework/include/QualityControl/AggregatorInterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "QualityControl/UserCodeInterface.h"
2424
#include "QualityControl/Quality.h"
2525
#include "QualityControl/Activity.h"
26-
#include "QualityControl/Data.h"
26+
#include "QualityControl/QCInputs.h"
2727

2828
namespace o2::quality_control::checker
2929
{

Framework/include/QualityControl/CheckInterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "QualityControl/UserCodeInterface.h"
2323
#include "QualityControl/Activity.h"
2424

25-
#include "QualityControl/Data.h"
25+
#include "QualityControl/QCInputs.h"
2626

2727
namespace o2::quality_control::core
2828
{

Framework/include/QualityControl/Data.h

Lines changed: 0 additions & 87 deletions
This file was deleted.

Framework/include/QualityControl/DataAdapters.h

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
// Copyright 2025 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
///
13+
/// \file QCInputs.h
14+
/// \author Michal Tichak
15+
/// \brief Generic container for heterogeneous QC input data.
16+
///
17+
/// \par Example
18+
/// \code{.cpp}
19+
/// QCInputs data;
20+
/// data.insert("count", 42u);
21+
/// if (auto opt = data.get<unsigned>("count")) {
22+
/// std::cout << "Count: " << opt->get() << std::endl;
23+
/// }
24+
/// for (const auto& v : data.iterateByType<unsigned>()) {
25+
/// // process each value
26+
/// }
27+
/// \endcode
28+
///
29+
30+
#ifndef QC_CORE_DATA_H
31+
#define QC_CORE_DATA_H
32+
33+
#include <any>
34+
#include <concepts>
35+
#include <functional>
36+
#include <memory>
37+
#include <optional>
38+
#include <string>
39+
#include <ranges>
40+
#include <type_traits>
41+
42+
namespace o2::quality_control::core
43+
{
44+
45+
/// \brief Requires a callable to return exactly the specified type.
46+
/// \tparam Function Callable type to invoke.
47+
/// \tparam Result Expected return type.
48+
/// \tparam Args Argument types for invocation.
49+
template <typename Function, typename Result, typename... Args>
50+
concept invocable_r = std::invocable<Function, Args...> &&
51+
std::same_as<std::invoke_result_t<Function, Args...>, Result>;
52+
53+
/// \brief Heterogeneous storage for named QC input objects.
54+
///
55+
/// Stores values in an std::any-based container keyed by strings,
56+
/// offering type-safe get, iteration, filtering, and transformation.
57+
/// Example of such container is transparent_unordered_map at the end of this file
58+
template <typename ContainerMap>
59+
class QCInputsGeneric
60+
{
61+
public:
62+
QCInputsGeneric() = default;
63+
64+
/// \brief Retrieve the object stored under the given key with matching type.
65+
/// \tparam Result Expected stored type.
66+
/// \param key Identifier for the stored object.
67+
/// \returns Optional reference to const Result if found desired item of type Result.
68+
/// \par Example
69+
/// \code{.cpp}
70+
/// if (auto opt = data.get<unsigned>("count")) {
71+
/// if (opt.has_value()){
72+
/// const unsigned& value = opt.value(); // careful about using auto here as we want to invoke implicit conversion operator of reference_wrapper
73+
/// }
74+
/// }
75+
/// \endcode
76+
template <typename Result>
77+
std::optional<std::reference_wrapper<const Result>> get(std::string_view key);
78+
79+
/// \brief Construct and store an object of type T under the given key.
80+
/// \tparam T Type to construct and store.
81+
/// \param key Identifier under which to store the object.
82+
/// \param args Arguments forwarded to T's constructor.
83+
/// \par Example
84+
/// \code{.cpp}
85+
/// data.emplace<std::string>("greeting", "hello");
86+
/// \endcode
87+
template <typename T, typename... Args>
88+
void emplace(std::string_view key, Args&&... args);
89+
90+
/// \brief Store a copy of value under the given key.
91+
/// \tparam T Type of the value to store.
92+
/// \param key Identifier under which to store the value.
93+
/// \param value Const reference to the value to insert.
94+
/// \par Example
95+
/// \code{.cpp}
96+
/// data.insert("count", 10u);
97+
/// \endcode
98+
template <typename T>
99+
void insert(std::string_view key, const T& value);
100+
101+
/// \brief Iterate over all stored objects matching type Result.
102+
/// \tparam Result Type filter for iteration.
103+
/// \returns Range of const references to stored Result instances.
104+
/// \par Example
105+
/// \code{.cpp}
106+
/// for (auto& val : data.iterateByResultype<unsigned>()) {
107+
/// // use val
108+
/// }
109+
/// \endcode
110+
template <typename Result>
111+
auto iterateByType() const;
112+
113+
/// \brief Iterate over stored objects of type Result satisfying a predicate.
114+
/// \tparam Result type filter for iteration.
115+
/// \tparam Pred Callable predicate on (key, Result*) pairs.
116+
/// \param filter Predicate to apply for filtering entries.
117+
/// \returns Range of const references to Result passing the filter.
118+
/// \par Example
119+
/// \code{.cpp}
120+
/// auto even = [](auto const& pair) { return pair.second % 2 == 0; };
121+
/// for (auto& val : data.iterateByTypeAndFilter<unsigned>(even)) {
122+
/// // use val
123+
/// }
124+
/// \endcode
125+
template <typename Result, std::predicate<const std::pair<std::string_view, const Result*>&> Pred>
126+
auto iterateByTypeAndFilter(Pred&& filter) const;
127+
128+
/// \brief Filter entries of type Stored, then transform to type Result.
129+
/// \tparam Stored Original stored type for filtering.
130+
/// \tparam Result Target type after transformation.
131+
/// \tparam Pred Callable predicate on (key, Stored*) pairs.
132+
/// \tparam Transform Callable transforming Stored* to Result*.
133+
/// This Callable can return nullptr but it will be filtered out
134+
/// from results
135+
/// \param filter Predicate to apply before transformation.
136+
/// \param transform Callable to convert Stored to Result.
137+
/// \returns Range of const references to resulting objects.
138+
/// \par Example
139+
/// \code{.cpp}
140+
/// // if we stored some MOs that are not TH1F, these will be filtered out of results
141+
/// auto toHistogram = [](auto const& p) { return dynamic_cast<TH1F*>(p.second->getObject()); };
142+
/// for (auto& h : data.iterateByTypeFilterAndTransform<MonitorObject, TH1F>([](auto const& p){ return p.first=="histo"; }, toHistogram)) {
143+
/// // use histogram h
144+
/// }
145+
/// \endcode
146+
template <typename Stored, typename Result, std::predicate<const std::pair<std::string_view, const Stored*>&> Pred, invocable_r<const Result*, const Stored*> Transform>
147+
auto iterateByTypeFilterAndTransform(Pred&& filter, Transform&& transform) const;
148+
149+
/// \brief Number of stored entries.
150+
/// \returns Size of the underlying container.
151+
/// \par Example
152+
/// \code{.cpp}
153+
/// size_t n = data.size();
154+
/// \endcode
155+
size_t size() const noexcept;
156+
157+
private:
158+
ContainerMap mObjects;
159+
};
160+
161+
/// \brief Transparent hash functor for string and string_view.
162+
///
163+
/// Enables heterogeneous lookup in unordered maps keyed by std::string.
164+
struct StringHash {
165+
using is_transparent = void; // Required for heterogeneous lookup
166+
167+
std::size_t operator()(const std::string& str) const
168+
{
169+
return std::hash<std::string>{}(str);
170+
}
171+
172+
std::size_t operator()(std::string_view sv) const
173+
{
174+
return std::hash<std::string_view>{}(sv);
175+
}
176+
};
177+
178+
/// \brief Unordered map storing std::any values with heterogeneous key lookup. It was chosen based on benchmark
179+
/// in testQCInputs.cxx
180+
using transparent_unordered_map = std::unordered_map<std::string, std::any, StringHash, std::equal_to<>>;
181+
182+
/// \brief Default alias for QC inputs using transparent_unordered_map container.
183+
using QCInputs = QCInputsGeneric<transparent_unordered_map>;
184+
185+
} // namespace o2::quality_control::core
186+
187+
#include "QCInputs.inl"
188+
189+
#endif

0 commit comments

Comments
 (0)