11 #ifndef ROOT_RLAZYDSIMPL
12 #define ROOT_RLAZYDSIMPL
40 template <
typename... ColumnTypes>
41 class RLazyDS final :
public ROOT::RDF::RDataSource {
42 using PointerHolderPtrs_t = std::vector<ROOT::Internal::TDS::TPointerHolder *>;
44 std::tuple<RResultPtr<std::vector<ColumnTypes>>...> fColumns;
45 const std::vector<std::string> fColNames;
46 const std::map<std::string, std::string> fColTypesMap;
51 const PointerHolderPtrs_t fPointerHoldersModels;
52 std::vector<PointerHolderPtrs_t> fPointerHolders;
53 std::vector<std::pair<ULong64_t, ULong64_t>> fEntryRanges{};
54 unsigned int fNSlots{0};
56 Record_t GetColumnReadersImpl(std::string_view colName,
const std::type_info &
id)
58 auto colNameStr = std::string(colName);
60 const auto idName = ROOT::Internal::RDF::TypeID2TypeName(
id);
61 auto it = fColTypesMap.find(colNameStr);
62 if (fColTypesMap.end() == it) {
63 std::string err =
"The specified column name, \"" + colNameStr +
"\" is not known to the data source.";
64 throw std::runtime_error(err);
67 const auto colIdName = it->second;
68 if (colIdName != idName) {
69 std::string err =
"Column " + colNameStr +
" has type " + colIdName +
70 " while the id specified is associated to type " + idName;
71 throw std::runtime_error(err);
74 const auto colBegin = fColNames.begin();
75 const auto colEnd = fColNames.end();
76 const auto namesIt = std::find(colBegin, colEnd, colName);
77 const auto index = std::distance(colBegin, namesIt);
79 Record_t ret(fNSlots);
80 for (
auto slot : ROOT::TSeqU(fNSlots)) {
81 ret[slot] = fPointerHolders[index][slot]->GetPointerAddr();
86 size_t GetEntriesNumber() {
return std::get<0>(fColumns)->size(); }
87 template <std::size_t... S>
88 void SetEntryHelper(
unsigned int slot, ULong64_t entry, std::index_sequence<S...>)
90 std::initializer_list<int> expander{
91 (*
static_cast<ColumnTypes *
>(fPointerHolders[S][slot]->GetPointer()) = (*std::get<S>(fColumns))[entry], 0)...};
95 template <std::size_t... S>
96 void ColLenghtChecker(std::index_sequence<S...>)
101 const std::vector<size_t> colLengths{std::get<S>(fColumns)->size()...};
102 const auto expectedLen = colLengths[0];
104 for (
auto i : TSeqI(1, colLengths.size())) {
105 if (expectedLen != colLengths[i]) {
106 err +=
"Column \"" + fColNames[i] +
"\" and column \"" + fColNames[0] +
107 "\" have different lengths: " + std::to_string(expectedLen) +
" and " +
108 std::to_string(colLengths[i]);
112 throw std::runtime_error(err);
117 std::string AsString() {
return "lazy data source"; };
120 RLazyDS(std::pair<std::string, RResultPtr<std::vector<ColumnTypes>>>... colsNameVals)
121 : fColumns(std::tuple<RResultPtr<std::vector<ColumnTypes>>...>(colsNameVals.second...)),
122 fColNames({colsNameVals.first...}),
123 fColTypesMap({{colsNameVals.first, ROOT::Internal::RDF::TypeID2TypeName(
typeid(ColumnTypes))}...}),
124 fPointerHoldersModels({
new ROOT::Internal::TDS::TTypedPointerHolder<ColumnTypes>(
new ColumnTypes())...})
130 for (
auto &&ptrHolderv : fPointerHolders) {
131 for (
auto &&ptrHolder : ptrHolderv) {
137 const std::vector<std::string> &GetColumnNames()
const {
return fColNames; }
139 std::vector<std::pair<ULong64_t, ULong64_t>> GetEntryRanges()
141 auto entryRanges(std::move(fEntryRanges));
145 std::string GetTypeName(std::string_view colName)
const
147 const auto key = std::string(colName);
148 return fColTypesMap.at(key);
151 bool HasColumn(std::string_view colName)
const
153 const auto key = std::string(colName);
154 const auto endIt = fColTypesMap.end();
155 return endIt != fColTypesMap.find(key);
158 bool SetEntry(
unsigned int slot, ULong64_t entry)
160 SetEntryHelper(slot, entry, std::index_sequence_for<ColumnTypes...>());
164 void SetNSlots(
unsigned int nSlots)
167 const auto nCols = fColNames.size();
168 fPointerHolders.resize(nCols);
170 for (
auto &&ptrHolderv : fPointerHolders) {
171 for (
auto slot : ROOT::TSeqI(fNSlots)) {
172 auto ptrHolder = fPointerHoldersModels[colIndex]->GetDeepCopy();
173 ptrHolderv.emplace_back(ptrHolder);
178 for (
auto &&ptrHolder : fPointerHoldersModels)
184 ColLenghtChecker(std::index_sequence_for<ColumnTypes...>());
185 const auto nEntries = GetEntriesNumber();
186 const auto nEntriesInRange = nEntries / fNSlots;
187 auto reminder = 1U == fNSlots ? 0 : nEntries % fNSlots;
188 fEntryRanges.resize(fNSlots);
191 for (
auto &&range : fEntryRanges) {
192 end = init + nEntriesInRange;
203 std::string GetLabel() {
return "LazyDS"; }