00001 #ifndef artdaq_DAQrate_detail_FragCounter_hh
00002 #define artdaq_DAQrate_detail_FragCounter_hh
00003
00004 #include <unordered_map>
00005 #include <atomic>
00006 #include <limits>
00007 #include <mutex>
00008
00009 namespace artdaq
00010 {
00011 namespace detail
00012 {
00013 class FragCounter;
00014 }
00015 }
00016
00020 class artdaq::detail::FragCounter
00021 {
00022 public:
00026 explicit FragCounter();
00027
00032 void incSlot(size_t slot);
00033
00039 void incSlot(size_t slot, size_t inc);
00040
00046 void setSlot(size_t slot, size_t val);
00047
00052 size_t nSlots() const;
00053
00058 size_t count() const;
00059
00065 size_t slotCount(size_t slot) const;
00066
00071 size_t minCount() const;
00072
00078 size_t operator[](size_t slot) const { return slotCount(slot); }
00079
00080 private:
00081 mutable std::mutex receipts_mutex_;
00082 std::unordered_map<size_t, std::atomic<size_t>> receipts_;
00083 };
00084
00085 inline
00086 artdaq::detail::FragCounter::
00087 FragCounter()
00088 : receipts_() {}
00089
00090 inline
00091 void
00092 artdaq::detail::FragCounter::
00093 incSlot(size_t slot)
00094 {
00095 incSlot(slot, 1);
00096 }
00097
00098 inline
00099 void
00100 artdaq::detail::FragCounter::
00101 incSlot(size_t slot, size_t inc)
00102 {
00103 std::unique_lock<std::mutex> lk(receipts_mutex_);
00104 receipts_[slot].fetch_add(inc);
00105 }
00106
00107 inline
00108 void
00109 artdaq::detail::FragCounter::
00110 setSlot(size_t slot, size_t val)
00111 {
00112 std::unique_lock<std::mutex> lk(receipts_mutex_);
00113 receipts_[slot] = val;
00114 }
00115
00116 inline
00117 size_t
00118 artdaq::detail::FragCounter::
00119 nSlots() const
00120 {
00121 std::unique_lock<std::mutex> lk(receipts_mutex_);
00122 return receipts_.size();
00123 }
00124
00125 inline
00126 size_t
00127 artdaq::detail::FragCounter::
00128 count() const
00129 {
00130 std::unique_lock<std::mutex> lk(receipts_mutex_);
00131 size_t acc = 0;
00132 for (auto& it : receipts_)
00133 {
00134 acc += it.second;
00135 }
00136 return acc;
00137 }
00138
00139 inline
00140 size_t
00141 artdaq::detail::FragCounter::
00142 slotCount(size_t slot) const
00143 {
00144 std::unique_lock<std::mutex> lk(receipts_mutex_);
00145 return receipts_.count(slot) ? receipts_.at(slot).load() : 0;
00146 }
00147
00148 inline
00149 size_t
00150 artdaq::detail::FragCounter::
00151 minCount() const
00152 {
00153 std::unique_lock<std::mutex> lk(receipts_mutex_);
00154 size_t min = std::numeric_limits<size_t>::max();
00155 for (auto& it : receipts_)
00156 {
00157 if (it.second < min) min = it.second;
00158 }
00159 return min;
00160 }
00161
00162 #endif