artdaq  v3_04_01
RoundRobin_policy.cc
1 #include "artdaq/Application/Routing/RoutingMasterPolicy.hh"
2 #include "artdaq/Application/Routing/PolicyMacros.hh"
3 #include "fhiclcpp/ParameterSet.h"
4 #include "tracemf.h"
5 #define TRACE_NAME "RoundRobin_policy"
6 
7 namespace artdaq
8 {
14  {
15  public:
23  explicit RoundRobinPolicy(fhicl::ParameterSet ps)
25  , minimum_participants_(ps.get<int>("minimum_participants", 0))
26  {
27  }
28 
32  virtual ~RoundRobinPolicy() = default;
33 
43 
44  private:
45  int minimum_participants_;
46  };
47 
49  {
50  TLOG(12) << "RoundRobinPolicy::GetCurrentTable start";
51  auto tokens = getTokensSnapshot();
52  TLOG(13) << "RoundRobinPolicy::GetCurrentTable token list size is " << tokens->size();
53  std::map<int, int> table;
54  for (auto token : *tokens.get())
55  {
56  TLOG(14) << "RoundRobinPolicy::GetCurrentTable adding token for rank " << token << " to table";
57  table[token]++;
58  }
59  tokens->clear();
60  TLOG(13) << "RoundRobinPolicy::GetCurrentTable table size is " << table.size() << ", token list size is " << tokens->size();
61 
62  detail::RoutingPacket output;
63 
64  // If 0 or negative, add minimum_participants_ to GetRecevierCount to ensure that it's correct
65  auto minimum = minimum_participants_ > 0 ? minimum_participants_ : GetReceiverCount() + minimum_participants_;
66  if (minimum < 1) minimum = 1; // Can't go below 1
67 
68 
69  auto endCondition = table.size() < minimum;
70  TLOG(15) << "RoundRobinPolicy::GetCurrentTable initial endCondition is " << endCondition;
71 
72  while (!endCondition)
73  {
74  for (auto it = table.begin(); it != table.end();)
75  {
76  TLOG(16) << "RoundRobinPolicy::GetCurrentTable assigning sequenceID " << next_sequence_id_ << " to rank " << it->first;
77  output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, it->first));
78  table[it->first]--;
79 
80  if (table[it->first] <= 0) it = table.erase(it);
81  else ++it;
82  }
83  endCondition = table.size() < minimum;
84  }
85 
86  for(auto r : table)
87  {
88  for(auto i = 0;i < r.second; ++i)
89  {
90  tokens->push_back(r.first);
91  }
92  }
93  TLOG(13) << "RoundRobinPolicy::GetCurrentTable unused tokens for " << tokens->size() << " ranks will be saved for later";
94  addUnusedTokens(std::move(tokens));
95 
96  TLOG(12) << "RoundRobinPolicy::GetCurrentTable return with table size " << output.size();
97  return output;
98  }
99 }
100 
101 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.