File indexing completed on 2025-09-16 09:08:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_REntry
0015 #define ROOT_REntry
0016
0017 #include <ROOT/RError.hxx>
0018 #include <ROOT/RField.hxx>
0019 #include <ROOT/RFieldToken.hxx>
0020 #include <string_view>
0021
0022 #include <TError.h>
0023
0024 #include <algorithm>
0025 #include <iterator>
0026 #include <memory>
0027 #include <type_traits>
0028 #include <utility>
0029 #include <vector>
0030 #include <unordered_map>
0031
0032 namespace ROOT {
0033
0034 class RNTupleReader;
0035
0036 namespace Experimental {
0037 class RNTupleFillContext;
0038 class RNTupleProcessor;
0039 class RNTupleSingleProcessor;
0040 class RNTupleChainProcessor;
0041 class RNTupleJoinProcessor;
0042 }
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 class REntry {
0055 friend class RNTupleModel;
0056 friend class RNTupleReader;
0057 friend class Experimental::RNTupleFillContext;
0058 friend class Experimental::RNTupleProcessor;
0059 friend class Experimental::RNTupleSingleProcessor;
0060 friend class Experimental::RNTupleChainProcessor;
0061 friend class Experimental::RNTupleJoinProcessor;
0062
0063 private:
0064
0065 std::uint64_t fModelId = 0;
0066
0067 std::uint64_t fSchemaId = 0;
0068
0069 std::vector<ROOT::RFieldBase::RValue> fValues;
0070
0071 std::unordered_map<std::string, std::size_t> fFieldName2Token;
0072
0073 std::vector<std::string> fFieldTypes;
0074
0075
0076 REntry() = default;
0077 explicit REntry(std::uint64_t modelId, std::uint64_t schemaId) : fModelId(modelId), fSchemaId(schemaId) {}
0078
0079 void AddValue(ROOT::RFieldBase::RValue &&value)
0080 {
0081 fFieldName2Token[value.GetField().GetQualifiedFieldName()] = fValues.size();
0082 fFieldTypes.push_back(value.GetField().GetTypeName());
0083 fValues.emplace_back(std::move(value));
0084 }
0085
0086
0087 template <typename T>
0088 std::shared_ptr<T> AddValue(ROOT::RField<T> &field)
0089 {
0090 fFieldName2Token[field.GetQualifiedFieldName()] = fValues.size();
0091 fFieldTypes.push_back(field.GetTypeName());
0092 auto value = field.CreateValue();
0093 fValues.emplace_back(value);
0094 return value.template GetPtr<T>();
0095 }
0096
0097
0098
0099 void UpdateValue(ROOT::RFieldToken token, ROOT::RFieldBase::RValue &&value)
0100 {
0101 std::swap(fValues.at(token.fIndex), value);
0102 }
0103 void UpdateValue(ROOT::RFieldToken token, ROOT::RFieldBase::RValue &value)
0104 {
0105 std::swap(fValues.at(token.fIndex), value);
0106 }
0107
0108
0109 ROOT::RFieldBase::RValue &GetValue(ROOT::RFieldToken token) { return fValues.at(token.fIndex); }
0110 ROOT::RFieldBase::RValue &GetValue(std::string_view fieldName) { return GetValue(GetToken(fieldName)); }
0111
0112 void Read(ROOT::NTupleSize_t index)
0113 {
0114 for (auto &v : fValues) {
0115 v.Read(index);
0116 }
0117 }
0118
0119 std::size_t Append()
0120 {
0121 std::size_t bytesWritten = 0;
0122 for (auto &v : fValues) {
0123 bytesWritten += v.Append();
0124 }
0125 return bytesWritten;
0126 }
0127
0128 void EnsureMatchingModel(ROOT::RFieldToken token) const
0129 {
0130 if (fSchemaId != token.fSchemaId) {
0131 throw RException(R__FAIL("invalid token for this entry, "
0132 "make sure to use a token from a model with the same schema as this entry."));
0133 }
0134 }
0135
0136
0137 const std::string &FindFieldName(ROOT::RFieldToken token) const
0138 {
0139 for (const auto &[fieldName, index] : fFieldName2Token) {
0140 if (index == token.fIndex) {
0141 return fieldName;
0142 }
0143 }
0144
0145 static const std::string empty = "";
0146 return empty;
0147 }
0148
0149 template <typename T>
0150 void EnsureMatchingType(ROOT::RFieldToken token [[maybe_unused]]) const
0151 {
0152 if constexpr (!std::is_void_v<T>) {
0153 if (fFieldTypes[token.fIndex] != ROOT::RField<T>::TypeName()) {
0154 throw RException(R__FAIL("type mismatch for field " + FindFieldName(token) + ": " +
0155 fFieldTypes[token.fIndex] + " vs. " + ROOT::RField<T>::TypeName()));
0156 }
0157 }
0158 }
0159
0160 public:
0161 using ConstIterator_t = decltype(fValues)::const_iterator;
0162
0163 REntry(const REntry &other) = delete;
0164 REntry &operator=(const REntry &other) = delete;
0165 REntry(REntry &&other) = default;
0166 REntry &operator=(REntry &&other) = default;
0167 ~REntry() = default;
0168
0169
0170 ROOT::RFieldToken GetToken(std::string_view fieldName) const
0171 {
0172 auto it = fFieldName2Token.find(std::string(fieldName));
0173 if (it == fFieldName2Token.end()) {
0174 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
0175 }
0176 return ROOT::RFieldToken(it->second, fSchemaId);
0177 }
0178
0179
0180 void EmplaceNewValue(ROOT::RFieldToken token)
0181 {
0182 EnsureMatchingModel(token);
0183 fValues[token.fIndex].EmplaceNew();
0184 }
0185
0186
0187 void EmplaceNewValue(std::string_view fieldName) { EmplaceNewValue(GetToken(fieldName)); }
0188
0189
0190
0191
0192 template <typename T>
0193 void BindValue(ROOT::RFieldToken token, std::shared_ptr<T> objPtr)
0194 {
0195 EnsureMatchingModel(token);
0196 EnsureMatchingType<T>(token);
0197 fValues[token.fIndex].Bind(objPtr);
0198 }
0199
0200
0201
0202
0203
0204
0205
0206
0207 template <typename T>
0208 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
0209 {
0210 BindValue<T>(GetToken(fieldName), objPtr);
0211 }
0212
0213
0214
0215
0216 template <typename T>
0217 void BindRawPtr(ROOT::RFieldToken token, T *rawPtr)
0218 {
0219 EnsureMatchingModel(token);
0220 EnsureMatchingType<T>(token);
0221 fValues[token.fIndex].BindRawPtr(rawPtr);
0222 }
0223
0224
0225
0226
0227
0228
0229
0230
0231 template <typename T>
0232 void BindRawPtr(std::string_view fieldName, T *rawPtr)
0233 {
0234 BindRawPtr<void>(GetToken(fieldName), rawPtr);
0235 }
0236
0237
0238
0239
0240 template <typename T>
0241 std::shared_ptr<T> GetPtr(ROOT::RFieldToken token) const
0242 {
0243 EnsureMatchingModel(token);
0244 EnsureMatchingType<T>(token);
0245 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
0246 }
0247
0248
0249
0250
0251
0252
0253
0254 template <typename T>
0255 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
0256 {
0257 return GetPtr<T>(GetToken(fieldName));
0258 }
0259
0260 const std::string &GetTypeName(ROOT::RFieldToken token) const
0261 {
0262 EnsureMatchingModel(token);
0263 return fFieldTypes[token.fIndex];
0264 }
0265
0266 const std::string &GetTypeName(std::string_view fieldName) const { return GetTypeName(GetToken(fieldName)); }
0267
0268 std::uint64_t GetModelId() const { return fModelId; }
0269 std::uint64_t GetSchemaId() const { return fSchemaId; }
0270
0271 ConstIterator_t begin() const { return fValues.cbegin(); }
0272 ConstIterator_t end() const { return fValues.cend(); }
0273 };
0274
0275 }
0276
0277 #endif