-
Sergey Linev authoredSergey Linev authored
RNTupleUtil.hxx 5.47 KiB
/// \file ROOT/RNTupleUtil.hxx
/// \ingroup NTuple ROOT7
/// \author Jakob Blomer <jblomer@cern.ch>
/// \date 2018-10-04
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!
/*************************************************************************
* Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT7_RNTupleUtil
#define ROOT7_RNTupleUtil
#include <cstdint>
#include <string>
namespace ROOT {
namespace Experimental {
/**
* The fields in the ntuple model tree can carry different structural information about the type system.
* Leaf fields contain just data, collection fields resolve to offset columns, record root fields have no
* materialization on the primitive column layer.
*/
enum ENTupleStructure {
kLeaf,
kCollection,
kRecord,
kVariant,
// unimplemented so far
kReference,
};
/// Integer type long enough to hold the maximum number of entries in a column
using NTupleSize_t = std::uint64_t;
constexpr NTupleSize_t kInvalidNTupleIndex = std::uint64_t(-1);
/// Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t
struct RClusterSize {
using ValueType = std::uint32_t;
RClusterSize() : fValue(0) {}
explicit constexpr RClusterSize(ValueType value) : fValue(value) {}
RClusterSize& operator =(const ValueType value) { fValue = value; return *this; }
RClusterSize& operator +=(const ValueType value) { fValue += value; return *this; }
RClusterSize operator++(int) { auto result = *this; fValue++; return result; }
operator ValueType() const { return fValue; }
ValueType fValue;
};
using ClusterSize_t = RClusterSize;
constexpr ClusterSize_t kInvalidClusterIndex(std::uint32_t(-1));
/// Holds the index and the tag of a kSwitch column
class RColumnSwitch {
private:
ClusterSize_t fIndex;
std::uint32_t fTag = 0;
public:
RColumnSwitch() = default;
RColumnSwitch(ClusterSize_t index, std::uint32_t tag) : fIndex(index), fTag(tag) { }
ClusterSize_t GetIndex() const { return fIndex; }
std::uint32_t GetTag() const { return fTag; }
};
/// Uniquely identifies a physical column within the scope of the current process, used to tag pages
using ColumnId_t = std::int64_t;
constexpr ColumnId_t kInvalidColumnId = -1;
/// Distriniguishes elements of the same type within a descriptor, e.g. different fields
using DescriptorId_t = std::uint64_t;
constexpr DescriptorId_t kInvalidDescriptorId = std::uint64_t(-1);
/// Addresses a column element or field item relative to a particular cluster, instead of a global NTupleSize_t index
class RClusterIndex {
private:
DescriptorId_t fClusterId = kInvalidDescriptorId;
ClusterSize_t::ValueType fIndex = kInvalidClusterIndex;
public:
RClusterIndex() = default;
RClusterIndex(const RClusterIndex &other) = default;
RClusterIndex &operator =(const RClusterIndex &other) = default;
constexpr RClusterIndex(DescriptorId_t clusterId, ClusterSize_t::ValueType index)
: fClusterId(clusterId), fIndex(index) {}
RClusterIndex operator+(ClusterSize_t::ValueType off) const { return RClusterIndex(fClusterId, fIndex + off); }
RClusterIndex operator-(ClusterSize_t::ValueType off) const { return RClusterIndex(fClusterId, fIndex - off); }
RClusterIndex operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
RClusterIndex& operator++() /* prefix */ { ++fIndex; return *this; }
bool operator==(const RClusterIndex &other) const {
return fClusterId == other.fClusterId && fIndex == other.fIndex;
}
bool operator!=(const RClusterIndex &other) const { return !(*this == other); }
DescriptorId_t GetClusterId() const { return fClusterId; }
ClusterSize_t::ValueType GetIndex() const { return fIndex; }
};
/// Every NTuple is identified by a UUID. TODO(jblomer): should this be a TUUID?
using RNTupleUuid = std::string;
/// 64 possible flags to apply to all versioned entities (so far unused).
using NTupleFlags_t = std::uint64_t;
/// For forward and backward compatibility, attach version information to
/// the consitituents of the file format (column, field, cluster, ntuple).
class RNTupleVersion {
private:
/// The version used to write an entity
std::uint32_t fVersionUse = 0;
/// The minimum required version necessary to read an entity
std::uint32_t fVersionMin = 0;
NTupleFlags_t fFlags = 0;
public:
RNTupleVersion() = default;
RNTupleVersion(std::uint32_t versionUse, std::uint32_t versionMin)
: fVersionUse(versionUse), fVersionMin(versionMin)
{}
RNTupleVersion(std::uint32_t versionUse, std::uint32_t versionMin, NTupleFlags_t flags)
: fVersionUse(versionUse), fVersionMin(versionMin), fFlags(flags)
{}
bool operator ==(const RNTupleVersion &other) const {
return fVersionUse == other.fVersionUse && fVersionMin == other.fVersionMin && fFlags == other.fFlags;
}
std::uint32_t GetVersionUse() const { return fVersionUse; }
std::uint32_t GetVersionMin() const { return fVersionMin; }
NTupleFlags_t GetFlags() const { return fFlags; }
};
} // namespace Experimental
} // namespace ROOT
#endif