Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
RColumnElementBase.hxx
Go to the documentation of this file.
1/// \file ROOT/RColumnElementBase.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2018-10-09
4
5/*************************************************************************
6 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_RColumnElementBase
14#define ROOT_RColumnElementBase
15
16#include "RtypesCore.h"
17#include <ROOT/RError.hxx>
18#include <ROOT/RFloat16.hxx>
19#include <ROOT/RNTupleTypes.hxx>
20
21#include <Byteswap.h>
22#include <TError.h>
23
24#include <cstring> // for memcpy
25#include <cstddef> // for std::byte
26#include <cstdint>
27#include <memory>
28#include <optional>
29#include <string>
30#include <type_traits>
31#include <typeindex>
32#include <typeinfo>
33#include <utility>
34
35namespace ROOT::Internal {
36
37// clang-format off
38/**
39\class ROOT::Internal::RColumnElementBase
40\ingroup NTuple
41\brief A column element encapsulates the translation between basic C++ types and their column representation.
42
43Usually the on-disk element should map bitwise to the in-memory element. Sometimes that's not the case
44though, for instance on big endian platforms or for bools.
45
46There is a template specialization for every valid pair of C++ type and column representation.
47These specialized child classes are responsible for overriding `Pack()` / `Unpack()` for packing / unpacking elements
48as appropriate.
49*/
50// clang-format on
52protected:
53 /// Size of the C++ value that corresponds to the on-disk element
54 std::size_t fSize;
55 std::size_t fBitsOnStorage;
56 /// This is only meaningful for column elements that support it (e.g. Real32Quant)
57 std::optional<std::pair<double, double>> fValueRange = std::nullopt;
58
59 explicit RColumnElementBase(std::size_t size, std::size_t bitsOnStorage = 0)
60 : fSize(size), fBitsOnStorage(bitsOnStorage ? bitsOnStorage : 8 * size)
61 {
62 }
63
64public:
65 /// Every concrete RColumnElement type is identified by its on-disk type (column type) and the
66 /// in-memory C++ type, given by a type index.
67 struct RIdentifier {
68 std::type_index fInMemoryType = std::type_index(typeid(void));
70
71 bool operator==(const RIdentifier &other) const
72 {
73 return this->fInMemoryType == other.fInMemoryType && this->fOnDiskType == other.fOnDiskType;
74 }
75
76 bool operator!=(const RIdentifier &other) const { return !(*this == other); }
77 };
78
79 RColumnElementBase(const RColumnElementBase &other) = default;
83 virtual ~RColumnElementBase() = default;
84
85 /// If CppT == void, use the default C++ type for the given column type
86 template <typename CppT = void>
87 static std::unique_ptr<RColumnElementBase> Generate(ROOT::ENTupleColumnType type);
89 /// Most types have a fixed on-disk bit width. Some low-precision column types
90 /// have a range of possible bit widths. Return the minimum and maximum allowed
91 /// bit size per type.
92 static std::pair<std::uint16_t, std::uint16_t> GetValidBitRange(ROOT::ENTupleColumnType type);
93
94 /// Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout
95 virtual bool IsMappable() const
96 {
97 R__ASSERT(false);
98 return false;
99 }
100
101 virtual void SetBitsOnStorage(std::size_t bitsOnStorage)
102 {
103 if (bitsOnStorage != fBitsOnStorage)
104 throw RException(R__FAIL(std::string("internal error: cannot change bit width of this column type")));
105 }
106
107 virtual void SetValueRange(double, double)
108 {
109 throw RException(R__FAIL(std::string("internal error: cannot change value range of this column type")));
110 }
111
112 /// If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-memory page
113 virtual void Pack(void *destination, const void *source, std::size_t count) const
114 {
115 std::memcpy(destination, source, count);
116 }
117
118 /// If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-storage page
119 virtual void Unpack(void *destination, const void *source, std::size_t count) const
120 {
121 std::memcpy(destination, source, count);
122 }
123
124 std::size_t GetSize() const { return fSize; }
125 std::size_t GetBitsOnStorage() const { return fBitsOnStorage; }
126 std::optional<std::pair<double, double>> GetValueRange() const { return fValueRange; }
127 std::size_t GetPackedSize(std::size_t nElements = 1U) const { return (nElements * fBitsOnStorage + 7) / 8; }
128
129 virtual RIdentifier GetIdentifier() const = 0;
130}; // class RColumnElementBase
131
133 std::uint32_t dummy;
134};
135
136std::unique_ptr<RColumnElementBase>
137GenerateColumnElement(std::type_index inMemoryType, ROOT::ENTupleColumnType onDiskType);
138
139std::unique_ptr<RColumnElementBase> GenerateColumnElement(const RColumnElementBase::RIdentifier &elementId);
140
141template <typename CppT>
142std::unique_ptr<RColumnElementBase> RColumnElementBase::Generate(ROOT::ENTupleColumnType onDiskType)
143{
144 return GenerateColumnElement(std::type_index(typeid(CppT)), onDiskType);
145}
146
147template <>
148std::unique_ptr<RColumnElementBase> RColumnElementBase::Generate<void>(ROOT::ENTupleColumnType onDiskType);
149
150} // namespace ROOT::Internal
151
152#endif
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:299
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Basic types used by ROOT and required by TInterpreter.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
RColumnElementBase(std::size_t size, std::size_t bitsOnStorage=0)
virtual bool IsMappable() const
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
static const char * GetColumnTypeName(ROOT::ENTupleColumnType type)
RColumnElementBase & operator=(RColumnElementBase &&other)=default
static std::unique_ptr< RColumnElementBase > Generate(ROOT::ENTupleColumnType type)
If CppT == void, use the default C++ type for the given column type.
virtual void SetBitsOnStorage(std::size_t bitsOnStorage)
static std::pair< std::uint16_t, std::uint16_t > GetValidBitRange(ROOT::ENTupleColumnType type)
Most types have a fixed on-disk bit width.
RColumnElementBase(std::size_t size, std::size_t bitsOnStorage=0)
std::optional< std::pair< double, double > > GetValueRange() const
RColumnElementBase & operator=(const RColumnElementBase &other)=delete
virtual void SetValueRange(double, double)
virtual void Unpack(void *destination, const 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-...
std::size_t fSize
Size of the C++ value that corresponds to the on-disk element.
RColumnElementBase(const RColumnElementBase &other)=default
std::optional< std::pair< double, double > > fValueRange
This is only meaningful for column elements that support it (e.g. Real32Quant).
virtual ~RColumnElementBase()=default
virtual RIdentifier GetIdentifier() const =0
RColumnElementBase(RColumnElementBase &&other)=default
virtual void Pack(void *destination, const 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-...
std::size_t GetPackedSize(std::size_t nElements=1U) const
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
std::unique_ptr< RColumnElementBase > GenerateColumnElement(std::type_index inMemoryType, ROOT::ENTupleColumnType onDiskType)
ENTupleColumnType
Every concrete RColumnElement type is identified by its on-disk type (column type) and the in-memory ...
Every concrete RColumnElement type is identified by its on-disk type (column type) and the in-memory ...
bool operator!=(const RIdentifier &other) const
bool operator==(const RIdentifier &other) const