Logo ROOT  
Reference Guide
RColumnElement.hxx
Go to the documentation of this file.
1/// \file ROOT/RColumnElement.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-09
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#ifndef ROOT7_RColumnElement
17#define ROOT7_RColumnElement
18
19#include <ROOT/RColumnModel.hxx>
20#include <ROOT/RNTupleUtil.hxx>
21
22#include <TError.h>
23
24#include <cstring> // for memcpy
25#include <cstdint>
26#include <memory>
27#include <string>
28#include <type_traits>
29
30namespace ROOT {
31namespace Experimental {
32
33namespace Detail {
34
35// clang-format off
36/**
37\class ROOT::Experimental::Detail::RColumnElement
38\ingroup NTuple
39\brief A column element points either to the content of an RFieldValue or into a memory mapped page.
40
41The content pointed to by fRawContent can be a single element or the first element of an array.
42Usually the on-disk element should map bitwise to the in-memory element. Sometimes that's not the case
43though, for instance on big endian platforms and for exotic physical columns like 8 bit float.
44
45This class does not provide protection around the raw pointer, fRawContent has to be managed correctly
46by the user of this class.
47*/
48// clang-format on
50protected:
51 /// Points to valid C++ data, either a single value or an array of values
53 /// Size of the C++ value pointed to by fRawContent (not necessarily equal to the on-disk element size)
54 std::size_t fSize;
55
56public:
58 : fRawContent(nullptr)
59 , fSize(0)
60 {}
61 RColumnElementBase(void *rawContent, std::size_t size) : fRawContent(rawContent), fSize(size)
62 {}
63 RColumnElementBase(const RColumnElementBase &elemArray, std::size_t at)
64 : fRawContent(static_cast<unsigned char *>(elemArray.fRawContent) + elemArray.fSize * at)
65 , fSize(elemArray.fSize)
66 {}
67 RColumnElementBase(const RColumnElementBase& other) = default;
71 virtual ~RColumnElementBase() = default;
72
73 static std::unique_ptr<RColumnElementBase> Generate(EColumnType type);
74 static std::size_t GetBitsOnStorage(EColumnType type);
75 static std::string GetTypeName(EColumnType type);
76
77 /// Write one or multiple column elements into destination
78 void WriteTo(void *destination, std::size_t count) const {
79 std::memcpy(destination, fRawContent, fSize * count);
80 }
81
82 /// Set the column element or an array of elements from the memory location source
83 void ReadFrom(void *source, std::size_t count) {
84 std::memcpy(fRawContent, source, fSize * count);
85 }
86
87 /// Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout
88 virtual bool IsMappable() const { R__ASSERT(false); return false; }
89 virtual std::size_t GetBitsOnStorage() const { R__ASSERT(false); return 0; }
90
91 /// If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-memory page
92 virtual void Pack(void *destination, void *source, std::size_t count) const
93 {
94 std::memcpy(destination, source, count);
95 }
96
97 /// If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-storage page
98 virtual void Unpack(void *destination, void *source, std::size_t count) const
99 {
100 std::memcpy(destination, source, count);
101 }
102
103 void *GetRawContent() const { return fRawContent; }
104 std::size_t GetSize() const { return fSize; }
105 std::size_t GetPackedSize(std::size_t nElements) const { return (nElements * GetBitsOnStorage() + 7) / 8; }
106};
107
108/**
109 * Pairs of C++ type and column type, like float and EColumnType::kReal32
110 */
111template <typename CppT, EColumnType ColumnT = EColumnType::kUnknown>
113public:
114 explicit RColumnElement(CppT* value) : RColumnElementBase(value, sizeof(CppT))
115 {
116 // Do not allow this template to be instantiated unless there is a specialization. The assert needs to depend
117 // on the template type or else the static_assert will always fire.
118 static_assert(sizeof(CppT) != sizeof(CppT), "No column mapping for this C++ type");
119 }
120};
121
122template <>
124public:
125 static constexpr std::size_t kSize = sizeof(bool);
126 explicit RColumnElement(bool *value) : RColumnElementBase(value, kSize) {}
127};
128
129template <>
131public:
132 static constexpr std::size_t kSize = sizeof(char);
133 explicit RColumnElement(char *value) : RColumnElementBase(value, kSize) {}
134};
135
136template <>
137class RColumnElement<std::int8_t, EColumnType::kUnknown> : public RColumnElementBase {
138public:
139 static constexpr std::size_t kSize = sizeof(std::int8_t);
140 explicit RColumnElement(std::int8_t *value) : RColumnElementBase(value, kSize) {}
141};
142
143template <>
144class RColumnElement<std::uint8_t, EColumnType::kUnknown> : public RColumnElementBase {
145public:
146 static constexpr std::size_t kSize = sizeof(std::uint8_t);
147 explicit RColumnElement(std::uint8_t *value) : RColumnElementBase(value, kSize) {}
148};
149
150template <>
151class RColumnElement<std::int16_t, EColumnType::kUnknown> : public RColumnElementBase {
152public:
153 static constexpr std::size_t kSize = sizeof(std::int16_t);
154 explicit RColumnElement(std::int16_t *value) : RColumnElementBase(value, kSize) {}
155};
156
157template <>
158class RColumnElement<std::uint16_t, EColumnType::kUnknown> : public RColumnElementBase {
159public:
160 static constexpr std::size_t kSize = sizeof(std::uint16_t);
161 explicit RColumnElement(std::uint16_t *value) : RColumnElementBase(value, kSize) {}
162};
163
164template <>
165class RColumnElement<std::int32_t, EColumnType::kUnknown> : public RColumnElementBase {
166public:
167 static constexpr std::size_t kSize = sizeof(std::int32_t);
168 explicit RColumnElement(std::int32_t *value) : RColumnElementBase(value, kSize) {}
169};
170
171template <>
172class RColumnElement<std::uint32_t, EColumnType::kUnknown> : public RColumnElementBase {
173public:
174 static constexpr std::size_t kSize = sizeof(std::uint32_t);
175 explicit RColumnElement(std::uint32_t *value) : RColumnElementBase(value, kSize) {}
176};
177
178template <>
179class RColumnElement<std::int64_t, EColumnType::kUnknown> : public RColumnElementBase {
180public:
181 static constexpr std::size_t kSize = sizeof(std::int64_t);
182 explicit RColumnElement(std::int64_t *value) : RColumnElementBase(value, kSize) {}
183};
184
185template <>
186class RColumnElement<std::uint64_t, EColumnType::kUnknown> : public RColumnElementBase {
187public:
188 static constexpr std::size_t kSize = sizeof(std::uint64_t);
189 explicit RColumnElement(std::uint64_t *value) : RColumnElementBase(value, kSize) {}
190};
191
192template <>
194public:
195 static constexpr std::size_t kSize = sizeof(float);
196 explicit RColumnElement(float *value) : RColumnElementBase(value, kSize) {}
197};
198
199template <>
201public:
202 static constexpr std::size_t kSize = sizeof(double);
203 explicit RColumnElement(double *value) : RColumnElementBase(value, kSize) {}
204};
205
206template <>
208public:
209 static constexpr std::size_t kSize = sizeof(ClusterSize_t);
211};
212
213template <>
215public:
216 static constexpr std::size_t kSize = sizeof(RColumnSwitch);
218};
219
220
221template <>
223public:
224 static constexpr bool kIsMappable = true;
225 static constexpr std::size_t kSize = sizeof(float);
226 static constexpr std::size_t kBitsOnStorage = kSize * 8;
227 explicit RColumnElement(float *value) : RColumnElementBase(value, kSize) {}
228 bool IsMappable() const final { return kIsMappable; }
229 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
230};
231
232template <>
234public:
235 static constexpr bool kIsMappable = true;
236 static constexpr std::size_t kSize = sizeof(double);
237 static constexpr std::size_t kBitsOnStorage = kSize * 8;
238 explicit RColumnElement(double *value) : RColumnElementBase(value, kSize) {}
239 bool IsMappable() const final { return kIsMappable; }
240 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
241};
242
243template <>
244class RColumnElement<std::int8_t, EColumnType::kByte> : public RColumnElementBase {
245public:
246 static constexpr bool kIsMappable = true;
247 static constexpr std::size_t kSize = sizeof(std::int8_t);
248 static constexpr std::size_t kBitsOnStorage = kSize * 8;
249 explicit RColumnElement(std::int8_t *value) : RColumnElementBase(value, kSize) {}
250 bool IsMappable() const final { return kIsMappable; }
251 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
252};
253
254template <>
255class RColumnElement<std::uint8_t, EColumnType::kByte> : public RColumnElementBase {
256public:
257 static constexpr bool kIsMappable = true;
258 static constexpr std::size_t kSize = sizeof(std::uint8_t);
259 static constexpr std::size_t kBitsOnStorage = kSize * 8;
260 explicit RColumnElement(std::uint8_t *value) : RColumnElementBase(value, kSize) {}
261 bool IsMappable() const final { return kIsMappable; }
262 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
263};
264
265template<>
266class RColumnElement<std::int16_t, EColumnType::kInt16> : public RColumnElementBase {
267public:
268 static constexpr bool kIsMappable = true;
269 static constexpr std::size_t kSize = sizeof(std::int16_t);
270 static constexpr std::size_t kBitsOnStorage = kSize * 8;
271 explicit RColumnElement(std::int16_t *value) : RColumnElementBase(value, kSize) {}
272 bool IsMappable() const final { return kIsMappable; }
273 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
274};
275
276template<>
277class RColumnElement<std::uint16_t, EColumnType::kInt16> : public RColumnElementBase {
278public:
279 static constexpr bool kIsMappable = true;
280 static constexpr std::size_t kSize = sizeof(std::uint16_t);
281 static constexpr std::size_t kBitsOnStorage = kSize * 8;
282 explicit RColumnElement(std::uint16_t *value) : RColumnElementBase(value, kSize) {}
283 bool IsMappable() const final { return kIsMappable; }
284 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
285};
286
287template <>
288class RColumnElement<std::int32_t, EColumnType::kInt32> : public RColumnElementBase {
289public:
290 static constexpr bool kIsMappable = true;
291 static constexpr std::size_t kSize = sizeof(std::int32_t);
292 static constexpr std::size_t kBitsOnStorage = kSize * 8;
293 explicit RColumnElement(std::int32_t *value) : RColumnElementBase(value, kSize) {}
294 bool IsMappable() const final { return kIsMappable; }
295 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
296};
297
298template <>
299class RColumnElement<std::uint32_t, EColumnType::kInt32> : public RColumnElementBase {
300public:
301 static constexpr bool kIsMappable = true;
302 static constexpr std::size_t kSize = sizeof(std::uint32_t);
303 static constexpr std::size_t kBitsOnStorage = kSize * 8;
304 explicit RColumnElement(std::uint32_t *value) : RColumnElementBase(value, kSize) {}
305 bool IsMappable() const final { return kIsMappable; }
306 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
307};
308
309template <>
310class RColumnElement<std::int64_t, EColumnType::kInt64> : public RColumnElementBase {
311public:
312 static constexpr bool kIsMappable = true;
313 static constexpr std::size_t kSize = sizeof(std::int64_t);
314 static constexpr std::size_t kBitsOnStorage = kSize * 8;
315 explicit RColumnElement(std::int64_t *value) : RColumnElementBase(value, kSize) {}
316 bool IsMappable() const final { return kIsMappable; }
317 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
318};
319
320template <>
321class RColumnElement<std::uint64_t, EColumnType::kInt64> : public RColumnElementBase {
322public:
323 static constexpr bool kIsMappable = true;
324 static constexpr std::size_t kSize = sizeof(std::uint64_t);
325 static constexpr std::size_t kBitsOnStorage = kSize * 8;
326 explicit RColumnElement(std::uint64_t *value) : RColumnElementBase(value, kSize) {}
327 bool IsMappable() const final { return kIsMappable; }
328 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
329};
330
331template <>
333public:
334 static constexpr bool kIsMappable = true;
335 static constexpr std::size_t kSize = sizeof(ROOT::Experimental::ClusterSize_t);
336 static constexpr std::size_t kBitsOnStorage = kSize * 8;
338 bool IsMappable() const final { return kIsMappable; }
339 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
340};
341
342template <>
344public:
345 static constexpr bool kIsMappable = true;
346 static constexpr std::size_t kSize = sizeof(ROOT::Experimental::RColumnSwitch);
347 static constexpr std::size_t kBitsOnStorage = kSize * 8;
349 bool IsMappable() const final { return kIsMappable; }
350 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
351};
352
353template <>
355public:
356 static constexpr bool kIsMappable = true;
357 static constexpr std::size_t kSize = sizeof(char);
358 static constexpr std::size_t kBitsOnStorage = kSize * 8;
359 explicit RColumnElement(char *value) : RColumnElementBase(value, kSize) {}
360 bool IsMappable() const final { return kIsMappable; }
361 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
362};
363
364template <>
366public:
367 static constexpr bool kIsMappable = false;
368 static constexpr std::size_t kSize = sizeof(bool);
369 static constexpr std::size_t kBitsOnStorage = 1;
370 explicit RColumnElement(bool *value) : RColumnElementBase(value, kSize) {}
371 bool IsMappable() const final { return kIsMappable; }
372 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
373
374 void Pack(void *dst, void *src, std::size_t count) const final;
375 void Unpack(void *dst, void *src, std::size_t count) const final;
376};
377
378template <>
379class RColumnElement<std::int64_t, EColumnType::kInt32> : public RColumnElementBase {
380public:
381 static constexpr bool kIsMappable = false;
382 static constexpr std::size_t kSize = sizeof(std::int64_t);
383 static constexpr std::size_t kBitsOnStorage = 32;
384 explicit RColumnElement(std::int64_t *value) : RColumnElementBase(value, kSize) {}
385 bool IsMappable() const final { return kIsMappable; }
386 std::size_t GetBitsOnStorage() const final { return kBitsOnStorage; }
387
388 void Pack(void *dst, void *src, std::size_t count) const final;
389 void Unpack(void *dst, void *src, std::size_t count) const final;
390};
391
392} // namespace Detail
393} // namespace Experimental
394} // namespace ROOT
395
396#endif
double
Definition: Converters.cxx:939
uint8_t
Definition: Converters.cxx:876
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define R__ASSERT(e)
Definition: TError.h:118
int type
Definition: TGX11.cxx:121
@ kSize
Definition: TStructNode.h:26
@ kUnknown
Definition: TStructNode.h:19
virtual void Pack(void *destination, void *source, std::size_t count) const
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
static std::unique_ptr< RColumnElementBase > Generate(EColumnType type)
void WriteTo(void *destination, std::size_t count) const
Write one or multiple column elements into destination.
RColumnElementBase(RColumnElementBase &&other)=default
virtual bool IsMappable() const
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
void * fRawContent
Points to valid C++ data, either a single value or an array of values.
RColumnElementBase(void *rawContent, std::size_t size)
RColumnElementBase(const RColumnElementBase &other)=default
RColumnElementBase & operator=(const RColumnElementBase &other)=delete
std::size_t fSize
Size of the C++ value pointed to by fRawContent (not necessarily equal to the on-disk element size)
static std::string GetTypeName(EColumnType type)
void ReadFrom(void *source, std::size_t count)
Set the column element or an array of elements from the memory location source.
virtual void Unpack(void *destination, void *source, std::size_t count) const
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
RColumnElementBase(const RColumnElementBase &elemArray, std::size_t at)
std::size_t GetPackedSize(std::size_t nElements) const
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
Pairs of C++ type and column type, like float and EColumnType::kReal32.
Holds the index and the tag of a kSwitch column.
Definition: RNTupleUtil.hxx:96
RClusterSize ClusterSize_t
Definition: RNTupleUtil.hxx:92
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:80