-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This makes the interface more low-level, but that's exactly what we want, e.g. for eventual integration with the `RNTupleProcessor`. This commit also introduces the policy that only trivial types (PODs and `std::strings`) can be used as indices.
- Loading branch information
Showing
8 changed files
with
178 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,18 @@ | ||
/// \file ROOT/RNTupleView.hxx | ||
/// \file ROOT/RNTupleIndex.hxx | ||
/// \ingroup NTuple ROOT7 | ||
/// \author Florine de Geus <[email protected]> | ||
/// \date 2024-02-08 | ||
/// \date 2024-04-02 | ||
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback | ||
/// is welcome! | ||
|
||
/************************************************************************* | ||
* Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. * | ||
* All rights reserved. * | ||
* * | ||
* For the licensing terms see $ROOTSYS/LICENSE. * | ||
* For the list of contributors see $ROOTSYS/README/CREDITS. * | ||
*************************************************************************/ | ||
|
||
#ifndef ROOT7_RNTupleIndex | ||
#define ROOT7_RNTupleIndex | ||
|
||
|
@@ -20,66 +28,36 @@ | |
namespace ROOT { | ||
namespace Experimental { | ||
namespace Internal { | ||
|
||
// clang-format off | ||
/** | ||
\class ROOT::Experimental::RNTupleIndex | ||
\class ROOT::Experimental::Internal::RNTupleIndex | ||
\ingroup NTuple | ||
\brief Build an index for an RNTuple so it can be joined onto other RNTuples. | ||
*/ | ||
// clang-format on | ||
template <class IndexValueT> | ||
class RNTupleIndex { | ||
friend class RNTupleReader; | ||
|
||
private: | ||
/// The maximum number of index elements we allow to be kept in memory. Used as a failsafe. | ||
std::size_t fMaxElemsInMemory = 64 * 1024 * 1024; | ||
std::size_t fNElems = 0; | ||
std::string fFieldName; // TODO store more field info (for merging checks) | ||
std::unordered_map<IndexValueT, std::set<NTupleSize_t>> fIndex; | ||
std::unique_ptr<RFieldBase> fField; | ||
std::unordered_map<NTupleIndexValue_t, std::set<NTupleSize_t>> fIndex; | ||
|
||
void Merge(const RNTupleIndex<IndexValueT> &other) | ||
{ | ||
if (fFieldName != other.fFieldName) | ||
throw RException(R__FAIL("can only merge indices for the same field")); | ||
|
||
fNElems += other.fNElems; | ||
|
||
for (const auto &val : other.fIndex) { | ||
auto res = fIndex.insert(val); | ||
if (!res.second) { | ||
// The index value is already present so the insertion failed. Instead, we have to merge the values. | ||
fIndex.at(val.first).insert(val.second.begin(), val.second.end()); | ||
} | ||
} | ||
} | ||
void Merge(const RNTupleIndex &other); | ||
|
||
public: | ||
RNTupleIndex(std::string_view fieldName) : fFieldName(std::string(fieldName)) {} | ||
RNTupleIndex() : fFieldName("") {} | ||
RNTupleIndex<IndexValueT> &operator=(const RNTupleIndex<IndexValueT> &other) | ||
{ | ||
fFieldName = other.fFieldName; | ||
fNElems = other.fNElems; | ||
fIndex = other.fIndex; | ||
return *this; | ||
} | ||
RNTupleIndex(std::unique_ptr<RFieldBase> field) : fField(std::move(field)) {} | ||
RNTupleIndex() : fField(nullptr) {} | ||
RNTupleIndex(const RNTupleIndex &other) { *this = other; } | ||
RNTupleIndex &operator=(const RNTupleIndex &other); | ||
|
||
void SetMaxElementsInMemory(std::size_t maxElems) { fMaxElemsInMemory = maxElems; } | ||
|
||
std::size_t GetNElems() const { return fNElems; } | ||
|
||
void Add(const IndexValueT &value, NTupleSize_t entry) | ||
{ | ||
if (fNElems > fMaxElemsInMemory) { | ||
throw RException( | ||
R__FAIL("in-memory index exceeds maximum allowed size (" + std::to_string(fMaxElemsInMemory) + ")")); | ||
} | ||
|
||
fIndex[value].insert(entry); | ||
fNElems++; | ||
} | ||
void Add(void *objPtr, NTupleSize_t entry); | ||
|
||
///////////////////////////////////////////////////////////////////////////// | ||
/// \brief Get the entry number containing the given index value **after** the provided minimum entry. | ||
|
@@ -88,18 +66,16 @@ public: | |
/// \param[in] lowerBound The minimum entry number (inclusive) to retrieve. By default, all entries are considered. | ||
/// \return The entry number, starting from `lowerBound`, containing the specified index value. When no such entry | ||
/// exists, return `kInvalidNTupleIndex` | ||
NTupleSize_t GetEntry(const IndexValueT &value, NTupleSize_t lowerBound = 0) const | ||
{ | ||
if (!fIndex.count(value)) { | ||
return kInvalidNTupleIndex; | ||
} | ||
|
||
auto indexEntries = fIndex.at(value); | ||
|
||
if (auto entry = indexEntries.lower_bound(lowerBound); entry != indexEntries.end()) | ||
return *entry; | ||
NTupleSize_t GetEntry(void *valuePtr, NTupleSize_t lowerBound = 0) const; | ||
|
||
return kInvalidNTupleIndex; | ||
///////////////////////////////////////////////////////////////////////////// | ||
/// \brief Get the entry number containing the given index value **after** the provided minimum entry. | ||
/// | ||
/// \sa GetEntry(void *valuePtr, NTupleSize_t lowerBound = 0) | ||
template <typename T> | ||
NTupleSize_t GetEntry(std::shared_ptr<T> valuePtr, NTupleSize_t lowerBound = 0) const | ||
{ | ||
return GetEntry(valuePtr.get(), lowerBound); | ||
} | ||
|
||
///////////////////////////////////////////////////////////////////////////// | ||
|
@@ -110,14 +86,7 @@ public: | |
/// | ||
/// \return A new RNTupleIndex resulting from the concatenation | ||
/// | ||
static RNTupleIndex<IndexValueT> | ||
Concatenate(const RNTupleIndex<IndexValueT> &left, const RNTupleIndex<IndexValueT> &right) | ||
{ | ||
RNTupleIndex<IndexValueT> index(left.fFieldName); | ||
index.Merge(left); | ||
index.Merge(right); | ||
return index; | ||
} | ||
static RNTupleIndex Concatenate(const RNTupleIndex &left, const RNTupleIndex &right); | ||
}; | ||
|
||
} // namespace Internal | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.