Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RColumnElementBase.hxx
Go to the documentation of this file.
1/// \file ROOT/RColumnElementBase.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_RColumnElementBase
17#define ROOT7_RColumnElementBase
18
19#include "RtypesCore.h"
20#include <ROOT/RError.hxx>
21#include <ROOT/RFloat16.hxx>
22#include <ROOT/RNTupleUtil.hxx>
23
24#include <Byteswap.h>
25#include <TError.h>
26
27#include <cstring> // for memcpy
28#include <cstddef> // for std::byte
29#include <cstdint>
30#include <memory>
31#include <optional>
32#include <string>
33#include <type_traits>
34#include <typeindex>
35#include <typeinfo>
36#include <utility>
37
39
40// clang-format off
41/**
42\class ROOT::Experimental::Internal::RColumnElementBase
43\ingroup NTuple
44\brief A column element encapsulates the translation between basic C++ types and their column representation.
45
46Usually the on-disk element should map bitwise to the in-memory element. Sometimes that's not the case
47though, for instance on big endian platforms or for bools.
48
49There is a template specialization for every valid pair of C++ type and column representation.
50These specialized child classes are responsible for overriding `Pack()` / `Unpack()` for packing / unpacking elements
51as appropriate.
52*/
53// clang-format on
55protected:
56 /// Size of the C++ value that corresponds to the on-disk element
57 std::size_t fSize;
58 std::size_t fBitsOnStorage;
59 /// This is only meaningful for column elements that support it (e.g. Real32Quant)
60 std::optional<std::pair<double, double>> fValueRange = std::nullopt;
61
62 explicit RColumnElementBase(std::size_t size, std::size_t bitsOnStorage = 0)
63 : fSize(size), fBitsOnStorage(bitsOnStorage ? bitsOnStorage : 8 * size)
64 {
65 }
66
67public:
68 /// Every concrete RColumnElement type is identified by its on-disk type (column type) and the
69 /// in-memory C++ type, given by a type index.
70 struct RIdentifier {
71 std::type_index fInMemoryType = std::type_index(typeid(void));
73
74 bool operator==(const RIdentifier &other) const
75 {
76 return this->fInMemoryType == other.fInMemoryType && this->fOnDiskType == other.fOnDiskType;
77 }
78
79 bool operator!=(const RIdentifier &other) const { return !(*this == other); }
80 };
81
82 RColumnElementBase(const RColumnElementBase &other) = default;
86 virtual ~RColumnElementBase() = default;
87
88 /// If CppT == void, use the default C++ type for the given column type
89 template <typename CppT = void>
90 static std::unique_ptr<RColumnElementBase> Generate(EColumnType type);
91 static const char *GetColumnTypeName(EColumnType type);
92 /// Most types have a fixed on-disk bit width. Some low-precision column types
93 /// have a range of possible bit widths. Return the minimum and maximum allowed
94 /// bit size per type.
95 static std::pair<std::uint16_t, std::uint16_t> GetValidBitRange(EColumnType type);
96
97 /// Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout
98 virtual bool IsMappable() const
99 {
100 R__ASSERT(false);
101 return false;
102 }
103
104 virtual void SetBitsOnStorage(std::size_t bitsOnStorage)
105 {
106 if (bitsOnStorage != fBitsOnStorage)
107 throw RException(R__FAIL(std::string("internal error: cannot change bit width of this column type")));
108 }
109
110 virtual void SetValueRange(double, double)
111 {
112 throw RException(R__FAIL(std::string("internal error: cannot change value range of this column type")));
113 }
114
115 /// If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-memory page
116 virtual void Pack(void *destination, const void *source, std::size_t count) const
117 {
118 std::memcpy(destination, source, count);
119 }
120
121 /// If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-storage page
122 virtual void Unpack(void *destination, const void *source, std::size_t count) const
123 {
124 std::memcpy(destination, source, count);
125 }
126
127 std::size_t GetSize() const { return fSize; }
128 std::size_t GetBitsOnStorage() const { return fBitsOnStorage; }
129 std::optional<std::pair<double, double>> GetValueRange() const { return fValueRange; }
130 std::size_t GetPackedSize(std::size_t nElements = 1U) const { return (nElements * fBitsOnStorage + 7) / 8; }
131
132 virtual RIdentifier GetIdentifier() const = 0;
133}; // class RColumnElementBase
134
136 std::uint32_t dummy;
137};
138
139std::unique_ptr<RColumnElementBase> GenerateColumnElement(std::type_index inMemoryType, EColumnType onDiskType);
140
141std::unique_ptr<RColumnElementBase> GenerateColumnElement(const RColumnElementBase::RIdentifier &elementId);
142
143template <typename CppT>
144std::unique_ptr<RColumnElementBase> RColumnElementBase::Generate(EColumnType onDiskType)
145{
146 return GenerateColumnElement(std::type_index(typeid(CppT)), onDiskType);
147}
148
149template <>
150std::unique_ptr<RColumnElementBase> RColumnElementBase::Generate<void>(EColumnType onDiskType);
151
152} // namespace ROOT::Experimental::Internal
153
154#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:290
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
A column element encapsulates the translation between basic C++ types and their column representation...
RColumnElementBase & operator=(const RColumnElementBase &other)=delete
RColumnElementBase(std::size_t size, std::size_t bitsOnStorage=0)
virtual RIdentifier GetIdentifier() const =0
static const char * GetColumnTypeName(EColumnType type)
virtual bool IsMappable() const
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
std::optional< std::pair< double, double > > fValueRange
This is only meaningful for column elements that support it (e.g. Real32Quant)
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 fSize
Size of the C++ value that corresponds to the on-disk element.
std::optional< std::pair< double, double > > GetValueRange() const
RColumnElementBase(const RColumnElementBase &other)=default
RColumnElementBase & operator=(RColumnElementBase &&other)=default
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-...
virtual void SetBitsOnStorage(std::size_t bitsOnStorage)
static std::unique_ptr< RColumnElementBase > Generate(EColumnType type)
If CppT == void, use the default C++ type for the given column type.
std::size_t GetPackedSize(std::size_t nElements=1U) const
static std::pair< std::uint16_t, std::uint16_t > GetValidBitRange(EColumnType type)
Most types have a fixed on-disk bit width.
RColumnElementBase(RColumnElementBase &&other)=default
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
std::unique_ptr< RColumnElementBase > GenerateColumnElement(std::type_index inMemoryType, EColumnType onDiskType)
Every concrete RColumnElement type is identified by its on-disk type (column type) and the in-memory ...