artdaq_demo  v2_10_00
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
NthEvent_policy.cc
1 #include "artdaq/Application/Routing/RoutingMasterPolicy.hh"
2 #include "artdaq/Application/Routing/PolicyMacros.hh"
3 #include <fhiclcpp/ParameterSet.h>
4 
5 namespace artdaq
6 {
11  class NthEventPolicy : public RoutingMasterPolicy
12  {
13  public:
14  explicit NthEventPolicy(fhicl::ParameterSet ps);
15 
16  virtual ~NthEventPolicy() { }
17 
18  detail::RoutingPacket GetCurrentTable() override;
19  private:
20  size_t nth_;
21  int nth_rank_;
22  };
23 
34  NthEventPolicy::NthEventPolicy(fhicl::ParameterSet ps)
35  : RoutingMasterPolicy(ps)
36  , nth_(ps.get<size_t>("nth_event"))
37  , 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  TRACE(5, "NthEvent_policy: table[nth_rank_]=%i, Next nth=%zu, max seq=%zu\n", table[nth_rank_], ((next_sequence_id_ / nth_) + 1) * nth_, next_sequence_id_ + table.size() - 1 );
61  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));
62  while (!endCondition)
63  {
64  for (auto r : table)
65  {
66  TRACE(5,"NthEvent_policy: nth_=%zu, nth_rank=%i, r=%i, next_sequence_id=%zu\n", nth_, nth_rank_, r.first, next_sequence_id_);
67  if(next_sequence_id_ % nth_ == 0)
68  {
69  TRACE(5,"NthEvent_policy: Diverting event %zu to EVB %i\n", next_sequence_id_, nth_rank_);
70  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, nth_rank_));
71  table[nth_rank_]--;
72  }
73  if (r.first != nth_rank_) {
74  TRACE(5, "NthEvent_policy: Sending event %zu to EVB %i\n", next_sequence_id_, r.first);
75  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, r.first));
76  if (!endCondition) endCondition = r.second == 1;
77  table[r.first]--;
78  }
79  }
80  TRACE(5, "NthEvent_policy: table[nth_rank_]=%i, Next nth=%zu, max seq=%zu\n", table[nth_rank_], ((next_sequence_id_ / nth_) + 1) * nth_, next_sequence_id_ + table.size() - 1 );
81  endCondition = endCondition || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || (next_sequence_id_ / nth_) * nth_ + nth_ < next_sequence_id_ + table.size() - 1));
82  }
83 
84  for (auto r : table)
85  {
86  for (auto i = 0; i < r.second; ++i)
87  {
88  tokens->push_back(r.first);
89  }
90  }
91  addUnusedTokens(std::move(tokens));
92 
93  return output;
94  }
95 }
96 
97 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.