Move CMedianFilter to timedata.cpp
Now that we no longer use the median filter to keep track of the number of blocks of peers, that's the only place it is used.
This commit is contained in:
parent
49f954f154
commit
d1e26d4e71
5 changed files with 98 additions and 81 deletions
|
@ -61,6 +61,7 @@ BITCOIN_TESTS =\
|
||||||
test/sigopcount_tests.cpp \
|
test/sigopcount_tests.cpp \
|
||||||
test/skiplist_tests.cpp \
|
test/skiplist_tests.cpp \
|
||||||
test/test_bitcoin.cpp \
|
test/test_bitcoin.cpp \
|
||||||
|
test/timedata_tests.cpp \
|
||||||
test/transaction_tests.cpp \
|
test/transaction_tests.cpp \
|
||||||
test/uint256_tests.cpp \
|
test/uint256_tests.cpp \
|
||||||
test/univalue_tests.cpp \
|
test/univalue_tests.cpp \
|
||||||
|
|
38
src/test/timedata_tests.cpp
Normal file
38
src/test/timedata_tests.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
//
|
||||||
|
#include "timedata.h"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(timedata_tests)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(util_MedianFilter)
|
||||||
|
{
|
||||||
|
CMedianFilter<int> filter(5, 15);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(filter.median(), 15);
|
||||||
|
|
||||||
|
filter.input(20); // [15 20]
|
||||||
|
BOOST_CHECK_EQUAL(filter.median(), 17);
|
||||||
|
|
||||||
|
filter.input(30); // [15 20 30]
|
||||||
|
BOOST_CHECK_EQUAL(filter.median(), 20);
|
||||||
|
|
||||||
|
filter.input(3); // [3 15 20 30]
|
||||||
|
BOOST_CHECK_EQUAL(filter.median(), 17);
|
||||||
|
|
||||||
|
filter.input(7); // [3 7 15 20 30]
|
||||||
|
BOOST_CHECK_EQUAL(filter.median(), 15);
|
||||||
|
|
||||||
|
filter.input(18); // [3 7 18 20 30]
|
||||||
|
BOOST_CHECK_EQUAL(filter.median(), 18);
|
||||||
|
|
||||||
|
filter.input(0); // [0 3 7 18 30]
|
||||||
|
BOOST_CHECK_EQUAL(filter.median(), 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -36,31 +36,6 @@ BOOST_AUTO_TEST_CASE(util_criticalsection)
|
||||||
} while(0);
|
} while(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(util_MedianFilter)
|
|
||||||
{
|
|
||||||
CMedianFilter<int> filter(5, 15);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(filter.median(), 15);
|
|
||||||
|
|
||||||
filter.input(20); // [15 20]
|
|
||||||
BOOST_CHECK_EQUAL(filter.median(), 17);
|
|
||||||
|
|
||||||
filter.input(30); // [15 20 30]
|
|
||||||
BOOST_CHECK_EQUAL(filter.median(), 20);
|
|
||||||
|
|
||||||
filter.input(3); // [3 15 20 30]
|
|
||||||
BOOST_CHECK_EQUAL(filter.median(), 17);
|
|
||||||
|
|
||||||
filter.input(7); // [3 7 15 20 30]
|
|
||||||
BOOST_CHECK_EQUAL(filter.median(), 15);
|
|
||||||
|
|
||||||
filter.input(18); // [3 7 18 20 30]
|
|
||||||
BOOST_CHECK_EQUAL(filter.median(), 18);
|
|
||||||
|
|
||||||
filter.input(0); // [0 3 7 18 30]
|
|
||||||
BOOST_CHECK_EQUAL(filter.median(), 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const unsigned char ParseHex_expected[65] = {
|
static const unsigned char ParseHex_expected[65] = {
|
||||||
0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
|
0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
|
||||||
0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
|
0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
|
||||||
|
|
|
@ -6,9 +6,68 @@
|
||||||
#define BITCOIN_TIMEDATA_H
|
#define BITCOIN_TIMEDATA_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
class CNetAddr;
|
class CNetAddr;
|
||||||
|
|
||||||
|
/** 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;
|
||||||
|
unsigned int nSize;
|
||||||
|
public:
|
||||||
|
CMedianFilter(unsigned 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();
|
||||||
|
assert(size>0);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int size() const
|
||||||
|
{
|
||||||
|
return vValues.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<T> sorted () const
|
||||||
|
{
|
||||||
|
return vSorted;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* Functions to keep track of adjusted P2P time */
|
/* Functions to keep track of adjusted P2P time */
|
||||||
int64_t GetTimeOffset();
|
int64_t GetTimeOffset();
|
||||||
int64_t GetAdjustedTime();
|
int64_t GetAdjustedTime();
|
||||||
|
|
56
src/util.h
56
src/util.h
|
@ -356,62 +356,6 @@ bool TimingResistantEqual(const T& a, const T& b)
|
||||||
return accumulator == 0;
|
return accumulator == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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;
|
|
||||||
unsigned int nSize;
|
|
||||||
public:
|
|
||||||
CMedianFilter(unsigned 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();
|
|
||||||
assert(size>0);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int size() const
|
|
||||||
{
|
|
||||||
return vValues.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<T> sorted () const
|
|
||||||
{
|
|
||||||
return vSorted;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
inline void SetThreadPriority(int nPriority)
|
inline void SetThreadPriority(int nPriority)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue