artdaq_demo  v3_06_02
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()) { table[token]++; }
53  if (table.count(nth_rank_) == 0) table[nth_rank_] = 0;
54  tokens->clear();
55 
56  detail::RoutingPacket output;
57  TLOG(5) << "table[nth_rank_]=" << (table[nth_rank_])
58  << ", Next nth=" << (((next_sequence_id_ / nth_) + 1) * nth_)
59  << ", max seq=" << (next_sequence_id_ + table.size() - 1);
60  auto endCondition =
61  table.size() < GetReceiverCount() ||
62  (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || ((next_sequence_id_ / nth_) + 1) * nth_ <
63  next_sequence_id_ + table.size() - 1));
64  while (!endCondition)
65  {
66  for (auto r : table)
67  {
68  TLOG(5) << "nth_=" << nth_ << ", nth_rank=" << nth_rank_ << ", r=" << r.first
69  << ", next_sequence_id=" << next_sequence_id_;
70  if (next_sequence_id_ % nth_ == 0)
71  {
72  TLOG(5) << "Diverting event " << next_sequence_id_ << " to EVB " << nth_rank_;
73  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, nth_rank_));
74  table[nth_rank_]--;
75  }
76  if (r.first != nth_rank_)
77  {
78  TLOG(5) << "Sending event " << next_sequence_id_ << " to EVB " << r.first;
79  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, r.first));
80  if (!endCondition) endCondition = r.second == 1;
81  table[r.first]--;
82  }
83  }
84  TLOG(5) << "table[nth_rank_]=" << table[nth_rank_]
85  << ", Next nth=" << (((next_sequence_id_ / nth_) + 1) * nth_)
86  << ", max seq=" << (next_sequence_id_ + table.size() - 1);
87  endCondition = endCondition || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 ||
88  (next_sequence_id_ / nth_) * nth_ + nth_ <
89  next_sequence_id_ + table.size() - 1));
90  }
91 
92  for (auto r : table)
93  {
94  for (auto i = 0; i < r.second; ++i) { tokens->push_back(r.first); }
95  }
96  addUnusedTokens(std::move(tokens));
97 
98  return output;
99 }
100 } // namespace artdaq
101 
102 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.