aboutsummaryrefslogtreecommitdiff
path: root/src/util.h
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2011-09-28 21:35:58 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2011-09-28 21:35:58 +0200
commita8b95ce6ed5e84d34748ecdd0ff1db4d03377cf0 (patch)
treef416d18e89f6e619a84d9e316134afc5380df282 /src/util.h
parent59020408744664fde902406cf41de125859d461f (diff)
use median filter for peer-reported reported number of blocks
- fixes problem that one misconfigured or malicious node can mess up progress bar - implementation in src/util.h - testcase in src/test/util_tests.cpp
Diffstat (limited to 'src/util.h')
-rw-r--r--src/util.h44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/util.h b/src/util.h
index fabcaf9303..290195cbfa 100644
--- a/src/util.h
+++ b/src/util.h
@@ -565,6 +565,50 @@ inline uint160 Hash160(const std::vector<unsigned char>& vch)
}
+// Median filter over a stream of values
+// Returns the median of the last N numbers
+template <typename T> class CMedianFilter
+{
+private:
+ std::vector<T> vValues;
+ std::vector<T> vSorted;
+ int nSize;
+public:
+ CMedianFilter(int size, T initial_value):
+ nSize(size)
+ {
+ vValues.reserve(size);
+ vValues.push_back(initial_value);
+ vSorted = vValues;
+ }
+
+ void input(T value)
+ {
+ if(vValues.size() == nSize)
+ {
+ vValues.erase(vValues.begin());
+ }
+ vValues.push_back(value);
+
+ vSorted.resize(vValues.size());
+ std::copy(vValues.begin(), vValues.end(), vSorted.begin());
+ std::sort(vSorted.begin(), vSorted.end());
+ }
+
+ T median() const
+ {
+ int size = vSorted.size();
+ if(size & 1) // Odd number of elements
+ {
+ return vSorted[size/2];
+ }
+ else // Even number of elements
+ {
+ return (vSorted[size/2-1] + vSorted[size/2]) / 2;
+ }
+ }
+};
+