00001 #include "artdaq/Application/Routing/RoutingMasterPolicy.hh" 00002 #include "artdaq/Application/Routing/PolicyMacros.hh" 00003 #include "fhiclcpp/ParameterSet.h" 00004 #include "cetlib_except/exception.h" 00005 00006 namespace artdaq 00007 { 00012 class NthEventPolicy : public RoutingMasterPolicy 00013 { 00014 public: 00015 explicit NthEventPolicy(fhicl::ParameterSet ps); 00016 00017 virtual ~NthEventPolicy() { } 00018 00019 detail::RoutingPacket GetCurrentTable() override; 00020 private: 00021 size_t nth_; 00022 int nth_rank_; 00023 }; 00024 00035 NthEventPolicy::NthEventPolicy(fhicl::ParameterSet ps) 00036 : RoutingMasterPolicy(ps) 00037 , nth_(ps.get<size_t>("nth_event")) 00038 , nth_rank_(ps.get<int>("target_receiver")) 00039 { 00040 if (nth_ == 0) throw cet::exception("NthEvent_policy") << "nth_event must be greater than 0!"; 00041 } 00042 00049 detail::RoutingPacket NthEventPolicy::GetCurrentTable() 00050 { 00051 auto tokens = getTokensSnapshot(); 00052 std::map<int, int> table; 00053 for (auto token : *tokens.get()) 00054 { 00055 table[token]++; 00056 } 00057 if (table.count(nth_rank_) == 0) table[nth_rank_] = 0; 00058 tokens->clear(); 00059 00060 detail::RoutingPacket output; 00061 TLOG_ARB(5, "NthEvent_policy") << "table[nth_rank_]=" << std::to_string(table[nth_rank_]) 00062 << ", Next nth=" << std::to_string(((next_sequence_id_ / nth_) + 1) * nth_) 00063 << ", max seq=" << std::to_string(next_sequence_id_ + table.size() - 1) << TLOG_ENDL; 00064 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)); 00065 while (!endCondition) 00066 { 00067 for (auto r : table) 00068 { 00069 TLOG_ARB(5, "NthEvent_policy") << "nth_=" << std::to_string(nth_) 00070 << ", nth_rank=" << std::to_string(nth_rank_) 00071 << ", r=" << std::to_string(r.first) 00072 << ", next_sequence_id=" << std::to_string(next_sequence_id_) << TLOG_ENDL; 00073 if (next_sequence_id_ % nth_ == 0) 00074 { 00075 TLOG_ARB(5, "NthEvent_policy") << "Diverting event " << std::to_string(next_sequence_id_) << " to EVB " << nth_rank_ << TLOG_ENDL; 00076 output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, nth_rank_)); 00077 table[nth_rank_]--; 00078 } 00079 if (r.first != nth_rank_) { 00080 TLOG_ARB(5, "NthEvent_policy") << "Sending event " << std::to_string(next_sequence_id_) << " to EVB " << r.first << TLOG_ENDL; 00081 output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, r.first)); 00082 if (!endCondition) endCondition = r.second == 1; 00083 table[r.first]--; 00084 } 00085 } 00086 TLOG_ARB(5, "NthEvent_policy") << "table[nth_rank_]=" << std::to_string(table[nth_rank_]) 00087 << ", Next nth=" << std::to_string(((next_sequence_id_ / nth_) + 1) * nth_) 00088 << ", max seq=" << std::to_string(next_sequence_id_ + table.size() - 1) << TLOG_ENDL; 00089 endCondition = endCondition || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || (next_sequence_id_ / nth_) * nth_ + nth_ < next_sequence_id_ + table.size() - 1)); 00090 } 00091 00092 for (auto r : table) 00093 { 00094 for (auto i = 0; i < r.second; ++i) 00095 { 00096 tokens->push_back(r.first); 00097 } 00098 } 00099 addUnusedTokens(std::move(tokens)); 00100 00101 return output; 00102 } 00103 } 00104 00105 DEFINE_ARTDAQ_ROUTING_POLICY(artdaq::NthEventPolicy)