Logo ROOT   6.12/07
Reference Guide
TBufferMerger.hxx
Go to the documentation of this file.
1 // @(#)root/io:$Id$
2 // Author: Philippe Canal, Witold Pokorski, and Guilherme Amadio
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TBufferMerger
13 #define ROOT_TBufferMerger
14 
15 #include "TMemFile.h"
16 
17 #include <condition_variable>
18 #include <functional>
19 #include <memory>
20 #include <mutex>
21 #include <queue>
22 #include <thread>
23 
24 class TBufferFile;
25 class TFile;
26 
27 namespace ROOT {
28 namespace Experimental {
29 
30 class TBufferMergerFile;
31 
32 /**
33  * \class TBufferMerger TBufferMerger.hxx
34  * \ingroup IO
35  *
36  * TBufferMerger is a class to facilitate writing data in
37  * parallel from multiple threads, while writing to a single
38  * output file. Its purpose is similar to TParallelMergingFile,
39  * but instead of using processes that connect to a network
40  * socket, TBufferMerger uses threads that each write to a
41  * TBufferMergerFile, which in turn push data into a queue
42  * managed by the TBufferMerger.
43  */
44 
46 public:
47  /** Constructor
48  * @param name Output file name
49  * @param option Output file creation options
50  * @param compression Output file compression level
51  */
52  TBufferMerger(const char *name, Option_t *option = "RECREATE", Int_t compress = 1);
53 
54  /** Constructor
55  * @param output Output \c TFile
56  */
57  TBufferMerger(std::unique_ptr<TFile> output);
58 
59  /** Destructor */
60  virtual ~TBufferMerger();
61 
62  /** Returns a TBufferMergerFile to which data can be written.
63  * At the end, all TBufferMergerFiles get merged into the output file.
64  * The user is responsible to "cd" into the file to associate objects
65  * such as histograms or trees to it.
66  *
67  * After the creation of this file, the user must reset the kMustCleanup
68  * bit on any objects attached to it and take care of their deletion, as
69  * there is a possibility that a race condition will happen that causes
70  * a crash if ROOT manages these objects.
71  */
72  std::shared_ptr<TBufferMergerFile> GetFile();
73 
74  /** Returns the number of buffers currently in the queue. */
75  size_t GetQueueSize() const;
76 
77  /** Register a user callback function to be called after a buffer has been
78  * removed from the merging queue and finished being processed. This
79  * function can be useful to allow asynchronous launching of new tasks to
80  * push more data into the queue once its size satisfies user requirements.
81  */
82  void RegisterCallback(const std::function<void(void)> &f);
83 
84  /** Returns the current value of the auto save setting in bytes (default = 0). */
85  size_t GetAutoSave() const;
86 
87  /** By default, TBufferMerger will call TFileMerger::PartialMerge() for each
88  * buffer pushed onto its merge queue. This function lets the user change
89  * this behaviour by telling TBufferMerger to accumulate at least @param size
90  * bytes in memory before performing a partial merge and flushing to disk.
91  * This can be useful to avoid an excessive amount of work to happen in the
92  * output thread, as the number of TTree headers (which require compression)
93  * written to disk can be reduced.
94  */
95  void SetAutoSave(size_t size);
96 
97  friend class TBufferMergerFile;
98 
99 private:
100  /** TBufferMerger has no default constructor */
101  TBufferMerger();
102 
103  /** TBufferMerger has no copy constructor */
104  TBufferMerger(const TBufferMerger &);
105 
106  /** TBufferMerger has no copy operator */
108 
109  void Init(std::unique_ptr<TFile>);
110 
111  void Push(TBufferFile *buffer);
112  void WriteOutputFile();
113 
114  TFile* fFile; //< Output file.
115  size_t fAutoSave; //< AutoSave only every fAutoSave bytes
116  std::mutex fQueueMutex; //< Mutex used to lock fQueue
117  std::condition_variable fDataAvailable; //< Condition variable used to wait for data
118  std::queue<TBufferFile *> fQueue; //< Queue to which data is pushed and merged
119  std::unique_ptr<std::thread> fMergingThread; //< Worker thread that writes to disk
120  std::vector<std::weak_ptr<TBufferMergerFile>> fAttachedFiles; //< Attached files
121  std::function<void(void)> fCallback; //< Callback for when data is removed from queue
122 
124 };
125 
126 /**
127  * \class TBufferMerger TBufferMerger.hxx
128  * \ingroup IO
129  *
130  * A TBufferMergerFile is similar to a TMemFile, but when data
131  * is written to it, it is appended to the TBufferMerger queue.
132  * The TBufferMerger merges all data into the output file on disk.
133  */
134 
135 class TBufferMergerFile : public TMemFile {
136 private:
137  TBufferMerger &fMerger; //< TBufferMerger this file is attached to
138 
139  /** Constructor. Can only be called by TBufferMerger.
140  * @param m Merger this file is attached to. */
142 
143  /** TBufferMergerFile has no default constructor. */
145 
146  /** TBufferMergerFile has no copy constructor. */
148 
149  /** TBufferMergerFile has no copy operator */
151 
152  friend class TBufferMerger;
153 
154 public:
155  /** Destructor */
157 
158  using TMemFile::Write;
159 
160  /** Write data into a TBufferFile and append it to TBufferMerger.
161  * @param name Name
162  * @param opt Options
163  * @param bufsize Buffer size
164  * This function must be called before the TBufferMergerFile gets destroyed,
165  * or no data is appended to the TBufferMerger.
166  */
167  virtual Int_t Write(const char *name = nullptr, Int_t opt = 0, Int_t bufsize = 0) override;
168 
170 };
171 
172 } // namespace Experimental
173 } // namespace ROOT
174 
175 #endif
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket...
Definition: TBufferFile.h:47
auto * m
Definition: textangle.C:8
std::vector< std::weak_ptr< TBufferMergerFile > > fAttachedFiles
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
const char Option_t
Definition: RtypesCore.h:62
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:46
int Int_t
Definition: RtypesCore.h:41
size_t GetAutoSave() const
Returns the current value of the auto save setting in bytes (default = 0).
void Push(TBufferFile *buffer)
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition: TMemFile.h:17
void Init(std::unique_ptr< TFile >)
std::queue< TBufferFile * > fQueue
#define ClassDef(name, id)
Definition: Rtypes.h:320
TBufferMerger & operator=(const TBufferMerger &)
TBufferMerger has no copy operator.
void SetAutoSave(size_t size)
By default, TBufferMerger will call TFileMerger::PartialMerge() for each buffer pushed onto its merge...
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:146
size_t GetQueueSize() const
Returns the number of buffers currently in the queue.
void RegisterCallback(const std::function< void(void)> &f)
Register a user callback function to be called after a buffer has been removed from the merging queue...
virtual ~TBufferMerger()
Destructor.
std::condition_variable fDataAvailable
virtual Int_t Write(const char *name=0, Int_t opt=0, Int_t bufsiz=0)
Write memory objects to this file.
Definition: TFile.cxx:2313
TBufferMerger is a class to facilitate writing data in parallel from multiple threads, while writing to a single output file.
std::unique_ptr< std::thread > fMergingThread
TBufferMerger()
TBufferMerger has no default constructor.
std::function< void(void)> fCallback
std::shared_ptr< TBufferMergerFile > GetFile()
Returns a TBufferMergerFile to which data can be written.
#define ClassDefOverride(name, id)
Definition: Rtypes.h:324
A ROOT file.
Definition: TFile.hxx:45
char name[80]
Definition: TGX11.cxx:109