mirror of https://github.com/aria2/aria2
2008-01-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Rewritten get*Missing*Index functions. Now no need to allocate memory each time these functions are called. * src/BitfieldMan.{h, cc} * test/BitfieldManTest.cc * src/array_fun.h * test/array_funTest.cc Now BitfieldMan::countBlock() returns BitfieldMan::blocks. Added new BitfieldMan::countFilteredBlock() to get the number of blocks filtered. Removed unnecessary cast to int32_t. * src/BitfieldMan.{h, cc}pull/1/head
parent
5b8358b4d5
commit
83c82f3ec2
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2008-01-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Rewritten get*Missing*Index functions. Now no need to allocate memory
|
||||
each time these functions are called.
|
||||
* src/BitfieldMan.{h, cc}
|
||||
* test/BitfieldManTest.cc
|
||||
* src/array_fun.h
|
||||
* test/array_funTest.cc
|
||||
|
||||
Now BitfieldMan::countBlock() returns BitfieldMan::blocks.
|
||||
Added new BitfieldMan::countFilteredBlock() to get the number of blocks
|
||||
filtered. Removed unnecessary cast to int32_t.
|
||||
* src/BitfieldMan.{h, cc}
|
||||
|
||||
2008-01-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Fixed the bug that EX_TOO_LONG_PAYLOAD exception is thrown if just
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
/* copyright --> */
|
||||
#include "BitfieldMan.h"
|
||||
#include "Util.h"
|
||||
#include "array_fun.h"
|
||||
#include <string.h>
|
||||
|
||||
BitfieldMan::BitfieldMan(int32_t blockLength, int64_t totalLength)
|
||||
|
@ -131,8 +132,9 @@ int32_t BitfieldMan::getNthBitIndex(const unsigned char bitfield, int32_t nth) c
|
|||
return index;
|
||||
}
|
||||
|
||||
template<typename Array>
|
||||
int32_t
|
||||
BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield,
|
||||
BitfieldMan::getMissingIndexRandomly(const Array& bitfield,
|
||||
int32_t bitfieldLength) const
|
||||
{
|
||||
/*
|
||||
|
@ -192,47 +194,35 @@ int32_t BitfieldMan::getMissingIndex(const unsigned char* peerBitfield, int32_t
|
|||
if(bitfieldLength != length) {
|
||||
return -1;
|
||||
}
|
||||
unsigned char* tempBitfield = new unsigned char[bitfieldLength];
|
||||
for(int32_t i = 0; i < bitfieldLength; ++i) {
|
||||
tempBitfield[i] = peerBitfield[i] & ~bitfield[i];
|
||||
if(filterEnabled) {
|
||||
tempBitfield[i] &= filterBitfield[i];
|
||||
}
|
||||
array_fun<unsigned char> bf = array_and(array_negate(bitfield), peerBitfield);
|
||||
if(filterEnabled) {
|
||||
bf = array_and(bf, filterBitfield);
|
||||
}
|
||||
int32_t index = getMissingIndexRandomly(tempBitfield, bitfieldLength);
|
||||
delete [] tempBitfield;
|
||||
return index;
|
||||
return getMissingIndexRandomly(bf, bitfieldLength);
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::getMissingUnusedIndex(const unsigned char* peerBitfield, int32_t length) const {
|
||||
if(bitfieldLength != length) {
|
||||
return -1;
|
||||
}
|
||||
unsigned char* tempBitfield = new unsigned char[bitfieldLength];
|
||||
for(int32_t i = 0; i < bitfieldLength; ++i) {
|
||||
tempBitfield[i] = peerBitfield[i] & ~bitfield[i] & ~useBitfield[i];
|
||||
if(filterEnabled) {
|
||||
tempBitfield[i] &= filterBitfield[i];
|
||||
}
|
||||
array_fun<unsigned char> bf = array_and(array_and(array_negate(bitfield),
|
||||
array_negate(useBitfield)),
|
||||
peerBitfield);
|
||||
if(filterEnabled) {
|
||||
bf = array_and(bf, filterBitfield);
|
||||
}
|
||||
int32_t index = getMissingIndexRandomly(tempBitfield, bitfieldLength);
|
||||
delete [] tempBitfield;
|
||||
return index;
|
||||
return getMissingIndexRandomly(bf, bitfieldLength);
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::getFirstMissingUnusedIndex(const unsigned char* peerBitfield, int32_t length) const {
|
||||
if(bitfieldLength != length) {
|
||||
return -1;
|
||||
}
|
||||
template<typename Array>
|
||||
int32_t BitfieldMan::getFirstMissingIndex(const Array& bitfield, int32_t bitfieldLength) const
|
||||
{
|
||||
for(int32_t i = 0; i < bitfieldLength; ++i) {
|
||||
unsigned char bit = peerBitfield[i] & ~bitfield[i] & ~useBitfield[i];
|
||||
if(filterEnabled) {
|
||||
bit &= filterBitfield[i];
|
||||
}
|
||||
for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) {
|
||||
unsigned char mask = 1 << bs;
|
||||
if(bit & mask) {
|
||||
return i*8+7-bs;
|
||||
int32_t base = i*8;
|
||||
for(int32_t bi = 0; bi < 8 && base+bi < blocks; ++bi) {
|
||||
unsigned char mask = 128 >> bi;
|
||||
if(bitfield[i] & mask) {
|
||||
return base+bi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -240,40 +230,38 @@ int32_t BitfieldMan::getFirstMissingUnusedIndex(const unsigned char* peerBitfiel
|
|||
}
|
||||
|
||||
int32_t BitfieldMan::getFirstMissingUnusedIndex() const {
|
||||
for(int32_t i = 0; i < bitfieldLength; ++i) {
|
||||
unsigned char bit = ~bitfield[i] & ~useBitfield[i];
|
||||
if(filterEnabled) {
|
||||
bit &= filterBitfield[i];
|
||||
}
|
||||
for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) {
|
||||
unsigned char mask = 1 << bs;
|
||||
if(bit & mask) {
|
||||
return i*8+7-bs;
|
||||
}
|
||||
}
|
||||
array_fun<unsigned char> bf = array_and(array_negate(bitfield),
|
||||
array_negate(useBitfield));
|
||||
if(filterEnabled) {
|
||||
bf = array_and(bf, filterBitfield);
|
||||
}
|
||||
return -1;
|
||||
return getFirstMissingIndex(bf, bitfieldLength);
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::getFirstMissingIndex() const
|
||||
{
|
||||
array_fun<unsigned char> bf = array_negate(bitfield);
|
||||
if(filterEnabled) {
|
||||
bf = array_and(bf, filterBitfield);
|
||||
}
|
||||
return getFirstMissingIndex(bf, bitfieldLength);
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::getMissingIndex() const {
|
||||
unsigned char* tempBitfield = new unsigned char[bitfieldLength];
|
||||
for(int32_t i = 0; i < bitfieldLength; ++i) {
|
||||
tempBitfield[i] = ~bitfield[i];
|
||||
if(filterEnabled) {
|
||||
tempBitfield[i] &= filterBitfield[i];
|
||||
}
|
||||
array_fun<unsigned char> bf = array_negate(bitfield);
|
||||
if(filterEnabled) {
|
||||
bf = array_and(bf, filterBitfield);
|
||||
}
|
||||
int32_t index = getMissingIndexRandomly(tempBitfield, bitfieldLength);
|
||||
delete [] tempBitfield;
|
||||
return index;
|
||||
return getMissingIndexRandomly(bf, bitfieldLength);
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::getMissingUnusedIndex() const {
|
||||
unsigned char* tempBitfield = new unsigned char[bitfieldLength];
|
||||
memset(tempBitfield, 0xff, bitfieldLength);
|
||||
int32_t index = getMissingUnusedIndex(tempBitfield, bitfieldLength);
|
||||
delete [] tempBitfield;
|
||||
return index;
|
||||
array_fun<unsigned char> bf = array_and(array_negate(bitfield),
|
||||
array_negate(useBitfield));
|
||||
if(filterEnabled) {
|
||||
bf = array_and(bf, filterBitfield);
|
||||
}
|
||||
return getMissingIndexRandomly(bf, bitfieldLength);
|
||||
}
|
||||
|
||||
// [startIndex, endIndex)
|
||||
|
@ -298,8 +286,7 @@ public:
|
|||
};
|
||||
|
||||
int32_t BitfieldMan::getStartIndex(int32_t index) const {
|
||||
while(index < (int32_t)blocks &&
|
||||
(isUseBitSet(index) || isBitSet(index))) {
|
||||
while(index < blocks && (isUseBitSet(index) || isBitSet(index))) {
|
||||
index++;
|
||||
}
|
||||
if((int32_t)blocks <= index) {
|
||||
|
@ -310,8 +297,7 @@ int32_t BitfieldMan::getStartIndex(int32_t index) const {
|
|||
}
|
||||
|
||||
int32_t BitfieldMan::getEndIndex(int32_t index) const {
|
||||
while(index < (int32_t)blocks &&
|
||||
(!isUseBitSet(index) && !isBitSet(index))) {
|
||||
while(index < blocks && (!isUseBitSet(index) && !isBitSet(index))) {
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
|
@ -320,9 +306,8 @@ int32_t BitfieldMan::getEndIndex(int32_t index) const {
|
|||
int32_t BitfieldMan::getSparseMissingUnusedIndex() const {
|
||||
Range maxRange;
|
||||
int32_t index = 0;
|
||||
int32_t blocks = countBlock();
|
||||
Range currentRange;
|
||||
while(index < (int32_t)blocks) {
|
||||
while(index < blocks) {
|
||||
currentRange.startIndex = getStartIndex(index);
|
||||
if(currentRange.startIndex == -1) {
|
||||
break;
|
||||
|
@ -346,41 +331,40 @@ int32_t BitfieldMan::getSparseMissingUnusedIndex() const {
|
|||
}
|
||||
}
|
||||
|
||||
BlockIndexes BitfieldMan::getAllMissingIndexes() const {
|
||||
template<typename Array>
|
||||
BlockIndexes BitfieldMan::getAllMissingIndexes(const Array& bitfield, int32_t bitfieldLength) const
|
||||
{
|
||||
BlockIndexes missingIndexes;
|
||||
for(int32_t i = 0; i < bitfieldLength; ++i) {
|
||||
unsigned char bit = ~bitfield[i];
|
||||
if(filterEnabled) {
|
||||
bit &= filterBitfield[i];
|
||||
}
|
||||
for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) {
|
||||
unsigned char mask = 1 << bs;
|
||||
if(bit & mask) {
|
||||
missingIndexes.push_back(i*8+7-bs);
|
||||
int32_t base = i*8;
|
||||
for(int32_t bi = 0; bi < 8 && base+bi < blocks; ++bi) {
|
||||
unsigned char mask = 128 >> bi;
|
||||
if(bitfield[i] & mask) {
|
||||
missingIndexes.push_back(base+bi);
|
||||
}
|
||||
}
|
||||
}
|
||||
return missingIndexes;
|
||||
}
|
||||
|
||||
BlockIndexes BitfieldMan::getAllMissingIndexes() const {
|
||||
array_fun<unsigned char> bf = array_negate(bitfield);
|
||||
if(filterEnabled) {
|
||||
bf = array_and(bf, filterBitfield);
|
||||
}
|
||||
return getAllMissingIndexes(bf, bitfieldLength);
|
||||
}
|
||||
|
||||
BlockIndexes BitfieldMan::getAllMissingIndexes(const unsigned char* peerBitfield, int32_t peerBitfieldLength) const {
|
||||
BlockIndexes missingIndexes;
|
||||
if(bitfieldLength != peerBitfieldLength) {
|
||||
return missingIndexes;
|
||||
return BlockIndexes();
|
||||
}
|
||||
for(int32_t i = 0; i < bitfieldLength; ++i) {
|
||||
unsigned char bit = peerBitfield[i] & ~bitfield[i];
|
||||
if(filterEnabled) {
|
||||
bit &= filterBitfield[i];
|
||||
}
|
||||
for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) {
|
||||
unsigned char mask = 1 << bs;
|
||||
if(bit & mask) {
|
||||
missingIndexes.push_back(i*8+7-bs);
|
||||
}
|
||||
}
|
||||
array_fun<unsigned char> bf = array_and(array_negate(bitfield),
|
||||
peerBitfield);
|
||||
if(filterEnabled) {
|
||||
bf = array_and(bf, filterBitfield);
|
||||
}
|
||||
return missingIndexes;
|
||||
return getAllMissingIndexes(bf, bitfieldLength);
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::countMissingBlock() const {
|
||||
|
@ -402,12 +386,12 @@ int32_t BitfieldMan::countMissingBlockNow() const {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::countFilteredBlock() const {
|
||||
return cachedNumFilteredBlock;
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::countBlock() const {
|
||||
if(filterEnabled) {
|
||||
return cachedNumFilteredBlock;
|
||||
} else {
|
||||
return blocks;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
int32_t BitfieldMan::countFilteredBlockNow() const {
|
||||
|
@ -419,7 +403,7 @@ int32_t BitfieldMan::countFilteredBlockNow() const {
|
|||
}
|
||||
|
||||
bool BitfieldMan::setBitInternal(unsigned char* bitfield, int32_t index, bool on) {
|
||||
if((int32_t)blocks <= index) { return false; }
|
||||
if(blocks <= index) { return false; }
|
||||
unsigned char mask = 128 >> index%8;
|
||||
if(on) {
|
||||
bitfield[index/8] |= mask;
|
||||
|
@ -479,7 +463,7 @@ bool BitfieldMan::isAllBitSet() const {
|
|||
}
|
||||
|
||||
bool BitfieldMan::isBitSetInternal(const unsigned char* bitfield, int32_t index) const {
|
||||
if(index < 0 || (int32_t)blocks <= index) { return false; }
|
||||
if(index < 0 || blocks <= index) { return false; }
|
||||
unsigned char mask = 128 >> index%8;
|
||||
return (bitfield[index/8] & mask) != 0;
|
||||
}
|
||||
|
@ -535,7 +519,7 @@ void BitfieldMan::addFilter(int64_t offset, int64_t length) {
|
|||
}
|
||||
int32_t startBlock = offset/blockLength;
|
||||
int32_t endBlock = (offset+length-1)/blockLength;
|
||||
for(int i = startBlock; i <= endBlock && i < (int32_t)blocks; i++) {
|
||||
for(int i = startBlock; i <= endBlock && i < blocks; i++) {
|
||||
setFilterBit(i);
|
||||
}
|
||||
updateCache();
|
||||
|
|
|
@ -63,6 +63,17 @@ private:
|
|||
int32_t countSetBit(const unsigned char* bitfield, int32_t len) const;
|
||||
int32_t getNthBitIndex(const unsigned char bit, int32_t nth) const;
|
||||
int32_t getMissingIndexRandomly(const unsigned char* bitfield, int32_t len) const;
|
||||
|
||||
template<typename Array>
|
||||
int32_t
|
||||
getMissingIndexRandomly(const Array& bitfield,
|
||||
int32_t bitfieldLength) const;
|
||||
template<typename Array>
|
||||
int32_t getFirstMissingIndex(const Array& bitfield, int32_t bitfieldLength) const;
|
||||
|
||||
template<typename Array>
|
||||
BlockIndexes getAllMissingIndexes(const Array& bitfield, int32_t bitfieldLength) const;
|
||||
|
||||
bool isBitSetInternal(const unsigned char* bitfield, int32_t index) const;
|
||||
bool setBitInternal(unsigned char* bitfield, int32_t index, bool on);
|
||||
bool setFilterBit(int32_t index);
|
||||
|
@ -112,9 +123,9 @@ public:
|
|||
}
|
||||
|
||||
int32_t getBlockLength(int32_t index) const {
|
||||
if(index == (int32_t)(blocks-1)) {
|
||||
if(index == blocks-1) {
|
||||
return getLastBlockLength();
|
||||
} else if(0 <= index && index < (int32_t)(blocks-1)) {
|
||||
} else if(0 <= index && index < blocks-1) {
|
||||
return getBlockLength();
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -143,6 +154,10 @@ public:
|
|||
* affected by filter
|
||||
*/
|
||||
int32_t getFirstMissingUnusedIndex() const;
|
||||
/**
|
||||
* affected by filter
|
||||
*/
|
||||
int32_t getFirstMissingIndex() const;
|
||||
/**
|
||||
* affected by filter
|
||||
*/
|
||||
|
@ -194,6 +209,8 @@ public:
|
|||
/**
|
||||
* affected by filter
|
||||
*/
|
||||
int32_t countFilteredBlock() const;
|
||||
|
||||
int32_t countBlock() const;
|
||||
/**
|
||||
* affected by filter
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_ARRAY_FUN_H_
|
||||
#define _D_ARRAY_FUN_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
template<typename T>
|
||||
class bit_negate:public std::unary_function<T, T> {
|
||||
public:
|
||||
T operator()(const T& t) const
|
||||
{
|
||||
return ~t;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class bit_and:public std::binary_function<T, T, T> {
|
||||
public:
|
||||
T operator()(const T& t1, const T& t2) const
|
||||
{
|
||||
return t1&t2;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename R>
|
||||
class array_function_base {
|
||||
public:
|
||||
virtual ~array_function_base() {}
|
||||
|
||||
virtual R operator[](std::size_t index) const = 0;
|
||||
|
||||
virtual array_function_base* clone() const = 0;
|
||||
};
|
||||
|
||||
template<typename A, typename F>
|
||||
class array_unary_function:public array_function_base<typename F::result_type> {
|
||||
private:
|
||||
A _a;
|
||||
F _f;
|
||||
public:
|
||||
array_unary_function(A a, F f):_a(a), _f(f) {}
|
||||
|
||||
virtual typename F::result_type operator[](std::size_t index) const
|
||||
{
|
||||
return _f(_a[index]);
|
||||
}
|
||||
|
||||
virtual array_function_base<typename F::result_type>* clone() const
|
||||
{
|
||||
return new array_unary_function(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename A, typename B, typename F>
|
||||
class array_binary_function:public array_function_base<typename F::result_type>{
|
||||
private:
|
||||
A _a;
|
||||
B _b;
|
||||
F _f;
|
||||
public:
|
||||
array_binary_function(A a, B b, F f):_a(a), _b(b), _f(f) {}
|
||||
|
||||
virtual typename F::result_type operator[](std::size_t index) const
|
||||
{
|
||||
return _f(_a[index], _b[index]);
|
||||
}
|
||||
|
||||
virtual array_function_base<typename F::result_type>* clone() const
|
||||
{
|
||||
return new array_binary_function(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename R>
|
||||
class array_fun {
|
||||
private:
|
||||
array_function_base<R>* _p;
|
||||
public:
|
||||
template<typename A, typename F>
|
||||
array_fun(A a, F f):_p(new array_unary_function<A, F>(a, f)) {}
|
||||
|
||||
template<typename A, typename B, typename F>
|
||||
array_fun(A a, B b, F f):_p(new array_binary_function<A, B, F>(a, b, f)) {}
|
||||
|
||||
array_fun(const array_fun& af):_p(af._p->clone()) {}
|
||||
|
||||
~array_fun()
|
||||
{
|
||||
delete _p;
|
||||
}
|
||||
|
||||
array_fun& operator=(const array_fun& af)
|
||||
{
|
||||
if(this != &af) {
|
||||
delete _p;
|
||||
_p = af._p->clone();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
R operator[](std::size_t index) const
|
||||
{
|
||||
return (*_p)[index];
|
||||
}
|
||||
|
||||
typedef R result_type;
|
||||
};
|
||||
|
||||
template<typename R, typename A>
|
||||
array_fun<R>
|
||||
array_negate(A a)
|
||||
{
|
||||
return array_fun<R>(a, bit_negate<R>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
array_fun<T>
|
||||
array_negate(T* a)
|
||||
{
|
||||
return array_fun<T>(a, bit_negate<T>());
|
||||
}
|
||||
|
||||
template<typename A>
|
||||
array_fun<typename A::result_type>
|
||||
array_negate(A a)
|
||||
{
|
||||
return array_fun<typename A::result_type>(a, bit_negate<typename A::result_type>());
|
||||
}
|
||||
|
||||
template<typename R, typename A, typename B>
|
||||
array_fun<R>
|
||||
array_and(A a, B b)
|
||||
{
|
||||
return array_fun<R>(a, b, bit_and<R>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
array_fun<T>
|
||||
array_and(T* a, T* b)
|
||||
{
|
||||
return array_fun<T>(a, b, bit_and<T>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
array_fun<typename T::result_type>
|
||||
array_and(T a, T b)
|
||||
{
|
||||
return array_fun<typename T::result_type>(a, b, bit_and<typename T::result_type>());
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
array_fun<typename A::result_type>
|
||||
array_and(A a, B b)
|
||||
{
|
||||
return array_fun<typename A::result_type>(a, b, bit_and<typename A::result_type>());
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
array_fun<typename B::result_type>
|
||||
array_and(A a, B b)
|
||||
{
|
||||
return array_fun<typename B::result_type>(a, b, bit_and<typename B::result_type>());
|
||||
}
|
||||
|
||||
#endif // _D_ARRAY_FUN_H_
|
|
@ -1,16 +1,13 @@
|
|||
#include "BitfieldMan.h"
|
||||
#include "FixedNumberRandomizer.h"
|
||||
#include "BitfieldManFactory.h"
|
||||
#include <string>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BitfieldManTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(BitfieldManTest);
|
||||
CPPUNIT_TEST(testGetBlockSize);
|
||||
CPPUNIT_TEST(testGetFirstMissingUnusedIndex);
|
||||
CPPUNIT_TEST(testGetFirstMissingIndex);
|
||||
CPPUNIT_TEST(testIsAllBitSet);
|
||||
CPPUNIT_TEST(testFilter);
|
||||
CPPUNIT_TEST(testGetMissingIndex);
|
||||
|
@ -19,6 +16,12 @@ class BitfieldManTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testIsBitSetOffsetRange);
|
||||
CPPUNIT_TEST(testGetMissingUnusedLength);
|
||||
CPPUNIT_TEST(testSetBitRange);
|
||||
CPPUNIT_TEST(testGetAllMissingIndexes);
|
||||
CPPUNIT_TEST(testGetAllMissingIndexes_noarg);
|
||||
CPPUNIT_TEST(testGetMissingUnusedIndex);
|
||||
CPPUNIT_TEST(testGetMissingIndex_noarg);
|
||||
CPPUNIT_TEST(testGetMissingUnusedIndex_noarg);
|
||||
CPPUNIT_TEST(testCountFilteredBlock);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
RandomizerHandle fixedNumberRandomizer;
|
||||
|
@ -35,14 +38,22 @@ public:
|
|||
|
||||
void testGetBlockSize();
|
||||
void testGetFirstMissingUnusedIndex();
|
||||
void testGetFirstMissingIndex();
|
||||
void testGetMissingIndex();
|
||||
void testGetMissingIndex_noarg();
|
||||
void testGetMissingUnusedIndex();
|
||||
void testGetMissingUnusedIndex_noarg();
|
||||
void testGetAllMissingIndexes();
|
||||
void testGetAllMissingIndexes_noarg();
|
||||
|
||||
void testIsAllBitSet();
|
||||
void testFilter();
|
||||
void testGetMissingIndex();
|
||||
void testGetSparceMissingUnusedIndex();
|
||||
void testGetSparceMissingUnusedIndex_setBit();
|
||||
void testIsBitSetOffsetRange();
|
||||
void testGetMissingUnusedLength();
|
||||
void testSetBitRange();
|
||||
void testCountFilteredBlock();
|
||||
};
|
||||
|
||||
|
||||
|
@ -58,27 +69,116 @@ void BitfieldManTest::testGetBlockSize() {
|
|||
CPPUNIT_ASSERT_EQUAL((int32_t)0, bt2.getBlockLength(11));
|
||||
}
|
||||
|
||||
void BitfieldManTest::testGetFirstMissingUnusedIndex() {
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
unsigned char bitfield[2];
|
||||
memset(bitfield, 0xff, sizeof(bitfield));
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)0, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield)));
|
||||
CPPUNIT_ASSERT(bt1.setUseBit(0));
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)1, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield)));
|
||||
CPPUNIT_ASSERT(bt1.unsetUseBit(0));
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)0, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield)));
|
||||
CPPUNIT_ASSERT(bt1.setBit(0));
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)1, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield)));
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
CPPUNIT_ASSERT(bt1.setBit(i));
|
||||
void BitfieldManTest::testGetFirstMissingUnusedIndex()
|
||||
{
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt1.getFirstMissingUnusedIndex());
|
||||
bt1.setUseBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getFirstMissingUnusedIndex());
|
||||
bt1.unsetUseBit(0);
|
||||
bt1.setBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getFirstMissingUnusedIndex());
|
||||
bt1.setAllBit();
|
||||
CPPUNIT_ASSERT_EQUAL(-1, bt1.getFirstMissingUnusedIndex());
|
||||
}
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)8, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield)));
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)8, bt1.getFirstMissingUnusedIndex());
|
||||
CPPUNIT_ASSERT(bt1.setUseBit(8));
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)9, bt1.getFirstMissingUnusedIndex());
|
||||
bt1.addFilter(1024, 1024*10);
|
||||
bt1.enableFilter();
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getFirstMissingUnusedIndex());
|
||||
bt1.setUseBit(1);
|
||||
CPPUNIT_ASSERT_EQUAL(2, bt1.getFirstMissingUnusedIndex());
|
||||
bt1.setBit(2);
|
||||
CPPUNIT_ASSERT_EQUAL(3, bt1.getFirstMissingUnusedIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void BitfieldManTest::testGetFirstMissingIndex()
|
||||
{
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt1.getFirstMissingIndex());
|
||||
bt1.setUseBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt1.getFirstMissingIndex());
|
||||
bt1.unsetUseBit(0);
|
||||
bt1.setBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getFirstMissingIndex());
|
||||
bt1.setAllBit();
|
||||
CPPUNIT_ASSERT_EQUAL(-1, bt1.getFirstMissingIndex());
|
||||
}
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
|
||||
bt1.addFilter(1024, 1024*10);
|
||||
bt1.enableFilter();
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getFirstMissingIndex());
|
||||
bt1.setUseBit(1);
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getFirstMissingIndex());
|
||||
bt1.setBit(1);
|
||||
CPPUNIT_ASSERT_EQUAL(2, bt1.getFirstMissingIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void BitfieldManTest::testGetMissingUnusedIndex_noarg()
|
||||
{
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
bt1.setRandomizer(fixedNumberRandomizer);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt1.getMissingUnusedIndex());
|
||||
bt1.setUseBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getMissingUnusedIndex());
|
||||
bt1.unsetUseBit(0);
|
||||
bt1.setBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getMissingUnusedIndex());
|
||||
bt1.setAllBit();
|
||||
CPPUNIT_ASSERT_EQUAL(-1, bt1.getMissingUnusedIndex());
|
||||
}
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
bt1.setRandomizer(fixedNumberRandomizer);
|
||||
|
||||
bt1.addFilter(1024, 1024*10);
|
||||
bt1.enableFilter();
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getMissingUnusedIndex());
|
||||
bt1.setUseBit(1);
|
||||
CPPUNIT_ASSERT_EQUAL(2, bt1.getMissingUnusedIndex());
|
||||
bt1.setBit(2);
|
||||
CPPUNIT_ASSERT_EQUAL(3, bt1.getMissingUnusedIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void BitfieldManTest::testGetMissingIndex_noarg()
|
||||
{
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
bt1.setRandomizer(fixedNumberRandomizer);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt1.getMissingIndex());
|
||||
bt1.setUseBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt1.getMissingIndex());
|
||||
bt1.unsetUseBit(0);
|
||||
bt1.setBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getMissingIndex());
|
||||
bt1.setAllBit();
|
||||
CPPUNIT_ASSERT_EQUAL(-1, bt1.getMissingIndex());
|
||||
}
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*10);
|
||||
bt1.setRandomizer(fixedNumberRandomizer);
|
||||
|
||||
bt1.addFilter(1024, 1024*10);
|
||||
bt1.enableFilter();
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getMissingIndex());
|
||||
bt1.setUseBit(1);
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getMissingIndex());
|
||||
bt1.setBit(1);
|
||||
CPPUNIT_ASSERT_EQUAL(2, bt1.getMissingIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void BitfieldManTest::testIsAllBitSet() {
|
||||
|
@ -178,6 +278,11 @@ void BitfieldManTest::testGetMissingIndex() {
|
|||
};
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)0, bt1.getMissingIndex(bitArray, 32));
|
||||
|
||||
bt1.addFilter(1024, 1024*256);
|
||||
bt1.enableFilter();
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)1, bt1.getMissingIndex(bitArray, 32));
|
||||
bt1.disableFilter();
|
||||
|
||||
unsigned char bitArray2[] = {
|
||||
0x0f, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
|
@ -354,3 +459,103 @@ void BitfieldManTest::testSetBitRange()
|
|||
}
|
||||
CPPUNIT_ASSERT_EQUAL(int64_t(5*blockLength), bf.getCompletedLength());
|
||||
}
|
||||
|
||||
void BitfieldManTest::testGetAllMissingIndexes_noarg()
|
||||
{
|
||||
int32_t blockLength = 16*1024;
|
||||
int64_t totalLength = 1024*1024;
|
||||
BitfieldMan bf(blockLength, totalLength);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)64, bf.getAllMissingIndexes().size());
|
||||
for(int32_t i = 0; i < 63; ++i) {
|
||||
bf.setBit(i);
|
||||
}
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, bf.getAllMissingIndexes().size());
|
||||
CPPUNIT_ASSERT_EQUAL(63, bf.getAllMissingIndexes().front());
|
||||
}
|
||||
|
||||
void BitfieldManTest::testGetAllMissingIndexes()
|
||||
{
|
||||
int32_t blockLength = 16*1024;
|
||||
int64_t totalLength = 1024*1024;
|
||||
BitfieldMan bf(blockLength, totalLength);
|
||||
BitfieldMan peerBf(blockLength, totalLength);
|
||||
peerBf.setAllBit();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)64, bf.getAllMissingIndexes(peerBf.getBitfield(),
|
||||
peerBf.getBitfieldLength()).size());
|
||||
for(int32_t i = 0; i < 62; ++i) {
|
||||
bf.setBit(i);
|
||||
}
|
||||
peerBf.unsetBit(62);
|
||||
|
||||
{
|
||||
Integers indexes = bf.getAllMissingIndexes(peerBf.getBitfield(),
|
||||
peerBf.getBitfieldLength());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, indexes.size());
|
||||
CPPUNIT_ASSERT_EQUAL(63, indexes.front());
|
||||
}
|
||||
}
|
||||
|
||||
void BitfieldManTest::testGetMissingUnusedIndex()
|
||||
{
|
||||
BitfieldMan bt1(1024, 1024*256);
|
||||
bt1.setRandomizer(fixedNumberRandomizer);
|
||||
|
||||
unsigned char bitArray[] = {
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
};
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt1.getMissingUnusedIndex(bitArray, 32));
|
||||
|
||||
bt1.addFilter(1024, 1024*256);
|
||||
bt1.enableFilter();
|
||||
CPPUNIT_ASSERT_EQUAL(1, bt1.getMissingUnusedIndex(bitArray, 32));
|
||||
bt1.setUseBit(1);
|
||||
CPPUNIT_ASSERT_EQUAL(2, bt1.getMissingUnusedIndex(bitArray, 32));
|
||||
bt1.disableFilter();
|
||||
|
||||
bt1.setBit(0);
|
||||
CPPUNIT_ASSERT_EQUAL(2, bt1.getMissingUnusedIndex(bitArray, 32));
|
||||
|
||||
bt1.setAllBit();
|
||||
CPPUNIT_ASSERT_EQUAL(-1, bt1.getMissingUnusedIndex(bitArray, 32));
|
||||
|
||||
bt1.clearAllBit();
|
||||
bt1.setAllUseBit();
|
||||
CPPUNIT_ASSERT_EQUAL(-1, bt1.getMissingUnusedIndex(bitArray, 32));
|
||||
|
||||
unsigned char bitArray4[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(-1, bt1.getMissingUnusedIndex(bitArray4, 32));
|
||||
}
|
||||
|
||||
void BitfieldManTest::testCountFilteredBlock()
|
||||
{
|
||||
BitfieldMan bt(1024, 1024*256);
|
||||
CPPUNIT_ASSERT_EQUAL(256, bt.countBlock());
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt.countFilteredBlock());
|
||||
bt.addFilter(1024, 1024*256);
|
||||
bt.enableFilter();
|
||||
CPPUNIT_ASSERT_EQUAL(256, bt.countBlock());
|
||||
CPPUNIT_ASSERT_EQUAL(255, bt.countFilteredBlock());
|
||||
bt.disableFilter();
|
||||
CPPUNIT_ASSERT_EQUAL(256, bt.countBlock());
|
||||
CPPUNIT_ASSERT_EQUAL(0, bt.countFilteredBlock());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
#include "array_fun.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class array_funTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(array_funTest);
|
||||
CPPUNIT_TEST(testBit_negate);
|
||||
CPPUNIT_TEST(testBit_and);
|
||||
CPPUNIT_TEST(testArray_negate);
|
||||
CPPUNIT_TEST(testArray_and);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
public:
|
||||
void testBit_negate();
|
||||
void testBit_and();
|
||||
void testArray_negate();
|
||||
void testArray_and();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(array_funTest);
|
||||
|
||||
void array_funTest::testBit_negate()
|
||||
{
|
||||
unsigned char b = 0xaa;
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x55, bit_negate<unsigned char>()(b));
|
||||
}
|
||||
|
||||
void array_funTest::testBit_and()
|
||||
{
|
||||
unsigned char b = 0xaa;
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x0a, bit_and<unsigned char>()(b, 0x0a));
|
||||
}
|
||||
|
||||
void array_funTest::testArray_negate()
|
||||
{
|
||||
unsigned char a[] = { 0xaa, 0x55 };
|
||||
array_fun<unsigned char> f = array_negate((unsigned char*)a);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x55, f[0]);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0xaa, f[1]);
|
||||
|
||||
array_fun<unsigned char> ff = array_negate(f);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0xaa, ff[0]);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x55, ff[1]);
|
||||
}
|
||||
|
||||
void array_funTest::testArray_and()
|
||||
{
|
||||
unsigned char a1[] = { 0xaa, 0x55 };
|
||||
unsigned char a2[] = { 0x1a, 0x25 };
|
||||
array_fun<unsigned char> f = array_and((unsigned char*)a1, (unsigned char*)a2);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x0a, f[0]);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x05, f[1]);
|
||||
|
||||
array_fun<unsigned char> f2 = array_and((unsigned char*)a1, array_negate(a2));
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0xa0, f2[0]);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x50, f2[1]);
|
||||
|
||||
array_fun<unsigned char> f3 = array_and(array_negate(a2), (unsigned char*)a1);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0xa0, f3[0]);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x50, f3[1]);
|
||||
|
||||
array_fun<unsigned char> f4 = array_and(array_negate(a1), array_negate(a2));
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x45, f4[0]);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0x8a, f4[1]);
|
||||
}
|
Loading…
Reference in New Issue