|
|
|||
Warning, file /include/root/ROOT/RNTupleParallelWriter.hxx was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /// \file ROOT/RNTupleParallelWriter.hxx 0002 /// \ingroup NTuple 0003 /// \author Jonas Hahnfeld <jonas.hahnfeld@cern.ch> 0004 /// \date 2024-02-01 0005 0006 /************************************************************************* 0007 * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. * 0008 * All rights reserved. * 0009 * * 0010 * For the licensing terms see $ROOTSYS/LICENSE. * 0011 * For the list of contributors see $ROOTSYS/README/CREDITS. * 0012 *************************************************************************/ 0013 0014 #ifndef ROOT_RNTupleParallelWriter 0015 #define ROOT_RNTupleParallelWriter 0016 0017 #include <ROOT/RNTupleMetrics.hxx> 0018 #include <ROOT/RNTupleWriteOptions.hxx> 0019 0020 #include <memory> 0021 #include <mutex> 0022 #include <string_view> 0023 #include <vector> 0024 0025 class TDirectory; 0026 0027 namespace ROOT { 0028 0029 class RNTupleModel; 0030 0031 namespace Internal { 0032 class RPageSink; 0033 } // namespace Internal 0034 0035 class RNTupleFillContext; 0036 0037 /** 0038 \class ROOT::RNTupleParallelWriter 0039 \ingroup NTuple 0040 \brief A writer to fill an RNTuple from multiple contexts 0041 0042 Compared to the sequential RNTupleWriter, a parallel writer enables the creation of multiple RNTupleFillContext (see 0043 CreateFillContext()). Each fill context prepares independent clusters that are appended to the common RNTuple with 0044 internal synchronization. Before destruction, all fill contexts must have flushed their data and been destroyed (or 0045 data could be lost!). 0046 0047 For user convenience, CreateFillContext() is thread-safe and may be called from multiple threads in parallel at any 0048 time, also after some data has already been written. Internally, the original model is cloned and ownership is passed 0049 to a newly created RNTupleFillContext. For that reason, it is recommended to use RNTupleModel::CreateBare when creating 0050 the model for parallel writing and avoid the allocation of a useless default REntry per context. 0051 0052 Note that the sequence of independently prepared clusters is indeterminate and therefore entries are only partially 0053 ordered: Entries from one context are totally ordered as they were filled. However, there is no orderering with other 0054 contexts and the entries may be appended to the RNTuple either before or after other entries written in parallel into 0055 other contexts. In addition, two consecutive entries in one fill context can end up separated in the final RNTuple, if 0056 they happen to fall onto a cluster boundary and other contexts append more entries before the next cluster is full. 0057 0058 At the moment, the parallel writer does not (yet) support incremental updates of the underlying model. Please refer to 0059 RNTupleWriter::CreateModelUpdater if required for your use case. 0060 */ 0061 class RNTupleParallelWriter { 0062 private: 0063 /// A global mutex to protect the internal data structures of this object. 0064 std::mutex fMutex; 0065 /// A mutex to synchronize the final page sink. 0066 std::mutex fSinkMutex; 0067 /// The final RPageSink that represents the synchronization point. 0068 std::unique_ptr<ROOT::Internal::RPageSink> fSink; 0069 /// The original RNTupleModel connected to fSink; needs to be destructed before it. 0070 std::unique_ptr<ROOT::RNTupleModel> fModel; 0071 Experimental::Detail::RNTupleMetrics fMetrics; 0072 /// List of all created helpers. They must be destroyed before this RNTupleParallelWriter is destructed. 0073 std::vector<std::weak_ptr<RNTupleFillContext>> fFillContexts; 0074 0075 RNTupleParallelWriter(std::unique_ptr<ROOT::RNTupleModel> model, std::unique_ptr<ROOT::Internal::RPageSink> sink); 0076 RNTupleParallelWriter(const RNTupleParallelWriter &) = delete; 0077 RNTupleParallelWriter &operator=(const RNTupleParallelWriter &) = delete; 0078 0079 public: 0080 /// Recreate a new file and return a writer to write an RNTuple. 0081 static std::unique_ptr<RNTupleParallelWriter> 0082 Recreate(std::unique_ptr<ROOT::RNTupleModel> model, std::string_view ntupleName, std::string_view storage, 0083 const ROOT::RNTupleWriteOptions &options = ROOT::RNTupleWriteOptions()); 0084 /// Append an RNTuple to the existing file. 0085 /// 0086 /// While the writer synchronizes between multiple fill contexts created from the same writer, there is no 0087 /// synchronization with other writers or other clients that write into the same file. The caller must ensure that 0088 /// the underlying file is not be accessed while data is filled into any created context. To improve performance, it 0089 /// is allowed to use special methods that are guaranteed to not interact with the underlying file, such as 0090 /// RNTupleFillContext::FillNoFlush(). 0091 static std::unique_ptr<RNTupleParallelWriter> 0092 Append(std::unique_ptr<ROOT::RNTupleModel> model, std::string_view ntupleName, TDirectory &fileOrDirectory, 0093 const ROOT::RNTupleWriteOptions &options = ROOT::RNTupleWriteOptions()); 0094 0095 ~RNTupleParallelWriter(); 0096 0097 /// Create a new RNTupleFillContext that can be used to fill entries and prepare clusters in parallel. This method is 0098 /// thread-safe and may be called from multiple threads in parallel at any time, also after some data has already 0099 /// been written. 0100 /// 0101 /// Note that all fill contexts must be destroyed before CommitDataset() is called. 0102 std::shared_ptr<RNTupleFillContext> CreateFillContext(); 0103 0104 /// Automatically called by the destructor 0105 void CommitDataset(); 0106 0107 void EnableMetrics() { fMetrics.Enable(); } 0108 const Experimental::Detail::RNTupleMetrics &GetMetrics() const { return fMetrics; } 0109 }; 0110 0111 } // namespace ROOT 0112 0113 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|