mirror of https://github.com/aria2/aria2
2007-02-06 Tatsuhiro Tsujikawa <tujikawa dot rednoah dot com>
To fix the bug that causes crash on Max OS X: * src/SimpleRandomizer.h (getInstance): Create new instance if the static variable is null. * src/SimpleRandomizer.cc (randomizer): Initialized to 0. * src/BitfieldManFactory.h (getNewFactory): Removed the call to setRandomizer(). To fix the miscalculation of the range of checksum: * src/BitfieldMan.h (isBitSetOffsetRange): New function. * src/BitfieldMan.cc (isBitSetOffsetRange): New function. * src/SegmentMan.cc (tryChunkChecksumValidation): Use BitfieldMan::isBitSetOffsetRange(). Use bitfield->getBlockLength() instead of segment.segmentLength.pull/1/head
parent
a4e7bd7ec4
commit
5b2f8f036e
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
|||
2007-02-06 Tatsuhiro Tsujikawa <tujikawa dot rednoah dot com>
|
||||
|
||||
To fix the bug that causes crash on Max OS X:
|
||||
|
||||
* src/SimpleRandomizer.h
|
||||
(getInstance): Create new instance if the static variable is null.
|
||||
* src/SimpleRandomizer.cc
|
||||
(randomizer): Initialized to 0.
|
||||
* src/BitfieldManFactory.h
|
||||
(getNewFactory): Removed the call to setRandomizer().
|
||||
|
||||
To fix the miscalculation of the range of checksum:
|
||||
|
||||
* src/BitfieldMan.h
|
||||
(isBitSetOffsetRange): New function.
|
||||
* src/BitfieldMan.cc
|
||||
(isBitSetOffsetRange): New function.
|
||||
* src/SegmentMan.cc
|
||||
(tryChunkChecksumValidation): Use BitfieldMan::isBitSetOffsetRange().
|
||||
Use bitfield->getBlockLength() instead of segment.segmentLength.
|
||||
|
||||
2007-02-03 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
To lower CPU usage in BitTorrent download when --max-upload-limit
|
||||
|
|
|
@ -644,3 +644,24 @@ void BitfieldMan::unsetBitRange(int32_t startIndex, int32_t endIndex)
|
|||
}
|
||||
updateCache();
|
||||
}
|
||||
|
||||
bool BitfieldMan::isBitSetOffsetRange(int64_t offset, int64_t length) const
|
||||
{
|
||||
if(length <= 0) {
|
||||
return false;
|
||||
}
|
||||
if(totalLength <= offset) {
|
||||
return false;
|
||||
}
|
||||
if(totalLength < offset+length) {
|
||||
length = totalLength-offset;
|
||||
}
|
||||
int32_t startBlock = offset/blockLength;
|
||||
int32_t endBlock = (offset+length-1)/blockLength;
|
||||
for(int32_t i = startBlock; i <= endBlock; i++) {
|
||||
if(!isBitSet(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -254,6 +254,9 @@ public:
|
|||
bool isBitRangeSet(int32_t startIndex, int32_t endIndex) const;
|
||||
|
||||
void unsetBitRange(int32_t startIndex, int32_t endIndex);
|
||||
|
||||
bool isBitSetOffsetRange(int64_t offset, int64_t length) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // _D_BITFIELD_MAN_H_
|
||||
|
|
|
@ -53,9 +53,7 @@ public:
|
|||
~BitfieldManFactory() {}
|
||||
|
||||
static BitfieldManFactoryHandle getNewFactory() {
|
||||
BitfieldManFactoryHandle factory =
|
||||
BitfieldManFactoryHandle(new BitfieldManFactory());
|
||||
factory->setRandomizer(defaultRandomizer);
|
||||
BitfieldManFactoryHandle factory = new BitfieldManFactory();
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
|
|
@ -497,10 +497,12 @@ void SegmentMan::tryChunkChecksumValidation(const Segment& segment)
|
|||
segment.getPosition(),
|
||||
segment.writtenLength,
|
||||
chunkHashLength);
|
||||
if(hashStartIndex*chunkHashLength < segment.getPosition() && !bitfield->isBitSet(segment.index-1)) {
|
||||
if(!bitfield->isBitSetOffsetRange((int64_t)hashStartIndex*chunkHashLength,
|
||||
chunkHashLength)) {
|
||||
++hashStartIndex;
|
||||
}
|
||||
if(hashEndIndex*(chunkHashLength+1) > segment.getPosition()+segment.segmentLength && !bitfield->isBitSet(segment.index+1)) {
|
||||
if(!bitfield->isBitSetOffsetRange((int64_t)hashEndIndex*chunkHashLength,
|
||||
chunkHashLength)) {
|
||||
--hashEndIndex;
|
||||
}
|
||||
logger->debug("hashStartIndex=%d, hashEndIndex=%d",
|
||||
|
@ -515,7 +517,7 @@ void SegmentMan::tryChunkChecksumValidation(const Segment& segment)
|
|||
Util::indexRange(startIndex, endIndex,
|
||||
hashOffset,
|
||||
(hashEndIndex-hashStartIndex+1)*chunkHashLength,
|
||||
segment.segmentLength);
|
||||
bitfield->getBlockLength());
|
||||
logger->debug("startIndex=%d, endIndex=%d", startIndex, endIndex);
|
||||
if(bitfield->isBitRangeSet(startIndex, endIndex)) {
|
||||
for(int32_t index = hashStartIndex; index <= hashEndIndex; ++index) {
|
||||
|
|
|
@ -34,4 +34,4 @@
|
|||
/* copyright --> */
|
||||
#include "SimpleRandomizer.h"
|
||||
|
||||
RandomizerHandle SimpleRandomizer::randomizer = RandomizerHandle(new SimpleRandomizer());
|
||||
RandomizerHandle SimpleRandomizer::randomizer = 0;
|
||||
|
|
|
@ -47,11 +47,14 @@ private:
|
|||
public:
|
||||
|
||||
static RandomizerHandle getInstance() {
|
||||
if(randomizer.isNull()) {
|
||||
randomizer = new SimpleRandomizer();
|
||||
}
|
||||
return randomizer;
|
||||
}
|
||||
|
||||
static void init() {
|
||||
srandom(time(NULL));
|
||||
srandom(time(0));
|
||||
}
|
||||
|
||||
virtual ~SimpleRandomizer() {}
|
||||
|
|
|
@ -15,6 +15,7 @@ class BitfieldManTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testFilter);
|
||||
CPPUNIT_TEST(testGetMissingIndex);
|
||||
CPPUNIT_TEST(testGetSparceMissingUnusedIndex);
|
||||
CPPUNIT_TEST(testIsBitSetOffsetRange);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
RandomizerHandle fixedNumberRandomizer;
|
||||
|
@ -35,6 +36,7 @@ public:
|
|||
void testFilter();
|
||||
void testGetMissingIndex();
|
||||
void testGetSparceMissingUnusedIndex();
|
||||
void testIsBitSetOffsetRange();
|
||||
};
|
||||
|
||||
|
||||
|
@ -233,3 +235,35 @@ void BitfieldManTest::testGetSparceMissingUnusedIndex() {
|
|||
bitfield.setBit(9);
|
||||
CPPUNIT_ASSERT_EQUAL(-1, bitfield.getSparseMissingUnusedIndex());
|
||||
}
|
||||
|
||||
void BitfieldManTest::testIsBitSetOffsetRange()
|
||||
{
|
||||
int64_t totalLength = (int64_t)4*1024*1024*1024;
|
||||
int32_t pieceLength = 4*1024*1024;
|
||||
BitfieldMan bitfield(pieceLength, totalLength);
|
||||
bitfield.setAllBit();
|
||||
|
||||
CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(0, 0));
|
||||
CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(0, -1));
|
||||
CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(totalLength, 100));
|
||||
CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(totalLength+1, 100));
|
||||
|
||||
CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(0, totalLength));
|
||||
CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(0, totalLength+1));
|
||||
|
||||
bitfield.clearAllBit();
|
||||
|
||||
bitfield.setBit(100);
|
||||
bitfield.setBit(101);
|
||||
|
||||
CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*2));
|
||||
CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100-10, pieceLength*2));
|
||||
CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*2+1));
|
||||
|
||||
bitfield.clearAllBit();
|
||||
|
||||
bitfield.setBit(100);
|
||||
bitfield.setBit(102);
|
||||
|
||||
CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*3));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue