/* */ #include "DHTRoutingTable.h" #include "DHTNode.h" #include "DHTBucket.h" #include "BNode.h" #include "DHTTaskQueue.h" #include "DHTTaskFactory.h" #include "DHTTask.h" #include "Util.h" #include "LogFactory.h" #include "Logger.h" namespace aria2 { DHTRoutingTable::DHTRoutingTable(const SharedHandle& localNode): _localNode(localNode), _root(new BNode(new DHTBucket(localNode))), _numBucket(1), _taskQueue(0), _taskFactory(0), _logger(LogFactory::getInstance()) {} DHTRoutingTable::~DHTRoutingTable() { delete _root; } bool DHTRoutingTable::addNode(const SharedHandle& node) { return addNode(node, false); } bool DHTRoutingTable::addGoodNode(const SharedHandle& node) { return addNode(node, true); } bool DHTRoutingTable::addNode(const SharedHandle& node, bool good) { _logger->debug("Trying to add node:%s", node->toString().c_str()); BNode* bnode = BNode::findBNodeFor(_root, node->getID()); SharedHandle bucket = bnode->getBucket(); while(1) { if(bucket->addNode(node)) { _logger->debug("Added DHTNode."); return true; } else if(bucket->splitAllowed()) { _logger->debug("Splitting bucket. Range:%s-%s", Util::toHex(bucket->getMinID(), DHT_ID_LENGTH).c_str(), Util::toHex(bucket->getMaxID(), DHT_ID_LENGTH).c_str()); SharedHandle r = bucket->split(); bnode->setBucket(0); BNode* lbnode = new BNode(bucket); BNode* rbnode = new BNode(r); bnode->setLeft(lbnode); bnode->setRight(rbnode); ++_numBucket; if(r->isInRange(node)) { bucket = r; bnode = rbnode; } else { bnode = lbnode; } } else { if(good && bucket->containsQuestionableNode()) { _logger->debug("Issuing ReplaceNodeTask: new node=%s", node->toString().c_str()); _taskQueue->addImmediateTask(_taskFactory->createReplaceNodeTask(bucket, node)); } return false; } } return false; } std::deque > DHTRoutingTable::getClosestKNodes(const unsigned char* key) const { return BNode::findClosestKNodes(_root, key); } size_t DHTRoutingTable::countBucket() const { return _numBucket; } void DHTRoutingTable::showBuckets() const {/* for(std::deque >::const_iterator itr = _buckets.begin(); itr != _buckets.end(); ++itr) { cerr << "prefix = " << (*itr)->getPrefixLength() << ", " << "nodes = " << (*itr)->countNode() << endl; } */ } SharedHandle DHTRoutingTable::getBucketFor(const unsigned char* nodeID) const { return BNode::findBucketFor(_root, nodeID); } SharedHandle DHTRoutingTable::getBucketFor(const SharedHandle& node) const { return getBucketFor(node->getID()); } SharedHandle DHTRoutingTable::getNode(const unsigned char* nodeID, const std::string& ipaddr, uint16_t port) const { SharedHandle bucket = getBucketFor(nodeID); return bucket->getNode(nodeID, ipaddr, port); } void DHTRoutingTable::dropNode(const SharedHandle& node) { getBucketFor(node)->dropNode(node); } /* void DHTRoutingTable::moveBucketHead(const SharedHandle& node) { getBucketFor(node)->moveToHead(node); } */ void DHTRoutingTable::moveBucketTail(const SharedHandle& node) { getBucketFor(node)->moveToTail(node); } std::deque > DHTRoutingTable::getBuckets() const { return BNode::enumerateBucket(_root); } void DHTRoutingTable::setTaskQueue(const SharedHandle& taskQueue) { _taskQueue = taskQueue; } void DHTRoutingTable::setTaskFactory(const SharedHandle& taskFactory) { _taskFactory = taskFactory; } } // namespace aria2