diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2006-05-24 15:18:58 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2006-05-24 15:18:58 +0000 |
| commit | 0411de92716bbdefa5dc795f1ecb8a2c2d61004e (patch) | |
| tree | 374ffa60e707f21a17d3e599459e6614eda98489 /src/BitfieldMan.cc | |
| parent | 896ca193e01f9f629f222fe992e05aebdca23a24 (diff) | |
2006-05-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To attempt to handle EINTR:
* src/SocketCore.cc
(isReadable): Added EINTR handling.
(isWritable): Added EINTR handling.
To improve the performance:
* src/AbstractCommand.cc
(isTimeoutDetected): Use Util::difftvsec() instead of
Util::difftv().
* src/PeerInteractionCommand.h
(receiveMessage): Renamed as receiveMessages().
(receiveMessages): New function.
* src/PeerInteractionCommand.cc
(executeInternal): receiveMessage loop is moved to new
receiveMessages
() function. detectMessageFlooding() is moved here.
(detectMessageFlooding): Use Util::difftvsec() instead of
Util::difftv
(). The flooding detection for have message is comment out.
(checkLongTimePeerChoking): Use Util::difftvsec() instead of
Util::difftv().
(receiveMessage): Renamed as receiveMessages().
(receiveMessages): New function.
(keepAlive): Use Util::difftvsec() instead of Util::difftv().
(beforeSocketCheck): Commented out checkLongTimePeerChoking().
* src/SleepCommand.cc
(execute): Use Util::difftvsec() instead of Util::difftv().
* src/BitfieldMan.h
(getNthBitIndex): New function.
(hasMissingPiece): New function.
(getAllMissingIndexes): New function.
* src/BitfieldMan.cc
(countSetBit): Rewritten.
(getNthBitIndex): New function.
(getMissingIndexRandomly): Rewritten.
(hasMissingPiece): New function.
(getAllMissingIndexes): New function.
* src/TorrentMan.cc
(hasMissingPiece): New function.
(deleteUsedPiece): Rewritten using STL.
* src/PeerInteraction.cc
(getNewPieceAndSendInterest): Use TorrentMan::hasMissingPiece(),
which
is a little bit faster then TorrentMan::getMissingPieceIndex().
(addRequests): Updated the number of pending requests.
* src/PeerAbstractCommand.cc
(isTimeoutDetected): Use Util::difftvsec() instead of
Util::difftv().
(execute): Returns true if TorrentMan::isHalt() is true.
Corrected the condition of upload limit checking.
* src/Util.h
(countBit): New function.
* src/Util.cc
(nbits): New variable.
(countBit): New function.
* src/DownloadEngine.h
(SockCmdMap): New type definition.
(waitData): Added an argument.
(addSocket): Added an argument.
(addSocketForReadCheck): Added an argument.
(addSocketForWriteCheck): Added an argument.
* src/DownloadEngine.cc
(run): Executes only commands whose sockets are ready to read or
write.
All commands are executed in every 1 second.
(waitData): Calls select() again if it returned
EINTR.
(addSocket): Saves socket and command object pair to the map.
(deleteSocket): Deletes socket and command object pair from the
map.
(addSocketForReadCheck): Added an argument.
(addSocketForWriteCheck): Added an argument.
* src/DownloadCommand.cc
(executeInternal): Use Util::difftvsec() instead of
Util::difftv().
To send "event=stopped" to the tracker when the application
finishes:
* src/PeerChokeCommand.h
(checkPoint): New variable.
* src/PeerChokeCommand.cc
(PeerChokeCommand): Added the initialization of checkPoint.
(execute): The interval check is now done by checkPoint, not
SleepCommand. Return true if TorrentMan::isHalt() is true.
* src/TorrentMan.h
(halt): New function.
(hasMissingPiece): New function.
(isHalt): New function.
(setHalt): New function.
* src/TorrentMan.cc
(TorrentMan): Added the initialization of halt.
* src/TorrentAutoSaveCommand.h
(checkPoint): New variable.
* src/PeerListenCommand.cc
(execute): Returns true if TorrentMan::isHalt() is true.
* src/main.cc
(setSignalHander): Added flags argument.
(torrentHandler): Just calls TorrentMan::setHalt(true) and
returns.
(main): Set SA_ONESHOT flag of the signal hander of SIGINT and
SIGTERM.
Removed printDownloadAbortMessage() after torrent downloading
loop.
* src/TorrentAutoSaveCommand.cc
(TorrentAutoSaveCommand): Added the initialization of
checkPoint.
(execute): Returns true if TorrentMan::isHalt() is true.
The interval check is now done by checkPoint, not SleepCommand.
* src/TrackerWatcherCommand.cc
(execute): If TorrentMan::isHalt(), then create a tracker
request with
event=stopped.
* src/TrackerUpdateCommand.cc
(prepareForRetry): Do not use SleepCommand here.
(execute): Returns true if TorrentMan::isHalt() is true.
Others:
* src/TorrentMan.cc
(getMissingPieceIndex): Updated log message.
* src/PeerInteraction.cc
(createPeerMessag): Updated log message.
Diffstat (limited to 'src/BitfieldMan.cc')
| -rw-r--r-- | src/BitfieldMan.cc | 95 |
1 files changed, 84 insertions, 11 deletions
diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc index c5c120f9..0e32f912 100644 --- a/src/BitfieldMan.cc +++ b/src/BitfieldMan.cc @@ -20,6 +20,7 @@ */ /* copyright --> */ #include "BitfieldMan.h" +#include "Util.h" #include <string.h> BitfieldMan::BitfieldMan(int blockLength, long long int totalLength) @@ -92,24 +93,21 @@ BitfieldMan& BitfieldMan::operator=(const BitfieldMan& bitfieldMan) { int BitfieldMan::countSetBit(const unsigned char* bitfield, int len) const { int count = 0; - for(int i = 0; i < len; i++) { - unsigned char bit = bitfield[i]; - for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { - unsigned char mask = 1 << bs; - if(bit & mask) { - count++; - } - } + int size = sizeof(unsigned int); + for(int i = 0; i < len/size; i++) { + count += Util::countBit(*(unsigned int*)&bitfield[i*size]); + } + for(int i = len-len%size; i < len; i++) { + count += Util::countBit((unsigned int)bitfield[i]); } return count; } -int BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield, int len, int randMax) const { +int BitfieldMan::getNthBitIndex(const unsigned char* bitfield, int len, int nth) const { int index = -1; - int nth = 1+(int)(((double)randMax)*random()/(RAND_MAX+1.0)); for(int i = 0; i < len && index == -1; i++) { unsigned char bit = bitfield[i]; - for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + for(int bs = 7; bs >= 0; bs--) { unsigned char mask = 1 << bs; if(bit & mask) { nth--; @@ -123,6 +121,61 @@ int BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield, int len, return index; } +int BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield, int len, int randMax) const { + int nth = 1+(int)(((double)randMax)*random()/(RAND_MAX+1.0)); + + int count = 0; + int size = sizeof(unsigned int); + for(int i = 0; i < len/size; i++) { + int temp = Util::countBit(*(unsigned int*)&bitfield[i*size]); + if(nth <= count+temp) { + int t = i*size*8+getNthBitIndex(&bitfield[i*size], size, nth-count); + return t; + } else { + count += temp; + } + } + for(int i = len-len%size; i < len; i++) { + int temp = Util::countBit((unsigned int)bitfield[i]); + if(nth <= count+temp) { + int t = i*8+getNthBitIndex(&bitfield[i], 1, nth-count); + return t; + } else { + count += temp; + } + } + return -1; +} + +bool BitfieldMan::hasMissingPiece(const unsigned char* peerBitfield, int length) const { + if(bitfieldLength != length) { + return false; + } + unsigned char* tempBitfield = new unsigned char[bitfieldLength]; + for(int i = 0; i < bitfieldLength; i++) { + tempBitfield[i] = peerBitfield[i] & ~bitfield[i]; + if(filterEnabled) { + tempBitfield[i] &= filterBitfield[i]; + } + } + bool retval = false; + int size = sizeof(unsigned int); + for(int i = 0; i < length/size; i++) { + if(Util::countBit(*(unsigned int*)&tempBitfield[i*size]) > 0) { + retval = true; + break; + } + } + for(int i = length-length%size; i < length && retval == false; i++) { + if(Util::countBit((unsigned int)tempBitfield[i]) > 0) { + retval = true; + break; + } + } + delete [] tempBitfield; + return retval; +} + int BitfieldMan::getMissingIndex(const unsigned char* peerBitfield, int length) const { if(bitfieldLength != length) { return -1; @@ -223,6 +276,26 @@ BlockIndexes BitfieldMan::getAllMissingIndexes() const { return missingIndexes; } +BlockIndexes BitfieldMan::getAllMissingIndexes(const unsigned char* peerBitfield, int peerBitfieldLength) const { + BlockIndexes missingIndexes; + if(bitfieldLength != peerBitfieldLength) { + return missingIndexes; + } + for(int i = 0; i < bitfieldLength; i++) { + unsigned char bit = peerBitfield[i] & ~bitfield[i]; + if(filterEnabled) { + bit &= filterBitfield[i]; + } + for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + unsigned char mask = 1 << bs; + if(bit & mask) { + missingIndexes.push_back(i*8+7-bs); + } + } + } + return missingIndexes; +} + int BitfieldMan::countMissingBlock() const { if(filterEnabled) { unsigned char* temp = new unsigned char[bitfieldLength]; |
