mirror of https://github.com/aria2/aria2
2010-02-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Moved getFirstNMissingIndex to bitfield.h and made it return the number of appended indexes. * src/BitfieldMan.cc * src/BitfieldMan.h * src/Piece.cc * src/Piece.h * src/bitfield.h * test/BitfieldManTest.ccpull/1/head
parent
aa1139bb67
commit
e3e3f0438d
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2010-02-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Moved getFirstNMissingIndex to bitfield.h and made it return the
|
||||||
|
number of appended indexes.
|
||||||
|
* src/BitfieldMan.cc
|
||||||
|
* src/BitfieldMan.h
|
||||||
|
* src/Piece.cc
|
||||||
|
* src/Piece.h
|
||||||
|
* src/bitfield.h
|
||||||
|
* test/BitfieldManTest.cc
|
||||||
|
|
||||||
2010-02-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2010-02-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Added more tests.
|
Added more tests.
|
||||||
|
|
|
@ -268,44 +268,17 @@ bool BitfieldMan::getFirstMissingUnusedIndex(size_t& index) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Array, typename OutputIterator>
|
size_t BitfieldMan::getFirstNMissingUnusedIndex
|
||||||
static bool getFirstNMissingIndex
|
|
||||||
(OutputIterator out, size_t n,
|
|
||||||
const Array& bitfield, size_t bitfieldLength, size_t blocks)
|
|
||||||
{
|
|
||||||
if(n == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const size_t origN = n;
|
|
||||||
for(size_t i = 0; i < bitfieldLength; ++i) {
|
|
||||||
unsigned char bits = bitfield[i];
|
|
||||||
unsigned char mask = 128;
|
|
||||||
size_t tindex = i*8;
|
|
||||||
for(size_t bi = 0; bi < 8 && tindex < blocks; ++bi, mask >>= 1, ++tindex) {
|
|
||||||
if(bits & mask) {
|
|
||||||
*out++ = tindex;
|
|
||||||
if(--n == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return origN > n;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BitfieldMan::getFirstNMissingUnusedIndex
|
|
||||||
(std::vector<size_t>& out, size_t n) const
|
(std::vector<size_t>& out, size_t n) const
|
||||||
{
|
{
|
||||||
if(filterEnabled) {
|
if(filterEnabled) {
|
||||||
return getFirstNMissingIndex
|
return bitfield::getFirstNMissingIndex
|
||||||
(std::back_inserter(out), n,
|
(std::back_inserter(out), n,
|
||||||
~array(bitfield)&~array(useBitfield)&array(filterBitfield),
|
~array(bitfield)&~array(useBitfield)&array(filterBitfield), blocks);
|
||||||
bitfieldLength, blocks);
|
|
||||||
} else {
|
} else {
|
||||||
return getFirstNMissingIndex
|
return bitfield::getFirstNMissingIndex
|
||||||
(std::back_inserter(out), n,
|
(std::back_inserter(out), n,
|
||||||
~array(bitfield)&~array(useBitfield),
|
~array(bitfield)&~array(useBitfield), blocks);
|
||||||
bitfieldLength, blocks);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,12 +147,13 @@ public:
|
||||||
*/
|
*/
|
||||||
bool getFirstMissingUnusedIndex(size_t& index) const;
|
bool getFirstMissingUnusedIndex(size_t& index) const;
|
||||||
/**
|
/**
|
||||||
* Stores at most n missing unused index in out. This function
|
* Appends at most n missing unused index to out. This function
|
||||||
* doesn't delete existing elements in out.
|
* doesn't delete existing elements in out. Returns the number of
|
||||||
|
* appended elements.
|
||||||
*
|
*
|
||||||
* affected by filter
|
* affected by filter
|
||||||
*/
|
*/
|
||||||
bool getFirstNMissingUnusedIndex(std::vector<size_t>& out, size_t n) const;
|
size_t getFirstNMissingUnusedIndex(std::vector<size_t>& out, size_t n) const;
|
||||||
/**
|
/**
|
||||||
* affected by filter
|
* affected by filter
|
||||||
*/
|
*/
|
||||||
|
|
11
src/Piece.cc
11
src/Piece.cc
|
@ -173,18 +173,17 @@ bool Piece::getMissingUnusedBlockIndex(size_t& index) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Piece::getMissingUnusedBlockIndex
|
size_t Piece::getMissingUnusedBlockIndex
|
||||||
(std::vector<size_t>& indexes, size_t n) const
|
(std::vector<size_t>& indexes, size_t n) const
|
||||||
{
|
{
|
||||||
if(bitfield->getFirstNMissingUnusedIndex(indexes, n)) {
|
size_t num = bitfield->getFirstNMissingUnusedIndex(indexes, n);
|
||||||
for(std::vector<size_t>::const_iterator i = indexes.begin();
|
if(num) {
|
||||||
|
for(std::vector<size_t>::const_iterator i = indexes.end()-num;
|
||||||
i != indexes.end(); ++i) {
|
i != indexes.end(); ++i) {
|
||||||
bitfield->setUseBit(*i);
|
bitfield->setUseBit(*i);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Piece::getFirstMissingBlockIndexWithoutLock(size_t& index) const
|
bool Piece::getFirstMissingBlockIndexWithoutLock(size_t& index) const
|
||||||
|
|
11
src/Piece.h
11
src/Piece.h
|
@ -98,11 +98,12 @@ public:
|
||||||
// TODO This function only used by unit tests
|
// TODO This function only used by unit tests
|
||||||
bool getMissingUnusedBlockIndex(size_t& index) const;
|
bool getMissingUnusedBlockIndex(size_t& index) const;
|
||||||
|
|
||||||
// Stores at most n missing unused block index to indexes. For all i
|
// Appends at most n missing unused block index to indexes. For all
|
||||||
// in indexes, call bitfield->setUseBit(i). This function just add
|
// i in retrieved indexes, call bitfield->setUseBit(i). This
|
||||||
// index to indexes and it doesn't remove anything from
|
// function just append index to indexes and it doesn't remove
|
||||||
// it. Therefore Caller must pass empty indexes.
|
// anything from it. Returns the number of indexes to retrieved.
|
||||||
bool getMissingUnusedBlockIndex(std::vector<size_t>& indexes, size_t n) const;
|
size_t getMissingUnusedBlockIndex
|
||||||
|
(std::vector<size_t>& indexes, size_t n) const;
|
||||||
|
|
||||||
bool getFirstMissingBlockIndexWithoutLock(size_t& index) const;
|
bool getFirstMissingBlockIndexWithoutLock(size_t& index) const;
|
||||||
bool getAllMissingBlockIndexes(unsigned char* misbitfield,
|
bool getAllMissingBlockIndexes(unsigned char* misbitfield,
|
||||||
|
|
|
@ -118,6 +118,32 @@ inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
|
||||||
|
|
||||||
void flipBit(unsigned char* data, size_t length, size_t bitIndex);
|
void flipBit(unsigned char* data, size_t length, size_t bitIndex);
|
||||||
|
|
||||||
|
// Appends first at most n set bit index in bitfield to out. bitfield
|
||||||
|
// contains nbits bits. Returns the number of appended bit indexes.
|
||||||
|
template<typename Array, typename OutputIterator>
|
||||||
|
size_t getFirstNMissingIndex
|
||||||
|
(OutputIterator out, size_t n, const Array& bitfield, size_t nbits)
|
||||||
|
{
|
||||||
|
if(n == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const size_t origN = n;
|
||||||
|
const size_t bitfieldLength = (nbits+7)/8;
|
||||||
|
for(size_t i = 0; i < bitfieldLength; ++i) {
|
||||||
|
unsigned char mask = 128;
|
||||||
|
size_t tindex = i*8;
|
||||||
|
for(size_t bi = 0; bi < 8 && tindex < nbits; ++bi, mask >>= 1, ++tindex) {
|
||||||
|
if(bitfield[i] & mask) {
|
||||||
|
*out++ = tindex;
|
||||||
|
if(--n == 0) {
|
||||||
|
return origN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return origN-n;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace bitfield
|
} // namespace bitfield
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -852,26 +852,26 @@ void BitfieldManTest::testGetFirstNMissingUnusedIndex()
|
||||||
bt.setUseBit(1);
|
bt.setUseBit(1);
|
||||||
bt.setBit(5);
|
bt.setBit(5);
|
||||||
std::vector<size_t> out;
|
std::vector<size_t> out;
|
||||||
CPPUNIT_ASSERT(bt.getFirstNMissingUnusedIndex(out, 256));
|
CPPUNIT_ASSERT_EQUAL((size_t)8, bt.getFirstNMissingUnusedIndex(out, 256));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)8, out.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)8, out.size());
|
||||||
const size_t ans[] = {0, 2, 3, 4, 6, 7, 8, 9};
|
const size_t ans[] = {0, 2, 3, 4, 6, 7, 8, 9};
|
||||||
for(size_t i = 0; i < out.size(); ++i) {
|
for(size_t i = 0; i < out.size(); ++i) {
|
||||||
CPPUNIT_ASSERT_EQUAL(ans[i], out[i]);
|
CPPUNIT_ASSERT_EQUAL(ans[i], out[i]);
|
||||||
}
|
}
|
||||||
out.clear();
|
out.clear();
|
||||||
CPPUNIT_ASSERT(bt.getFirstNMissingUnusedIndex(out, 3));
|
CPPUNIT_ASSERT_EQUAL((size_t)3, bt.getFirstNMissingUnusedIndex(out, 3));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)3, out.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)3, out.size());
|
||||||
for(size_t i = 0; i < out.size(); ++i) {
|
for(size_t i = 0; i < out.size(); ++i) {
|
||||||
CPPUNIT_ASSERT_EQUAL(ans[i], out[i]);
|
CPPUNIT_ASSERT_EQUAL(ans[i], out[i]);
|
||||||
}
|
}
|
||||||
CPPUNIT_ASSERT(!bt.getFirstNMissingUnusedIndex(out, 0));
|
CPPUNIT_ASSERT_EQUAL((size_t)0, bt.getFirstNMissingUnusedIndex(out, 0));
|
||||||
bt.setAllBit();
|
bt.setAllBit();
|
||||||
CPPUNIT_ASSERT(!bt.getFirstNMissingUnusedIndex(out, 10));
|
CPPUNIT_ASSERT_EQUAL((size_t)0, bt.getFirstNMissingUnusedIndex(out, 10));
|
||||||
bt.clearAllBit();
|
bt.clearAllBit();
|
||||||
out.clear();
|
out.clear();
|
||||||
bt.addFilter(1024*9, 1024);
|
bt.addFilter(1024*9, 1024);
|
||||||
bt.enableFilter();
|
bt.enableFilter();
|
||||||
CPPUNIT_ASSERT(bt.getFirstNMissingUnusedIndex(out, 256));
|
CPPUNIT_ASSERT_EQUAL((size_t)1, bt.getFirstNMissingUnusedIndex(out, 256));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, out.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1, out.size());
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)9, out[0]);
|
CPPUNIT_ASSERT_EQUAL((size_t)9, out[0]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue