Skip to content
Snippets Groups Projects
Unverified Commit b4b39f52 authored by Adrien Béraud's avatar Adrien Béraud Committed by Simon Désaulniers
Browse files

dht: new insertNode algorithm

parent c7a6e11a
Branches
Tags
No related merge requests found
...@@ -163,6 +163,7 @@ private: ...@@ -163,6 +163,7 @@ private:
struct Dht::SearchNode { struct Dht::SearchNode {
SearchNode() : node() {}
SearchNode(std::shared_ptr<Node> node) : node(node) {} SearchNode(std::shared_ptr<Node> node) : node(node) {}
using AnnounceStatusMap = std::map<Value::Id, std::shared_ptr<Request>>; using AnnounceStatusMap = std::map<Value::Id, std::shared_ptr<Request>>;
...@@ -576,31 +577,50 @@ Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, cons ...@@ -576,31 +577,50 @@ Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, cons
auto& node = *snode; auto& node = *snode;
const auto& nid = node.id; const auto& nid = node.id;
if (node.getFamily() != af) { if (node.getFamily() != af)
//DHT_LOG.DEBUG("Attempted to insert node in the wrong family.");
return false;
}
// Fast track for the case where the node is not relevant for this search
if (node.isExpired() && nodes.size() >= SEARCH_NODES && id.xorCmp(nid, nodes.back().node->id) > 0)
return false; return false;
bool found = false; bool found = false;
auto n = std::find_if(nodes.begin(), nodes.end(), [&](const SearchNode& sn) { auto n = nodes.end();
if (sn.node == snode) { while (n != nodes.begin()) {
--n;
if (n->node == snode) {
found = true; found = true;
return true; break;
}
if (id.xorCmp(nid, n->node->id) > 0) {
++n;
break;
}
} }
return id.xorCmp(nid, sn.node->id) < 0;
});
bool new_search_node = false; bool new_search_node = false;
if (!found) { if (!found) {
// Be more restricitve if there are too many // find if and where to trim excessive nodes
// good or unknown nodes in this search, auto t = nodes.cend();
unsigned num_bad_nodes = getNumberOfBadNodes(); size_t bad = 0; // number of bad nodes (if search is not expired)
if (nodes.size() - num_bad_nodes >= SEARCH_NODES) { bool full {false}; // is the search full (has the maximum nodes)
if (node.isExpired() or n == nodes.end()) if (expired) {
// if the search is expired, trim to SEARCH_NODES nodes
if (nodes.size() >= SEARCH_NODES) {
full = true;
t = nodes.begin() + SEARCH_NODES;
}
} else {
// otherwise, trim to SEARCH_NODES nodes, not counting bad nodes
bad = getNumberOfBadNodes();
full = nodes.size() - bad >= SEARCH_NODES;
while (std::distance(nodes.cbegin(), t) - bad > SEARCH_NODES) {
--t;
if (t->isBad())
bad--;
}
}
if (full) {
if (t != nodes.cend())
nodes.resize(std::distance(nodes.cbegin(), t));
if (n >= t)
return false; return false;
} }
...@@ -608,24 +628,22 @@ Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, cons ...@@ -608,24 +628,22 @@ Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, cons
if (nodes.empty()) { if (nodes.empty()) {
step_time = TIME_INVALID; step_time = TIME_INVALID;
} }
n = nodes.insert(n, SearchNode(snode)); n = nodes.insert(n, SearchNode(snode));
node.time = now; node.time = now;
new_search_node = true; new_search_node = true;
if (node.isExpired()) {
if (not expired)
bad++;
} else if (expired) {
bad = nodes.size() - 1;
expired = false;
}
// trim good nodes while (nodes.size() - bad > SEARCH_NODES) {
while (nodes.size() - num_bad_nodes > SEARCH_NODES) { if (not expired and nodes.back().isBad())
if (removeExpiredNode(now)) bad--;
num_bad_nodes--; nodes.pop_back();
auto to_remove = std::find_if(nodes.rbegin(), nodes.rend(),
[](const SearchNode& n) { return not n.isBad(); }
);
if (to_remove != nodes.rend()) {
nodes.erase(std::prev(to_remove.base()));
} // else, all nodes are expired.
} }
expired = false;
} }
if (not token.empty()) { if (not token.empty()) {
n->candidate = false; n->candidate = false;
...@@ -634,6 +652,9 @@ Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, cons ...@@ -634,6 +652,9 @@ Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, cons
n->token = token; n->token = token;
expired = false; expired = false;
} }
if (new_search_node) {
removeExpiredNode(now);
}
return new_search_node; return new_search_node;
} }
...@@ -729,10 +750,6 @@ Dht::searchStep(std::shared_ptr<Search> sr) ...@@ -729,10 +750,6 @@ Dht::searchStep(std::shared_ptr<Search> sr)
DHT_LOG.DEBUG("[search %s IPv%c] step (%d requests)", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', sr->currentGetRequests()); DHT_LOG.DEBUG("[search %s IPv%c] step (%d requests)", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', sr->currentGetRequests());
sr->step_time = now; sr->step_time = now;
/*
* The accurate delay between two refills has not been strongly determined.
* TODO: Emprical analysis over refill timeout.
*/
if (sr->refill_time + Node::NODE_EXPIRE_TIME < now and sr->nodes.size()-sr->getNumberOfBadNodes() < SEARCH_NODES) { if (sr->refill_time + Node::NODE_EXPIRE_TIME < now and sr->nodes.size()-sr->getNumberOfBadNodes() < SEARCH_NODES) {
if (auto added = sr->refill(sr->af == AF_INET ? buckets : buckets6, now)) { if (auto added = sr->refill(sr->af == AF_INET ? buckets : buckets6, now)) {
sr->refill_time = now; sr->refill_time = now;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment