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