diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2011-09-28 21:35:58 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2011-09-28 21:35:58 +0200 |
commit | a8b95ce6ed5e84d34748ecdd0ff1db4d03377cf0 (patch) | |
tree | f416d18e89f6e619a84d9e316134afc5380df282 /src/util.h | |
parent | 59020408744664fde902406cf41de125859d461f (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.h | 44 |
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; + } + } +}; + |