Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Unified Diff: webrtc/base/analytics/percentile_filter.h

Issue 2529063002: Templatize percentile_filter.h and move it to base/analytics. (Closed)
Patch Set: Only allow removing the oldest element from PercentileFilter. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/base/BUILD.gn ('k') | webrtc/base/analytics/percentile_filter_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/base/analytics/percentile_filter.h
diff --git a/webrtc/modules/video_coding/percentile_filter.cc b/webrtc/base/analytics/percentile_filter.h
similarity index 33%
rename from webrtc/modules/video_coding/percentile_filter.cc
rename to webrtc/base/analytics/percentile_filter.h
index 6495567540961c86a721b58de9ba99a51694973e..d730669cf0dcc889aab570d1422c09545296866e 100644
--- a/webrtc/modules/video_coding/percentile_filter.cc
+++ b/webrtc/base/analytics/percentile_filter.h
@@ -8,25 +8,71 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/modules/video_coding/percentile_filter.h"
+#ifndef WEBRTC_BASE_ANALYTICS_PERCENTILE_FILTER_H_
+#define WEBRTC_BASE_ANALYTICS_PERCENTILE_FILTER_H_
+
+#include <stdint.h>
#include <iterator>
+#include <list>
+#include <set>
#include "webrtc/base/checks.h"
namespace webrtc {
-PercentileFilter::PercentileFilter(float percentile)
+// Class to efficiently get the percentile value from a group of observations.
+// The percentile is the value below which a given percentage of the
+// observations fall.
+template <typename T>
+class PercentileFilter {
+ public:
+ // Construct filter. |percentile| should be between 0 and 1.
+ explicit PercentileFilter(float percentile);
+
+ // Insert one observation. The complexity of this operation is logarithmic in
+ // the size of the container.
+ void Push(const T& value);
+
+ // Remove the oldest observation. The complexity of this operation is
+ // logarithmic in the size of the container.
+ void Pop();
+
+ // Get the percentile value. The complexity of this operation is constant.
+ T GetPercentileValue() const;
+
+ // Returns the number of observations in the container.
+ size_t Size() const;
+
+ private:
+ // Update iterator and index to point at target percentile value.
+ void UpdatePercentileIterator();
+
+ const float percentile_;
+ std::list<typename std::multiset<T>::iterator> history_;
magjed_webrtc 2016/11/30 10:58:25 An std::queue seems more appropriate. Any reason f
+ std::multiset<T> set_;
+ // Maintain iterator and index of current target percentile value.
+ typename std::multiset<T>::iterator percentile_it_;
+ int64_t percentile_index_;
+};
+
+template <typename T>
+PercentileFilter<T>::PercentileFilter(float percentile)
: percentile_(percentile),
+ history_(),
+ set_(),
percentile_it_(set_.begin()),
percentile_index_(0) {
RTC_CHECK_GE(percentile, 0.0f);
RTC_CHECK_LE(percentile, 1.0f);
}
-void PercentileFilter::Insert(const int64_t& value) {
- // Insert element at the upper bound.
- set_.insert(value);
+template <typename T>
+void PercentileFilter<T>::Push(const T& value) {
+ // Insert element at the upper bound. This means that each range of equal
+ // elements will be stored in the same order that they were inserted.
+ auto it = set_.insert(value);
+ history_.push_back(it);
if (set_.size() == 1u) {
// First element inserted - initialize percentile iterator and index.
percentile_it_ = set_.begin();
@@ -38,24 +84,31 @@ void PercentileFilter::Insert(const int64_t& value) {
UpdatePercentileIterator();
}
-void PercentileFilter::Erase(const int64_t& value) {
- std::multiset<int64_t>::const_iterator it = set_.lower_bound(value);
- // Ignore erase operation if the element is not present in the current set.
- if (it == set_.end() || *it != value)
- return;
+template <typename T>
+void PercentileFilter<T>::Pop() {
+ RTC_DCHECK_GT(history_.size(), 0);
magjed_webrtc 2016/11/30 10:58:25 nit: I think this is cleaner and will give the sam
+ RTC_DCHECK_GT(set_.size(), 0);
+ auto it = history_.front();
+ history_.pop_front();
if (it == percentile_it_) {
- // If same iterator, update to the following element. Index is not affected.
- percentile_it_ = set_.erase(it);
+ // If removing the percentile value, update iterator to the following
+ // element. Index is not affected.
+ percentile_it_ = set_.erase(percentile_it_);
} else {
- set_.erase(it);
- // If erased element was before us, decrement |percentile_index_|.
- if (value <= *percentile_it_)
+ // If erased element is before percentile, decrement |percentile_index_|.
+ // Note that if the erased element compares equal to the percentile, but
+ // isn't the same iterator, then it has to be before the |percentile_index_|
+ // since each range of equal elements is stored in insertion order and we
+ // are erasing the oldest element.
+ if (*it <= *percentile_it_)
--percentile_index_;
+ set_.erase(it);
}
UpdatePercentileIterator();
}
-void PercentileFilter::UpdatePercentileIterator() {
+template <typename T>
+void PercentileFilter<T>::UpdatePercentileIterator() {
if (set_.empty())
return;
const int64_t index = static_cast<int64_t>(percentile_ * (set_.size() - 1));
@@ -63,8 +116,17 @@ void PercentileFilter::UpdatePercentileIterator() {
percentile_index_ = index;
}
-int64_t PercentileFilter::GetPercentileValue() const {
+template <typename T>
+T PercentileFilter<T>::GetPercentileValue() const {
return set_.empty() ? 0 : *percentile_it_;
}
+template <typename T>
+size_t PercentileFilter<T>::Size() const {
+ RTC_DCHECK_EQ(set_.size(), history_.size());
+ return history_.size();
+}
+
} // namespace webrtc
+
+#endif // WEBRTC_BASE_ANALYTICS_PERCENTILE_FILTER_H_
« no previous file with comments | « webrtc/base/BUILD.gn ('k') | webrtc/base/analytics/percentile_filter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698