Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleJoinTable.cxx
Go to the documentation of this file.
1/// \file RNTupleJoinTable.cxx
2/// \ingroup NTuple
3/// \author Florine de Geus <florine.de.geus@cern.ch>
4/// \date 2024-04-02
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-2024, 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
17
18namespace {
20{
22
23 switch (fieldValueSize) {
24 case 1: value = *reinterpret_cast<std::uint8_t *>(valuePtr); break;
25 case 2: value = *reinterpret_cast<std::uint16_t *>(valuePtr); break;
26 case 4: value = *reinterpret_cast<std::uint32_t *>(valuePtr); break;
27 case 8: value = *reinterpret_cast<std::uint64_t *>(valuePtr); break;
28 default: throw ROOT::RException(R__FAIL("value size not supported"));
29 }
30
31 return value;
32}
33} // anonymous namespace
34
36 ROOT::Internal::RPageSource &pageSource, const std::vector<std::string> &joinFieldNames,
38 : fJoinFieldNames(joinFieldNames)
39{
40 static const std::unordered_set<std::string> allowedTypes = {"std::int8_t", "std::int16_t", "std::int32_t",
41 "std::int64_t", "std::uint8_t", "std::uint16_t",
42 "std::uint32_t", "std::uint64_t"};
43
44 pageSource.Attach();
45 auto desc = pageSource.GetSharedDescriptorGuard();
46
47 std::vector<std::unique_ptr<ROOT::RFieldBase>> fields;
48 std::vector<ROOT::RFieldBase::RValue> fieldValues;
49 fieldValues.reserve(fJoinFieldNames.size());
50
51 for (const auto &fieldName : fJoinFieldNames) {
52 auto fieldId = desc->FindFieldId(fieldName);
54 throw RException(R__FAIL("could not find join field \"" + std::string(fieldName) + "\" in RNTuple \"" +
55 pageSource.GetNTupleName() + "\""));
56
57 const auto &fieldDesc = desc->GetFieldDescriptor(fieldId);
58
59 if (allowedTypes.find(fieldDesc.GetTypeName()) == allowedTypes.end()) {
60 throw RException(R__FAIL("cannot use field \"" + fieldName + "\" with type \"" + fieldDesc.GetTypeName() +
61 "\" in join table: only integral types are allowed"));
62 }
63
64 auto field = fieldDesc.CreateField(desc.GetRef());
66
67 fieldValues.emplace_back(field->CreateValue());
68 fJoinFieldValueSizes.emplace_back(field->GetValueSize());
69 fields.emplace_back(std::move(field));
70 }
71
72 std::vector<JoinValue_t> castJoinValues;
73 castJoinValues.reserve(fJoinFieldNames.size());
74
75 for (unsigned i = 0; i < pageSource.GetNEntries(); ++i) {
76 castJoinValues.clear();
77
78 for (auto &fieldValue : fieldValues) {
79 // TODO(fdegeus): use bulk reading
80 fieldValue.Read(i);
81
82 auto valuePtr = fieldValue.GetPtr<void>();
83 castJoinValues.push_back(CastValuePtr(valuePtr.get(), fieldValue.GetField().GetValueSize()));
84 }
85
87 }
88}
89
90const std::vector<ROOT::NTupleSize_t> *
91ROOT ::Experimental::Internal::RNTupleJoinTable::REntryMapping::GetEntryIndexes(std::vector<void *> valuePtrs) const
92{
93 if (valuePtrs.size() != fJoinFieldNames.size())
94 throw RException(R__FAIL("number of value pointers must match number of join fields"));
95
96 std::vector<JoinValue_t> castJoinValues;
97 castJoinValues.reserve(valuePtrs.size());
98
99 for (unsigned i = 0; i < valuePtrs.size(); ++i) {
100 castJoinValues.push_back(CastValuePtr(valuePtrs[i], fJoinFieldValueSizes[i]));
101 }
102
103 if (const auto &entries = fMapping.find(RCombinedJoinFieldValue(castJoinValues)); entries != fMapping.end()) {
104 return &entries->second;
105 }
106
107 return nullptr;
108}
109
110//------------------------------------------------------------------------------
111
112std::unique_ptr<ROOT::Experimental::Internal::RNTupleJoinTable>
114{
115 return std::unique_ptr<RNTupleJoinTable>(new RNTupleJoinTable(fieldNames));
116}
117
127
130{
131
132 for (const auto &partition : fPartitions) {
133 for (const auto &joinMapping : partition.second) {
134 auto entriesForMapping = joinMapping->GetEntryIndexes(valuePtrs);
135 if (entriesForMapping) {
136 return (*entriesForMapping)[0];
137 }
138 }
139 }
140
141 return kInvalidNTupleIndex;
142}
143
144std::vector<ROOT::NTupleSize_t>
147{
149 if (partition == fPartitions.end())
150 return {};
151
152 std::vector<ROOT::NTupleSize_t> entryIdxs{};
153
154 for (const auto &joinMapping : partition->second) {
155 auto entriesForMapping = joinMapping->GetEntryIndexes(valuePtrs);
158 }
159
160 return entryIdxs;
161}
162
163std::unordered_map<ROOT::Experimental::Internal::RNTupleJoinTable::PartitionKey_t, std::vector<ROOT::NTupleSize_t>>
165 const std::vector<void *> &valuePtrs, const std::vector<PartitionKey_t> &partitionKeys) const
166{
167 std::unordered_map<PartitionKey_t, std::vector<ROOT::NTupleSize_t>> entryIdxs{};
168
169 for (const auto &partitionKey : partitionKeys) {
171 if (!entriesForPartition.empty()) {
174 }
175 }
176
177 return entryIdxs;
178}
179
180std::unordered_map<ROOT::Experimental::Internal::RNTupleJoinTable::PartitionKey_t, std::vector<ROOT::NTupleSize_t>>
182{
183 std::unordered_map<PartitionKey_t, std::vector<ROOT::NTupleSize_t>> entryIdxs{};
184
185 for (const auto &partition : fPartitions) {
186 for (const auto &joinMapping : partition.second) {
187 auto entriesForMapping = joinMapping->GetEntryIndexes(valuePtrs);
188 if (entriesForMapping) {
191 }
192 }
193 }
194
195 return entryIdxs;
196}
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:300
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Provides a mapping from one or several join field values to an entry index.
REntryMapping(ROOT::Internal::RPageSource &pageSource, const std::vector< std::string > &joinFieldNames, ROOT::NTupleSize_t entryOffset=0)
Create a new entry mapping.
std::vector< std::size_t > fJoinFieldValueSizes
The size (in bytes) for each join field, corresponding to fJoinFieldNames.
std::vector< std::string > fJoinFieldNames
Names of the join fields used for the mapping to their respective entry indexes.
std::unordered_map< RCombinedJoinFieldValue, std::vector< ROOT::NTupleSize_t >, RCombinedJoinFieldValueHash > fMapping
The mapping itself.
Builds a join table on one or several fields of an RNTuple so it can be joined onto other RNTuples.
std::unordered_map< PartitionKey_t, std::vector< ROOT::NTupleSize_t > > GetPartitionedEntryIndexes(const std::vector< void * > &valuePtrs, const std::vector< PartitionKey_t > &partitionKeys) const
Get all entry indexes for the given join field value(s) for a specific set of partitions.
std::vector< ROOT::NTupleSize_t > GetEntryIndexes(const std::vector< void * > &valuePtrs, PartitionKey_t partitionKey=kDefaultPartitionKey) const
Get all entry indexes for the given join field value(s) within a partition.
static std::unique_ptr< RNTupleJoinTable > Create(const std::vector< std::string > &joinFieldNames)
Create an RNTupleJoinTable from an existing RNTuple.
std::vector< std::string > fJoinFieldNames
Names of the join fields used for the mapping to their respective entry indexes.
ROOT::NTupleSize_t GetEntryIndex(const std::vector< void * > &valuePtrs) const
Get an entry index (if it exists) for the given join field value(s), from any partition.
RNTupleJoinTable & Add(ROOT::Internal::RPageSource &pageSource, PartitionKey_t partitionKey=kDefaultPartitionKey, ROOT::NTupleSize_t entryOffset=0)
Add an entry mapping to the join table.
RNTupleJoinTable(const std::vector< std::string > &joinFieldNames)
Create an a new RNTupleJoinTable for the RNTuple represented by the provided page source.
std::unordered_map< PartitionKey_t, std::vector< std::unique_ptr< REntryMapping > > > fPartitions
Partitions of one or multiple entry mappings.
Abstract interface to read data from an ntuple.
Base class for all ROOT issued exceptions.
Definition RError.hxx:79
const_iterator begin() const
const_iterator end() const
void CallConnectPageSourceOnField(RFieldBase &, ROOT::Internal::RPageSource &)
constexpr NTupleSize_t kInvalidNTupleIndex
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr DescriptorId_t kInvalidDescriptorId