artdaq_demo  v3_00_01
NthEvent_policy.cc
1 #include "artdaq/Application/Routing/RoutingMasterPolicy.hh"
2 #include "artdaq/Application/Routing/PolicyMacros.hh"
3 #include "fhiclcpp/ParameterSet.h"
4 #include "cetlib_except/exception.h"
5 
6 namespace artdaq
7 {
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  private:
21  size_t nth_;
22  int nth_rank_;
23  };
24 
35  NthEventPolicy::NthEventPolicy(fhicl::ParameterSet ps)
36  : RoutingMasterPolicy(ps)
37  , nth_(ps.get<size_t>("nth_event"))
38  , nth_rank_(ps.get<int>("target_receiver"))
39  {
40  if (nth_ == 0) throw cet::exception("NthEvent_policy") << "nth_event must be greater than 0!";
41  }
42 
49  detail::RoutingPacket NthEventPolicy::GetCurrentTable()
50  {
51  auto tokens = getTokensSnapshot();
52  std::map<int, int> table;
53  for (auto token : *tokens.get())
54  {
55  table[token]++;
56  }
57  if (table.count(nth_rank_) == 0) table[nth_rank_] = 0;
58  tokens->clear();
59 
60  detail::RoutingPacket output;
61  TLOG_ARB(5, "NthEvent_policy") << "table[nth_rank_]=" << std::to_string(table[nth_rank_])
62  << ", Next nth=" << std::to_string(((next_sequence_id_ / nth_) + 1) * nth_)
63  << ", max seq=" << std::to_string(next_sequence_id_ + table.size() - 1) << TLOG_ENDL;
64  auto endCondition = table.size() < GetReceiverCount() || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || ((next_sequence_id_ / nth_) + 1) * nth_ < next_sequence_id_ + table.size() - 1));
65  while (!endCondition)
66  {
67  for (auto r : table)
68  {
69  TLOG_ARB(5, "NthEvent_policy") << "nth_=" << std::to_string(nth_)
70  << ", nth_rank=" << std::to_string(nth_rank_)
71  << ", r=" << std::to_string(r.first)
72  << ", next_sequence_id=" << std::to_string(next_sequence_id_) << TLOG_ENDL;
73  if (next_sequence_id_ % nth_ == 0)
74  {
75  TLOG_ARB(5, "NthEvent_policy") << "Diverting event " << std::to_string(next_sequence_id_) << " to EVB " << nth_rank_ << TLOG_ENDL;
76  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, nth_rank_));
77  table[nth_rank_]--;
78  }
79  if (r.first != nth_rank_) {
80  TLOG_ARB(5, "NthEvent_policy") << "Sending event " << std::to_string(next_sequence_id_) << " to EVB " << r.first << TLOG_ENDL;
81  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, r.first));
82  if (!endCondition) endCondition = r.second == 1;
83  table[r.first]--;
84  }
85  }
86  TLOG_ARB(5, "NthEvent_policy") << "table[nth_rank_]=" << std::to_string(table[nth_rank_])
87  << ", Next nth=" << std::to_string(((next_sequence_id_ / nth_) + 1) * nth_)
88  << ", max seq=" << std::to_string(next_sequence_id_ + table.size() - 1) << TLOG_ENDL;
89  endCondition = endCondition || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || (next_sequence_id_ / nth_) * nth_ + nth_ < next_sequence_id_ + table.size() - 1));
90  }
91 
92  for (auto r : table)
93  {
94  for (auto i = 0; i < r.second; ++i)
95  {
96  tokens->push_back(r.first);
97  }
98  }
99  addUnusedTokens(std::move(tokens));
100 
101  return output;
102  }
103 }
104 
105 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.