/* */ #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), _numBucket(1), _logger(LogFactory::getInstance()) { SharedHandle bucket(new DHTBucket(_localNode)); _root = new BNode(bucket); } 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(SharedHandle()); 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->cacheNode(node); _logger->debug("Cached node=%s", node->toString().c_str()); } return false; } } return false; } void DHTRoutingTable::getClosestKNodes(std::deque >& nodes, const unsigned char* key) const { BNode::findClosestKNodes(nodes, _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); } void DHTRoutingTable::getBuckets(std::deque >& buckets) const { BNode::enumerateBucket(buckets, _root); } void DHTRoutingTable::setTaskQueue(const SharedHandle& taskQueue) { _taskQueue = taskQueue; } void DHTRoutingTable::setTaskFactory(const SharedHandle& taskFactory) { _taskFactory = taskFactory; } } // namespace aria2