From a1df7a762e67e24699611f11aa836b7bbe15faab Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 16 Jan 2007 15:20:26 +0000 Subject: [PATCH] 2007-01-16 Tatsuhiro Tsujikawa To decrease CPU usage in bittorrent download, calculation results in BitfieldMan were cached and realtime fetching PeerObject was removed with WeakHandle introduced. Option values are set to the objects by setter before download begins. * src/DefaultBtRequestFactory.cc: Use messageFactory member. * src/DefaultBtRequestFactory.h (dispatcher): BtMessageDispatcherHandle -> BtMessageDispatcherWeakHandle. (messageFactory): New variable. (setBtMessageDispatcher): BtMessageDispatcherHandle -> BtMessageDispatcherWeakHandle. (setBtMessageFactory): New function. * src/DefaultBtMessageDispatcher.cc: (sendMessages): Use maxUploadSpeedLimit instead of fetching the value from Option. (checkRequestSlotAndDoNecessaryThing): Use requestTimeout instead of feating the value from Option. Use messageFactory member. * src/PeerInteractionCommand.cc (PeerInteractionCommand): Added maxDownloadSpeedLimit. Add reverse dependencies to factory object. Set maxUploadSpeedLimit and requestTimeout and messageFactory to dispatcher. Set messageFactory to receiver. Set keepAliveInterval and maxDownloadSpeedLimit and messageFactory to btInteractive. Set receiver to peerObject. Set maxDownloadSpeedLimit to this. (executeInternal): Use maxDownloadSpeedLimit member. * src/BtChokeMessage.cc (doReceivedAction): Use dispatcher, requestFactory member. (onSendComplete): Use dispatcher member. * src/PeerInteractionCommand.h (maxDownloadSpeedLimit): New variable. * src/DefaultBtMessageReceiver.h (peerConnection): PeerConnectionHandle -> PeerConnectionWeakHandle (dispatcher): BtMessageDispatcherHandle -> BtMessageDispatcherWeakHandle (messageFactory): New variable. (setPeerConnection): PeerConnectionHandle -> PeerConnectionWeakHandle (getPeerConnection): PeerConnectionHandle -> PeerConnectionWeakHandle (setDispatcher): BtMessageDispatcherHandle -> BtMessageDispatcherWeakHandle (setBtMessageFactory): New function. * src/DefaultBtInteractive.cc (initiateHandshake): Use messageFactory member. (addBitfieldMessageToQueue): Use messageFactory member. (addAllowedFastMessageToQueue): Use messageFactory member. (decideChoking): Use messageFactory member. (checkHave): Use messageFactory member. (sendKeepAlive): Use keepAliveInterval, messageFactory member. (receiveMessages): Use maxDownloadSpeedLimit member. (decideInterest): Use messageFactory member. * src/BtRequestMessage.cc (doReceivedAction): Use messageFactory, dispatcher member. (onQueued): Use dispatcher member. * src/BtPieceMessage.cc (doReceivedAction): Use dispatcher member. (send): Use peerConnection member. (onWrongPiece): Use requestFactory member. (handleChokingEvent): Use messageFactory, dispatcher member. (handleCancelSendingPieceEvent): Use messageFactory, dispatcher member. * src/BtMessageDispatcher.h (BtMessageDispatcherWeakHandle): New type definition. * src/SimpleBtMessage.cc (send): Use peerConnection member. * src/BtRejectMessage.cc (doReceivedAction): Use dispatcher member. * src/DefaultBtMessageDispatcher.h (Option.h): Removed include. (messageFactory): New variable. (option): Removed. (maxUploadSpeedLimit): New variable. (requestTimeout): New variable. (DefaultBtMessageDispatcher): Removed option. Added maxUploadSpeedLimit, requestTimeout. (setOption): Removed. (getOption): Removed. (setMaxUploadSpeedLimit): New function. (setRequestTimeout): New function. (setBtMessageFactory): New function. * src/DefaultBtInteractive.h (btMessageReceiver): BtMessageReceiverHandle -> BtMessageReceiverWeakHandle (dispatcher): BtMessageDispatcherHandle -> BtMessageReceiverWeakHandle (btRequestFactory): BtRequestFactoryHandle -> BtRequestFactoryWeakHandle (peerConnection): PeerConnectionHandle -> PeerConnectionWeakHandle (messageFactory): New variable. (option): Removed. (keepAliveInterval): New variable. (maxDownloadSpeedLimit): New variable. (DefaultBtInteractive): Added keepAliveInterval, maxDownloadSpeedLimit. (setBtMessageReceiver): BtMessageReceiverHandle -> BtMessageReceiverWeakHandle (setDispatcher): BtMessageDispatcherHandle -> BtMessageReceiverWeakHandle (setBtRequestFactory): BtRequestFactoryHandle -> BtRequestFactoryWeakHandle (setPeerConnection): PeerConnectionHandle -> PeerConnectionWeakHandle (setOption): Removed. (setKeepAliveInterval): New function. (setMaxDownloadSpeedLimit): New function. (setBtMessageFactory): New function. * src/BitfieldMan.h (cachedNumMissingBlock): New variable. (cachedNumFilteredBlock): New variable. (cachedCompletedLength): New variable. (cachedFilteredComletedLength): New variable. (cachedFilteredTotalLength): New variable. (countMissingBlockNow): New function. (countFilteredBlockNow): New function. (getFilteredTotalLengthNow): New function. (getCompletedLengthNow): New function. (getFilteredCompletedLengthNow): New function. (updateCache): New function. * src/AbstractBtMessage.h (BtMessageDispatcher.h): New include. (PeerConnection.h): New include. (BtRequestFactory.h): New include (BtMessageFactory.h): New include. (dispatcher): New variable. (messageFactory): New variable. (peerConnection: New variable. (setBtMessageDispatcher): New function. (setPeerConnection): New function. (setBtMessageFactory): New function. (setBtRequestFactory): New function. * src/DefaultBtMessageFactory.cc (setCommonProperty): Set dispatcher, requestFactory, this, peerConnection to msg. * src/BtRegistry.h (BT_MESSAGE_RECEIVER): New macro. * src/PeerConnection.h (PeerConnectionWeakHandle): New type definition. * src/BtMessageFactory.h (BtMessageFactoryWeakHandle): New type definition. * src/BitfieldMan.cc (BitfieldMan): Added cachedNumMissingBlock, cachedNumFilteredBlock, cachedCompletedLength, cachedFilteredComletedLength, cachedFilteredTotalLength. Call updateCache(). (countMissingBlock): Return cachedNumMissingBlock. (countMissingBlockNow): New function. (countBlock): Return cachedNumFilteredBlock if filterEnabled is true. (countFilteredBlockNow): New function. (setBit): Call updateCache(). (unsetBit): Call updateCache(). (setBitfield): Call updateCache(). (clearAllBit): Call updateCache(). (setAllBit): Use setBitInternal instead of setBit. Call updateCache(). (addFilter): Call updateCache(). (enableFilter): Call updateCache(). (disableFilter): Call updateCache(). (clearFilter): Call updateCache(). (getFilteredTotalLength): Return cachedFilteredTotalLength. (getFilteredTotalLengthNow): New function. (getCompletedLength): Return cachedCompletedLength. (getCompletedLengthNow): New function. (getFilteredCompletedLength): Return cachedFilteredComletedLength. (getFilteredCompletedLengthNow): New function. (updateCache): New function. * src/BtMessageReceiver.h (BtMessageReceiverWeakHandle): New type definition. * src/DefaultBtMessageReceiver.cc (receiveHandshake): Use messageFactory member. (sendHandshake): Use messageFactory member. (receiveMessage): Use messageFactory member. * src/DefaultBtMessageFactory.h (dispatcher): New variable. (requestFactory): New variable. (peerConnection): New variablle. (setBtMessageDispatcher): New function. (setBtRequestFactory): New function. (setPeerConnection): New function. * src/SharedHandle.h (RefCount): New class. (WeakHandle): New class. * src/PeerObject.h (BtMessageReceiver.h): New include. (PeerObject): Added btMessageReceiver. (btMessageReceiver): New variable. * src/Util.cc (countBit): Simplified. * src/BtCancelMessage.cc (doReceivedAction): Use dispatcher member. * src/BtRequestFactory.h (BtRequestFactoryWeakHandle): New type definition. * src/PeerStorage.h (downloadSpeed): int -> uint32_t (uploadSpeed): int -> uint32_t (sessionDownloadLength): long long int -> uint64_t (sessionUploadLength): long long int -> uint64_t --- ChangeLog | 202 ++++++++++++++++++++ TODO | 3 +- src/AbstractBtMessage.h | 28 +++ src/BitfieldMan.cc | 71 ++++++- src/BitfieldMan.h | 29 +++ src/BtCancelMessage.cc | 2 +- src/BtChokeMessage.cc | 6 +- src/BtMessageDispatcher.h | 2 +- src/BtMessageFactory.h | 2 +- src/BtMessageReceiver.h | 1 + src/BtPieceMessage.cc | 35 ++-- src/BtRegistry.h | 3 + src/BtRejectMessage.cc | 5 +- src/BtRequestFactory.h | 1 + src/BtRequestMessage.cc | 20 +- src/DefaultBtInteractive.cc | 46 ++--- src/DefaultBtInteractive.h | 44 +++-- src/DefaultBtMessageDispatcher.cc | 14 +- src/DefaultBtMessageDispatcher.h | 40 ++-- src/DefaultBtMessageFactory.cc | 6 +- src/DefaultBtMessageFactory.h | 20 ++ src/DefaultBtMessageReceiver.cc | 10 +- src/DefaultBtMessageReceiver.h | 15 +- src/DefaultBtRequestFactory.cc | 6 +- src/DefaultBtRequestFactory.h | 10 +- src/PeerConnection.h | 2 +- src/PeerInteractionCommand.cc | 36 ++-- src/PeerInteractionCommand.h | 1 + src/PeerObject.h | 3 + src/PeerStorage.h | 24 +-- src/SharedHandle.h | 255 +++++++++++++++++++++---- src/SimpleBtMessage.cc | 2 +- src/Util.cc | 17 +- test/BtCancelMessageTest.cc | 2 +- test/BtChokeMessageTest.cc | 22 ++- test/BtPieceMessageTest.cc | 2 + test/BtRejectMessageTest.cc | 2 +- test/BtRequestMessageTest.cc | 2 + test/DefaultBtMessageDispatcherTest.cc | 29 ++- test/DefaultBtRequestFactoryTest.cc | 1 + test/MockBtRequestFactory.h | 30 +++ 41 files changed, 813 insertions(+), 238 deletions(-) create mode 100644 test/MockBtRequestFactory.h diff --git a/ChangeLog b/ChangeLog index 1ab6f77d..ef41ce86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,205 @@ +2007-01-16 Tatsuhiro Tsujikawa + + To decrease CPU usage in bittorrent download, calculation results in + BitfieldMan were cached and realtime fetching PeerObject was removed + with WeakHandle introduced. Option values are set to the objects + by setter before download begins. + + * src/DefaultBtRequestFactory.cc: Use messageFactory member. + * src/DefaultBtRequestFactory.h + (dispatcher): BtMessageDispatcherHandle -> + BtMessageDispatcherWeakHandle. + (messageFactory): New variable. + (setBtMessageDispatcher): BtMessageDispatcherHandle -> + BtMessageDispatcherWeakHandle. + (setBtMessageFactory): New function. + * src/DefaultBtMessageDispatcher.cc: + (sendMessages): Use maxUploadSpeedLimit instead of fetching the value + from Option. + (checkRequestSlotAndDoNecessaryThing): Use requestTimeout instead of + feating the value from Option. + Use messageFactory member. + * src/PeerInteractionCommand.cc + (PeerInteractionCommand): Added maxDownloadSpeedLimit. + Add reverse dependencies to factory object. + Set maxUploadSpeedLimit and requestTimeout and messageFactory to + dispatcher. + Set messageFactory to receiver. + Set keepAliveInterval and maxDownloadSpeedLimit and messageFactory to + btInteractive. + Set receiver to peerObject. + Set maxDownloadSpeedLimit to this. + (executeInternal): Use maxDownloadSpeedLimit member. + * src/BtChokeMessage.cc + (doReceivedAction): Use dispatcher, requestFactory member. + (onSendComplete): Use dispatcher member. + * src/PeerInteractionCommand.h + (maxDownloadSpeedLimit): New variable. + * src/DefaultBtMessageReceiver.h + (peerConnection): PeerConnectionHandle -> PeerConnectionWeakHandle + (dispatcher): + BtMessageDispatcherHandle -> BtMessageDispatcherWeakHandle + (messageFactory): New variable. + (setPeerConnection): PeerConnectionHandle -> PeerConnectionWeakHandle + (getPeerConnection): PeerConnectionHandle -> PeerConnectionWeakHandle + (setDispatcher): + BtMessageDispatcherHandle -> BtMessageDispatcherWeakHandle + (setBtMessageFactory): New function. + * src/DefaultBtInteractive.cc + (initiateHandshake): Use messageFactory member. + (addBitfieldMessageToQueue): Use messageFactory member. + (addAllowedFastMessageToQueue): Use messageFactory member. + (decideChoking): Use messageFactory member. + (checkHave): Use messageFactory member. + (sendKeepAlive): Use keepAliveInterval, messageFactory member. + (receiveMessages): Use maxDownloadSpeedLimit member. + (decideInterest): Use messageFactory member. + * src/BtRequestMessage.cc + (doReceivedAction): Use messageFactory, dispatcher member. + (onQueued): Use dispatcher member. + * src/BtPieceMessage.cc + (doReceivedAction): Use dispatcher member. + (send): Use peerConnection member. + (onWrongPiece): Use requestFactory member. + (handleChokingEvent): Use messageFactory, dispatcher member. + (handleCancelSendingPieceEvent): Use messageFactory, dispatcher member. + * src/BtMessageDispatcher.h + (BtMessageDispatcherWeakHandle): New type definition. + * src/SimpleBtMessage.cc + (send): Use peerConnection member. + * src/BtRejectMessage.cc + (doReceivedAction): Use dispatcher member. + * src/DefaultBtMessageDispatcher.h + (Option.h): Removed include. + (messageFactory): New variable. + (option): Removed. + (maxUploadSpeedLimit): New variable. + (requestTimeout): New variable. + (DefaultBtMessageDispatcher): Removed option. + Added maxUploadSpeedLimit, requestTimeout. + (setOption): Removed. + (getOption): Removed. + (setMaxUploadSpeedLimit): New function. + (setRequestTimeout): New function. + (setBtMessageFactory): New function. + * src/DefaultBtInteractive.h + (btMessageReceiver): + BtMessageReceiverHandle -> BtMessageReceiverWeakHandle + (dispatcher): + BtMessageDispatcherHandle -> BtMessageReceiverWeakHandle + (btRequestFactory): + BtRequestFactoryHandle -> BtRequestFactoryWeakHandle + (peerConnection): + PeerConnectionHandle -> PeerConnectionWeakHandle + (messageFactory): New variable. + (option): Removed. + (keepAliveInterval): New variable. + (maxDownloadSpeedLimit): New variable. + (DefaultBtInteractive): Added keepAliveInterval, maxDownloadSpeedLimit. + (setBtMessageReceiver): + BtMessageReceiverHandle -> BtMessageReceiverWeakHandle + (setDispatcher): + BtMessageDispatcherHandle -> BtMessageReceiverWeakHandle + (setBtRequestFactory): + BtRequestFactoryHandle -> BtRequestFactoryWeakHandle + (setPeerConnection): + PeerConnectionHandle -> PeerConnectionWeakHandle + (setOption): Removed. + (setKeepAliveInterval): New function. + (setMaxDownloadSpeedLimit): New function. + (setBtMessageFactory): New function. + * src/BitfieldMan.h + (cachedNumMissingBlock): New variable. + (cachedNumFilteredBlock): New variable. + (cachedCompletedLength): New variable. + (cachedFilteredComletedLength): New variable. + (cachedFilteredTotalLength): New variable. + (countMissingBlockNow): New function. + (countFilteredBlockNow): New function. + (getFilteredTotalLengthNow): New function. + (getCompletedLengthNow): New function. + (getFilteredCompletedLengthNow): New function. + (updateCache): New function. + * src/AbstractBtMessage.h + (BtMessageDispatcher.h): New include. + (PeerConnection.h): New include. + (BtRequestFactory.h): New include + (BtMessageFactory.h): New include. + (dispatcher): New variable. + (messageFactory): New variable. + (peerConnection: New variable. + (setBtMessageDispatcher): New function. + (setPeerConnection): New function. + (setBtMessageFactory): New function. + (setBtRequestFactory): New function. + * src/DefaultBtMessageFactory.cc + (setCommonProperty): Set dispatcher, requestFactory, this, + peerConnection to msg. + * src/BtRegistry.h + (BT_MESSAGE_RECEIVER): New macro. + * src/PeerConnection.h + (PeerConnectionWeakHandle): New type definition. + * src/BtMessageFactory.h + (BtMessageFactoryWeakHandle): New type definition. + * src/BitfieldMan.cc + (BitfieldMan): Added cachedNumMissingBlock, cachedNumFilteredBlock, + cachedCompletedLength, cachedFilteredComletedLength, + cachedFilteredTotalLength. + Call updateCache(). + (countMissingBlock): Return cachedNumMissingBlock. + (countMissingBlockNow): New function. + (countBlock): Return cachedNumFilteredBlock if filterEnabled is true. + (countFilteredBlockNow): New function. + (setBit): Call updateCache(). + (unsetBit): Call updateCache(). + (setBitfield): Call updateCache(). + (clearAllBit): Call updateCache(). + (setAllBit): Use setBitInternal instead of setBit. + Call updateCache(). + (addFilter): Call updateCache(). + (enableFilter): Call updateCache(). + (disableFilter): Call updateCache(). + (clearFilter): Call updateCache(). + (getFilteredTotalLength): Return cachedFilteredTotalLength. + (getFilteredTotalLengthNow): New function. + (getCompletedLength): Return cachedCompletedLength. + (getCompletedLengthNow): New function. + (getFilteredCompletedLength): Return cachedFilteredComletedLength. + (getFilteredCompletedLengthNow): New function. + (updateCache): New function. + * src/BtMessageReceiver.h + (BtMessageReceiverWeakHandle): New type definition. + * src/DefaultBtMessageReceiver.cc + (receiveHandshake): Use messageFactory member. + (sendHandshake): Use messageFactory member. + (receiveMessage): Use messageFactory member. + * src/DefaultBtMessageFactory.h + (dispatcher): New variable. + (requestFactory): New variable. + (peerConnection): New variablle. + (setBtMessageDispatcher): New function. + (setBtRequestFactory): New function. + (setPeerConnection): New function. + * src/SharedHandle.h + (RefCount): New class. + (WeakHandle): New class. + * src/PeerObject.h + (BtMessageReceiver.h): New include. + (PeerObject): Added btMessageReceiver. + (btMessageReceiver): New variable. + * src/Util.cc + (countBit): Simplified. + * src/BtCancelMessage.cc + (doReceivedAction): Use dispatcher member. + * src/BtRequestFactory.h + (BtRequestFactoryWeakHandle): New type definition. + + * src/PeerStorage.h + (downloadSpeed): int -> uint32_t + (uploadSpeed): int -> uint32_t + (sessionDownloadLength): long long int -> uint64_t + (sessionUploadLength): long long int -> uint64_t + 2007-01-11 Tatsuhiro Tsujikawa To add RecoverableException, FatalException: diff --git a/TODO b/TODO index 079d77d3..b07db9b9 100644 --- a/TODO +++ b/TODO @@ -22,6 +22,7 @@ * Add --bt-timeout command line option. * Fix DefaultBtProgressInfoFile.cc: save(), load() * remove blockIndex +* Add an ability of seeding + * Add piece hash checking * Stop download after selective download completes -* Add an ability of seeding diff --git a/src/AbstractBtMessage.h b/src/AbstractBtMessage.h index 52cb88f0..7a4315c0 100644 --- a/src/AbstractBtMessage.h +++ b/src/AbstractBtMessage.h @@ -44,6 +44,10 @@ #include "BtEventListener.h" #include "BtContext.h" #include "BtRegistry.h" +#include "BtMessageDispatcher.h" +#include "PeerConnection.h" +#include "BtRequestFactory.h" +#include "BtMessageFactory.h" class AbstractBtMessage : public BtMessage { protected: @@ -58,6 +62,14 @@ protected: PeerHandle peer; + BtMessageDispatcherWeakHandle dispatcher; + + BtMessageFactoryWeakHandle messageFactory; + + BtRequestFactoryWeakHandle requestFactory; + + PeerConnectionWeakHandle peerConnection; + BtMessageValidatorHandle validator; BtEventListeners listeners; const Logger* logger; @@ -154,6 +166,22 @@ public: return btContext; } + void setBtMessageDispatcher(const BtMessageDispatcherWeakHandle& dispatcher) + { + this->dispatcher = dispatcher; + } + + void setPeerConnection(const PeerConnectionWeakHandle& peerConnection) { + this->peerConnection = peerConnection; + } + + void setBtMessageFactory(const BtMessageFactoryWeakHandle& factory) { + this->messageFactory = factory; + } + + void setBtRequestFactory(const BtRequestFactoryWeakHandle& factory) { + this->requestFactory = factory; + } }; typedef SharedHandle AbstractBtMessageHandle; diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc index c287fdaf..253dff26 100644 --- a/src/BitfieldMan.cc +++ b/src/BitfieldMan.cc @@ -43,7 +43,12 @@ BitfieldMan::BitfieldMan(uint32_t blockLength, uint64_t totalLength) useBitfield(0), filterBitfield(0), filterEnabled(false), - randomizer(0) + randomizer(0), + cachedNumMissingBlock(0), + cachedNumFilteredBlock(0), + cachedCompletedLength(0), + cachedFilteredComletedLength(0), + cachedFilteredTotalLength(0) { if(blockLength > 0 && totalLength > 0) { blocks = totalLength/blockLength+(totalLength%blockLength ? 1 : 0); @@ -52,6 +57,7 @@ BitfieldMan::BitfieldMan(uint32_t blockLength, uint64_t totalLength) useBitfield = new unsigned char[bitfieldLength]; memset(bitfield, 0, bitfieldLength); memset(useBitfield, 0, bitfieldLength); + updateCache(); } } @@ -60,7 +66,12 @@ BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan) useBitfield(0), filterBitfield(0), filterEnabled(false), - randomizer(0) + randomizer(0), + cachedNumMissingBlock(0), + cachedNumFilteredBlock(0), + cachedCompletedLength(0), + cachedFilteredComletedLength(0), + cachedFilteredTotalLength(0) { blockLength = bitfieldMan.blockLength; totalLength = bitfieldMan.totalLength; @@ -78,6 +89,7 @@ BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan) filterBitfield = 0; } this->randomizer = bitfieldMan.randomizer; + updateCache(); } BitfieldMan::~BitfieldMan() { @@ -361,6 +373,10 @@ BlockIndexes BitfieldMan::getAllMissingIndexes(const unsigned char* peerBitfield } uint32_t BitfieldMan::countMissingBlock() const { + return cachedNumMissingBlock; +} + +uint32_t BitfieldMan::countMissingBlockNow() const { if(filterEnabled) { unsigned char* temp = new unsigned char[bitfieldLength]; for(uint32_t i = 0; i < bitfieldLength; i++) { @@ -377,12 +393,20 @@ uint32_t BitfieldMan::countMissingBlock() const { uint32_t BitfieldMan::countBlock() const { if(filterEnabled) { - return countSetBit(filterBitfield, bitfieldLength); + return cachedNumFilteredBlock; } else { return blocks; } } +uint32_t BitfieldMan::countFilteredBlockNow() const { + if(filterEnabled) { + return countSetBit(filterBitfield, bitfieldLength); + } else { + return 0; + } +} + bool BitfieldMan::setBitInternal(unsigned char* bitfield, int32_t index, bool on) { if((int32_t)blocks <= index) { return false; } unsigned char mask = 128 >> index%8; @@ -403,11 +427,15 @@ bool BitfieldMan::unsetUseBit(int32_t index) { } bool BitfieldMan::setBit(int32_t index) { - return setBitInternal(bitfield, index, true); + bool b = setBitInternal(bitfield, index, true); + updateCache(); + return b; } bool BitfieldMan::unsetBit(int32_t index) { - return setBitInternal(bitfield, index, false); + bool b = setBitInternal(bitfield, index, false); + updateCache(); + return b; } bool BitfieldMan::isAllBitSet() const { @@ -452,25 +480,29 @@ void BitfieldMan::setBitfield(const unsigned char* bitfield, uint32_t bitfieldLe } memcpy(this->bitfield, bitfield, this->bitfieldLength); memset(this->useBitfield, 0, this->bitfieldLength); + updateCache(); } void BitfieldMan::clearAllBit() { memset(this->bitfield, 0, this->bitfieldLength); + updateCache(); } void BitfieldMan::setAllBit() { for(uint32_t i = 0; i < blocks; i++) { - setBit(i); + setBitInternal(bitfield, i, true); } + updateCache(); } void BitfieldMan::clearAllUseBit() { memset(this->useBitfield, 0, this->bitfieldLength); + updateCache(); } void BitfieldMan::setAllUseBit() { for(uint32_t i = 0; i < blocks; i++) { - setUseBit(i); + setBitInternal(useBitfield, i, true); } } @@ -488,14 +520,17 @@ void BitfieldMan::addFilter(int64_t offset, uint64_t length) { for(int i = startBlock; i <= endBlock && i < (int32_t)blocks; i++) { setFilterBit(i); } + updateCache(); } void BitfieldMan::enableFilter() { filterEnabled = true; + updateCache(); } void BitfieldMan::disableFilter() { filterEnabled = false; + updateCache(); } void BitfieldMan::clearFilter() { @@ -504,6 +539,7 @@ void BitfieldMan::clearFilter() { filterBitfield = 0; } filterEnabled = false; + updateCache(); } bool BitfieldMan::isFilterEnabled() const { @@ -511,6 +547,10 @@ bool BitfieldMan::isFilterEnabled() const { } uint64_t BitfieldMan::getFilteredTotalLength() const { + return cachedFilteredTotalLength; +} + +uint64_t BitfieldMan::getFilteredTotalLengthNow() const { if(!filterBitfield) { return 0; } @@ -553,9 +593,26 @@ uint64_t BitfieldMan::getCompletedLength(bool useFilter) const { } uint64_t BitfieldMan::getCompletedLength() const { + return cachedCompletedLength; +} + +uint64_t BitfieldMan::getCompletedLengthNow() const { return getCompletedLength(false); } uint64_t BitfieldMan::getFilteredCompletedLength() const { + return cachedFilteredComletedLength; +} + +uint64_t BitfieldMan::getFilteredCompletedLengthNow() const { return getCompletedLength(true); } + +void BitfieldMan::updateCache() +{ + cachedNumMissingBlock = countMissingBlockNow(); + cachedNumFilteredBlock = countFilteredBlockNow(); + cachedFilteredTotalLength = getFilteredTotalLengthNow(); + cachedCompletedLength = getCompletedLengthNow(); + cachedFilteredComletedLength = getFilteredCompletedLengthNow(); +} diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h index c78065b4..1703e00a 100644 --- a/src/BitfieldMan.h +++ b/src/BitfieldMan.h @@ -53,6 +53,13 @@ private: bool filterEnabled; RandomizerHandle randomizer; + // for caching + uint32_t cachedNumMissingBlock; + uint32_t cachedNumFilteredBlock; + uint64_t cachedCompletedLength; + uint64_t cachedFilteredComletedLength; + uint64_t cachedFilteredTotalLength; + uint32_t countSetBit(const unsigned char* bitfield, uint32_t len) const; int32_t getNthBitIndex(const unsigned char bit, uint32_t nth) const; int32_t getMissingIndexRandomly(const unsigned char* bitfield, uint32_t len) const; @@ -92,6 +99,8 @@ public: } else { filterBitfield = 0; } + + updateCache(); } return *this; } @@ -158,6 +167,10 @@ public: * affected by filter */ uint32_t countMissingBlock() const; + /** + * affected by filter + */ + uint32_t countMissingBlockNow() const; bool setUseBit(int32_t index); bool unsetUseBit(int32_t index); @@ -180,6 +193,10 @@ public: * affected by filter */ uint32_t countBlock() const; + /** + * affected by filter + */ + uint32_t countFilteredBlockNow() const; int32_t getMaxIndex() const { return blocks-1; } @@ -204,13 +221,23 @@ public: * affected by filter */ uint64_t getFilteredTotalLength() const; + /** + * affected by filter + */ + uint64_t getFilteredTotalLengthNow() const; uint64_t getCompletedLength() const; + uint64_t getCompletedLengthNow() const; + /** * affected by filter */ uint64_t getFilteredCompletedLength() const; + /** + * affected by filter + */ + uint64_t getFilteredCompletedLengthNow() const; void setRandomizer(const RandomizerHandle& randomizer) { this->randomizer = randomizer; @@ -219,6 +246,8 @@ public: RandomizerHandle getRandomizer() const { return randomizer; } + + void updateCache(); }; #endif // _D_BITFIELD_MAN_H_ diff --git a/src/BtCancelMessage.cc b/src/BtCancelMessage.cc index 9a866e6c..8113df1e 100644 --- a/src/BtCancelMessage.cc +++ b/src/BtCancelMessage.cc @@ -54,7 +54,7 @@ BtCancelMessageHandle BtCancelMessage::create(const unsigned char* data, uint32_ } void BtCancelMessage::doReceivedAction() { - BT_MESSAGE_DISPATCHER(btContext, peer)->doCancelSendingPieceAction(index, begin, length); + dispatcher->doCancelSendingPieceAction(index, begin, length); } uint32_t BtCancelMessage::MESSAGE_LENGTH = 17; diff --git a/src/BtChokeMessage.cc b/src/BtChokeMessage.cc index 61bd9372..14efa4a9 100644 --- a/src/BtChokeMessage.cc +++ b/src/BtChokeMessage.cc @@ -51,8 +51,8 @@ BtChokeMessageHandle BtChokeMessage::create(const unsigned char* data, uint32_t void BtChokeMessage::doReceivedAction() { peer->peerChoking = true; - BT_MESSAGE_DISPATCHER(btContext, peer)->doChokedAction(); - BT_REQUEST_FACTORY(btContext, peer)->doChokedAction(); + dispatcher->doChokedAction(); + requestFactory->doChokedAction(); } bool BtChokeMessage::sendPredicate() const { @@ -80,7 +80,7 @@ uint32_t BtChokeMessage::getMessageLength() { void BtChokeMessage::onSendComplete() { peer->amChoking = true; - BT_MESSAGE_DISPATCHER(btContext, peer)->doChokingAction(); + dispatcher->doChokingAction(); } string BtChokeMessage::toString() const { diff --git a/src/BtMessageDispatcher.h b/src/BtMessageDispatcher.h index 356b8bfa..6cfe9433 100644 --- a/src/BtMessageDispatcher.h +++ b/src/BtMessageDispatcher.h @@ -78,5 +78,5 @@ public: }; typedef SharedHandle BtMessageDispatcherHandle; - +typedef WeakHandle BtMessageDispatcherWeakHandle; #endif // _D_BT_MESSAGE_DISPATCHER_H_ diff --git a/src/BtMessageFactory.h b/src/BtMessageFactory.h index 4db24a5a..59f440c8 100644 --- a/src/BtMessageFactory.h +++ b/src/BtMessageFactory.h @@ -87,5 +87,5 @@ public: }; typedef SharedHandle BtMessageFactoryHandle; - +typedef WeakHandle BtMessageFactoryWeakHandle; #endif // _D_BT_MESSAGE_FACTORY_H_ diff --git a/src/BtMessageReceiver.h b/src/BtMessageReceiver.h index d39a128f..15315e75 100644 --- a/src/BtMessageReceiver.h +++ b/src/BtMessageReceiver.h @@ -50,5 +50,6 @@ public: }; typedef SharedHandle BtMessageReceiverHandle; +typedef WeakHandle BtMessageReceiverWeakHandle; #endif // _D_BT_MESSAGE_RECEIVER_H_ diff --git a/src/BtPieceMessage.cc b/src/BtPieceMessage.cc index b6814fa8..cd861e91 100644 --- a/src/BtPieceMessage.cc +++ b/src/BtPieceMessage.cc @@ -64,10 +64,9 @@ BtPieceMessageHandle BtPieceMessage::create(const unsigned char* data, uint32_t } void BtPieceMessage::doReceivedAction() { - RequestSlot slot = - BT_MESSAGE_DISPATCHER(btContext, peer)->getOutstandingRequest(index, - begin, - blockLength); + RequestSlot slot = dispatcher->getOutstandingRequest(index, + begin, + blockLength); peer->updateDownloadLength(blockLength); if(!RequestSlot::isNull(slot)) { peer->snubbing = false; @@ -85,7 +84,7 @@ void BtPieceMessage::doReceivedAction() { cuid, Util::toHex(piece->getBitfield(), piece->getBitfieldLength()).c_str()); - BT_MESSAGE_DISPATCHER(btContext, peer)->removeOutstandingRequest(slot); + dispatcher->removeOutstandingRequest(slot); if(piece->pieceComplete()) { if(checkPieceHash(piece)) { onNewPiece(piece); @@ -134,7 +133,7 @@ void BtPieceMessage::send() { sendingInProgress = true; } uint32_t writtenLength - = PEER_CONNECTION(btContext, peer)->sendMessage(msgHeader+getMessageHeaderLength()-leftDataLength, + = peerConnection->sendMessage(msgHeader+getMessageHeaderLength()-leftDataLength, leftDataLength); if(writtenLength == leftDataLength) { headerSent = true; @@ -166,7 +165,7 @@ uint32_t BtPieceMessage::sendPieceData(int64_t offset, uint32_t length) const { if(pieceStorage->getDiskAdaptor()->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < (int32_t)BUF_SIZE) { throw new DlAbortEx("Failed to read data from disk."); } - uint32_t ws = PEER_CONNECTION(btContext, peer)->sendMessage(buf, BUF_SIZE); + uint32_t ws = peerConnection->sendMessage(buf, BUF_SIZE); writtenLength += ws; if(ws != BUF_SIZE) { return writtenLength; @@ -178,7 +177,7 @@ uint32_t BtPieceMessage::sendPieceData(int64_t offset, uint32_t length) const { if(pieceStorage->getDiskAdaptor()->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) { throw new DlAbortEx("Failed to read data from disk."); } - uint32_t ws = PEER_CONNECTION(btContext, peer)->sendMessage(buf, rem); + uint32_t ws = peerConnection->sendMessage(buf, rem); writtenLength += ws; } return writtenLength; @@ -206,7 +205,7 @@ void BtPieceMessage::onWrongPiece(const PieceHandle& piece) { logger->error(MSG_GOT_WRONG_PIECE, cuid, piece->getIndex()); erasePieceOnDisk(piece); piece->clearAllBlock(); - BT_REQUEST_FACTORY(btContext, peer)->removeTargetPiece(piece); + requestFactory->removeTargetPiece(piece); } void BtPieceMessage::erasePieceOnDisk(const PieceHandle& piece) { @@ -246,11 +245,10 @@ void BtPieceMessage::handleChokingEvent(const BtEventHandle& event) { blockLength); if(peer->isFastExtensionEnabled()) { - BtMessageHandle rej = - BT_MESSAGE_FACTORY(btContext, peer)->createRejectMessage(index, - begin, - blockLength); - BT_MESSAGE_DISPATCHER(btContext, peer)->addMessageToQueue(rej); + BtMessageHandle rej = messageFactory->createRejectMessage(index, + begin, + blockLength); + dispatcher->addMessageToQueue(rej); } invalidate = true; } @@ -276,11 +274,10 @@ void BtPieceMessage::handleCancelSendingPieceEvent(const BtEventHandle& event) { " message received. index=%d, begin=%d, length=%u", cuid, index, begin, blockLength); if(peer->isFastExtensionEnabled()) { - BtMessageHandle rej = - BT_MESSAGE_FACTORY(btContext, peer)->createRejectMessage(index, - begin, - blockLength); - BT_MESSAGE_DISPATCHER(btContext, peer)->addMessageToQueue(rej); + BtMessageHandle rej = messageFactory->createRejectMessage(index, + begin, + blockLength); + dispatcher->addMessageToQueue(rej); } invalidate = true; } diff --git a/src/BtRegistry.h b/src/BtRegistry.h index a04e0c06..7a9eafb0 100644 --- a/src/BtRegistry.h +++ b/src/BtRegistry.h @@ -125,6 +125,9 @@ PEER_OBJECT_CLUSTER(btContext)->getHandle(peer->getId()) #define BT_MESSAGE_DISPATCHER(btContext, peer) \ PEER_OBJECT(btContext, peer)->btMessageDispatcher +#define BT_MESSAGE_RECEIVER(btContext, peer) \ +PEER_OBJECT(btContext, peer)->btMessageReceiver + #define BT_MESSAGE_FACTORY(btContext, peer) \ PEER_OBJECT(btContext, peer)->btMessageFactory diff --git a/src/BtRejectMessage.cc b/src/BtRejectMessage.cc index fd2b3899..5529cf09 100644 --- a/src/BtRejectMessage.cc +++ b/src/BtRejectMessage.cc @@ -60,12 +60,11 @@ void BtRejectMessage::doReceivedAction() { } // TODO Current implementation does not close a connection even if // a request for this reject message has never sent. - RequestSlot slot = - BT_MESSAGE_DISPATCHER(btContext, peer)->getOutstandingRequest(index, begin, length); + RequestSlot slot = dispatcher->getOutstandingRequest(index, begin, length); if(RequestSlot::isNull(slot)) { //throw new DlAbortEx("reject recieved, but it is not in the request slots."); } else { - BT_MESSAGE_DISPATCHER(btContext, peer)->removeOutstandingRequest(slot); + dispatcher->removeOutstandingRequest(slot); } } diff --git a/src/BtRequestFactory.h b/src/BtRequestFactory.h index 0f33ece9..a883d76b 100644 --- a/src/BtRequestFactory.h +++ b/src/BtRequestFactory.h @@ -70,5 +70,6 @@ public: }; typedef SharedHandle BtRequestFactoryHandle; +typedef WeakHandle BtRequestFactoryWeakHandle; #endif // _D_BT_REQUEST_FACTORY_H_ diff --git a/src/BtRequestMessage.cc b/src/BtRequestMessage.cc index ba7164f4..5b944d91 100644 --- a/src/BtRequestMessage.cc +++ b/src/BtRequestMessage.cc @@ -58,18 +58,16 @@ void BtRequestMessage::doReceivedAction() { if(pieceStorage->hasPiece(index) && (!peer->amChoking || peer->amChoking && peer->isInAmAllowedIndexSet(index))) { - BtMessageHandle msg = - BT_MESSAGE_FACTORY(btContext, peer)->createPieceMessage(index, - begin, - length); - BT_MESSAGE_DISPATCHER(btContext, peer)->addMessageToQueue(msg); + BtMessageHandle msg = messageFactory->createPieceMessage(index, + begin, + length); + dispatcher->addMessageToQueue(msg); } else { if(peer->isFastExtensionEnabled()) { - BtMessageHandle msg = - BT_MESSAGE_FACTORY(btContext, peer)->createRejectMessage(index, - begin, - length); - BT_MESSAGE_DISPATCHER(btContext, peer)->addMessageToQueue(msg); + BtMessageHandle msg = messageFactory->createRejectMessage(index, + begin, + length); + dispatcher->addMessageToQueue(msg); } } } @@ -106,7 +104,7 @@ string BtRequestMessage::toString() const { void BtRequestMessage::onQueued() { RequestSlot requestSlot(index, begin, length, blockIndex); - BT_MESSAGE_DISPATCHER(btContext, peer)->addOutstandingRequest(requestSlot); + dispatcher->addOutstandingRequest(requestSlot); } bool BtRequestMessage::BtAbortOutstandingRequestEventListener::canHandle(const BtEventHandle& event) { diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc index 03c5e61c..ab20c6de 100644 --- a/src/DefaultBtInteractive.cc +++ b/src/DefaultBtInteractive.cc @@ -43,10 +43,8 @@ #include "DlAbortEx.h" void DefaultBtInteractive::initiateHandshake() { - BtMessageHandle message = - BT_MESSAGE_FACTORY(btContext, peer)-> - createHandshakeMessage(btContext->getInfoHash(), - btContext->getPeerId()); + BtMessageHandle message = messageFactory->createHandshakeMessage(btContext->getInfoHash(), + btContext->getPeerId()); dispatcher->addMessageToQueue(message); dispatcher->sendMessages(); } @@ -79,18 +77,17 @@ void DefaultBtInteractive::doPostHandshakeProcessing() { } void DefaultBtInteractive::addBitfieldMessageToQueue() { - BtMessageFactoryHandle factory = BT_MESSAGE_FACTORY(btContext, peer); if(peer->isFastExtensionEnabled()) { if(pieceStorage->downloadFinished()) { - dispatcher->addMessageToQueue(factory->createHaveAllMessage()); + dispatcher->addMessageToQueue(messageFactory->createHaveAllMessage()); } else if(pieceStorage->getCompletedLength() > 0) { - dispatcher->addMessageToQueue(factory->createBitfieldMessage()); + dispatcher->addMessageToQueue(messageFactory->createBitfieldMessage()); } else { - dispatcher->addMessageToQueue(factory->createHaveNoneMessage()); + dispatcher->addMessageToQueue(messageFactory->createHaveNoneMessage()); } } else { if(pieceStorage->getCompletedLength() > 0) { - dispatcher->addMessageToQueue(factory->createBitfieldMessage()); + dispatcher->addMessageToQueue(messageFactory->createBitfieldMessage()); } } } @@ -103,8 +100,7 @@ void DefaultBtInteractive::addAllowedFastMessageToQueue() { allowedFastSetSize); for(Integers::const_iterator itr = fastSet.begin(); itr != fastSet.end(); itr++) { - dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)-> - createAllowedFastMessage(*itr)); + dispatcher->addMessageToQueue(messageFactory->createAllowedFastMessage(*itr)); } } } @@ -112,38 +108,35 @@ void DefaultBtInteractive::addAllowedFastMessageToQueue() { void DefaultBtInteractive::decideChoking() { if(peer->shouldBeChoking()) { if(!peer->amChoking) { - dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)-> - createChokeMessage()); + dispatcher->addMessageToQueue(messageFactory->createChokeMessage()); } } else { if(peer->amChoking) { - dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)-> - createUnchokeMessage()); + dispatcher->addMessageToQueue(messageFactory->createUnchokeMessage()); } } } void DefaultBtInteractive::checkHave() { - BtMessageFactoryHandle factory = BT_MESSAGE_FACTORY(btContext, peer); Integers indexes = pieceStorage->getAdvertisedPieceIndexes(cuid, haveCheckPoint); haveCheckPoint.reset(); if(indexes.size() >= 20) { if(peer->isFastExtensionEnabled() && pieceStorage->downloadFinished()) { - dispatcher->addMessageToQueue(factory->createHaveAllMessage()); + dispatcher->addMessageToQueue(messageFactory->createHaveAllMessage()); } else { - dispatcher->addMessageToQueue(factory->createBitfieldMessage()); + dispatcher->addMessageToQueue(messageFactory->createBitfieldMessage()); } } else { for(Integers::iterator itr = indexes.begin(); itr != indexes.end(); itr++) { - dispatcher->addMessageToQueue(factory->createHaveMessage(*itr)); + dispatcher->addMessageToQueue(messageFactory->createHaveMessage(*itr)); } } } void DefaultBtInteractive::sendKeepAlive() { - if(keepAliveCheckPoint.elapsed(option->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL))) { - dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->createKeepAliveMessage()); + if(keepAliveCheckPoint.elapsed(keepAliveInterval)) { + dispatcher->addMessageToQueue(messageFactory->createKeepAliveMessage()); dispatcher->sendMessages(); keepAliveCheckPoint.reset(); } @@ -151,10 +144,9 @@ void DefaultBtInteractive::sendKeepAlive() { void DefaultBtInteractive::receiveMessages() { for(int i = 0; i < 50; i++) { - int maxSpeedLimit = option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT); - if(maxSpeedLimit > 0) { + if(maxDownloadSpeedLimit > 0) { TransferStat stat = peerStorage->calculateStat(); - if(maxSpeedLimit < stat.downloadSpeed) { + if(maxDownloadSpeedLimit < stat.downloadSpeed) { break; } } @@ -190,15 +182,13 @@ void DefaultBtInteractive::decideInterest() { if(!peer->amInterested) { logger->debug("CUID#%d - Interested in the peer", cuid); dispatcher-> - addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)-> - createInterestedMessage()); + addMessageToQueue(messageFactory->createInterestedMessage()); } } else { if(peer->amInterested) { logger->debug("CUID#%d - Not interested in the peer", cuid); dispatcher-> - addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)-> - createNotInterestedMessage()); + addMessageToQueue(messageFactory->createNotInterestedMessage()); } } } diff --git a/src/DefaultBtInteractive.h b/src/DefaultBtInteractive.h index cc6f99a9..0e4da687 100644 --- a/src/DefaultBtInteractive.h +++ b/src/DefaultBtInteractive.h @@ -89,17 +89,19 @@ private: BtContextHandle btContext; PeerStorageHandle peerStorage; PieceStorageHandle pieceStorage; - BtMessageReceiverHandle btMessageReceiver; - BtMessageDispatcherHandle dispatcher; - BtRequestFactoryHandle btRequestFactory; - PeerConnectionHandle peerConnection; + BtMessageReceiverWeakHandle btMessageReceiver; + BtMessageDispatcherWeakHandle dispatcher; + BtRequestFactoryWeakHandle btRequestFactory; + PeerConnectionWeakHandle peerConnection; + BtMessageFactoryWeakHandle messageFactory; const Logger* logger; uint32_t allowedFastSetSize; Time haveCheckPoint; Time keepAliveCheckPoint; Time floodingCheckPoint; FloodingStat floodingStat; - const Option* option; + uint32_t keepAliveInterval; + uint32_t maxDownloadSpeedLimit; static const uint32_t FLOODING_CHECK_INTERVAL = 5; @@ -122,14 +124,12 @@ public: btRequestFactory(0), peerConnection(0), logger(LogFactory::getInstance()), - allowedFastSetSize(10) - { - logger->debug("DefaultBtInteractive instantiated."); - } + allowedFastSetSize(10), + keepAliveInterval(120), + maxDownloadSpeedLimit(0) + {} - virtual ~DefaultBtInteractive() { - logger->debug("DefaultBtInteractive deleted."); - } + virtual ~DefaultBtInteractive() {} virtual void initiateHandshake(); @@ -169,24 +169,32 @@ public: this->pieceStorage = PIECE_STORAGE(btContext); } - void setBtMessageReceiver(const BtMessageReceiverHandle& receiver) { + void setBtMessageReceiver(const BtMessageReceiverWeakHandle& receiver) { this->btMessageReceiver = receiver; } - void setDispatcher(const BtMessageDispatcherHandle& dispatcher) { + void setDispatcher(const BtMessageDispatcherWeakHandle& dispatcher) { this->dispatcher = dispatcher; } - void setBtRequestFactory(const BtRequestFactoryHandle& factory) { + void setBtRequestFactory(const BtRequestFactoryWeakHandle& factory) { this->btRequestFactory = factory; } - void setPeerConnection(const PeerConnectionHandle& peerConnection) { + void setPeerConnection(const PeerConnectionWeakHandle& peerConnection) { this->peerConnection = peerConnection; } - void setOption(const Option* option) { - this->option = option; + void setKeepAliveInterval(uint32_t keepAliveInterval) { + this->keepAliveInterval = keepAliveInterval; + } + + void setMaxDownloadSpeedLimit(uint32_t maxDownloadSpeedLimit) { + this->maxDownloadSpeedLimit = maxDownloadSpeedLimit; + } + + void setBtMessageFactory(const BtMessageFactoryWeakHandle& factory) { + this->messageFactory = factory; } }; diff --git a/src/DefaultBtMessageDispatcher.cc b/src/DefaultBtMessageDispatcher.cc index 33cfe3f1..7923c0af 100644 --- a/src/DefaultBtMessageDispatcher.cc +++ b/src/DefaultBtMessageDispatcher.cc @@ -58,13 +58,12 @@ void DefaultBtMessageDispatcher::addMessageToQueue(const BtMessages& btMessages) void DefaultBtMessageDispatcher::sendMessages() { BtMessages tempQueue; - int32_t uploadLimit = option->getAsInt(PREF_MAX_UPLOAD_LIMIT); while(messageQueue.size() > 0) { BtMessageHandle msg = messageQueue.front(); messageQueue.pop_front(); - if(uploadLimit > 0) { + if(maxUploadSpeedLimit > 0) { TransferStat stat = peerStorage->calculateStat(); - if(uploadLimit < stat.getUploadSpeed() && + if(maxUploadSpeedLimit < stat.getUploadSpeed() && msg->isUploading() && !msg->isSendingInProgress()) { tempQueue.push_back(msg); continue; @@ -168,7 +167,7 @@ void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing() itr != requestSlots.end();) { RequestSlot& slot = *itr; PieceHandle piece = pieceStorage->getPiece(slot.getIndex()); - if(slot.isTimeout(option->getAsInt(PREF_BT_REQUEST_TIMEOUT))) { + if(slot.isTimeout(requestTimeout)) { logger->debug("CUID#%d - Deleting request slot blockIndex=%d" " because of time out", cuid, @@ -181,10 +180,9 @@ void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing() " the block has been acquired.", cuid, slot.getBlockIndex()); - addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)-> - createCancelMessage(slot.getIndex(), - slot.getBegin(), - slot.getLength())); + addMessageToQueue(messageFactory->createCancelMessage(slot.getIndex(), + slot.getBegin(), + slot.getLength())); itr = requestSlots.erase(itr); } else { itr++; diff --git a/src/DefaultBtMessageDispatcher.h b/src/DefaultBtMessageDispatcher.h index 6bba3f33..0a12aca9 100644 --- a/src/DefaultBtMessageDispatcher.h +++ b/src/DefaultBtMessageDispatcher.h @@ -42,7 +42,6 @@ #include "RequestSlot.h" #include "BtMessage.h" #include "Peer.h" -#include "Option.h" #include "LogFactory.h" #include "Logger.h" #include "BtRegistry.h" @@ -55,8 +54,10 @@ private: BtContextHandle btContext; PeerStorageHandle peerStorage; PieceStorageHandle pieceStorage; + BtMessageFactoryWeakHandle messageFactory; PeerHandle peer; - const Option* option; + uint32_t maxUploadSpeedLimit; + uint32_t requestTimeout; const Logger* logger; public: DefaultBtMessageDispatcher(): @@ -65,17 +66,12 @@ public: peerStorage(0), pieceStorage(0), peer(0), - option(0), - logger(LogFactory::getInstance()) - { - logger->debug("DefaultBtMessageDispatcher::instantiated"); - } - - virtual ~DefaultBtMessageDispatcher() - { - logger->debug("DefaultBtMessageDispatcher::deleted"); - } + maxUploadSpeedLimit(0), + requestTimeout(0), + logger(LogFactory::getInstance()) {} + virtual ~DefaultBtMessageDispatcher() {} + virtual void addMessageToQueue(const BtMessageHandle& btMessage); virtual void addMessageToQueue(const BtMessages& btMessages); @@ -132,14 +128,6 @@ public: return messageQueue; } - void setOption(const Option* option) { - this->option = option; - } - - const Option* getOption() const { - return option; - } - RequestSlots& getRequestSlots() { return requestSlots; } @@ -157,6 +145,18 @@ public: void setCuid(int32_t cuid) { this->cuid = cuid; } + + void setMaxUploadSpeedLimit(uint32_t maxUploadSpeedLimit) { + this->maxUploadSpeedLimit = maxUploadSpeedLimit; + } + + void setRequestTimeout(uint32_t requestTimeout) { + this->requestTimeout = requestTimeout; + } + + void setBtMessageFactory(const BtMessageFactoryWeakHandle& factory) { + this->messageFactory = factory; + } }; typedef SharedHandle DefaultBtMessageDispatcherHandle; diff --git a/src/DefaultBtMessageFactory.cc b/src/DefaultBtMessageFactory.cc index 3e1435a2..e2f29bbe 100644 --- a/src/DefaultBtMessageFactory.cc +++ b/src/DefaultBtMessageFactory.cc @@ -172,7 +172,11 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, uint32_t dat void DefaultBtMessageFactory::setCommonProperty(const AbstractBtMessageHandle& msg) { msg->setCuid(cuid); msg->setPeer(peer); - msg->setBtContext(btContext); + msg->setBtContext(btContext); + msg->setBtMessageDispatcher(dispatcher); + msg->setBtRequestFactory(requestFactory); + msg->setBtMessageFactory(this); + msg->setPeerConnection(peerConnection); } BtMessageHandle diff --git a/src/DefaultBtMessageFactory.h b/src/DefaultBtMessageFactory.h index 400fe3fa..63f3cbc8 100644 --- a/src/DefaultBtMessageFactory.h +++ b/src/DefaultBtMessageFactory.h @@ -47,6 +47,12 @@ private: PieceStorageHandle pieceStorage; PeerHandle peer; + BtMessageDispatcherWeakHandle dispatcher; + + BtRequestFactoryWeakHandle requestFactory; + + PeerConnectionWeakHandle peerConnection; + void setCommonProperty(const AbstractBtMessageHandle& msg); public: DefaultBtMessageFactory():cuid(0), @@ -124,6 +130,20 @@ public: void setCuid(int32_t cuid) { this->cuid = cuid; } + + void setBtMessageDispatcher(const BtMessageDispatcherWeakHandle& dispatcher) + { + this->dispatcher = dispatcher; + } + + void setBtRequestFactory(const BtRequestFactoryWeakHandle& factory) { + this->requestFactory = factory; + } + + void setPeerConnection(const PeerConnectionWeakHandle& connection) { + this->peerConnection = connection; + } + }; typedef SharedHandle DefaultBtMessageFactoryHandle; diff --git a/src/DefaultBtMessageReceiver.cc b/src/DefaultBtMessageReceiver.cc index 119404fb..dd9dc9dd 100644 --- a/src/DefaultBtMessageReceiver.cc +++ b/src/DefaultBtMessageReceiver.cc @@ -50,8 +50,7 @@ BtMessageHandle DefaultBtMessageReceiver::receiveHandshake(bool quickReply) { if(!retval) { return 0; } - BtHandshakeMessageHandle msg = - BT_MESSAGE_FACTORY(btContext, peer)->createHandshakeMessage(data, dataLength); + BtHandshakeMessageHandle msg = messageFactory->createHandshakeMessage(data, dataLength); Errors errors; if(msg->validate(errors)) { if(msg->isFastExtensionSupported()) { @@ -70,8 +69,8 @@ BtMessageHandle DefaultBtMessageReceiver::receiveAndSendHandshake() { void DefaultBtMessageReceiver::sendHandshake() { BtHandshakeMessageHandle msg = - BT_MESSAGE_FACTORY(btContext, peer)->createHandshakeMessage(btContext->getInfoHash(), - btContext->getPeerId()); + messageFactory->createHandshakeMessage(btContext->getInfoHash(), + btContext->getPeerId()); dispatcher->addMessageToQueue(msg); dispatcher->sendMessages(); } @@ -82,8 +81,7 @@ BtMessageHandle DefaultBtMessageReceiver::receiveMessage() { if(!peerConnection->receiveMessage(data, dataLength)) { return 0; } - BtMessageHandle msg = - BT_MESSAGE_FACTORY(btContext, peer)->createBtMessage(data, dataLength); + BtMessageHandle msg = messageFactory->createBtMessage(data, dataLength); Errors errors; if(msg->validate(errors)) { return msg; diff --git a/src/DefaultBtMessageReceiver.h b/src/DefaultBtMessageReceiver.h index b8d0f89e..7a598386 100644 --- a/src/DefaultBtMessageReceiver.h +++ b/src/DefaultBtMessageReceiver.h @@ -50,8 +50,9 @@ private: bool handshakeSent; BtContextHandle btContext; PeerHandle peer; - PeerConnectionHandle peerConnection; - BtMessageDispatcherHandle dispatcher; + PeerConnectionWeakHandle peerConnection; + BtMessageDispatcherWeakHandle dispatcher; + BtMessageFactoryWeakHandle messageFactory; const Logger* logger; void sendHandshake(); @@ -86,11 +87,11 @@ public: return cuid; } - void setPeerConnection(const PeerConnectionHandle& peerConnection) { + void setPeerConnection(const PeerConnectionWeakHandle& peerConnection) { this->peerConnection = peerConnection; } - PeerConnectionHandle getPeerConnection() const { + PeerConnectionWeakHandle getPeerConnection() const { return peerConnection; } @@ -110,9 +111,13 @@ public: return peer; } - void setDispatcher(const BtMessageDispatcherHandle& dispatcher) { + void setDispatcher(const BtMessageDispatcherWeakHandle& dispatcher) { this->dispatcher = dispatcher; } + + void setBtMessageFactory(const BtMessageFactoryWeakHandle& factory) { + this->messageFactory = factory; + } }; typedef SharedHandle DefaultBtMessageReceiverHandle; diff --git a/src/DefaultBtRequestFactory.cc b/src/DefaultBtRequestFactory.cc index e52678b2..54c22167 100644 --- a/src/DefaultBtRequestFactory.cc +++ b/src/DefaultBtRequestFactory.cc @@ -84,8 +84,7 @@ BtMessages DefaultBtRequestFactory::createRequestMessages(uint32_t max) { int32_t blockIndex; while(requests.size() < (size_t)max && (blockIndex = piece->getMissingUnusedBlockIndex()) != -1) { - requests.push_back(BT_MESSAGE_FACTORY(btContext, peer)-> - createRequestMessage(piece, blockIndex)); + requests.push_back(messageFactory->createRequestMessage(piece, blockIndex)); } } return requests; @@ -104,8 +103,7 @@ BtMessages DefaultBtRequestFactory::createRequestMessagesOnEndGame(uint32_t max) int32_t blockIndex = *bitr; if(!dispatcher->isOutstandingRequest(piece->getIndex(), blockIndex)) { - requests.push_back(BT_MESSAGE_FACTORY(btContext, peer)-> - createRequestMessage(piece, blockIndex)); + requests.push_back(messageFactory->createRequestMessage(piece, blockIndex)); } } } diff --git a/src/DefaultBtRequestFactory.h b/src/DefaultBtRequestFactory.h index 62f26a55..f2e295ae 100644 --- a/src/DefaultBtRequestFactory.h +++ b/src/DefaultBtRequestFactory.h @@ -50,7 +50,8 @@ private: BtContextHandle btContext; PieceStorageHandle pieceStorage; PeerHandle peer; - BtMessageDispatcherHandle dispatcher; + BtMessageDispatcherWeakHandle dispatcher; + BtMessageFactoryWeakHandle messageFactory; Pieces pieces; public: DefaultBtRequestFactory(): @@ -117,9 +118,14 @@ public: this->peer = peer; } - void setBtMessageDispatcher(const BtMessageDispatcherHandle& dispatcher) { + void setBtMessageDispatcher(const BtMessageDispatcherWeakHandle& dispatcher) + { this->dispatcher = dispatcher; } + + void setBtMessageFactory(const BtMessageFactoryWeakHandle& factory) { + this->messageFactory = factory; + } }; typedef SharedHandle DefaultBtRequestFactoryHandle; diff --git a/src/PeerConnection.h b/src/PeerConnection.h index af2040e8..6042ba5c 100644 --- a/src/PeerConnection.h +++ b/src/PeerConnection.h @@ -76,5 +76,5 @@ public: }; typedef SharedHandle PeerConnectionHandle; - +typedef WeakHandle PeerConnectionWeakHandle; #endif // _D_PEER_CONNECTION_H_ diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc index 8371b168..ce1cbcb9 100644 --- a/src/PeerInteractionCommand.cc +++ b/src/PeerInteractionCommand.cc @@ -56,7 +56,8 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, int sequence) :PeerAbstractCommand(cuid, p, e, btContext, s), sequence(sequence), - btInteractive(0) + btInteractive(0), + maxDownloadSpeedLimit(0) { // TODO move following bunch of processing to separate method, like init() if(sequence == INITIATOR_SEND_HANDSHAKE) { @@ -64,6 +65,11 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, setWriteCheckSocket(socket); setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT)); } + DefaultBtMessageFactoryHandle factory = new DefaultBtMessageFactory(); + factory->setCuid(cuid); + factory->setBtContext(btContext); + factory->setPeer(peer); + PeerConnectionHandle peerConnection = new PeerConnection(cuid, socket, e->option); @@ -71,7 +77,9 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, dispatcher->setCuid(cuid); dispatcher->setPeer(peer); dispatcher->setBtContext(btContext); - dispatcher->setOption(e->option); + dispatcher->setMaxUploadSpeedLimit(e->option->getAsInt(PREF_MAX_UPLOAD_LIMIT)); + dispatcher->setRequestTimeout(e->option->getAsInt(PREF_BT_REQUEST_TIMEOUT)); + dispatcher->setBtMessageFactory(factory); DefaultBtMessageReceiverHandle receiver = new DefaultBtMessageReceiver(); receiver->setCuid(cuid); @@ -79,12 +87,14 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, receiver->setBtContext(btContext); receiver->setPeerConnection(peerConnection); receiver->setDispatcher(dispatcher); + receiver->setBtMessageFactory(factory); DefaultBtRequestFactoryHandle reqFactory = new DefaultBtRequestFactory(); reqFactory->setCuid(cuid); reqFactory->setPeer(peer); reqFactory->setBtContext(btContext); reqFactory->setBtMessageDispatcher(dispatcher); + reqFactory->setBtMessageFactory(factory); DefaultBtInteractiveHandle btInteractive = new DefaultBtInteractive(); btInteractive->setCuid(cuid); @@ -94,24 +104,29 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, btInteractive->setDispatcher(dispatcher); btInteractive->setBtRequestFactory(reqFactory); btInteractive->setPeerConnection(peerConnection); - btInteractive->setOption(e->option); + btInteractive->setKeepAliveInterval(e->option->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL)); + btInteractive->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT)); + btInteractive->setBtMessageFactory(factory); this->btInteractive = btInteractive; - DefaultBtMessageFactoryHandle factory = new DefaultBtMessageFactory(); - factory->setCuid(cuid); - factory->setBtContext(btContext); - factory->setPeer(peer); + // reverse depends + factory->setBtMessageDispatcher(dispatcher); + factory->setBtRequestFactory(reqFactory); + factory->setPeerConnection(peerConnection); PeerObjectHandle peerObject = new PeerObject(); peerObject->btMessageDispatcher = dispatcher; + peerObject->btMessageReceiver = receiver; peerObject->btMessageFactory = factory; peerObject->btRequestFactory = reqFactory; peerObject->peerConnection = peerConnection; - + PEER_OBJECT_CLUSTER(btContext)->registerHandle(peer->getId(), peerObject); setUploadLimit(e->option->getAsInt(PREF_MAX_UPLOAD_LIMIT)); peer->activate(); + + maxDownloadSpeedLimit = e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT); } PeerInteractionCommand::~PeerInteractionCommand() { @@ -171,10 +186,9 @@ bool PeerInteractionCommand::executeInternal() { if(btInteractive->countPendingMessage() > 0) { setNoCheck(true); } - int maxSpeedLimit = e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT); - if(maxSpeedLimit > 0) { + if(maxDownloadSpeedLimit > 0) { TransferStat stat = peerStorage->calculateStat(); - if(maxSpeedLimit < stat.downloadSpeed) { + if(maxDownloadSpeedLimit < stat.downloadSpeed) { disableReadCheckSocket(); setNoCheck(true); } diff --git a/src/PeerInteractionCommand.h b/src/PeerInteractionCommand.h index fb02b8ea..3f7a526c 100644 --- a/src/PeerInteractionCommand.h +++ b/src/PeerInteractionCommand.h @@ -42,6 +42,7 @@ class PeerInteractionCommand : public PeerAbstractCommand { private: int sequence; BtInteractiveHandle btInteractive; + uint32_t maxDownloadSpeedLimit; protected: virtual bool executeInternal(); virtual bool prepareForRetry(int wait); diff --git a/src/PeerObject.h b/src/PeerObject.h index 3accdc03..77b19c3b 100644 --- a/src/PeerObject.h +++ b/src/PeerObject.h @@ -40,17 +40,20 @@ #include "BtRequestFactory.h" #include "BtMessageDispatcher.h" #include "PeerConnection.h" +#include "BtMessageReceiver.h" class PeerObject { public: PeerObject():btMessageFactory(0), btRequestFactory(0), btMessageDispatcher(0), + btMessageReceiver(0), peerConnection(0) {} BtMessageFactoryHandle btMessageFactory; BtRequestFactoryHandle btRequestFactory; BtMessageDispatcherHandle btMessageDispatcher; + BtMessageReceiverHandle btMessageReceiver; PeerConnectionHandle peerConnection; }; diff --git a/src/PeerStorage.h b/src/PeerStorage.h index c5bc49e4..e1267eea 100644 --- a/src/PeerStorage.h +++ b/src/PeerStorage.h @@ -40,45 +40,45 @@ class TransferStat { public: - int downloadSpeed; - int uploadSpeed; - long long int sessionDownloadLength; - long long int sessionUploadLength; + uint32_t downloadSpeed; + uint32_t uploadSpeed; + uint64_t sessionDownloadLength; + uint64_t sessionUploadLength; public: TransferStat():downloadSpeed(0), uploadSpeed(0), sessionDownloadLength(0), sessionUploadLength(0) {} - int getDownloadSpeed() const { + uint32_t getDownloadSpeed() const { return downloadSpeed; } - void setDownloadSpeed(int s) { downloadSpeed = s; } + void setDownloadSpeed(uint32_t s) { downloadSpeed = s; } - int getUploadSpeed() const { + uint32_t getUploadSpeed() const { return uploadSpeed; } - void setUploadSpeed(int s) { uploadSpeed = s; } + void setUploadSpeed(uint32_t s) { uploadSpeed = s; } /** * Returns the number of bytes downloaded since the program started. * This is not the total number of bytes downloaded. */ - long long int getSessionDownloadLength() const { + uint64_t getSessionDownloadLength() const { return sessionDownloadLength; } - void setSessionDownloadLength(long long int s) { sessionDownloadLength = s; } + void setSessionDownloadLength(uint64_t s) { sessionDownloadLength = s; } /** * Returns the number of bytes uploaded since the program started. * This is not the total number of bytes uploaded. */ - long long int getSessionUploadLength() const { + uint64_t getSessionUploadLength() const { return sessionUploadLength; } - void setSessionUploadLength(long long int s) { sessionUploadLength = s; } + void setSessionUploadLength(uint64_t s) { sessionUploadLength = s; } }; class PeerStorage { diff --git a/src/SharedHandle.h b/src/SharedHandle.h index 0cb08575..938e898e 100644 --- a/src/SharedHandle.h +++ b/src/SharedHandle.h @@ -37,69 +37,104 @@ #include -template -class SharedHandle { +class RefCount { +public: + RefCount():totalRefCount(0), strongRefCount(0) {} - template + RefCount(uint32_t totalRefCount, uint32_t strongRefCount) + :totalRefCount(totalRefCount), strongRefCount(strongRefCount) {} + + uint32_t totalRefCount; + uint32_t strongRefCount; +}; + +template +class SharedHandle; + +template +class WeakHandle; + +template +class SharedHandle { +private: + template friend std::ostream& operator<<(std::ostream& o, const SharedHandle& sp); - template + template friend bool operator==(const SharedHandle& t1, const SharedHandle& t2); - template + template friend bool operator!=(const SharedHandle& t1, const SharedHandle& t2); - template + template friend bool operator<(const SharedHandle& t1, const SharedHandle& t2); -private: T* obj; - int* ucount; -public: - SharedHandle():obj(new T()), ucount(new int(1)) {} - SharedHandle(T* obj):obj(obj), ucount(new int(1)) {} - SharedHandle(const SharedHandle& t):obj(t.get()), ucount(t.getRefCount()) { - ++*ucount; + + RefCount* ucount; + + void releaseReference() { + if(--ucount->strongRefCount == 0) { + delete obj; + obj = 0; + } + if(--ucount->totalRefCount == 0) { + delete ucount; + ucount = 0; + } } - template + +public: + SharedHandle():obj(new T()), ucount(new RefCount(1, 1)) {} + + SharedHandle(T* obj):obj(obj), ucount(new RefCount(1, 1)) {} + + SharedHandle(const SharedHandle& t):obj(t.get()), ucount(t.getRefCount()) { + ++ucount->totalRefCount; + ++ucount->strongRefCount; + } + + template SharedHandle(const SharedHandle& t) { obj = dynamic_cast(t.get()); if(obj) { ucount = t.getRefCount(); - ++*ucount; + ++ucount->totalRefCount; + ++ucount->strongRefCount; } else { - ucount = new int(1); + ucount = new RefCount(1, 1); } } ~SharedHandle() { - if(--*ucount == 0) { - delete obj; - delete ucount; - } + releaseReference(); } SharedHandle& operator=(const SharedHandle& t) { - ++*t.getRefCount(); - if(--*ucount == 0) { - delete obj; - delete ucount; - } + ++t.getRefCount()->totalRefCount; + ++t.getRefCount()->strongRefCount; + releaseReference(); obj = t.get(); ucount = t.getRefCount(); return *this; } - template - SharedHandle& operator=(const SharedHandle& t) { - ++*t.getRefCount(); - if(--*ucount == 0) { - delete obj; - delete ucount; + + template + SharedHandle& operator=(const SharedHandle& t) { + T* to = dynamic_cast(t.get()); + if(to) { + ++t.getRefCount()->totalRefCount; + ++t.getRefCount()->strongRefCount; + releaseReference(); + obj = to; + ucount = t.getRefCount(); + } else { + releaseReference(); + obj = 0; + ucount = new RefCount(1, 1); } - obj = t.get(); - ucount = t.getRefCount(); return *this; } @@ -111,7 +146,7 @@ public: return obj; } - int* getRefCount() const { + RefCount* getRefCount() const { return ucount; } @@ -120,25 +155,169 @@ public: } }; -template +template std::ostream& operator<<(std::ostream& o, const SharedHandle& sp) { o << *sp.obj; return o; } -template +template bool operator==(const SharedHandle& t1, const SharedHandle& t2) { return *t1.obj == *t2.obj; } -template +template bool operator!=(const SharedHandle& t1, const SharedHandle& t2) { return *t1.obj != *t2.obj; } -template +template bool operator<(const SharedHandle& t1, const SharedHandle& t2) { return *t1.obj < *t2.obj; } +template +class WeakHandle { +private: + template + friend std::ostream& operator<<(std::ostream& o, const WeakHandle& sp); + + template + friend bool operator==(const WeakHandle& t1, + const WeakHandle& t2); + + template + friend bool operator!=(const WeakHandle& t1, + const WeakHandle& t2); + + template + friend bool operator<(const WeakHandle& t1, const WeakHandle& t2); + + T* obj; + + RefCount* ucount; + + void releaseReference() { + if(--ucount->totalRefCount == 0) { + delete ucount; + ucount = 0; + } + } +public: + WeakHandle():obj(0), ucount(new RefCount(1, 0)) {} + + WeakHandle(T* obj):obj(obj), ucount(new RefCount(1, 1)) {} + + WeakHandle(const WeakHandle& t):obj(t.get()), ucount(t.getRefCount()) { + ++ucount->totalRefCount; + } + + template + WeakHandle(const SharedHandle& t):obj(t.get()), ucount(t.getRefCount()) { + obj = dynamic_cast(t.get()); + if(obj) { + ucount = t.getRefCount(); + ++ucount->totalRefCount; + } else { + ucount = new RefCount(1, 0); + } + } + + template + WeakHandle(const WeakHandle& t) { + obj = dynamic_cast(t.get()); + if(obj) { + ucount = t.getRefCount(); + ++ucount->totalRefCount; + } else { + ucount = new RefCount(1, 0); + } + } + + ~WeakHandle() { + releaseReference(); + } + + WeakHandle& operator=(const WeakHandle& t) { + ++t.getRefCount()->totalRefCount; + releaseReference(); + obj = t.get(); + ucount = t.getRefCount(); + return *this; + } + + template + WeakHandle& operator=(const SharedHandle& t) { + T* to = dynamic_cast(t.get()); + if(to) { + ++t.getRefCount()->totalRefCount; + releaseReference(); + obj = to; + ucount = t.getRefCount(); + } else { + releaseReference(); + obj = 0; + ucount = new RefCount(1, 0); + } + return *this; + } + + template + WeakHandle& operator=(const WeakHandle& t) { + T* to = dynamic_cast(t.get()); + if(to) { + ++t.getRefCount()->totalRefCount; + releaseReference(); + obj = to; + ucount = t.getRefCount(); + } else { + releaseReference(); + obj = 0; + ucount = new RefCount(1, 0); + } + return *this; + } + + T* operator->() { return obj; } + + T* operator->() const { return obj; } + + T* get() const { + if(isNull()) { + return 0; + } else { + return obj; + } + } + + RefCount* getRefCount() const { + return ucount; + } + + bool isNull() const { + return ucount->strongRefCount == 0 || obj == 0; + } +}; + +template +std::ostream& operator<<(std::ostream& o, const WeakHandle& sp) { + o << *sp.obj; + return o; +} + +template +bool operator==(const WeakHandle& t1, const WeakHandle& t2) { + return *t1.obj == *t2.obj; +} + +template +bool operator!=(const WeakHandle& t1, const WeakHandle& t2) { + return *t1.obj != *t2.obj; +} + +template +bool operator<(const WeakHandle& t1, const WeakHandle& t2) { + return *t1.obj < *t2.obj; +} + #endif // _D_SHARED_HANDLE_H_ diff --git a/src/SimpleBtMessage.cc b/src/SimpleBtMessage.cc index a79f5091..587c3c9e 100644 --- a/src/SimpleBtMessage.cc +++ b/src/SimpleBtMessage.cc @@ -53,7 +53,7 @@ void SimpleBtMessage::send() { leftDataLength = getMessageLength(); } sendingInProgress = false; - int writtenLength = PEER_CONNECTION(btContext, peer)->sendMessage(msg+msgLength-leftDataLength, leftDataLength); + int writtenLength = peerConnection->sendMessage(msg+msgLength-leftDataLength, leftDataLength); if(writtenLength == leftDataLength) { onSendComplete(); } else { diff --git a/src/Util.cc b/src/Util.cc index fe0fd3b6..3ba201df 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -574,20 +574,11 @@ static int nbits[] = { }; uint32_t Util::countBit(uint32_t n) { - /* return - nbits[n & 0xffu]+ - nbits[(n >> 8) & 0xffu]+ - nbits[(n >> 16) & 0xffu]+ - nbits[(n >> 24) & 0xffu]; - */ - uint32_t count = 0; - int size = sizeof(uint32_t); - for(int i = 0; i < size; i++) { - count += nbits[(n >> i*8) & 0xffu]; - } - - return count; + nbits[n&0xffu]+ + nbits[(n >> 8)&0xffu]+ + nbits[(n >> 16)&0xffu]+ + nbits[(n >> 24)&0xffu]; } string Util::randomAlpha(int length) { diff --git a/test/BtCancelMessageTest.cc b/test/BtCancelMessageTest.cc index adf82b1f..5ecaf984 100644 --- a/test/BtCancelMessageTest.cc +++ b/test/BtCancelMessageTest.cc @@ -109,7 +109,7 @@ void BtCancelMessageTest::testDoReceivedAction() { msg.setBtContext(btContext); msg.setPeer(peer); MockBtMessageDispatcher2Handle dispatcher = new MockBtMessageDispatcher2(); - PEER_OBJECT(btContext, peer)->btMessageDispatcher = dispatcher; + msg.setBtMessageDispatcher(dispatcher); msg.doReceivedAction(); CPPUNIT_ASSERT_EQUAL(msg.getIndex(), dispatcher->index); diff --git a/test/BtChokeMessageTest.cc b/test/BtChokeMessageTest.cc index 1a4f1684..bc4df245 100644 --- a/test/BtChokeMessageTest.cc +++ b/test/BtChokeMessageTest.cc @@ -1,6 +1,7 @@ #include "BtChokeMessage.h" #include "PeerMessageUtil.h" #include "MockBtMessageDispatcher.h" +#include "MockBtRequestFactory.h" #include "MockBtContext.h" #include @@ -56,6 +57,19 @@ public: }; typedef SharedHandle MockBtMessageDispatcher2Handle; + + class MockBtRequestFactory2 : public MockBtRequestFactory { + public: + bool doChokedActionCalled; + public: + MockBtRequestFactory2():doChokedActionCalled(false) {} + + virtual void doChokedAction() { + doChokedActionCalled = true; + } + }; + + typedef SharedHandle MockBtRequestFactory2Handle; }; @@ -99,8 +113,9 @@ void BtChokeMessageTest::testDoReceivedAction() { msg.setBtContext(btContext); MockBtMessageDispatcher2Handle dispatcher = new MockBtMessageDispatcher2(); - - PEER_OBJECT(btContext, peer)->btMessageDispatcher = dispatcher; + msg.setBtMessageDispatcher(dispatcher); + MockBtRequestFactory2Handle requestFactory = new MockBtRequestFactory2(); + msg.setBtRequestFactory(requestFactory); msg.doReceivedAction(); @@ -115,8 +130,7 @@ void BtChokeMessageTest::testOnSendComplete() { msg.setBtContext(btContext); MockBtMessageDispatcher2Handle dispatcher = new MockBtMessageDispatcher2(); - - PEER_OBJECT(btContext, peer)->btMessageDispatcher = dispatcher; + msg.setBtMessageDispatcher(dispatcher); msg.onSendComplete(); diff --git a/test/BtPieceMessageTest.cc b/test/BtPieceMessageTest.cc index 8a396c4d..39de49a2 100644 --- a/test/BtPieceMessageTest.cc +++ b/test/BtPieceMessageTest.cc @@ -94,6 +94,8 @@ public: msg->setBlockLength(16*1024); msg->setBtContext(btContext); msg->setPeer(peer); + msg->setBtMessageDispatcher(btMessageDispatcher); + msg->setBtMessageFactory(BT_MESSAGE_FACTORY(btContext, peer)); } }; diff --git a/test/BtRejectMessageTest.cc b/test/BtRejectMessageTest.cc index 3746cf25..bb626e49 100644 --- a/test/BtRejectMessageTest.cc +++ b/test/BtRejectMessageTest.cc @@ -82,7 +82,7 @@ public: msg->setIndex(1); msg->setBegin(16); msg->setLength(32); - + msg->setBtMessageDispatcher(dispatcher); } }; diff --git a/test/BtRequestMessageTest.cc b/test/BtRequestMessageTest.cc index 3331a099..5c55d72b 100644 --- a/test/BtRequestMessageTest.cc +++ b/test/BtRequestMessageTest.cc @@ -116,6 +116,8 @@ public: msg->setBegin(16); msg->setLength(32); msg->setBlockIndex(2); + msg->setBtMessageDispatcher(dispatcher); + msg->setBtMessageFactory(BT_MESSAGE_FACTORY(btContext, peer)); } }; diff --git a/test/DefaultBtMessageDispatcherTest.cc b/test/DefaultBtMessageDispatcherTest.cc index a8f6f91e..8461d7c9 100644 --- a/test/DefaultBtMessageDispatcherTest.cc +++ b/test/DefaultBtMessageDispatcherTest.cc @@ -33,7 +33,6 @@ class DefaultBtMessageDispatcherTest:public CppUnit::TestFixture { CPPUNIT_TEST_SUITE_END(); private: BtContextHandle btContext; - Option* option; PeerHandle peer; DefaultBtMessageDispatcherHandle btMessageDispatcher; MockPeerStorageHandle peerStorage; @@ -41,9 +40,7 @@ private: public: DefaultBtMessageDispatcherTest():btContext(0), peer(0), btMessageDispatcher(0) {} - void tearDown() { - delete option; - } + void tearDown() {} void testAddMessage(); void testSendMessages(); @@ -132,7 +129,6 @@ public: void setUp() { btContext = new DefaultBtContext(); btContext->load("test.torrent"); - option = new Option(); peer = new Peer("192.168.0.1", 6969, btContext->getPieceLength(), btContext->getTotalLength()); @@ -155,7 +151,8 @@ public: btMessageDispatcher->setCuid(1); btMessageDispatcher->setBtContext(btContext); btMessageDispatcher->setPeer(peer); - btMessageDispatcher->setOption(option); + btMessageDispatcher->setMaxUploadSpeedLimit(0); + btMessageDispatcher->setBtMessageFactory(peerObject->btMessageFactory); } }; @@ -172,7 +169,6 @@ void DefaultBtMessageDispatcherTest::testAddMessage() { } void DefaultBtMessageDispatcherTest::testSendMessages() { - option->put(PREF_MAX_UPLOAD_LIMIT, "0"); TransferStat stat; stat.setUploadSpeed(0); peerStorage->setStat(stat); @@ -192,7 +188,6 @@ void DefaultBtMessageDispatcherTest::testSendMessages() { } void DefaultBtMessageDispatcherTest::testSendMessages_underUploadLimit() { - option->put(PREF_MAX_UPLOAD_LIMIT, "0"); TransferStat stat; stat.setUploadSpeed(0); peerStorage->setStat(stat); @@ -212,7 +207,7 @@ void DefaultBtMessageDispatcherTest::testSendMessages_underUploadLimit() { } void DefaultBtMessageDispatcherTest::testSendMessages_overUploadLimit() { - option->put(PREF_MAX_UPLOAD_LIMIT, "100"); + btMessageDispatcher->setMaxUploadSpeedLimit(100); TransferStat stat; stat.setUploadSpeed(150); peerStorage->setStat(stat); @@ -289,13 +284,11 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() { CPPUNIT_ASSERT(BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(), pieceStorage)); - option->put(PREF_BT_REQUEST_TIMEOUT, "60"); - btMessageDispatcher = new DefaultBtMessageDispatcher(); btMessageDispatcher->setCuid(1); btMessageDispatcher->setBtContext(btContext); btMessageDispatcher->setPeer(peer); - btMessageDispatcher->setOption(option); + btMessageDispatcher->setRequestTimeout(60); btMessageDispatcher->addOutstandingRequest(slot); @@ -317,14 +310,15 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_tim pieceStorage->setPiece(piece); CPPUNIT_ASSERT(BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(), pieceStorage)); - option->put(PREF_BT_REQUEST_TIMEOUT, "60"); btMessageDispatcher = new DefaultBtMessageDispatcher(); btMessageDispatcher->setCuid(1); btMessageDispatcher->setBtContext(btContext); btMessageDispatcher->setPeer(peer); - btMessageDispatcher->setOption(option); - + btMessageDispatcher->setRequestTimeout(60); + btMessageDispatcher->setBtMessageFactory(BT_MESSAGE_FACTORY(btContext, + peer)); + btMessageDispatcher->addOutstandingRequest(slot); btMessageDispatcher->checkRequestSlotAndDoNecessaryThing(); @@ -346,13 +340,14 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_com CPPUNIT_ASSERT(BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(), pieceStorage)); - option->put(PREF_BT_REQUEST_TIMEOUT, "60"); btMessageDispatcher = new DefaultBtMessageDispatcher(); btMessageDispatcher->setCuid(1); btMessageDispatcher->setBtContext(btContext); btMessageDispatcher->setPeer(peer); - btMessageDispatcher->setOption(option); + btMessageDispatcher->setRequestTimeout(60); + btMessageDispatcher->setBtMessageFactory(BT_MESSAGE_FACTORY(btContext, + peer)); btMessageDispatcher->addOutstandingRequest(slot); diff --git a/test/DefaultBtRequestFactoryTest.cc b/test/DefaultBtRequestFactoryTest.cc index d03f95ce..f974e561 100644 --- a/test/DefaultBtRequestFactoryTest.cc +++ b/test/DefaultBtRequestFactoryTest.cc @@ -77,6 +77,7 @@ public: btRequestFactory->setBtContext(btContext); btRequestFactory->setPeer(peer); btRequestFactory->setBtMessageDispatcher(new MockBtMessageDispatcher()); + btRequestFactory->setBtMessageFactory(peerObject->btMessageFactory); } }; diff --git a/test/MockBtRequestFactory.h b/test/MockBtRequestFactory.h new file mode 100644 index 00000000..b87b6155 --- /dev/null +++ b/test/MockBtRequestFactory.h @@ -0,0 +1,30 @@ +#ifndef _D_MOCK_BT_REQUEST_FACTORY_H_ +#define _D_MOCK_BT_REQUEST_FACTORY_H_ + +#include "BtRequestFactory.h" + +class MockBtRequestFactory : public BtRequestFactory { +public: + virtual ~MockBtRequestFactory() {} + + virtual void addTargetPiece(const PieceHandle& piece) {} + + virtual void removeTargetPiece(const PieceHandle& piece) {} + + virtual void removeAllTargetPiece() {} + + virtual int countTargetPiece() { return 0; } + + virtual void removeCompletedPiece() {} + + virtual void doChokedAction() {} + + virtual BtMessages createRequestMessages(uint32_t max) { return BtMessages(); } + + virtual BtMessages createRequestMessagesOnEndGame(uint32_t max) { return BtMessages(); } +}; + +typedef SharedHandle MockBtRequestFactoryHandle; +typedef WeakHandle MockBtRequestFactoryWeakHandle; + +#endif // _D_MOCK_BT_REQUEST_FACTORY_H_