Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RNTupleUtil.hxx
Go to the documentation of this file.
1 /// \file ROOT/RNTupleUtil.hxx
2 /// \ingroup NTuple ROOT7
3 /// \author Jakob Blomer <jblomer@cern.ch>
4 /// \date 2018-10-04
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_RNTupleUtil
17 #define ROOT7_RNTupleUtil
18 
19 #include <cstdint>
20 
21 #include <string>
22 #include <vector>
23 
24 namespace ROOT {
25 namespace Experimental {
26 
27 
28 /**
29  * The fields in the ntuple model tree can carry different structural information about the type system.
30  * Leaf fields contain just data, collection fields resolve to offset columns, record root fields have no
31  * materialization on the primitive column layer.
32  */
33 enum ENTupleStructure {
34  kLeaf,
35  kCollection,
36  kRecord,
37  kVariant,
38  // unimplemented so far
39  kReference,
40 };
41 
42 /// Integer type long enough to hold the maximum number of entries in a column
43 using NTupleSize_t = std::uint64_t;
44 constexpr NTupleSize_t kInvalidNTupleIndex = std::uint64_t(-1);
45 /// Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t
46 struct RClusterSize {
47  using ValueType = std::uint32_t;
48 
49  RClusterSize() : fValue(0) {}
50  explicit constexpr RClusterSize(ValueType value) : fValue(value) {}
51  RClusterSize& operator =(const ValueType value) { fValue = value; return *this; }
52  RClusterSize& operator +=(const ValueType value) { fValue += value; return *this; }
53  RClusterSize operator++(int) { auto result = *this; fValue++; return result; }
54  operator ValueType() const { return fValue; }
55 
56  ValueType fValue;
57 };
58 using ClusterSize_t = RClusterSize;
59 constexpr ClusterSize_t kInvalidClusterIndex(std::uint32_t(-1));
60 
61 /// Holds the index and the tag of a kSwitch column
62 class RColumnSwitch {
63 private:
64  ClusterSize_t fIndex;
65  std::uint32_t fTag = 0;
66 
67 public:
68  RColumnSwitch() = default;
69  RColumnSwitch(ClusterSize_t index, std::uint32_t tag) : fIndex(index), fTag(tag) { }
70  ClusterSize_t GetIndex() const { return fIndex; }
71  std::uint32_t GetTag() const { return fTag; }
72 };
73 
74 /// Uniquely identifies a physical column within the scope of the current process, used to tag pages
75 using ColumnId_t = std::int64_t;
76 constexpr ColumnId_t kInvalidColumnId = -1;
77 
78 /// Distriniguishes elements of the same type within a descriptor, e.g. different fields
79 using DescriptorId_t = std::uint64_t;
80 constexpr DescriptorId_t kInvalidDescriptorId = std::uint64_t(-1);
81 
82 /// Addresses a column element or field item relative to a particular cluster, instead of a global NTupleSize_t index
83 class RClusterIndex {
84 private:
85  DescriptorId_t fClusterId = kInvalidDescriptorId;
86  ClusterSize_t::ValueType fIndex = kInvalidClusterIndex;
87 public:
88  RClusterIndex() = default;
89  RClusterIndex(const RClusterIndex &other) = default;
90  RClusterIndex &operator =(const RClusterIndex &other) = default;
91  constexpr RClusterIndex(DescriptorId_t clusterId, ClusterSize_t::ValueType index)
92  : fClusterId(clusterId), fIndex(index) {}
93 
94  RClusterIndex operator+(ClusterSize_t::ValueType off) const { return RClusterIndex(fClusterId, fIndex + off); }
95  RClusterIndex operator-(ClusterSize_t::ValueType off) const { return RClusterIndex(fClusterId, fIndex - off); }
96  RClusterIndex operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
97  RClusterIndex& operator++() /* prefix */ { ++fIndex; return *this; }
98  bool operator==(const RClusterIndex &other) const {
99  return fClusterId == other.fClusterId && fIndex == other.fIndex;
100  }
101  bool operator!=(const RClusterIndex &other) const { return !(*this == other); }
102 
103  DescriptorId_t GetClusterId() const { return fClusterId; }
104  ClusterSize_t::ValueType GetIndex() const { return fIndex; }
105 };
106 
107 /// Every NTuple is identified by a UUID. TODO(jblomer): should this be a TUUID?
108 using RNTupleUuid = std::string;
109 
110 
111 /// 64 possible flags to apply to all versioned entities (so far unused).
112 using NTupleFlags_t = std::uint64_t;
113 /// For forward and backward compatibility, attach version information to
114 /// the consitituents of the file format (column, field, cluster, ntuple).
115 class RNTupleVersion {
116 private:
117  /// The version used to write an entity
118  std::uint32_t fVersionUse = 0;
119  /// The minimum required version necessary to read an entity
120  std::uint32_t fVersionMin = 0;
121  NTupleFlags_t fFlags = 0;
122 
123 public:
124  RNTupleVersion() = default;
125  RNTupleVersion(std::uint32_t versionUse, std::uint32_t versionMin)
126  : fVersionUse(versionUse), fVersionMin(versionMin)
127  {}
128  RNTupleVersion(std::uint32_t versionUse, std::uint32_t versionMin, NTupleFlags_t flags)
129  : fVersionUse(versionUse), fVersionMin(versionMin), fFlags(flags)
130  {}
131 
132  bool operator ==(const RNTupleVersion &other) const {
133  return fVersionUse == other.fVersionUse && fVersionMin == other.fVersionMin && fFlags == other.fFlags;
134  }
135 
136  std::uint32_t GetVersionUse() const { return fVersionUse; }
137  std::uint32_t GetVersionMin() const { return fVersionMin; }
138  NTupleFlags_t GetFlags() const { return fFlags; }
139 };
140 
141 } // namespace Experimental
142 } // namespace ROOT
143 
144 #endif