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>
|
||||
|
||||
Added more tests.
|
||||
|
|
|
@ -268,44 +268,17 @@ bool BitfieldMan::getFirstMissingUnusedIndex(size_t& index) const
|
|||
}
|
||||
}
|
||||
|
||||
template<typename Array, typename OutputIterator>
|
||||
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
|
||||
size_t BitfieldMan::getFirstNMissingUnusedIndex
|
||||
(std::vector<size_t>& out, size_t n) const
|
||||
{
|
||||
if(filterEnabled) {
|
||||
return getFirstNMissingIndex
|
||||
return bitfield::getFirstNMissingIndex
|
||||
(std::back_inserter(out), n,
|
||||
~array(bitfield)&~array(useBitfield)&array(filterBitfield),
|
||||
bitfieldLength, blocks);
|
||||
~array(bitfield)&~array(useBitfield)&array(filterBitfield), blocks);
|
||||
} else {
|
||||
return getFirstNMissingIndex
|
||||
return bitfield::getFirstNMissingIndex
|
||||
(std::back_inserter(out), n,
|
||||
~array(bitfield)&~array(useBitfield),
|
||||
bitfieldLength, blocks);
|
||||
~array(bitfield)&~array(useBitfield), blocks);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -147,12 +147,13 @@ public:
|
|||
*/
|
||||
bool getFirstMissingUnusedIndex(size_t& index) const;
|
||||
/**
|
||||
* Stores at most n missing unused index in out. This function
|
||||
* doesn't delete existing elements in out.
|
||||
* Appends at most n missing unused index to out. This function
|
||||
* doesn't delete existing elements in out. Returns the number of
|
||||
* appended elements.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
|
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
|
||||
{
|
||||
if(bitfield->getFirstNMissingUnusedIndex(indexes, n)) {
|
||||
for(std::vector<size_t>::const_iterator i = indexes.begin();
|
||||
size_t num = bitfield->getFirstNMissingUnusedIndex(indexes, n);
|
||||
if(num) {
|
||||
for(std::vector<size_t>::const_iterator i = indexes.end()-num;
|
||||
i != indexes.end(); ++i) {
|
||||
bitfield->setUseBit(*i);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
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
|
||||
bool getMissingUnusedBlockIndex(size_t& index) const;
|
||||
|
||||
// Stores at most n missing unused block index to indexes. For all i
|
||||
// in indexes, call bitfield->setUseBit(i). This function just add
|
||||
// index to indexes and it doesn't remove anything from
|
||||
// it. Therefore Caller must pass empty indexes.
|
||||
bool getMissingUnusedBlockIndex(std::vector<size_t>& indexes, size_t n) const;
|
||||
// Appends at most n missing unused block index to indexes. For all
|
||||
// i in retrieved indexes, call bitfield->setUseBit(i). This
|
||||
// function just append index to indexes and it doesn't remove
|
||||
// anything from it. Returns the number of indexes to retrieved.
|
||||
size_t getMissingUnusedBlockIndex
|
||||
(std::vector<size_t>& indexes, size_t n) const;
|
||||
|
||||
bool getFirstMissingBlockIndexWithoutLock(size_t& index) const;
|
||||
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);
|
||||
|
||||
// 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 aria2
|
||||
|
|
|
@ -852,26 +852,26 @@ void BitfieldManTest::testGetFirstNMissingUnusedIndex()
|
|||
bt.setUseBit(1);
|
||||
bt.setBit(5);
|
||||
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());
|
||||
const size_t ans[] = {0, 2, 3, 4, 6, 7, 8, 9};
|
||||
for(size_t i = 0; i < out.size(); ++i) {
|
||||
CPPUNIT_ASSERT_EQUAL(ans[i], out[i]);
|
||||
}
|
||||
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());
|
||||
for(size_t i = 0; i < out.size(); ++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();
|
||||
CPPUNIT_ASSERT(!bt.getFirstNMissingUnusedIndex(out, 10));
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)0, bt.getFirstNMissingUnusedIndex(out, 10));
|
||||
bt.clearAllBit();
|
||||
out.clear();
|
||||
bt.addFilter(1024*9, 1024);
|
||||
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)9, out[0]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue