From e3e3f0438dc80b696a926dc87b82ed288ef0313b Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 11 Feb 2010 07:24:06 +0000 Subject: [PATCH] 2010-02-11 Tatsuhiro Tsujikawa 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 --- ChangeLog | 11 +++++++++++ src/BitfieldMan.cc | 37 +++++-------------------------------- src/BitfieldMan.h | 7 ++++--- src/Piece.cc | 11 +++++------ src/Piece.h | 11 ++++++----- src/bitfield.h | 26 ++++++++++++++++++++++++++ test/BitfieldManTest.cc | 10 +++++----- 7 files changed, 62 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3949936..e0a8a8f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-02-11 Tatsuhiro Tsujikawa + + 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 Added more tests. diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc index a11dcee8..2ab00812 100644 --- a/src/BitfieldMan.cc +++ b/src/BitfieldMan.cc @@ -268,44 +268,17 @@ bool BitfieldMan::getFirstMissingUnusedIndex(size_t& index) const } } -template -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& 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); } } diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h index 11ba95c5..0a6c3359 100644 --- a/src/BitfieldMan.h +++ b/src/BitfieldMan.h @@ -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& out, size_t n) const; + size_t getFirstNMissingUnusedIndex(std::vector& out, size_t n) const; /** * affected by filter */ diff --git a/src/Piece.cc b/src/Piece.cc index 2d5a689b..79c848da 100644 --- a/src/Piece.cc +++ b/src/Piece.cc @@ -173,18 +173,17 @@ bool Piece::getMissingUnusedBlockIndex(size_t& index) const } } -bool Piece::getMissingUnusedBlockIndex +size_t Piece::getMissingUnusedBlockIndex (std::vector& indexes, size_t n) const { - if(bitfield->getFirstNMissingUnusedIndex(indexes, n)) { - for(std::vector::const_iterator i = indexes.begin(); + size_t num = bitfield->getFirstNMissingUnusedIndex(indexes, n); + if(num) { + for(std::vector::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 diff --git a/src/Piece.h b/src/Piece.h index 3177ac89..af2a7a92 100644 --- a/src/Piece.h +++ b/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& 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& indexes, size_t n) const; bool getFirstMissingBlockIndexWithoutLock(size_t& index) const; bool getAllMissingBlockIndexes(unsigned char* misbitfield, diff --git a/src/bitfield.h b/src/bitfield.h index e4088b88..0a253124 100644 --- a/src/bitfield.h +++ b/src/bitfield.h @@ -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 +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 diff --git a/test/BitfieldManTest.cc b/test/BitfieldManTest.cc index d9fff894..76f7aa9a 100644 --- a/test/BitfieldManTest.cc +++ b/test/BitfieldManTest.cc @@ -852,26 +852,26 @@ void BitfieldManTest::testGetFirstNMissingUnusedIndex() bt.setUseBit(1); bt.setBit(5); std::vector 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]); }