artdaq_demo  v3_08_00
NthEvent_policy.cc
1 #define TRACE_NAME "NthEventPolicy"
2 #include "artdaq/RoutingPolicies/PolicyMacros.hh"
3 #include "artdaq/RoutingPolicies/RoutingMasterPolicy.hh"
4 #include "cetlib_except/exception.h"
5 #include "fhiclcpp/ParameterSet.h"
6 
7 namespace artdaq {
12 class NthEventPolicy : public RoutingMasterPolicy
13 {
14 public:
15  explicit NthEventPolicy(fhicl::ParameterSet ps);
16 
17  virtual ~NthEventPolicy() {}
18 
19  detail::RoutingPacket GetCurrentTable() override;
20 
21 private:
22  size_t nth_;
23  int nth_rank_;
24 };
25 
36 NthEventPolicy::NthEventPolicy(fhicl::ParameterSet ps)
37  : RoutingMasterPolicy(ps), nth_(ps.get<size_t>("nth_event")), nth_rank_(ps.get<int>("target_receiver"))
38 {
39  if (nth_ == 0) throw cet::exception("NthEvent_policy") << "nth_event must be greater than 0!";
40 }
41 
48 detail::RoutingPacket NthEventPolicy::GetCurrentTable()
49 {
50  auto tokens = getTokensSnapshot();
51  std::map<int, int> table;
52  for (auto token : *tokens.get())
53  {
54  table[token]++;
55  }
56  if (table.count(nth_rank_) == 0) table[nth_rank_] = 0;
57  tokens->clear();
58 
59  detail::RoutingPacket output;
60  TLOG(5) << "table[nth_rank_]=" << (table[nth_rank_])
61  << ", Next nth=" << (((next_sequence_id_ / nth_) + 1) * nth_)
62  << ", max seq=" << (next_sequence_id_ + table.size() - 1);
63  auto endCondition =
64  table.size() < GetReceiverCount() ||
65  (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || ((next_sequence_id_ / nth_) + 1) * nth_ <
66  next_sequence_id_ + table.size() - 1));
67  while (!endCondition)
68  {
69  for (auto r : table)
70  {
71  TLOG(5) << "nth_=" << nth_ << ", nth_rank=" << nth_rank_ << ", r=" << r.first
72  << ", next_sequence_id=" << next_sequence_id_;
73  if (next_sequence_id_ % nth_ == 0)
74  {
75  TLOG(5) << "Diverting event " << next_sequence_id_ << " to EVB " << nth_rank_;
76  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, nth_rank_));
77  table[nth_rank_]--;
78  }
79  if (r.first != nth_rank_)
80  {
81  TLOG(5) << "Sending event " << next_sequence_id_ << " to EVB " << r.first;
82  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, r.first));
83  if (!endCondition) endCondition = r.second == 1;
84  table[r.first]--;
85  }
86  }
87  TLOG(5) << "table[nth_rank_]=" << table[nth_rank_]
88  << ", Next nth=" << (((next_sequence_id_ / nth_) + 1) * nth_)
89  << ", max seq=" << (next_sequence_id_ + table.size() - 1);
90  endCondition = endCondition || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 ||
91  (next_sequence_id_ / nth_) * nth_ + nth_ <
92  next_sequence_id_ + table.size() - 1));
93  }
94 
95  for (auto r : table)
96  {
97  for (auto i = 0; i < r.second; ++i)
98  {
99  tokens->push_back(r.first);
100  }
101  }
102  addUnusedTokens(std::move(tokens));
103 
104  return output;
105 }
106 } // namespace artdaq
107 
108 DEFINE_ARTDAQ_ROUTING_POLICY(artdaq::NthEventPolicy)
NthEventPolicy(fhicl::ParameterSet ps)
NthEventPolicy Constructor.
An example RoutingMasterPolicy which redirects every Nth event to a desginated destination. Other events are Round-Robin&#39;ed to the other configured destinations.
detail::RoutingPacket GetCurrentTable() override
Construct a Routing Table using the current tokens.