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
	
	 Tatsuhiro Tsujikawa
						Tatsuhiro Tsujikawa