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