artdaq_demo  v3_06_01
NthEvent_policy.cc
1 #define TRACE_NAME "NthEventPolicy"
2 #include "artdaq/RoutingPolicies/PolicyMacros.hh"
3 #include "artdaq/RoutingPolicies/RoutingMasterPolicy.hh"
4 #include "cetlib_except/exception.h"
5 #include "fhiclcpp/ParameterSet.h"
6 
7 namespace artdaq {
12 class NthEventPolicy : public RoutingMasterPolicy
13 {
14 public:
15  explicit NthEventPolicy( fhicl::ParameterSet ps );
16 
17  virtual ~NthEventPolicy() {}
18 
19  detail::RoutingPacket GetCurrentTable() override;
20 
21 private:
22  size_t nth_;
23  int nth_rank_;
24 };
25 
36 NthEventPolicy::NthEventPolicy( fhicl::ParameterSet ps )
37  : RoutingMasterPolicy( ps ), nth_( ps.get<size_t>( "nth_event" ) ), nth_rank_( ps.get<int>( "target_receiver" ) )
38 {
39  if ( nth_ == 0 ) throw cet::exception( "NthEvent_policy" ) << "nth_event must be greater than 0!";
40 }
41 
48 detail::RoutingPacket NthEventPolicy::GetCurrentTable()
49 {
50  auto tokens = getTokensSnapshot();
51  std::map<int, int> table;
52  for ( auto token : *tokens.get() ) { table[ token ]++; }
53  if ( table.count( nth_rank_ ) == 0 ) table[ nth_rank_ ] = 0;
54  tokens->clear();
55 
56  detail::RoutingPacket output;
57  TLOG( 5 ) << "table[nth_rank_]=" << ( table[ nth_rank_ ] )
58  << ", Next nth=" << ( ( ( next_sequence_id_ / nth_ ) + 1 ) * nth_ )
59  << ", max seq=" << ( next_sequence_id_ + table.size() - 1 );
60  auto endCondition =
61  table.size() < GetReceiverCount() ||
62  ( table[ nth_rank_ ] <= 0 && ( next_sequence_id_ % nth_ == 0 || ( ( next_sequence_id_ / nth_ ) + 1 ) * nth_ <
63  next_sequence_id_ + table.size() - 1 ) );
64  while ( !endCondition )
65  {
66  for ( auto r : table )
67  {
68  TLOG( 5 ) << "nth_=" << nth_ << ", nth_rank=" << nth_rank_ << ", r=" << r.first
69  << ", next_sequence_id=" << next_sequence_id_;
70  if ( next_sequence_id_ % nth_ == 0 )
71  {
72  TLOG( 5 ) << "Diverting event " << next_sequence_id_ << " to EVB " << nth_rank_;
73  output.emplace_back( detail::RoutingPacketEntry( next_sequence_id_++, nth_rank_ ) );
74  table[ nth_rank_ ]--;
75  }
76  if ( r.first != nth_rank_ )
77  {
78  TLOG( 5 ) << "Sending event " << next_sequence_id_ << " to EVB " << r.first;
79  output.emplace_back( detail::RoutingPacketEntry( next_sequence_id_++, r.first ) );
80  if ( !endCondition ) endCondition = r.second == 1;
81  table[ r.first ]--;
82  }
83  }
84  TLOG( 5 ) << "table[nth_rank_]=" << table[ nth_rank_ ]
85  << ", Next nth=" << ( ( ( next_sequence_id_ / nth_ ) + 1 ) * nth_ )
86  << ", max seq=" << ( next_sequence_id_ + table.size() - 1 );
87  endCondition = endCondition || ( table[ nth_rank_ ] <= 0 && ( next_sequence_id_ % nth_ == 0 ||
88  ( next_sequence_id_ / nth_ ) * nth_ + nth_ <
89  next_sequence_id_ + table.size() - 1 ) );
90  }
91 
92  for ( auto r : table )
93  {
94  for ( auto i = 0; i < r.second; ++i ) { tokens->push_back( r.first ); }
95  }
96  addUnusedTokens( std::move( tokens ) );
97 
98  return output;
99 }
100 } // namespace artdaq
101 
102 DEFINE_ARTDAQ_ROUTING_POLICY( artdaq::NthEventPolicy )
NthEventPolicy(fhicl::ParameterSet ps)
NthEventPolicy Constructor.
An example RoutingMasterPolicy which redirects every Nth event to a desginated destination. Other events are Round-Robin&#39;ed to the other configured destinations.
detail::RoutingPacket GetCurrentTable() override
Construct a Routing Table using the current tokens.