Logo ROOT  
Reference Guide
RPageSinkBuf.hxx
Go to the documentation of this file.
1/// \file ROOT/RPageSinkBuf.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \author Max Orok <maxwellorok@gmail.com>
5/// \date 2021-03-17
6/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
7/// is welcome!
8
9/*************************************************************************
10 * Copyright (C) 1995-2021, Rene Brun and Fons Rademakers. *
11 * All rights reserved. *
12 * *
13 * For the licensing terms see $ROOTSYS/LICENSE. *
14 * For the list of contributors see $ROOTSYS/README/CREDITS. *
15 *************************************************************************/
16
17#ifndef ROOT7_RPageSinkBuf
18#define ROOT7_RPageSinkBuf
19
21#include <ROOT/RPageStorage.hxx>
22
23#include <deque>
24#include <iterator>
25#include <memory>
26
27namespace ROOT {
28namespace Experimental {
29namespace Detail {
30
31// clang-format off
32/**
33\class ROOT::Experimental::Detail::RPageSinkBuf
34\ingroup NTuple
35\brief Wrapper sink that coalesces cluster column page writes
36*/
37// clang-format on
38class RPageSinkBuf : public RPageSink {
39private:
40 /// A buffered column. The column is not responsible for RPage memory management (i.e.
41 /// ReservePage/ReleasePage), which is handled by the enclosing RPageSinkBuf.
42 class RColumnBuf {
43 public:
44 struct RPageZipItem {
46 // Compression scratch buffer for fSealedPage.
47 std::unique_ptr<unsigned char[]> fBuf;
49 explicit RPageZipItem(RPage page)
50 : fPage(page), fBuf(nullptr) {}
51 bool IsSealed() const {
52 return fSealedPage.fBuffer != nullptr;
53 }
55 fBuf = std::make_unique<unsigned char[]>(fPage.GetNBytes());
56 }
57 };
58 public:
59 RColumnBuf() = default;
60 RColumnBuf(const RColumnBuf&) = delete;
61 RColumnBuf& operator=(const RColumnBuf&) = delete;
62 RColumnBuf(RColumnBuf&&) = default;
64 ~RColumnBuf() = default;
65
66 using iterator = std::deque<RPageZipItem>::iterator;
67 /// Returns an iterator to the newly buffered page. The iterator remains
68 /// valid until the return value of DrainBufferedPages() is destroyed.
70 RPageStorage::ColumnHandle_t columnHandle, const RPage &page)
71 {
72 if (!fCol) {
73 fCol = columnHandle;
74 }
75 // Safety: Insertion at the end of a deque never invalidates existing
76 // iterators.
77 fBufferedPages.push_back(RPageZipItem(page));
78 return std::prev(fBufferedPages.end());
79 }
80 const RPageStorage::ColumnHandle_t &GetHandle() const { return fCol; }
81 // When the return value of DrainBufferedPages() is destroyed, all iterators
82 // returned by GetBuffer are invalidated.
83 std::deque<RPageZipItem> DrainBufferedPages() {
84 std::deque<RPageZipItem> drained;
85 std::swap(fBufferedPages, drained);
86 return drained;
87 }
88 private:
90 // Using a deque guarantees that element iterators are never invalidated
91 // by appends to the end of the iterator by BufferPage.
92 std::deque<RPageZipItem> fBufferedPages;
93 };
94
95private:
96 /// I/O performance counters that get registered in fMetrics
97 struct RCounters {
99 };
100 std::unique_ptr<RCounters> fCounters;
102 /// The inner sink, responsible for actually performing I/O.
103 std::unique_ptr<RPageSink> fInnerSink;
104 /// The buffered page sink maintains a copy of the RNTupleModel for the inner sink.
105 /// For the unbuffered case, the RNTupleModel is instead managed by a RNTupleWriter.
106 std::unique_ptr<RNTupleModel> fInnerModel;
107 /// Vector of buffered column pages. Indexed by column id.
108 std::vector<RColumnBuf> fBufferedColumns;
109
110protected:
111 void CreateImpl(const RNTupleModel &model) final;
112 RClusterDescriptor::RLocator CommitPageImpl(ColumnHandle_t columnHandle, const RPage &page) final;
114 std::uint64_t CommitClusterImpl(NTupleSize_t nEntries) final;
115 void CommitDatasetImpl() final;
116
117public:
118 explicit RPageSinkBuf(std::unique_ptr<RPageSink> inner);
119 RPageSinkBuf(const RPageSinkBuf&) = delete;
120 RPageSinkBuf& operator=(const RPageSinkBuf&) = delete;
122 RPageSinkBuf& operator=(RPageSinkBuf&&) = default;
123 virtual ~RPageSinkBuf() = default;
124
125 RPage ReservePage(ColumnHandle_t columnHandle, std::size_t nElements) final;
126 void ReleasePage(RPage &page) final;
127
128 RNTupleMetrics &GetMetrics() final { return fMetrics; }
129};
130
131} // namespace Detail
132} // namespace Experimental
133} // namespace ROOT
134
135#endif
A collection of Counter objects with a name, a unit, and a description.
A non thread-safe integral performance counter.
const RPageStorage::ColumnHandle_t & GetHandle() const
iterator BufferPage(RPageStorage::ColumnHandle_t columnHandle, const RPage &page)
Returns an iterator to the newly buffered page.
RColumnBuf & operator=(const RColumnBuf &)=delete
RColumnBuf & operator=(RColumnBuf &&)=default
std::deque< RPageZipItem >::iterator iterator
Wrapper sink that coalesces cluster column page writes.
RClusterDescriptor::RLocator CommitSealedPageImpl(DescriptorId_t columnId, const RSealedPage &sealedPage) final
void ReleasePage(RPage &page) final
Every page store needs to be able to free pages it handed out.
std::unique_ptr< RCounters > fCounters
RPage ReservePage(ColumnHandle_t columnHandle, std::size_t nElements) final
Get a new, empty page for the given column that can be filled with up to nElements.
std::unique_ptr< RPageSink > fInnerSink
The inner sink, responsible for actually performing I/O.
RClusterDescriptor::RLocator CommitPageImpl(ColumnHandle_t columnHandle, const RPage &page) final
RNTupleMetrics & GetMetrics() final
Returns the default metrics object. Subclasses might alternatively provide their own metrics object b...
std::vector< RColumnBuf > fBufferedColumns
Vector of buffered column pages. Indexed by column id.
void CreateImpl(const RNTupleModel &model) final
std::uint64_t CommitClusterImpl(NTupleSize_t nEntries) final
Returns the number of bytes written to storage (excluding metadata)
std::unique_ptr< RNTupleModel > fInnerModel
The buffered page sink maintains a copy of the RNTupleModel for the inner sink.
Abstract interface to write data into an ntuple.
A page is a slice of a column that is mapped into memory.
Definition: RPage.hxx:41
ClusterSize_t::ValueType GetNBytes() const
The space taken by column elements in the buffer.
Definition: RPage.hxx:81
The RNTupleModel encapulates the schema of an ntuple.
void swap(RDirectoryEntry &e1, RDirectoryEntry &e2) noexcept
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:77
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
I/O performance counters that get registered in fMetrics.
A sealed page contains the bytes of a page as written to storage (packed & compressed).
Generic information about the physical location of data.