summaryrefslogtreecommitdiff
path: root/src/DHTAbstractNodeLookupTask.h
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-06-13 11:25:21 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-06-13 11:25:21 +0000
commit3dfbec0f9ff13c660252d20dce17c88041280019 (patch)
treef8197ebb95b99bb861e81236334d268e45d571a7 /src/DHTAbstractNodeLookupTask.h
parent532fc3724d5ece7a7a02cbe3b8db24d85da69626 (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.h160
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