Logo ROOT  
Reference Guide
RRange.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN 09/2018
2
3/*************************************************************************
4 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#ifndef ROOT_RDFRANGE
12#define ROOT_RDFRANGE
13
16#include "RtypesCore.h"
17
18#include <memory>
19
20namespace ROOT {
21
22// fwd decl
23namespace Internal {
24namespace RDF {
25namespace GraphDrawing {
26std::shared_ptr<GraphNode> CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr);
27} // ns GraphDrawing
28} // ns RDF
29} // ns Internal
30
31namespace Detail {
32namespace RDF {
34
35template <typename PrevData>
36class RRange final : public RRangeBase {
37 const std::shared_ptr<PrevData> fPrevDataPtr;
38 PrevData &fPrevData;
39
40public:
41 RRange(unsigned int start, unsigned int stop, unsigned int stride, std::shared_ptr<PrevData> pd)
42 : RRangeBase(pd->GetLoopManagerUnchecked(), start, stop, stride, pd->GetLoopManagerUnchecked()->GetNSlots()),
43 fPrevDataPtr(std::move(pd)), fPrevData(*fPrevDataPtr) {}
44
45 RRange(const RRange &) = delete;
46 RRange &operator=(const RRange &) = delete;
47 // must call Deregister here, before fPrevDataFrame is destroyed,
48 // otherwise if fPrevDataFrame is fLoopManager we get a use after delete
50
51 /// Ranges act as filters when it comes to selecting entries that downstream nodes should process
52 bool CheckFilters(unsigned int slot, Long64_t entry) final
53 {
54 if (entry != fLastCheckedEntry) {
55 if (fHasStopped)
56 return false;
57 if (!fPrevData.CheckFilters(slot, entry)) {
58 // a filter upstream returned false, cache the result
59 fLastResult = false;
60 } else {
61 // apply range filter logic, cache the result
64 (fStride != 1 && fNProcessedEntries % fStride != 0))
65 fLastResult = false;
66 else
67 fLastResult = true;
69 fHasStopped = true;
70 fPrevData.StopProcessing();
71 }
72 }
73 fLastCheckedEntry = entry;
74 }
75 return fLastResult;
76 }
77
78 // recursive chain of `Report`s
79 // RRange simply forwards these calls to the previous node
80 void Report(ROOT::RDF::RCutFlowReport &rep) const final { fPrevData.PartialReport(rep); }
81
82 void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final { fPrevData.PartialReport(rep); }
83
84 void StopProcessing() final
85 {
88 fPrevData.StopProcessing();
89 }
90
91 void IncrChildrenCount() final
92 {
93 ++fNChildren;
94 // propagate "children activation" upstream
95 if (fNChildren == 1)
96 fPrevData.IncrChildrenCount();
97 }
98
99 /// This function must be defined by all nodes, but only the filters will add their name
100 void AddFilterName(std::vector<std::string> &filters) { fPrevData.AddFilterName(filters); }
101 std::shared_ptr<RDFGraphDrawing::GraphNode> GetGraph()
102 {
103 // TODO: Ranges node have no information about custom columns, hence it is not possible now
104 // if defines have been used before.
105 auto prevNode = fPrevData.GetGraph();
106 auto prevColumns = prevNode->GetDefinedColumns();
107
108 auto thisNode = RDFGraphDrawing::CreateRangeNode(this);
109
110 /* If the returned node is not new, there is no need to perform any other operation.
111 * This is a likely scenario when building the entire graph in which branches share
112 * some nodes. */
113 if (!thisNode->GetIsNew()) {
114 return thisNode;
115 }
116 thisNode->SetPrevNode(prevNode);
117
118 // If there have been some defines between the last Filter and this Range node we won't detect them:
119 // Ranges don't keep track of Defines (they have no RBookedDefines data member).
120 // Let's pretend that the Defines of this node are the same as the node above, so that in the graph
121 // the Defines will just appear below the Range instead (no functional change).
122 thisNode->AddDefinedColumns(prevColumns);
123
124 return thisNode;
125 }
126};
127
128} // namespace RDF
129} // namespace Detail
130} // namespace ROOT
131
132#endif // ROOT_RDFRANGE
long long Long64_t
Definition: RtypesCore.h:80
const char * filters[]
void Deregister(RDFInternal::RActionBase *actionPtr)
virtual RLoopManager * GetLoopManagerUnchecked()
Definition: RNodeBase.hxx:65
unsigned int fNStopsReceived
Number of times that a children node signaled to stop processing entries.
Definition: RNodeBase.hxx:45
unsigned int fNChildren
Number of nodes of the functional graph hanging from this object.
Definition: RNodeBase.hxx:44
RLoopManager * fLoopManager
Definition: RNodeBase.hxx:43
bool fHasStopped
True if the end of the range has been reached.
Definition: RRangeBase.hxx:40
RRange & operator=(const RRange &)=delete
RRange(unsigned int start, unsigned int stop, unsigned int stride, std::shared_ptr< PrevData > pd)
Definition: RRange.hxx:41
std::shared_ptr< RDFGraphDrawing::GraphNode > GetGraph()
Definition: RRange.hxx:101
const std::shared_ptr< PrevData > fPrevDataPtr
Definition: RRange.hxx:37
void Report(ROOT::RDF::RCutFlowReport &rep) const final
Definition: RRange.hxx:80
RRange(const RRange &)=delete
void StopProcessing() final
Definition: RRange.hxx:84
void AddFilterName(std::vector< std::string > &filters)
This function must be defined by all nodes, but only the filters will add their name.
Definition: RRange.hxx:100
bool CheckFilters(unsigned int slot, Long64_t entry) final
Ranges act as filters when it comes to selecting entries that downstream nodes should process.
Definition: RRange.hxx:52
void IncrChildrenCount() final
Definition: RRange.hxx:91
void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
Definition: RRange.hxx:82
std::shared_ptr< GraphNode > CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr)
unsigned int GetNSlots()
Definition: RDFUtils.cxx:288
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...