Skip to content

Commit af1cea4

Browse files
authored
DPL: Improve LabeledArray (#5324)
* Use const char* in getters * Add more getters * Extract non-templated part into a separate base class
1 parent b06bb94 commit af1cea4

File tree

2 files changed

+86
-67
lines changed

2 files changed

+86
-67
lines changed

Framework/Core/include/Framework/Array2D.h

Lines changed: 83 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@
99
// or submit itself to any jurisdiction.
1010
#ifndef FRAMEWORK_ARRAY2D_H
1111
#define FRAMEWORK_ARRAY2D_H
12+
13+
#include <Framework/RuntimeError.h>
14+
1215
#include <cstdint>
1316
#include <vector>
1417
#include <unordered_map>
1518
#include <memory>
1619
#include <string>
17-
#include <cassert>
1820

1921
namespace o2::framework
2022
{
21-
// matrix-like wrapper for std::vector
23+
// matrix-like wrapper for C-array
2224
// has no range checks
2325
template <typename T>
2426
struct Array2D {
@@ -122,76 +124,95 @@ struct Array2D {
122124
static constexpr const char* const labels_rows_str = "labels_rows";
123125
static constexpr const char* const labels_cols_str = "labels_cols";
124126

127+
using labelmap_t = std::unordered_map<std::string, uint32_t>;
128+
struct LabelMap {
129+
LabelMap()
130+
: rowmap{},
131+
colmap{},
132+
labels_rows{},
133+
labels_cols{}
134+
{
135+
}
136+
LabelMap(uint32_t rows, uint32_t cols, std::vector<std::string> labels_rows_, std::vector<std::string> labels_cols_)
137+
: rowmap{populate(rows, labels_rows_)},
138+
colmap{populate(cols, labels_cols_)},
139+
labels_rows{labels_rows_},
140+
labels_cols{labels_cols_}
141+
{
142+
}
143+
144+
LabelMap(uint32_t size, std::vector<std::string> labels)
145+
: rowmap{},
146+
colmap{populate(size, labels)},
147+
labels_rows{},
148+
labels_cols{labels}
149+
{
150+
}
151+
152+
LabelMap(LabelMap const& other) = default;
153+
LabelMap(LabelMap&& other) = default;
154+
LabelMap& operator=(LabelMap const& other) = default;
155+
LabelMap& operator=(LabelMap&& other) = default;
156+
157+
labelmap_t rowmap;
158+
labelmap_t colmap;
159+
160+
std::vector<std::string> labels_rows;
161+
std::vector<std::string> labels_cols;
162+
163+
labelmap_t populate(uint32_t size, std::vector<std::string> labels)
164+
{
165+
labelmap_t map;
166+
if (labels.empty() == false) {
167+
if (labels.size() != size) {
168+
throw runtime_error("labels array size != array dimension");
169+
}
170+
for (auto i = 0u; i < size; ++i) {
171+
map.emplace(labels[i], (uint32_t)i);
172+
}
173+
}
174+
return map;
175+
}
176+
177+
auto getLabelsRows()
178+
{
179+
return labels_rows;
180+
}
181+
182+
auto getLabelsCols()
183+
{
184+
return labels_cols;
185+
}
186+
};
187+
125188
template <typename T>
126-
class LabeledArray
189+
class LabeledArray : public LabelMap
127190
{
128191
public:
129192
using element_t = T;
130193

131194
LabeledArray()
132195
: values{},
133-
labels_rows{},
134-
labels_cols{},
135-
rowmap{},
136-
colmap{}
196+
LabelMap{}
137197
{
138198
}
139199

140-
LabeledArray(T const* data, uint32_t rows, uint32_t cols, std::vector<std::string> labels_rows_ = {}, std::vector<std::string> labels_cols_ = {})
141-
: values{data, rows, cols},
142-
labels_rows{labels_rows_},
143-
labels_cols{labels_cols_},
144-
rowmap{},
145-
colmap{}
200+
LabeledArray(T const* data, uint32_t rows_, uint32_t cols_, std::vector<std::string> labels_rows_ = {}, std::vector<std::string> labels_cols_ = {})
201+
: values{data, rows_, cols_},
202+
LabelMap{rows_, cols_, labels_rows_, labels_cols_}
146203
{
147-
if (labels_rows.empty() == false) {
148-
assert(labels_rows.size() == rows);
149-
for (auto i = 0u; i < labels_rows.size(); ++i) {
150-
rowmap.emplace(labels_rows[i], (uint32_t)i);
151-
}
152-
}
153-
if (labels_cols.empty() == false) {
154-
assert(labels_cols.size() == cols);
155-
for (auto i = 0u; i < labels_cols.size(); ++i) {
156-
colmap.emplace(labels_cols[i], (uint32_t)i);
157-
}
158-
}
159204
}
160205

161206
LabeledArray(T const* data, uint32_t size, std::vector<std::string> labels_ = {})
162207
: values{data, 1, size},
163-
labels_rows{},
164-
labels_cols{labels_},
165-
rowmap{},
166-
colmap{}
208+
LabelMap{size, labels_}
167209
{
168-
if (labels_cols.empty() == false) {
169-
assert(labels_cols.size() == size);
170-
for (auto i = 0u; i < labels_cols.size(); ++i) {
171-
colmap.emplace(labels_cols[i], (uint32_t)i);
172-
}
173-
}
174210
}
175211

176212
LabeledArray(Array2D<T> const& data, std::vector<std::string> labels_rows_ = {}, std::vector<std::string> labels_cols_ = {})
177213
: values{data},
178-
labels_rows{labels_rows_},
179-
labels_cols{labels_cols_},
180-
rowmap{},
181-
colmap{}
214+
LabelMap{data.rows, data.cols, labels_rows_, labels_cols_}
182215
{
183-
if (labels_rows.empty() == false) {
184-
assert(labels_rows.size() == values.rows);
185-
for (auto i = 0u; i < labels_rows.size(); ++i) {
186-
rowmap.emplace(labels_rows[i], (uint32_t)i);
187-
}
188-
}
189-
if (labels_cols.empty() == false) {
190-
assert(labels_cols.size() == values.cols);
191-
for (auto i = 0u; i < labels_cols.size(); ++i) {
192-
colmap.emplace(labels_cols[i], (uint32_t)i);
193-
}
194-
}
195216
}
196217

197218
LabeledArray(LabeledArray<T> const& other) = default;
@@ -206,34 +227,34 @@ class LabeledArray
206227
return values(y, x);
207228
}
208229

209-
T get(std::string y, std::string x) const
230+
T get(const char* y, const char* x) const
210231
{
211232
return values(rowmap.find(y)->second, colmap.find(x)->second);
212233
}
213234

214-
T get(uint32_t x) const
235+
T get(const char* y, uint32_t x) const
215236
{
216-
return values[0][x];
237+
return values(rowmap.find(y)->second, x);
217238
}
218239

219-
T getRow(u_int32_t y) const
240+
T get(uint32_t y, const char* x) const
220241
{
221-
return values[y];
242+
return values(y, colmap.find(x)->second);
222243
}
223244

224-
T* operator[](uint32_t y) const
245+
T get(uint32_t x) const
225246
{
226-
return values[y];
247+
return values[0][x];
227248
}
228249

229-
auto getLabelsRows()
250+
T getRow(u_int32_t y) const
230251
{
231-
return labels_rows;
252+
return values[y];
232253
}
233254

234-
auto getLabelsCols()
255+
T* operator[](uint32_t y) const
235256
{
236-
return labels_cols;
257+
return values[y];
237258
}
238259

239260
auto getData()
@@ -253,10 +274,6 @@ class LabeledArray
253274

254275
private:
255276
Array2D<T> values;
256-
std::vector<std::string> labels_rows;
257-
std::vector<std::string> labels_cols;
258-
std::unordered_map<std::string, uint32_t> rowmap;
259-
std::unordered_map<std::string, uint32_t> colmap;
260277
};
261278
} // namespace o2::framework
262279

Framework/Core/test/test_Variants.cxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,9 @@ BOOST_AUTO_TEST_CASE(LabeledArrayTest)
225225
LabeledArray<float> laf{&m[0][0], 3, 4, {"r1", "r2", "r3"}, {"c1", "c2", "c3", "c4"}};
226226
for (auto i = 0u; i < 3; ++i) {
227227
for (auto j = 0u; j < 4; ++j) {
228-
BOOST_CHECK(laf.get(yl[i], xl[j]) == laf.get(i, j));
228+
BOOST_CHECK(laf.get(yl[i].c_str(), xl[j].c_str()) == laf.get(i, j));
229+
BOOST_CHECK(laf.get(i, xl[j].c_str()) == laf.get(i, j));
230+
BOOST_CHECK(laf.get(yl[i].c_str(), j) == laf.get(i, j));
229231
}
230232
}
231233
}

0 commit comments

Comments
 (0)