diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-06-13 11:25:21 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-06-13 11:25:21 +0000 |
| commit | 3dfbec0f9ff13c660252d20dce17c88041280019 (patch) | |
| tree | f8197ebb95b99bb861e81236334d268e45d571a7 /src/DHTAbstractNodeLookupTask.h | |
| parent | 532fc3724d5ece7a7a02cbe3b8db24d85da69626 (diff) | |
2010-06-13 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten DHTMessageCallback using Visitor pattern. Eliminated
dynamic_pointer_cast.
* src/DHTMessageCallbackImpl.cc: Removed
* src/DHTMessageReceiver.cc
* src/DHTAbstractNodeLookupTask.h
* src/DHTAnnouncePeerReplyMessage.h
* src/DHTReplaceNodeTask.h
* src/DHTFindNodeReplyMessage.cc
* src/DHTGetPeersReplyMessage.h
* src/DHTPeerLookupTask.h
* src/DHTMessageCallbackImpl.h: Removed
* src/DHTMessageFactory.h
* src/DHTNodeLookupTaskCallback.h
* src/DHTMessageTracker.h
* src/DHTMessageCallbackListener.h: Removed
* src/DHTGetPeersReplyMessage.cc
* src/DHTMessageCallback.h
* src/DHTAnnouncePeerReplyMessage.cc
* src/DHTNodeLookupTask.h
* src/DHTReplaceNodeTask.cc
* src/DHTPeerLookupTaskCallback.cc
* src/DHTMessageTracker.cc
* src/DHTPingReplyMessage.cc
* src/DHTPingTask.cc
* src/DHTMessageFactoryImpl.h
* src/Makefile.am
* src/DHTNodeLookupTask.cc
* src/DHTPeerLookupTaskCallback.h
* src/DHTPeerLookupTask.cc
* src/DHTMessageReceiver.h
* src/DHTMessageFactoryImpl.cc
* src/DHTResponseMessage.h
* src/DHTFindNodeReplyMessage.h
* src/DHTPingReplyMessageCallback.h
* src/Makefile.in
* src/DHTBucketRefreshTask.cc
* src/DHTNodeLookupTaskCallback.cc
* src/DHTPingTask.h
* src/DHTPingReplyMessage.h
* src/DHTAbstractNodeLookupTask.cc: Removed
* test/DHTMessageTrackerTest.cc
* test/DHTPingMessageTest.cc
* test/DHTGetPeersMessageTest.cc
* test/MockDHTMessage.h
* test/MockDHTMessageFactory.h
* test/DHTFindNodeMessageTest.cc
* test/MockDHTMessageCallback.h
* test/DHTAnnouncePeerMessageTest.cc
Diffstat (limited to 'src/DHTAbstractNodeLookupTask.h')
| -rw-r--r-- | src/DHTAbstractNodeLookupTask.h | 160 |
1 files changed, 141 insertions, 19 deletions
diff --git a/src/DHTAbstractNodeLookupTask.h b/src/DHTAbstractNodeLookupTask.h index 0846b557..70089cd2 100644 --- a/src/DHTAbstractNodeLookupTask.h +++ b/src/DHTAbstractNodeLookupTask.h @@ -37,20 +37,31 @@ #include "DHTAbstractTask.h" +#include <cstring> +#include <algorithm> #include <deque> #include <vector> -#include "DHTMessageCallbackListener.h" #include "DHTConstants.h" #include "DHTNodeLookupEntry.h" +#include "DHTRoutingTable.h" +#include "DHTMessageDispatcher.h" +#include "DHTMessageFactory.h" +#include "DHTMessage.h" +#include "DHTNode.h" +#include "DHTBucket.h" +#include "LogFactory.h" +#include "Logger.h" +#include "util.h" +#include "DHTIDCloser.h" namespace aria2 { class DHTNode; class DHTMessage; -class DHTAbstractNodeLookupTask:public DHTAbstractTask, - public DHTMessageCallbackListener { +template<class ResponseMessage> +class DHTAbstractNodeLookupTask:public DHTAbstractTask { private: unsigned char _targetID[DHT_ID_LENGTH]; @@ -69,11 +80,44 @@ private: } } - void sendMessage(); + void sendMessage() + { + for(std::deque<SharedHandle<DHTNodeLookupEntry> >::iterator i = + _entries.begin(), eoi = _entries.end(); + i != eoi && _inFlightMessage < ALPHA; ++i) { + if((*i)->used == false) { + ++_inFlightMessage; + (*i)->used = true; + SharedHandle<DHTMessage> m = createMessage((*i)->node); + SharedHandle<DHTMessageCallback> callback(createCallback()); + getMessageDispatcher()->addMessageToQueue(m, callback); + } + } + } - void updateBucket(); + void sendMessageAndCheckFinish() + { + if(needsAdditionalOutgoingMessage()) { + sendMessage(); + } + if(_inFlightMessage == 0) { + if(getLogger()->debug()) { + getLogger()->debug("Finished node_lookup for node ID %s", + util::toHex(_targetID, DHT_ID_LENGTH).c_str()); + } + onFinish(); + updateBucket(); + setFinished(true); + } else { + if(getLogger()->debug()) { + getLogger()->debug("%d in flight message for node ID %s", + _inFlightMessage, + util::toHex(_targetID, DHT_ID_LENGTH).c_str()); + } + } + } - void sendMessageAndCheckFinish(); + void updateBucket() {} protected: const unsigned char* getTargetID() const { @@ -84,21 +128,13 @@ protected: { return _entries; } -public: - DHTAbstractNodeLookupTask(const unsigned char* targetID); - - static const size_t ALPHA = 3; - - virtual void startup(); - - virtual void onReceived(const SharedHandle<DHTMessage>& message); - virtual void onTimeout(const SharedHandle<DHTNode>& node); - - virtual void getNodesFromMessage(std::vector<SharedHandle<DHTNode> >& nodes, - const SharedHandle<DHTMessage>& message) = 0; + virtual void getNodesFromMessage + (std::vector<SharedHandle<DHTNode> >& nodes, + const ResponseMessage* message) = 0; - virtual void onReceivedInternal(const SharedHandle<DHTMessage>& message) {} + virtual void onReceivedInternal + (const ResponseMessage* message) {} virtual bool needsAdditionalOutgoingMessage() { return true; } @@ -106,6 +142,92 @@ public: virtual SharedHandle<DHTMessage> createMessage (const SharedHandle<DHTNode>& remoteNode) = 0; + + virtual SharedHandle<DHTMessageCallback> createCallback() = 0; +public: + DHTAbstractNodeLookupTask(const unsigned char* targetID): + _inFlightMessage(0) + { + memcpy(_targetID, targetID, DHT_ID_LENGTH); + } + + static const size_t ALPHA = 3; + + virtual void startup() + { + std::vector<SharedHandle<DHTNode> > nodes; + getRoutingTable()->getClosestKNodes(nodes, _targetID); + _entries.clear(); + toEntries(_entries, nodes); + if(_entries.empty()) { + setFinished(true); + } else { + // TODO use RTT here + _inFlightMessage = 0; + sendMessage(); + if(_inFlightMessage == 0) { + if(getLogger()->debug()) { + getLogger()->debug("No message was sent in this lookup stage. Finished."); + } + setFinished(true); + } + } + } + + void onReceived(const ResponseMessage* message) + { + --_inFlightMessage; + onReceivedInternal(message); + std::vector<SharedHandle<DHTNode> > nodes; + getNodesFromMessage(nodes, message); + std::vector<SharedHandle<DHTNodeLookupEntry> > newEntries; + toEntries(newEntries, nodes); + + size_t count = 0; + for(std::vector<SharedHandle<DHTNodeLookupEntry> >::const_iterator i = + newEntries.begin(), eoi = newEntries.end(); i != eoi; ++i) { + if(memcmp(getLocalNode()->getID(), (*i)->node->getID(), + DHT_ID_LENGTH) != 0) { + _entries.push_front(*i); + ++count; + if(getLogger()->debug()) { + getLogger()->debug("Received nodes: id=%s, ip=%s", + util::toHex((*i)->node->getID(), + DHT_ID_LENGTH).c_str(), + (*i)->node->getIPAddress().c_str()); + } + } + } + if(getLogger()->debug()) { + getLogger()->debug("%u node lookup entries added.", count); + } + std::stable_sort(_entries.begin(), _entries.end(), DHTIDCloser(_targetID)); + _entries.erase(std::unique(_entries.begin(), _entries.end()), _entries.end()); + if(getLogger()->debug()) { + getLogger()->debug("%u node lookup entries are unique.", _entries.size()); + } + if(_entries.size() > DHTBucket::K) { + _entries.erase(_entries.begin()+DHTBucket::K, _entries.end()); + } + sendMessageAndCheckFinish(); + } + + void onTimeout(const SharedHandle<DHTNode>& node) + { + if(getLogger()->debug()) { + getLogger()->debug("node lookup message timeout for node ID=%s", + util::toHex(node->getID(), DHT_ID_LENGTH).c_str()); + } + --_inFlightMessage; + for(std::deque<SharedHandle<DHTNodeLookupEntry> >::iterator i = + _entries.begin(), eoi = _entries.end(); i != eoi; ++i) { + if((*i)->node == node) { + _entries.erase(i); + break; + } + } + sendMessageAndCheckFinish(); + } }; } // namespace aria2 |
