Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 09:08:36

0001 /// \file ROOT/RRawPtrWriteEntry.hxx
0002 /// \ingroup NTuple
0003 /// \author Jonas Hahnfeld <jonas.hahnfeld@cern.ch>
0004 /// \date 2025-03-19
0005 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
0006 /// is welcome!
0007 
0008 /*************************************************************************
0009  * Copyright (C) 1995-2025, Rene Brun and Fons Rademakers.               *
0010  * All rights reserved.                                                  *
0011  *                                                                       *
0012  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0013  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0014  *************************************************************************/
0015 
0016 #ifndef ROOT_RRawPtrWriteEntry
0017 #define ROOT_RRawPtrWriteEntry
0018 
0019 #include <ROOT/RFieldBase.hxx>
0020 #include <ROOT/RFieldToken.hxx>
0021 #include <ROOT/RError.hxx>
0022 
0023 #include <cstdint>
0024 #include <unordered_map>
0025 #include <vector>
0026 
0027 namespace ROOT {
0028 
0029 class RNTupleModel;
0030 
0031 namespace Experimental {
0032 
0033 class RNTupleFillContext;
0034 
0035 namespace Detail {
0036 
0037 // clang-format off
0038 /**
0039 \class ROOT::Experimental::Detail::RRawPtrWriteEntry
0040 \ingroup NTuple
0041 \brief A container of const raw pointers, corresponding to a row in the data set
0042 
0043 This class can be used to write constant data products in frameworks.  All other users are encouraged to use the API
0044 provided by REntry, with safe interfaces, type checks, and shared object ownership.
0045 */
0046 // clang-format on
0047 class RRawPtrWriteEntry {
0048    friend class ROOT::RNTupleModel;
0049    friend class ROOT::Experimental::RNTupleFillContext;
0050 
0051 private:
0052    /// The entry must be linked to a specific model, identified by a model ID
0053    std::uint64_t fModelId = 0;
0054    /// The entry and its tokens are also linked to a specific schema, identified by a schema ID
0055    std::uint64_t fSchemaId = 0;
0056    /// Corresponds to the fields of the linked model
0057    std::vector<ROOT::RFieldBase *> fFields;
0058    /// The raw pointers corresponding to the fields
0059    std::vector<const void *> fRawPtrs;
0060    /// For fast lookup of token IDs given a (sub)field name present in the entry
0061    std::unordered_map<std::string, std::size_t> fFieldName2Token;
0062 
0063    explicit RRawPtrWriteEntry(std::uint64_t modelId, std::uint64_t schemaId) : fModelId(modelId), fSchemaId(schemaId) {}
0064 
0065    void AddField(ROOT::RFieldBase &field)
0066    {
0067       fFieldName2Token[field.GetQualifiedFieldName()] = fFields.size();
0068       fFields.emplace_back(&field);
0069       fRawPtrs.emplace_back(nullptr);
0070    }
0071 
0072    std::size_t Append()
0073    {
0074       std::size_t bytesWritten = 0;
0075       for (std::size_t i = 0; i < fFields.size(); i++) {
0076          bytesWritten += fFields[i]->Append(fRawPtrs[i]);
0077       }
0078       return bytesWritten;
0079    }
0080 
0081    void EnsureMatchingModel(RFieldToken token) const
0082    {
0083       if (fSchemaId != token.fSchemaId) {
0084          throw RException(R__FAIL("invalid token for this entry, "
0085                                   "make sure to use a token from a model with the same schema as this entry."));
0086       }
0087    }
0088 
0089 public:
0090    RRawPtrWriteEntry(const RRawPtrWriteEntry &other) = delete;
0091    RRawPtrWriteEntry &operator=(const RRawPtrWriteEntry &other) = delete;
0092    RRawPtrWriteEntry(RRawPtrWriteEntry &&other) = default;
0093    RRawPtrWriteEntry &operator=(RRawPtrWriteEntry &&other) = default;
0094    ~RRawPtrWriteEntry() = default;
0095 
0096    /// The ordinal of the (sub)field fieldName; can be used in other methods to address the corresponding value
0097    RFieldToken GetToken(std::string_view fieldName) const
0098    {
0099       auto it = fFieldName2Token.find(std::string(fieldName));
0100       if (it == fFieldName2Token.end()) {
0101          throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
0102       }
0103       return RFieldToken(it->second, fSchemaId);
0104    }
0105 
0106    template <typename T>
0107    void BindRawPtr(RFieldToken token, const T *rawPtr)
0108    {
0109       EnsureMatchingModel(token);
0110       fRawPtrs[token.fIndex] = rawPtr;
0111    }
0112 
0113    template <typename T>
0114    void BindRawPtr(std::string_view fieldName, const T *rawPtr)
0115    {
0116       BindRawPtr(GetToken(fieldName), rawPtr);
0117    }
0118 
0119    std::uint64_t GetModelId() const { return fModelId; }
0120    std::uint64_t GetSchemaId() const { return fSchemaId; }
0121 };
0122 
0123 } // namespace Detail
0124 } // namespace Experimental
0125 } // namespace ROOT
0126 
0127 #endif