00001 #include "artdaq/Application/Routing/RoutingMasterPolicy.hh"
00002 #include "artdaq/Application/Routing/PolicyMacros.hh"
00003 #include "fhiclcpp/ParameterSet.h"
00004 #include "tracemf.h"
00005 #define TRACE_NAME "RoundRobin_policy"
00006
00007 namespace artdaq
00008 {
00013 class RoundRobinPolicy : public RoutingMasterPolicy
00014 {
00015 public:
00023 explicit RoundRobinPolicy(fhicl::ParameterSet ps)
00024 : RoutingMasterPolicy(ps)
00025 , minimum_participants_(ps.get<int>("minimum_participants", 0))
00026 {
00027 }
00028
00032 virtual ~RoundRobinPolicy() = default;
00033
00042 detail::RoutingPacket GetCurrentTable() override;
00043
00044 private:
00045 int minimum_participants_;
00046 };
00047
00048 detail::RoutingPacket RoundRobinPolicy::GetCurrentTable()
00049 {
00050 TLOG(12) << "RoundRobinPolicy::GetCurrentTable start";
00051 auto tokens = getTokensSnapshot();
00052 TLOG(13) << "RoundRobinPolicy::GetCurrentTable token list size is " << tokens->size();
00053 std::map<int, int> table;
00054 for (auto token : *tokens.get())
00055 {
00056 TLOG(14) << "RoundRobinPolicy::GetCurrentTable adding token for rank " << token << " to table";
00057 table[token]++;
00058 }
00059 tokens->clear();
00060 TLOG(13) << "RoundRobinPolicy::GetCurrentTable table size is " << table.size() << ", token list size is " << tokens->size();
00061
00062 detail::RoutingPacket output;
00063
00064
00065 auto minimum = minimum_participants_ > 0 ? minimum_participants_ : GetReceiverCount() + minimum_participants_;
00066 if (minimum < 1) minimum = 1;
00067
00068
00069 auto endCondition = table.size() < minimum;
00070 TLOG(15) << "RoundRobinPolicy::GetCurrentTable initial endCondition is " << endCondition;
00071
00072 while (!endCondition)
00073 {
00074 for (auto it = table.begin(); it != table.end();)
00075 {
00076 TLOG(16) << "RoundRobinPolicy::GetCurrentTable assigning sequenceID " << next_sequence_id_ << " to rank " << it->first;
00077 output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, it->first));
00078 table[it->first]--;
00079
00080 if (table[it->first] <= 0) it = table.erase(it);
00081 else ++it;
00082 }
00083 endCondition = table.size() < minimum;
00084 }
00085
00086 for(auto r : table)
00087 {
00088 for(auto i = 0;i < r.second; ++i)
00089 {
00090 tokens->push_back(r.first);
00091 }
00092 }
00093 TLOG(13) << "RoundRobinPolicy::GetCurrentTable unused tokens for " << tokens->size() << " ranks will be saved for later";
00094 addUnusedTokens(std::move(tokens));
00095
00096 TLOG(12) << "RoundRobinPolicy::GetCurrentTable return with table size " << output.size();
00097 return output;
00098 }
00099 }
00100
00101 DEFINE_ARTDAQ_ROUTING_POLICY(artdaq::RoundRobinPolicy)