30 namespace RDFDetail = ROOT::Detail::RDF;
31 namespace RDFGraphDrawing = ROOT::Internal::RDF::GraphDrawing;
34 namespace GraphDrawing {
35 std::shared_ptr<GraphNode> CreateDefineNode(
const std::string &colName,
const RDFDetail::RCustomColumnBase *columnPtr);
36 bool CheckIfDefaultOrDSColumn(
const std::string &name,
const std::shared_ptr<RDFDetail::RCustomColumnBase> &column);
40 template <
typename Dummy>
42 static_assert(
sizeof(Dummy) < 0,
"The unspecialized version of RActionCRTP should never be instantiated");
47 class RTypeErasedColumnValue {
48 std::shared_ptr<void> fPtr;
52 RTypeErasedColumnValue(std::unique_ptr<RColumnValue<T>> v) : fPtr(std::move(v))
59 return std::static_pointer_cast<RColumnValue<T>>(fPtr)->Get(e);
63 RColumnValue<T> *Cast()
65 return static_cast<RColumnValue<T> *
>(fPtr.get());
70 template <std::size_t... S,
typename... ColTypes>
71 void InitRDFValues(
unsigned int slot, std::vector<RTypeErasedColumnValue> &values, TTreeReader *r,
72 const ColumnNames_t &bn,
const RBookedCustomColumns &customCols, std::index_sequence<S...>,
73 ROOT::TypeTraits::TypeList<ColTypes...>,
const std::array<
bool,
sizeof...(S)> &isTmpColumn)
75 using expander =
int[];
78 (void)expander{(values.emplace_back(std::make_unique<RColumnValue<ColTypes>>()), 0)..., 0};
79 (void)expander{(isTmpColumn[S]
80 ? values[S].Cast<ColTypes>()->SetTmpColumn(slot, customCols.GetColumns().at(bn.at(S)).
get())
81 : values[S].Cast<ColTypes>()->MakeProxy(r, bn.at(S)),
87 template <std::size_t... S,
typename... ColTypes>
88 void ResetRDFValueTuple(std::vector<RTypeErasedColumnValue> &values, std::index_sequence<S...>,
89 ROOT::TypeTraits::TypeList<ColTypes...>)
91 using expander =
int[];
92 (void)expander{(values[S].Cast<ColTypes>()->Reset(), 0)...};
96 template <
typename Helper,
typename PrevDataFrame,
typename ColumnTypes_t>
101 template <
typename Helper,
typename PrevDataFrame,
typename ColumnTypes_t>
102 class RActionCRTP<RAction<Helper, PrevDataFrame, ColumnTypes_t>> :
public RActionBase {
103 using Action_t = RAction<Helper, PrevDataFrame, ColumnTypes_t>;
106 const std::shared_ptr<PrevDataFrame> fPrevDataPtr;
107 PrevDataFrame &fPrevData;
111 std::array<bool, ColumnTypes_t::list_size> fIsCustomColumn;
114 using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;
116 RActionCRTP(Helper &&h,
const ColumnNames_t &columns, std::shared_ptr<PrevDataFrame> pd,
117 RBookedCustomColumns &&customColumns)
118 : RActionBase(pd->GetLoopManagerUnchecked(), columns, std::move(customColumns)), fHelper(std::forward<Helper>(h)),
119 fPrevDataPtr(std::move(pd)), fPrevData(*fPrevDataPtr), fIsCustomColumn()
121 const auto nColumns = columns.size();
122 const auto &customCols = GetCustomColumns();
123 for (
auto i = 0u; i < nColumns; ++i)
124 fIsCustomColumn[i] = customCols.HasName(columns[i]);
127 RActionCRTP(
const RActionCRTP &) =
delete;
128 RActionCRTP &operator=(
const RActionCRTP &) =
delete;
131 ~RActionCRTP() { fLoopManager->Deregister(
this); }
133 Helper &GetHelper() {
return fHelper; }
135 void Initialize() final { fHelper.Initialize(); }
137 void InitSlot(TTreeReader *r,
unsigned int slot)
final
139 for (
auto &bookedBranch : GetCustomColumns().GetColumns())
140 bookedBranch.second->InitSlot(r, slot);
141 static_cast<Action_t *
>(
this)->InitColumnValues(r, slot);
142 fHelper.InitTask(r, slot);
145 void Run(
unsigned int slot, Long64_t entry)
final
148 if (fPrevData.CheckFilters(slot, entry))
149 static_cast<Action_t *>(
this)->Exec(slot, entry, TypeInd_t());
152 void TriggerChildrenCount() final { fPrevData.IncrChildrenCount(); }
154 void FinalizeSlot(
unsigned int slot)
final
156 ClearValueReaders(slot);
157 for (
auto &column : GetCustomColumns().GetColumns()) {
158 column.second->ClearValueReaders(slot);
160 fHelper.CallFinalizeTask(slot);
163 void ClearValueReaders(
unsigned int slot) {
static_cast<Action_t *
>(
this)->ResetColumnValues(slot, TypeInd_t()); }
165 void Finalize() final
171 std::shared_ptr<RDFGraphDrawing::GraphNode> GetGraph()
173 auto prevNode = fPrevData.GetGraph();
174 auto prevColumns = prevNode->GetDefinedColumns();
178 auto thisNode = std::make_shared<RDFGraphDrawing::GraphNode>(fHelper.GetActionName());
179 auto evaluatedNode = thisNode;
180 for (
auto &column : GetCustomColumns().GetColumns()) {
183 if (RDFGraphDrawing::CheckIfDefaultOrDSColumn(column.first, column.second))
185 if (std::find(prevColumns.begin(), prevColumns.end(), column.first) == prevColumns.end()) {
186 auto defineNode = RDFGraphDrawing::CreateDefineNode(column.first, column.second.get());
187 evaluatedNode->SetPrevNode(defineNode);
188 evaluatedNode = defineNode;
192 thisNode->AddDefinedColumns(GetCustomColumns().GetNames());
193 thisNode->SetAction(HasRun());
194 evaluatedNode->SetPrevNode(prevNode);
200 void *PartialUpdate(
unsigned int slot)
final {
return PartialUpdateImpl(slot); }
205 template <
typename H = Helper>
206 auto PartialUpdateImpl(
unsigned int slot) -> decltype(std::declval<H>().PartialUpdate(slot), (
void *)(
nullptr))
208 return &fHelper.PartialUpdate(slot);
212 void *PartialUpdateImpl(...) {
throw std::runtime_error(
"This action does not support callbacks!"); }
216 template <
typename Helper,
typename PrevDataFrame,
typename ColumnTypes_t =
typename Helper::ColumnTypes_t>
217 class RAction final :
public RActionCRTP<RAction<Helper, PrevDataFrame, ColumnTypes_t>> {
218 std::vector<RDFValueTuple_t<ColumnTypes_t>> fValues;
221 using ActionCRTP_t = RActionCRTP<RAction<Helper, PrevDataFrame, ColumnTypes_t>>;
223 RAction(Helper &&h,
const ColumnNames_t &bl, std::shared_ptr<PrevDataFrame> pd,
224 RBookedCustomColumns &&customColumns)
225 : ActionCRTP_t(std::forward<Helper>(h), bl, std::move(pd), std::move(customColumns)), fValues(GetNSlots()) { }
227 void InitColumnValues(TTreeReader *r,
unsigned int slot)
229 InitRDFValues(slot, fValues[slot], r, RActionBase::GetColumnNames(), RActionBase::GetCustomColumns(),
230 typename ActionCRTP_t::TypeInd_t{}, ActionCRTP_t::fIsCustomColumn);
233 template <std::size_t... S>
234 void Exec(
unsigned int slot, Long64_t entry, std::index_sequence<S...>)
237 ActionCRTP_t::GetHelper().Exec(slot, std::get<S>(fValues[slot]).Get(entry)...);
240 template <std::size_t... S>
241 void ResetColumnValues(
unsigned int slot, std::index_sequence<S...> s)
243 ResetRDFValueTuple(fValues[slot], s);
254 template <
typename... BranchTypes>
255 class SnapshotHelper;
257 template <
typename... BranchTypes>
258 class SnapshotHelperMT;
260 template <
typename PrevDataFrame,
typename... ColTypes>
261 class RAction<SnapshotHelper<ColTypes...>, PrevDataFrame, ROOT::TypeTraits::TypeList<ColTypes...>> final
262 :
public RActionCRTP<RAction<SnapshotHelper<ColTypes...>, PrevDataFrame, ROOT::TypeTraits::TypeList<ColTypes...>>> {
265 RActionCRTP<RAction<SnapshotHelper<ColTypes...>, PrevDataFrame, ROOT::TypeTraits::TypeList<ColTypes...>>>;
266 using ColumnTypes_t =
typename SnapshotHelper<ColTypes...>::ColumnTypes_t;
268 std::vector<std::vector<RTypeErasedColumnValue>> fValues;
271 RAction(SnapshotHelper<ColTypes...> &&h,
const ColumnNames_t &bl, std::shared_ptr<PrevDataFrame> pd,
272 RBookedCustomColumns &&customColumns)
273 : ActionCRTP_t(std::forward<SnapshotHelper<ColTypes...>>(h), bl, std::move(pd), std::move(customColumns)),
278 void InitColumnValues(TTreeReader *r,
unsigned int slot)
280 InitRDFValues(slot, fValues[slot], r, RActionBase::GetColumnNames(), RActionBase::GetCustomColumns(),
281 typename ActionCRTP_t::TypeInd_t{}, ColumnTypes_t{}, ActionCRTP_t::fIsCustomColumn);
284 template <std::size_t... S>
285 void Exec(
unsigned int slot, Long64_t entry, std::index_sequence<S...>)
288 ActionCRTP_t::GetHelper().Exec(slot, fValues[slot][S].
template Get<ColTypes>(entry)...);
291 template <std::size_t... S>
292 void ResetColumnValues(
unsigned int slot, std::index_sequence<S...> s)
294 ResetRDFValueTuple(fValues[slot], s, ColumnTypes_t{});
299 template <
typename PrevDataFrame,
typename... ColTypes>
300 class RAction<SnapshotHelperMT<ColTypes...>, PrevDataFrame, ROOT::TypeTraits::TypeList<ColTypes...>> final
301 :
public RActionCRTP<
302 RAction<SnapshotHelperMT<ColTypes...>, PrevDataFrame, ROOT::TypeTraits::TypeList<ColTypes...>>> {
305 RActionCRTP<RAction<SnapshotHelperMT<ColTypes...>, PrevDataFrame, ROOT::TypeTraits::TypeList<ColTypes...>>>;
306 using ColumnTypes_t =
typename SnapshotHelperMT<ColTypes...>::ColumnTypes_t;
308 std::vector<std::vector<RTypeErasedColumnValue>> fValues;
311 RAction(SnapshotHelperMT<ColTypes...> &&h,
const ColumnNames_t &bl, std::shared_ptr<PrevDataFrame> pd,
312 RBookedCustomColumns &&customColumns)
313 : ActionCRTP_t(std::forward<SnapshotHelperMT<ColTypes...>>(h), bl, std::move(pd), std::move(customColumns)),
318 void InitColumnValues(TTreeReader *r,
unsigned int slot)
320 InitRDFValues(slot, fValues[slot], r, RActionBase::GetColumnNames(), RActionBase::GetCustomColumns(),
321 typename ActionCRTP_t::TypeInd_t{}, ColumnTypes_t{}, ActionCRTP_t::fIsCustomColumn);
324 template <std::size_t... S>
325 void Exec(
unsigned int slot, Long64_t entry, std::index_sequence<S...>)
328 ActionCRTP_t::GetHelper().Exec(slot, fValues[slot][S].
template Get<ColTypes>(entry)...);
331 template <std::size_t... S>
332 void ResetColumnValues(
unsigned int slot, std::index_sequence<S...> s)
334 ResetRDFValueTuple(fValues[slot], s, ColumnTypes_t{});
342 #endif // ROOT_RACTION