Line data Source code
1 : #ifndef artdaq_DAQrate_detail_FragCounter_hh
2 : #define artdaq_DAQrate_detail_FragCounter_hh
3 :
4 : #include <atomic>
5 : #include <limits>
6 : #include <mutex>
7 : #include <unordered_map>
8 :
9 : namespace artdaq {
10 : namespace detail {
11 : class FragCounter;
12 : }
13 : } // namespace artdaq
14 :
15 : /**
16 : * \brief Keep track of the count of Fragments received from a set of sources
17 : */
18 : class artdaq::detail::FragCounter
19 : {
20 : public:
21 : /**
22 : * \brief Default Constructor
23 : */
24 : explicit FragCounter();
25 :
26 : /**
27 : * \brief Increment the given slot by one
28 : * \param slot Slot to increment
29 : */
30 : void incSlot(size_t slot);
31 :
32 : /**
33 : * \brief Increment the given slot by the given amount
34 : * \param slot Slot to increment
35 : * \param inc Amount to increment
36 : */
37 : void incSlot(size_t slot, size_t inc);
38 :
39 : /**
40 : * \brief Set the given slot to the given value
41 : * \param slot Slot to set
42 : * \param val Value to set
43 : */
44 : void setSlot(size_t slot, size_t val);
45 :
46 : /**
47 : * \brief Get the number of slots this FragCounter instance is tracking
48 : * \return The number of slots in this FragCounter instance
49 : */
50 : size_t nSlots() const;
51 :
52 : /**
53 : * \brief Get the total number of Fragments received
54 : * \return The total number of Fragments received
55 : */
56 : size_t count() const;
57 :
58 : /**
59 : * \brief Get the current count for the requested slot
60 : * \param slot Slot to get count for
61 : * \return The current count for the requested slot
62 : */
63 : size_t slotCount(size_t slot) const;
64 :
65 : /**
66 : * \brief Get the minimum slot count
67 : * \return The minimum slot count
68 : */
69 : size_t minCount() const;
70 :
71 : /**
72 : * \brief Get the current count for the requested slot
73 : * \param slot Slot to get count for
74 : * \return The current count for the requested slot
75 : */
76 : size_t operator[](size_t slot) const { return slotCount(slot); }
77 :
78 : private:
79 : mutable std::mutex receipts_mutex_;
80 : std::unordered_map<size_t, std::atomic<size_t>> receipts_;
81 : };
82 :
83 10 : inline artdaq::detail::FragCounter::
84 10 : FragCounter()
85 10 : : receipts_() {}
86 :
87 : inline void
88 5 : artdaq::detail::FragCounter::
89 : incSlot(size_t slot)
90 : {
91 5 : incSlot(slot, 1);
92 5 : }
93 :
94 : inline void
95 10 : artdaq::detail::FragCounter::
96 : incSlot(size_t slot, size_t inc)
97 : {
98 10 : std::unique_lock<std::mutex> lk(receipts_mutex_);
99 10 : receipts_[slot].fetch_add(inc);
100 10 : }
101 :
102 : inline void
103 4 : artdaq::detail::FragCounter::
104 : setSlot(size_t slot, size_t val)
105 : {
106 4 : std::unique_lock<std::mutex> lk(receipts_mutex_);
107 4 : receipts_[slot] = val;
108 4 : }
109 :
110 : inline size_t
111 1 : artdaq::detail::FragCounter::
112 : nSlots() const
113 : {
114 1 : std::unique_lock<std::mutex> lk(receipts_mutex_);
115 2 : return receipts_.size();
116 1 : }
117 :
118 : inline size_t
119 11 : artdaq::detail::FragCounter::
120 : count() const
121 : {
122 11 : std::unique_lock<std::mutex> lk(receipts_mutex_);
123 11 : size_t acc = 0;
124 24 : for (auto& it : receipts_)
125 : {
126 13 : acc += it.second;
127 : }
128 11 : return acc;
129 11 : }
130 :
131 : inline size_t
132 30 : artdaq::detail::FragCounter::
133 : slotCount(size_t slot) const
134 : {
135 30 : std::unique_lock<std::mutex> lk(receipts_mutex_);
136 88 : return receipts_.count(slot) ? receipts_.at(slot).load() : 0;
137 30 : }
138 :
139 : inline size_t
140 0 : artdaq::detail::FragCounter::
141 : minCount() const
142 : {
143 0 : std::unique_lock<std::mutex> lk(receipts_mutex_);
144 0 : size_t min = std::numeric_limits<size_t>::max();
145 0 : for (auto& it : receipts_)
146 : {
147 0 : if (it.second < min) min = it.second;
148 : }
149 0 : return min;
150 0 : }
151 :
152 : #endif /* artdaq_DAQrate_detail_FragCounter_hh */
|