artdaq  v3_09_01
RoundRobin_policy.cc
1 #include "artdaq/DAQdata/Globals.hh"
2 #define TRACE_NAME (app_name + "_RoundRobin_policy").c_str()
3 
4 #include "artdaq/RoutingPolicies/PolicyMacros.hh"
5 #include "artdaq/RoutingPolicies/RoutingManagerPolicy.hh"
6 
7 #include "fhiclcpp/ParameterSet.h"
8 #include "tracemf.h"
9 
10 namespace artdaq {
16 {
17 public:
25  explicit RoundRobinPolicy(const fhicl::ParameterSet& ps)
27  , minimum_participants_(ps.get<int>("minimum_participants", 0))
28  {
29  }
30 
34  ~RoundRobinPolicy() override = default;
35 
45 
46 private:
47  RoundRobinPolicy(RoundRobinPolicy const&) = delete;
49  RoundRobinPolicy& operator=(RoundRobinPolicy const&) = delete;
50  RoundRobinPolicy& operator=(RoundRobinPolicy&&) = delete;
51 
52  int minimum_participants_;
53 };
54 
56 {
57  TLOG(12) << "RoundRobinPolicy::GetCurrentTable start";
58  auto tokens = getTokensSnapshot();
59  TLOG(13) << "RoundRobinPolicy::GetCurrentTable token list size is " << tokens->size();
60  std::map<int, int> table;
61  for (auto token : *tokens)
62  {
63  TLOG(14) << "RoundRobinPolicy::GetCurrentTable adding token for rank " << token << " to table";
64  table[token]++;
65  }
66  tokens->clear();
67  TLOG(13) << "RoundRobinPolicy::GetCurrentTable table size is " << table.size() << ", token list size is " << tokens->size();
68 
69  detail::RoutingPacket output;
70 
71  // If 0 or negative, add minimum_participants_ to GetRecevierCount to ensure that it's correct
72  // 02-Apr-2019, KAB: changed the declared type of "minimum" from 'auto' to 'int' to avoid the
73  // situation in which the compiler chooses a type of 'unsigned int', the minimum_participants_ is
74  // a negative number that is larger (in absolute value) to the receiver count, and "minimum"
75  // ends up with a large positive value.
76  int minimum = minimum_participants_ > 0 ? minimum_participants_ : GetReceiverCount() + minimum_participants_;
77  if (minimum < 1)
78  {
79  minimum = 1; // Can't go below 1
80  }
81  if (minimum > static_cast<int>(GetReceiverCount()))
82  {
83  minimum = GetReceiverCount(); // Can't go above receiver count
84  }
85 
86  bool endCondition = table.size() < static_cast<size_t>(minimum);
87  TLOG(15) << "RoundRobinPolicy::GetCurrentTable initial endCondition is " << endCondition << ", minimum is " << minimum;
88 
89  while (!endCondition)
90  {
91  for (auto it = table.begin(); it != table.end();)
92  {
93  TLOG(16) << "RoundRobinPolicy::GetCurrentTable assigning sequenceID " << next_sequence_id_ << " to rank " << it->first;
94  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, it->first));
95  table[it->first]--;
96 
97  if (table[it->first] <= 0)
98  {
99  it = table.erase(it);
100  }
101  else
102  {
103  ++it;
104  }
105  }
106  endCondition = table.size() < static_cast<size_t>(minimum);
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  TLOG(13) << "RoundRobinPolicy::GetCurrentTable unused tokens for " << tokens->size() << " ranks will be saved for later";
117  addUnusedTokens(std::move(tokens));
118 
119  TLOG(12) << "RoundRobinPolicy::GetCurrentTable return with table size " << output.size();
120  return output;
121 }
122 } // namespace artdaq
123 
124 DEFINE_ARTDAQ_ROUTING_POLICY(artdaq::RoundRobinPolicy)
~RoundRobinPolicy() override=default
Default virtual Destructor.
A row of the Routing Table.
A RoutingManagerPolicy which evenly distributes Sequence IDs to all receivers. If an uneven number of...
Fragment::sequence_id_t next_sequence_id_
The next sequence ID to be assigned.
std::unique_ptr< std::deque< int > > getTokensSnapshot()
Gets the current token list, used for building Routing Tables.
The interface through which RoutingManagerCore obtains Routing Tables using received Routing Tokens...
detail::RoutingPacket GetCurrentTable() override
Create a Routing Table using the tokens that have been received.
void addUnusedTokens(std::unique_ptr< std::deque< int >> tokens)
If necessary, return unused tokens to the token list, for subsequent updates.
std::vector< RoutingPacketEntry > RoutingPacket
A RoutingPacket is simply a vector of RoutingPacketEntry objects. It is not suitable for network tran...
size_t GetReceiverCount() const
Get the number of configured receivers.
RoundRobinPolicy(const fhicl::ParameterSet &ps)
RoundRobinPolicy Constructor.