Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:14:32

0001 /// \file ROOT/RPageStorageDaos.hxx
0002 /// \ingroup NTuple
0003 /// \author Javier Lopez-Gomez <j.lopez@cern.ch>
0004 /// \date 2020-11-03
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-2021, 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_RPageStorageDaos
0017 #define ROOT_RPageStorageDaos
0018 
0019 #include <ROOT/RError.hxx>
0020 #include <ROOT/RPageStorage.hxx>
0021 #include <ROOT/RNTuple.hxx>
0022 #include <ROOT/RNTupleSerialize.hxx>
0023 #include <ROOT/RNTupleZip.hxx>
0024 #include <string_view>
0025 
0026 #include <array>
0027 #include <atomic>
0028 #include <cstdio>
0029 #include <memory>
0030 #include <string>
0031 #include <optional>
0032 
0033 namespace ROOT {
0034 
0035 namespace Internal {
0036 class RCluster;
0037 class RClusterPool;
0038 } // namespace Internal
0039 
0040 namespace Experimental {
0041 namespace Internal {
0042 using ntuple_index_t = std::uint32_t;
0043 class RDaosPool;
0044 class RDaosContainer;
0045 class RPageAllocatorHeap;
0046 enum EDaosLocatorFlags {
0047    // Indicates that the referenced page is "caged", i.e. it is stored in a larger blob that contains multiple pages.
0048    kCagedPage = 0x01,
0049 };
0050 
0051 // clang-format off
0052 /**
0053 \class ROOT::Experimental::Internal::RDaosNTupleAnchor
0054 \ingroup NTuple
0055 \brief Entry point for an RNTuple in a DAOS container. It encodes essential
0056 information to read the ntuple; currently, it contains (un)compressed size of
0057 the header/footer blobs and the object class for user data OIDs.
0058 The length of a serialized anchor cannot be greater than the value returned by the `GetSize` function.
0059 */
0060 // clang-format on
0061 struct RDaosNTupleAnchor {
0062    /// Allows for evolving the struct in future versions
0063    std::uint64_t fVersionAnchor = 1;
0064    /// Version of the binary format supported by the writer
0065    std::uint16_t fVersionEpoch = RNTuple::kVersionEpoch;
0066    std::uint16_t fVersionMajor = RNTuple::kVersionMajor;
0067    std::uint16_t fVersionMinor = RNTuple::kVersionMinor;
0068    std::uint16_t fVersionPatch = RNTuple::kVersionPatch;
0069    /// The size of the compressed ntuple header
0070    std::uint32_t fNBytesHeader = 0;
0071    /// The size of the uncompressed ntuple header
0072    std::uint32_t fLenHeader = 0;
0073    /// The size of the compressed ntuple footer
0074    std::uint32_t fNBytesFooter = 0;
0075    /// The size of the uncompressed ntuple footer
0076    std::uint32_t fLenFooter = 0;
0077    /// The object class for user data OIDs, e.g. `SX`
0078    std::string fObjClass{};
0079 
0080    bool operator ==(const RDaosNTupleAnchor &other) const {
0081       return fVersionAnchor == other.fVersionAnchor && fVersionEpoch == other.fVersionEpoch &&
0082              fVersionMajor == other.fVersionMajor && fVersionMinor == other.fVersionMinor &&
0083              fVersionPatch == other.fVersionPatch && fNBytesHeader == other.fNBytesHeader &&
0084              fLenHeader == other.fLenHeader && fNBytesFooter == other.fNBytesFooter && fLenFooter == other.fLenFooter &&
0085              fObjClass == other.fObjClass;
0086    }
0087 
0088    std::uint32_t Serialize(void *buffer) const;
0089    RResult<std::uint32_t> Deserialize(const void *buffer, std::uint32_t bufSize);
0090 
0091    static std::uint32_t GetSize();
0092 }; // struct RDaosNTupleAnchor
0093 
0094 // clang-format off
0095 /**
0096 \class ROOT::Experimental::Internal::RPageSinkDaos
0097 \ingroup NTuple
0098 \brief Storage provider that writes ntuple pages to into a DAOS container
0099 
0100 Currently, an object is allocated for ntuple metadata (anchor/header/footer).
0101 Objects can correspond to pages or clusters of pages depending on the RNTuple-DAOS mapping strategy.
0102 */
0103 // clang-format on
0104 class RPageSinkDaos : public ROOT::Internal::RPagePersistentSink {
0105 private:
0106    /// \brief Underlying DAOS container. An internal `std::shared_ptr` keep the pool connection alive.
0107    /// ISO C++ ensures the correct destruction order, i.e., `~RDaosContainer` is invoked first
0108    /// (which calls `daos_cont_close()`; the destructor for the `std::shared_ptr<RDaosPool>` is invoked
0109    /// after (which calls `daos_pool_disconect()`).
0110    std::unique_ptr<RDaosContainer> fDaosContainer;
0111    /// Page identifier for the next committed page; it is automatically incremented in `CommitSealedPageImpl()`
0112    std::atomic<std::uint64_t> fPageId{0};
0113    /// Cluster group counter for the next committed cluster pagelist; incremented in `CommitClusterGroupImpl()`
0114    std::atomic<std::uint64_t> fClusterGroupId{0};
0115    /// \brief A URI to a DAOS pool of the form 'daos://pool-label/container-label'
0116    std::string fURI;
0117    /// Tracks the number of bytes committed to the current cluster
0118    std::uint64_t fNBytesCurrentCluster{0};
0119 
0120    RDaosNTupleAnchor fNTupleAnchor;
0121    ntuple_index_t fNTupleIndex{0};
0122    uint32_t fCageSizeLimit{};
0123 
0124 protected:
0125    using RPagePersistentSink::InitImpl;
0126    void InitImpl(unsigned char *serializedHeader, std::uint32_t length) final;
0127    RNTupleLocator CommitPageImpl(ColumnHandle_t columnHandle, const ROOT::Internal::RPage &page) final;
0128    RNTupleLocator
0129    CommitSealedPageImpl(ROOT::DescriptorId_t physicalColumnId, const RPageStorage::RSealedPage &sealedPage) final;
0130    std::vector<RNTupleLocator>
0131    CommitSealedPageVImpl(std::span<RPageStorage::RSealedPageGroup> ranges, const std::vector<bool> &mask) final;
0132    std::uint64_t StageClusterImpl() final;
0133    RNTupleLocator CommitClusterGroupImpl(unsigned char *serializedPageList, std::uint32_t length) final;
0134    using RPagePersistentSink::CommitDatasetImpl;
0135    void CommitDatasetImpl(unsigned char *serializedFooter, std::uint32_t length) final;
0136    void WriteNTupleHeader(const void *data, size_t nbytes, size_t lenHeader);
0137    void WriteNTupleFooter(const void *data, size_t nbytes, size_t lenFooter);
0138    void WriteNTupleAnchor();
0139 
0140 public:
0141    RPageSinkDaos(std::string_view ntupleName, std::string_view uri, const ROOT::RNTupleWriteOptions &options);
0142    ~RPageSinkDaos() override;
0143 }; // class RPageSinkDaos
0144 
0145 // clang-format off
0146 /**
0147 \class ROOT::Experimental::Internal::RPageSourceDaos
0148 \ingroup NTuple
0149 \brief Storage provider that reads ntuple pages from a DAOS container
0150 */
0151 // clang-format on
0152 class RPageSourceDaos : public ROOT::Internal::RPageSource {
0153 private:
0154    ntuple_index_t fNTupleIndex{0};
0155 
0156    /// The last cluster from which a page got loaded.  Points into fClusterPool->fPool
0157    ROOT::Internal::RCluster *fCurrentCluster = nullptr;
0158    /// A container that stores object data (header/footer, pages, etc.)
0159    std::unique_ptr<RDaosContainer> fDaosContainer;
0160    /// A URI to a DAOS pool of the form 'daos://pool-label/container-label'
0161    std::string fURI;
0162    /// The cluster pool asynchronously preloads the next few clusters
0163    std::unique_ptr<ROOT::Internal::RClusterPool> fClusterPool;
0164 
0165    ROOT::Internal::RNTupleDescriptorBuilder fDescriptorBuilder;
0166 
0167    ROOT::Internal::RPageRef
0168    LoadPageImpl(ColumnHandle_t columnHandle, const RClusterInfo &clusterInfo, ROOT::NTupleSize_t idxInCluster) final;
0169 
0170 protected:
0171    void LoadStructureImpl() final {}
0172    ROOT::RNTupleDescriptor AttachImpl(ROOT::Internal::RNTupleSerializer::EDescriptorDeserializeMode mode) final;
0173    /// The cloned page source creates a new connection to the pool/container.
0174    std::unique_ptr<RPageSource> CloneImpl() const final;
0175 
0176 public:
0177    RPageSourceDaos(std::string_view ntupleName, std::string_view uri, const ROOT::RNTupleReadOptions &options);
0178    ~RPageSourceDaos() override;
0179 
0180    void
0181    LoadSealedPage(ROOT::DescriptorId_t physicalColumnId, RNTupleLocalIndex localIndex, RSealedPage &sealedPage) final;
0182 
0183    std::vector<std::unique_ptr<ROOT::Internal::RCluster>>
0184    LoadClusters(std::span<ROOT::Internal::RCluster::RKey> clusterKeys) final;
0185 
0186    /// Return the object class used for user data OIDs in this ntuple.
0187    std::string GetObjectClass() const;
0188 }; // class RPageSourceDaos
0189 
0190 } // namespace Internal
0191 
0192 } // namespace Experimental
0193 } // namespace ROOT
0194 
0195 #endif