28 #include <unordered_map>
33 bool StrEndsWith(
const std::string &str,
const std::string &suffix)
35 if (str.size() < suffix.size())
37 return (str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0);
42 ROOT::Experimental::Detail::RPageStorage::RPageStorage(std::string_view name) : fNTupleName(name)
46 ROOT::Experimental::Detail::RPageStorage::~RPageStorage()
54 ROOT::Experimental::Detail::RPageSource::RPageSource(std::string_view name,
const RNTupleReadOptions &options)
55 : RPageStorage(name), fOptions(options)
59 ROOT::Experimental::Detail::RPageSource::~RPageSource()
63 std::unique_ptr<ROOT::Experimental::Detail::RPageSource> ROOT::Experimental::Detail::RPageSource::Create(
64 std::string_view ntupleName, std::string_view location,
const RNTupleReadOptions &options)
66 if (StrEndsWith(std::string(location),
".root"))
67 return std::make_unique<RPageSourceRoot>(ntupleName, location, options);
68 return std::make_unique<RPageSourceRaw>(ntupleName, location, options);
71 ROOT::Experimental::Detail::RPageStorage::ColumnHandle_t
72 ROOT::Experimental::Detail::RPageSource::AddColumn(DescriptorId_t fieldId,
const RColumn &column)
74 R__ASSERT(fieldId != kInvalidDescriptorId);
75 auto columnId = fDescriptor.FindColumnId(fieldId, column.GetIndex());
76 R__ASSERT(columnId != kInvalidDescriptorId);
77 return ColumnHandle_t(columnId, &column);
80 ROOT::Experimental::NTupleSize_t ROOT::Experimental::Detail::RPageSource::GetNEntries()
82 return fDescriptor.GetNEntries();
85 ROOT::Experimental::NTupleSize_t ROOT::Experimental::Detail::RPageSource::GetNElements(ColumnHandle_t columnHandle)
87 return fDescriptor.GetNElements(columnHandle.fId);
90 ROOT::Experimental::ColumnId_t ROOT::Experimental::Detail::RPageSource::GetColumnId(ColumnHandle_t columnHandle)
93 return columnHandle.fId;
100 ROOT::Experimental::Detail::RPageSink::RPageSink(std::string_view name,
const RNTupleWriteOptions &options)
101 : RPageStorage(name), fOptions(options)
105 ROOT::Experimental::Detail::RPageSink::~RPageSink()
109 std::unique_ptr<ROOT::Experimental::Detail::RPageSink> ROOT::Experimental::Detail::RPageSink::Create(
110 std::string_view ntupleName, std::string_view location,
const RNTupleWriteOptions &options)
112 if (StrEndsWith(std::string(location),
".root"))
113 return std::make_unique<RPageSinkRoot>(ntupleName, location, options);
114 return std::make_unique<RPageSinkRaw>(ntupleName, location, options);
117 ROOT::Experimental::Detail::RPageStorage::ColumnHandle_t
118 ROOT::Experimental::Detail::RPageSink::AddColumn(DescriptorId_t fieldId,
const RColumn &column)
120 auto columnId = fLastColumnId++;
121 fDescriptorBuilder.AddColumn(columnId, fieldId, column.GetVersion(), column.GetModel(), column.GetIndex());
122 return ColumnHandle_t(columnId, &column);
126 void ROOT::Experimental::Detail::RPageSink::Create(RNTupleModel &model)
128 fDescriptorBuilder.SetNTuple(fNTupleName, model.GetDescription(),
"undefined author",
129 model.GetVersion(), model.GetUuid());
131 std::unordered_map<const RFieldBase *, DescriptorId_t> fieldPtr2Id;
132 const auto &rootField = *model.GetRootField();
133 fDescriptorBuilder.AddField(fLastFieldId, rootField.GetFieldVersion(), rootField.GetTypeVersion(),
134 rootField.GetName(), rootField.GetType(), rootField.GetNRepetitions(), rootField.GetStructure());
135 fieldPtr2Id[&rootField] = fLastFieldId++;
136 for (
auto& f : *model.GetRootField()) {
137 fDescriptorBuilder.AddField(fLastFieldId, f.GetFieldVersion(), f.GetTypeVersion(), f.GetName(), f.GetType(),
138 f.GetNRepetitions(), f.GetStructure());
139 fDescriptorBuilder.AddFieldLink(fieldPtr2Id[f.GetParent()], fLastFieldId);
141 Detail::RFieldFuse::Connect(fLastFieldId, *
this, f);
142 fieldPtr2Id[&f] = fLastFieldId++;
145 auto nColumns = fLastColumnId;
146 for (DescriptorId_t i = 0; i < nColumns; ++i) {
147 RClusterDescriptor::RColumnRange columnRange;
148 columnRange.fColumnId = i;
149 columnRange.fFirstElementIndex = 0;
150 columnRange.fNElements = 0;
151 columnRange.fCompressionSettings = fOptions.GetCompression();
152 fOpenColumnRanges.emplace_back(columnRange);
153 RClusterDescriptor::RPageRange pageRange;
154 pageRange.fColumnId = i;
155 fOpenPageRanges.emplace_back(std::move(pageRange));
162 void ROOT::Experimental::Detail::RPageSink::CommitPage(ColumnHandle_t columnHandle,
const RPage &page)
164 auto locator = DoCommitPage(columnHandle, page);
166 auto columnId = columnHandle.fId;
167 fOpenColumnRanges[columnId].fNElements += page.GetNElements();
168 RClusterDescriptor::RPageRange::RPageInfo pageInfo;
169 pageInfo.fNElements = page.GetNElements();
170 pageInfo.fLocator = locator;
171 fOpenPageRanges[columnId].fPageInfos.emplace_back(pageInfo);
175 void ROOT::Experimental::Detail::RPageSink::CommitCluster(ROOT::Experimental::NTupleSize_t nEntries)
177 auto locator = DoCommitCluster(nEntries);
179 R__ASSERT((nEntries - fPrevClusterNEntries) < ClusterSize_t(-1));
180 fDescriptorBuilder.AddCluster(fLastClusterId, RNTupleVersion(), fPrevClusterNEntries,
181 ClusterSize_t(nEntries - fPrevClusterNEntries));
182 fDescriptorBuilder.SetClusterLocator(fLastClusterId, locator);
183 for (
auto &range : fOpenColumnRanges) {
184 fDescriptorBuilder.AddClusterColumnRange(fLastClusterId, range);
185 range.fFirstElementIndex += range.fNElements;
186 range.fNElements = 0;
188 for (
auto &range : fOpenPageRanges) {
189 RClusterDescriptor::RPageRange fullRange;
190 std::swap(fullRange, range);
191 range.fColumnId = fullRange.fColumnId;
192 fDescriptorBuilder.AddClusterPageRange(fLastClusterId, std::move(fullRange));
195 fPrevClusterNEntries = nEntries;