artdaq_demo  v3_09_06
NthEvent_policy.cc
1 #define TRACE_NAME "NthEventPolicy"
2 #include "artdaq/RoutingPolicies/PolicyMacros.hh"
3 #include "artdaq/RoutingPolicies/RoutingManagerPolicy.hh"
4 #include "cetlib_except/exception.h"
5 #include "fhiclcpp/ParameterSet.h"
6 
7 namespace artdaq {
12 class NthEventPolicy : public RoutingManagerPolicy
13 {
14 public:
15  explicit NthEventPolicy(const fhicl::ParameterSet& ps);
16 
17  ~NthEventPolicy() override = default;
18 
19  detail::RoutingPacket GetCurrentTable() override;
20 
21 private:
22  NthEventPolicy(NthEventPolicy const&) = delete;
23  NthEventPolicy(NthEventPolicy&&) = delete;
24  NthEventPolicy& operator=(NthEventPolicy const&) = delete;
25  NthEventPolicy& operator=(NthEventPolicy&&) = delete;
26 
27  size_t nth_;
28  int nth_rank_;
29 };
30 
41 NthEventPolicy::NthEventPolicy(const fhicl::ParameterSet& ps)
42  : RoutingManagerPolicy(ps), nth_(ps.get<size_t>("nth_event")), nth_rank_(ps.get<int>("target_receiver"))
43 {
44  if (nth_ == 0)
45  {
46  throw cet::exception("NthEvent_policy") << "nth_event must be greater than 0!"; // NOLINT(cert-err60-cpp)
47  }
48 }
49 
56 detail::RoutingPacket NthEventPolicy::GetCurrentTable()
57 {
58  auto tokens = getTokensSnapshot();
59  std::map<int, int> table;
60  for (auto token : *tokens)
61  {
62  table[token]++;
63  }
64  if (table.count(nth_rank_) == 0)
65  {
66  table[nth_rank_] = 0;
67  }
68  tokens->clear();
69 
70  detail::RoutingPacket output;
71  TLOG(TLVL_DEBUG + 2) << "table[nth_rank_]=" << (table[nth_rank_])
72  << ", Next nth=" << (((next_sequence_id_ / nth_) + 1) * nth_)
73  << ", max seq=" << (next_sequence_id_ + table.size() - 1);
74  auto endCondition =
75  table.size() < GetReceiverCount() ||
76  (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || ((next_sequence_id_ / nth_) + 1) * nth_ <
77  next_sequence_id_ + table.size() - 1));
78  while (!endCondition)
79  {
80  for (auto r : table)
81  {
82  TLOG(TLVL_DEBUG + 2) << "nth_=" << nth_ << ", nth_rank=" << nth_rank_ << ", r=" << r.first
83  << ", next_sequence_id=" << next_sequence_id_;
84  if (next_sequence_id_ % nth_ == 0)
85  {
86  TLOG(TLVL_DEBUG + 2) << "Diverting event " << next_sequence_id_ << " to EVB " << nth_rank_;
87  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, nth_rank_));
88  table[nth_rank_]--;
89  }
90  if (r.first != nth_rank_)
91  {
92  TLOG(TLVL_DEBUG + 2) << "Sending event " << next_sequence_id_ << " to EVB " << r.first;
93  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, r.first));
94  if (!endCondition)
95  {
96  endCondition = r.second == 1;
97  }
98  table[r.first]--;
99  }
100  }
101  TLOG(TLVL_DEBUG + 2) << "table[nth_rank_]=" << table[nth_rank_]
102  << ", Next nth=" << (((next_sequence_id_ / nth_) + 1) * nth_)
103  << ", max seq=" << (next_sequence_id_ + table.size() - 1);
104  endCondition = endCondition || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 ||
105  (next_sequence_id_ / nth_) * nth_ + nth_ <
106  next_sequence_id_ + table.size() - 1));
107  }
108 
109  for (auto r : table)
110  {
111  for (auto i = 0; i < r.second; ++i)
112  {
113  tokens->push_back(r.first);
114  }
115  }
116  addUnusedTokens(std::move(tokens));
117 
118  return output;
119 }
120 } // namespace artdaq
121 
122 DEFINE_ARTDAQ_ROUTING_POLICY(artdaq::NthEventPolicy)
An example RoutingManagerPolicy 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.
NthEventPolicy(const fhicl::ParameterSet &ps)
NthEventPolicy Constructor.