Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RPageStorageRoot.hxx
Go to the documentation of this file.
1 /// \file ROOT/RPageStorage.hxx
2 /// \ingroup NTuple ROOT7
3 /// \author Jakob Blomer <jblomer@cern.ch>
4 /// \date 2018-07-19
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6 /// is welcome!
7 
8 /*************************************************************************
9  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10  * All rights reserved. *
11  * *
12  * For the licensing terms see $ROOTSYS/LICENSE. *
13  * For the list of contributors see $ROOTSYS/README/CREDITS. *
14  *************************************************************************/
15 
16 #ifndef ROOT7_RPageStorageRoot
17 #define ROOT7_RPageStorageRoot
18 
19 #include <ROOT/RPageAllocator.hxx>
20 #include <ROOT/RPageStorage.hxx>
21 #include <ROOT/RColumnModel.hxx>
23 #include <ROOT/RNTupleMetrics.hxx>
24 #include <ROOT/RNTupleUtil.hxx>
25 
26 #include <TDirectory.h>
27 #include <TFile.h>
28 
29 #include <memory>
30 #include <string>
31 #include <unordered_map>
32 
33 namespace ROOT {
34 namespace Experimental {
35 
36 namespace Internal {
37 
38 struct RNTupleBlob {
39  RNTupleBlob() {}
40  RNTupleBlob(int size, unsigned char *content) : fSize(size), fContent(content) {}
41  RNTupleBlob(const RNTupleBlob &other) = delete;
42  RNTupleBlob &operator =(const RNTupleBlob &other) = delete;
43  ~RNTupleBlob() = default;
44 
45  std::int32_t fVersion = 0;
46  int fSize = 0;
47  unsigned char* fContent = nullptr; //[fSize]
48 };
49 
50 } // namespace Internal
51 
52 
53 namespace Detail {
54 
55 class RPagePool;
56 
57 // clang-format off
58 /**
59 \class ROOT::Experimental::Detail::RPageSinkRoot
60 \ingroup NTuple
61 \brief Storage provider that write ntuple pages into a ROOT TFile
62 */
63 // clang-format on
64 class RPageSinkRoot : public RPageSink {
65 private:
66  static constexpr std::size_t kDefaultElementsPerPage = 10000;
67 
68  RNTupleMetrics fMetrics;
69  std::unique_ptr<RPageAllocatorHeap> fPageAllocator;
70 
71  /// Currently, an ntuple is stored as a directory in a TFile
72  std::unique_ptr<TFile> fFile;
73  TDirectory *fDirectory = nullptr;
74 
75  /// Instead of a physical file offset, pages in root are identified by an index which becomes part of the key
76  DescriptorId_t fLastPageIdx = 0;
77 
78 protected:
79  void DoCreate(const RNTupleModel &model) final;
80  RClusterDescriptor::RLocator DoCommitPage(ColumnHandle_t columnHandle, const RPage &page) final;
81  RClusterDescriptor::RLocator DoCommitCluster(NTupleSize_t nEntries) final;
82  void DoCommitDataset() final;
83 
84 public:
85  RPageSinkRoot(std::string_view ntupleName, std::string_view path, const RNTupleWriteOptions &options);
86  virtual ~RPageSinkRoot();
87 
88  RPage ReservePage(ColumnHandle_t columnHandle, std::size_t nElements = 0) final;
89  void ReleasePage(RPage &page) final;
90 
91  RNTupleMetrics &GetMetrics() final { return fMetrics; }
92 };
93 
94 
95 // clang-format off
96 /**
97 \class ROOT::Experimental::Detail::RPageAllocatorKey
98 \ingroup NTuple
99 \brief Adopts the memory returned by TKey->ReadObject()
100 */
101 // clang-format on
102 class RPageAllocatorKey {
103 public:
104  static RPage NewPage(ColumnId_t columnId, void *mem, std::size_t elementSize, std::size_t nElements);
105  static void DeletePage(const RPage& page, ROOT::Experimental::Internal::RNTupleBlob *payload);
106 };
107 
108 
109 // clang-format off
110 /**
111 \class ROOT::Experimental::Detail::RPageSourceRoot
112 \ingroup NTuple
113 \brief Storage provider that reads ntuple pages from a ROOT TFile
114 */
115 // clang-format on
116 class RPageSourceRoot : public RPageSource {
117 private:
118  RNTupleMetrics fMetrics;
119  std::unique_ptr<RPageAllocatorKey> fPageAllocator;
120  std::shared_ptr<RPagePool> fPagePool;
121 
122  /// Currently, an ntuple is stored as a directory in a TFile
123  std::unique_ptr<TFile> fFile;
124  TDirectory *fDirectory = nullptr;
125 
126  RPage PopulatePageFromCluster(ColumnHandle_t columnHandle, const RClusterDescriptor &clusterDescriptor,
127  ClusterSize_t::ValueType clusterIndex);
128 
129 protected:
130  RNTupleDescriptor DoAttach() final;
131 
132 public:
133  RPageSourceRoot(std::string_view ntupleName, std::string_view path, const RNTupleReadOptions &options);
134  std::unique_ptr<RPageSource> Clone() const final;
135  virtual ~RPageSourceRoot();
136 
137  RPage PopulatePage(ColumnHandle_t columnHandle, NTupleSize_t globalIndex) final;
138  RPage PopulatePage(ColumnHandle_t columnHandle, const RClusterIndex &clusterIndex) final;
139  void ReleasePage(RPage &page) final;
140 
141  RNTupleMetrics &GetMetrics() final { return fMetrics; }
142 };
143 
144 } // namespace Detail
145 
146 } // namespace Experimental
147 } // namespace ROOT
148 
149 #endif