Skip to content

Commit 754c370

Browse files
shahor02sawenzel
authored andcommitted
Aggregated container + access with global index
Allows to absorb the containers of objects usually derived from the common base class and to access them with global index (e.g. like AbstractRef)
1 parent ca46243 commit 754c370

5 files changed

Lines changed: 214 additions & 2 deletions

File tree

DataFormats/common/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ o2_add_library(CommonDataFormat
1313
src/BunchFilling.cxx
1414
src/FlatHisto1D.cxx
1515
src/FlatHisto2D.cxx
16+
src/AbstractRefAccessor.cxx
1617
PUBLIC_LINK_LIBRARIES O2::CommonConstants O2::GPUCommon
1718
ROOT::Core FairRoot::Base ms_gsl::ms_gsl)
1819

@@ -40,3 +41,8 @@ o2_add_test(FlatHisto
4041
SOURCES test/testFlatHisto.cxx
4142
COMPONENT_NAME CommonDataFormat
4243
PUBLIC_LINK_LIBRARIES O2::CommonDataFormat)
44+
45+
o2_add_test(AbstractRefAccessor
46+
SOURCES test/testAbstractRefAccessor.cxx
47+
COMPONENT_NAME CommonDataFormat
48+
PUBLIC_LINK_LIBRARIES O2::CommonDataFormat)
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
/// \file AbstractRefAccessor.h
12+
/// \brief Accessor for objects of the same base class located in different containers
13+
/// \author ruben.shahoyan@cern.ch
14+
15+
#ifndef O2_POLYACCESSOR_H
16+
#define O2_POLYACCESSOR_H
17+
18+
#include <array>
19+
#include <gsl/span>
20+
21+
namespace o2
22+
{
23+
namespace dataformats
24+
{
25+
26+
/*
27+
AbstractRefAccessor allows to register multiple containers of objects convertible to type T and
28+
to access them by providing a global index indicating the registered source ID and the
29+
index within the original container
30+
*/
31+
32+
template <typename T, int N>
33+
class AbstractRefAccessor
34+
{
35+
public:
36+
/// register container in the accessor
37+
template <typename C>
38+
void registerContainer(const C& cont, int src)
39+
{
40+
mSizeOfs[src] = sizeof(typename std::remove_reference<decltype(cont)>::type::value_type);
41+
mSizes[src] = cont.size();
42+
mContainerPtr[src] = reinterpret_cast<const char*>(cont.data());
43+
}
44+
45+
/// get object as user provided type from explicitly provided source, index
46+
template <typename U>
47+
const U& get_as(int src, int idx) const
48+
{
49+
return *reinterpret_cast<const U*>(getPtr(src, idx));
50+
}
51+
52+
/// get object as user provided type from explicitly provided source, index
53+
template <typename U, typename I>
54+
const U& get_as(const I globIdx) const
55+
{
56+
return get_as<U>(globIdx.getSource(), globIdx.getIndex());
57+
}
58+
59+
/// get object from explicitly provided source, index
60+
const T& get(int src, int idx) const
61+
{
62+
return get_as<T>(src, idx);
63+
}
64+
65+
/// get object from the global index
66+
template <typename I>
67+
const T& get(const I globIdx) const
68+
{
69+
return get_as<T>(globIdx.getSource(), globIdx.getIndex());
70+
}
71+
72+
/// access particula source container as a span
73+
template <typename U>
74+
auto getSpan(int src) const
75+
{
76+
return gsl::span<const U>(reinterpret_cast<const U*>(getPtr(src, 0), getSize(src)));
77+
}
78+
79+
size_t getSize(int src) const
80+
{
81+
return mSizes[src];
82+
}
83+
84+
private:
85+
auto getPtr(int src, int idx) const { return mContainerPtr[src] + mSizeOfs[src] * idx; }
86+
87+
std::array<size_t, N> mSizeOfs{}; // sizeof for all containers elements
88+
std::array<size_t, N> mSizes{}; // size of eack container
89+
std::array<const char*, N> mContainerPtr{}; // pointers on attached containers
90+
};
91+
92+
} // namespace dataformats
93+
} // namespace o2
94+
95+
#endif
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
/// \file AbstractRefAccessor.h
12+
/// \brief Accessor for objects of the same base class located in different containers
13+
/// \author ruben.shahoyan@cern.ch
14+
15+
#include "CommonDataFormat/AbstractRefAccessor.h"

DataFormats/common/src/CommonDataFormatLinkDef.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@
4242

4343
#pragma link C++ class std::vector < o2::dataformats::RangeReference < int, int>> + ;
4444

45+
#pragma link C++ class o2::dataformats::AbstractRef < 25, 4, 3> + ;
46+
4547
#pragma link C++ class o2::InteractionRecord + ;
4648
#pragma link C++ class o2::InteractionTimeRecord + ;
4749
#pragma link C++ class o2::BunchFilling + ;
4850

49-
#pragma link C++ class o2::dataformats::AbstractRef < 26, 3, 3> + ;
50-
5151
#pragma link C++ class o2::dataformats::FlatHisto1D < float> + ;
5252
#pragma link C++ class o2::dataformats::FlatHisto1D < double> + ;
5353
#pragma link C++ class o2::dataformats::FlatHisto1D_f + ;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#define BOOST_TEST_MODULE Test AbstractRefAccessor class
12+
#define BOOST_TEST_MAIN
13+
#define BOOST_TEST_DYN_LINK
14+
#include <numeric>
15+
#include <boost/test/unit_test.hpp>
16+
#include "CommonDataFormat/AbstractRefAccessor.h"
17+
#include "CommonDataFormat/AbstractRef.h"
18+
#include "Framework/Logger.h"
19+
20+
using namespace o2::dataformats;
21+
22+
struct Base {
23+
int b = 0;
24+
};
25+
26+
struct Foo1 : public Base {
27+
int f1 = 0;
28+
};
29+
30+
struct Foo2 : public Foo1 {
31+
int f2 = 0;
32+
};
33+
34+
struct Bar1 : public Base {
35+
double b1 = 0.;
36+
};
37+
38+
struct GloIdx : public AbstractRef<25, 4, 3> {
39+
enum Source : uint8_t { // provenance of the
40+
ID0,
41+
ID1,
42+
ID2,
43+
ID3,
44+
NSources
45+
};
46+
using AbstractRef<25, 4, 3>::AbstractRef;
47+
};
48+
49+
// basic AbstractRefAccessor
50+
BOOST_AUTO_TEST_CASE(AbstractRefAccess)
51+
{
52+
53+
std::vector<Base> vb(10);
54+
std::vector<Foo1> vf(10);
55+
std::array<Foo2, 10> af;
56+
std::vector<Bar1> bar(10);
57+
58+
std::vector<GloIdx> vid;
59+
60+
for (int i = 0; i < 10; i++) {
61+
vb[i].b = GloIdx::ID0 * 100 + i;
62+
vid.emplace_back(i, GloIdx::ID1);
63+
64+
vf[i].b = GloIdx::ID1 * 100 + i;
65+
vf[i].f1 = 0.5 + 100 + i;
66+
vid.emplace_back(i, GloIdx::ID2);
67+
68+
af[i].b = GloIdx::ID2 * 100 + i;
69+
af[i].f2 = 0.8 + 100 + i;
70+
vid.emplace_back(i, GloIdx::ID3);
71+
72+
bar[i].b = GloIdx::ID3 * 100 + i;
73+
bar[i].b1 = 0.2 + 300 + i;
74+
vid.emplace_back(i, GloIdx::ID3);
75+
}
76+
77+
AbstractRefAccessor<Base, GloIdx::NSources> acc;
78+
79+
acc.registerContainer(vb, GloIdx::ID0);
80+
acc.registerContainer(vf, GloIdx::ID1);
81+
acc.registerContainer(af, GloIdx::ID2);
82+
acc.registerContainer(bar, GloIdx::ID3);
83+
84+
size_t nid = vid.size();
85+
for (size_t i = 0; i < nid; i++) {
86+
auto gid = vid[i];
87+
const auto& obj = acc.get(gid);
88+
int expect = gid.getSource() * 100 + i / GloIdx::NSources;
89+
LOG(INFO) << i << " ? " << obj.b << " == " << expect << " for " << gid;
90+
BOOST_CHECK(obj.b == expect);
91+
}
92+
93+
const auto& barEl = acc.get_as<Bar1>(vid.back());
94+
LOG(INFO) << " ? " << barEl.b1 << " == " << bar.back().b1;
95+
BOOST_CHECK(barEl.b1 == bar.back().b1);
96+
}

0 commit comments

Comments
 (0)