@@ -121,21 +121,91 @@ template<typename STAT>
121121using TStoredStringPtrStatUMapQueueSerializer =
122122 typename TStoredStringPtrStatUMapQueue<STAT>::template CSerializer<CStoredStringPtrStatUMapSerializer<STAT>>;
123123
124+ class CMidTime {
125+ public:
126+ explicit CMidTime (core_t ::TTime bucketLength) : m_Time{bucketLength / 2 } {}
127+
128+ core_t ::TTime value () const { return m_Time; }
129+
130+ void add (core_t ::TTime, unsigned int ) {}
131+
132+ std::string toDelimited () const {
133+ return core::CStringUtils::typeToString (m_Time);
134+ }
135+ bool fromDelimited (const std::string& value) {
136+ return core::CStringUtils::stringToType (value, m_Time);
137+ }
138+ std::uint64_t checksum () const {
139+ return static_cast <std::uint64_t >(m_Time);
140+ }
141+
142+ private:
143+ core_t ::TTime m_Time{0 };
144+ };
145+
146+ class CLastTime {
147+ public:
148+ explicit CLastTime (core_t ::TTime) {}
149+
150+ core_t ::TTime value () const { return m_Time; }
151+
152+ void add (core_t ::TTime time, unsigned int ) { m_Time = time; }
153+
154+ std::string toDelimited () const {
155+ return core::CStringUtils::typeToString (m_Time);
156+ }
157+ bool fromDelimited (const std::string& value) {
158+ return core::CStringUtils::stringToType (value, m_Time);
159+ }
160+ std::uint64_t checksum () const {
161+ return static_cast <std::uint64_t >(m_Time);
162+ }
163+
164+ private:
165+ core_t ::TTime m_Time{0 };
166+ };
167+
168+ class CMeanTime {
169+ public:
170+ explicit CMeanTime (core_t ::TTime) {}
171+
172+ core_t ::TTime value () const {
173+ return static_cast <core_t ::TTime>(
174+ std::round (maths::common::CBasicStatistics::mean (m_Time)));
175+ }
176+
177+ void add (core_t ::TTime time, unsigned int count) {
178+ m_Time.add (static_cast <double >(time), count);
179+ }
180+
181+ std::string toDelimited () const {
182+ return m_Time.toDelimited ();
183+ }
184+ bool fromDelimited (const std::string& value) {
185+ return m_Time.fromDelimited (value);
186+ }
187+ std::uint64_t checksum () const {
188+ return m_Time.checksum ();
189+ }
190+
191+ private:
192+ TMeanAccumulator m_Time;
193+ };
194+
124195// ! \brief Gathers a STAT statistic and it's bucket time.
125- template <typename STAT>
196+ template <typename STAT, typename TIME >
126197class CStatGatherer {
127198public:
128199 using TStat = STAT;
129200
130201public:
131- explicit CStatGatherer (const STAT& initial = STAT{}) : m_Stat{initial} {}
202+ explicit CStatGatherer (core_t ::TTime bucketLength, const STAT& initial) : m_Time{bucketLength}, m_Stat{initial} {}
132203
133204 std::size_t dimension () const {
134205 return metric_stat_shims::dimension (m_Stat);
135206 }
136207 core_t ::TTime bucketTime (core_t ::TTime time) const {
137- return time + static_cast <core_t ::TTime>(
138- std::round (maths::common::CBasicStatistics::mean (m_Time)));
208+ return time + m_Time.value ();
139209 }
140210 TDouble1Vec value () const { return metric_stat_shims::value (m_Stat); }
141211 double count () const { return metric_stat_shims::count (m_Stat); }
@@ -146,7 +216,9 @@ class CStatGatherer {
146216 }
147217
148218 void add (core_t ::TTime bucketTime, const TDouble1Vec& value, unsigned int count) {
149- m_Time.add (bucketTime, count);
219+ if (metric_stat_shims::wouldAdd (value, m_Stat)) {
220+ m_Time.add (bucketTime, count);
221+ }
150222 metric_stat_shims::add (value, count, m_Stat);
151223 }
152224
@@ -168,17 +240,17 @@ class CStatGatherer {
168240 }
169241
170242private:
171- TMeanAccumulator m_Time;
243+ TIME m_Time;
172244 STAT m_Stat;
173245};
174246
175- using TSumGatherer = CStatGatherer<CSumAccumulator>;
176- using TMeanGatherer = CStatGatherer<TMeanAccumulator>;
177- using TMultivariateMeanGatherer = CStatGatherer<TMultivariateMeanAccumulator>;
178- using TMedianGatherer = CStatGatherer<TMedianAccumulator>;
179- using TMinGatherer = CStatGatherer<TMinAccumulator>;
180- using TMaxGatherer = CStatGatherer<TMaxAccumulator>;
181- using TVarianceGatherer = CStatGatherer<TVarianceAccumulator>;
247+ using TSumGatherer = CStatGatherer<CSumAccumulator, CMidTime >;
248+ using TMeanGatherer = CStatGatherer<TMeanAccumulator, CMeanTime >;
249+ using TMultivariateMeanGatherer = CStatGatherer<TMultivariateMeanAccumulator, CMeanTime >;
250+ using TMedianGatherer = CStatGatherer<TMedianAccumulator, CMeanTime >;
251+ using TMinGatherer = CStatGatherer<TMinAccumulator, CLastTime >;
252+ using TMaxGatherer = CStatGatherer<TMaxAccumulator, CLastTime >;
253+ using TVarianceGatherer = CStatGatherer<TVarianceAccumulator, CMeanTime >;
182254
183255} // metric_stat_gatherer_detail::
184256
@@ -215,7 +287,7 @@ class CMetricStatGatherer {
215287 m_BucketStats (latencyBuckets,
216288 bucketLength,
217289 startTime,
218- STAT{metric_stat_shims::makeStat<TBaseStat>(dimension)}),
290+ STAT{bucketLength, metric_stat_shims::makeStat<TBaseStat>(dimension)}),
219291 m_InfluencerBucketStats (
220292 std::distance (beginInfluencers, endInfluencers),
221293 TStoredStringPtrBaseStatUMapQueue(latencyBuckets,
@@ -264,9 +336,6 @@ class CMetricStatGatherer {
264336 gatherer.samples (time)};
265337 }
266338
267- // ! Returns false.
268- bool sample (core_t ::TTime, unsigned int ) { return false ; }
269-
270339 // ! Update the state with a new measurement.
271340 // !
272341 // ! \param[in] time The time of \p value.
@@ -292,15 +361,15 @@ class CMetricStatGatherer {
292361
293362 // ! Update the state to represent the start of a new bucket.
294363 void startNewBucket (core_t ::TTime time) {
295- m_BucketStats.push (STAT{m_BaseStat}, time);
364+ m_BucketStats.push (STAT{m_BucketStats. bucketLength (), m_BaseStat}, time);
296365 for (auto & stat : m_InfluencerBucketStats) {
297366 stat.push (TStoredStringPtrBaseStatUMap (1 ), time);
298367 }
299368 }
300369
301370 // ! Reset bucket.
302371 void resetBucket (core_t ::TTime bucketStart) {
303- m_BucketStats.get (bucketStart) = STAT{m_BaseStat};
372+ m_BucketStats.get (bucketStart) = STAT{m_BucketStats. bucketLength (), m_BaseStat};
304373 for (auto & stat : m_InfluencerBucketStats) {
305374 stat.get (bucketStart).clear ();
306375 }
0 commit comments