X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/691d7c891da0352a6fa38507a482b287c7e086de..e080adacaf1ba847ad467f5b8d21da385636ed3c:/examples/s4u/dht-kademlia/node.cpp diff --git a/examples/s4u/dht-kademlia/node.cpp b/examples/s4u/dht-kademlia/node.cpp index 2f7a7567d3..86130d5713 100644 --- a/examples/s4u/dht-kademlia/node.cpp +++ b/examples/s4u/dht-kademlia/node.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2019. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2020. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,7 +11,7 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(kademlia_node, "Messages specific for this example" namespace kademlia { static void destroy(void* message) { - Message* msg = static_cast(message); + const auto* msg = static_cast(message); delete msg->answer_; delete msg; } @@ -22,8 +22,7 @@ static void destroy(void* message) */ bool Node::join(unsigned int known_id) { - Answer* node_list; - unsigned int i; + const Answer* node_list; bool got_answer = false; /* Add the guy we know to our routing table and ourselves. */ @@ -41,10 +40,10 @@ bool Node::join(unsigned int known_id) XBT_DEBUG("Received an answer from the node I know."); got_answer = true; // retrieve the node list and ping them. - Message* msg = static_cast(received_msg); + const auto* msg = static_cast(received_msg); node_list = msg->answer_; if (node_list) { - for (auto contact : node_list->nodes) + for (auto const& contact : node_list->getNodes()) routingTableUpdate(contact.first); } else { handleFindNode(msg); @@ -56,10 +55,10 @@ bool Node::join(unsigned int known_id) simgrid::s4u::this_actor::sleep_for(1); } while (not got_answer); - /* Second step: Send a FIND_NODE to a a random node in buckets */ + /* Second step: Send a FIND_NODE to a random node in buckets */ unsigned int bucket_id = table.findBucket(known_id)->getId(); xbt_assert(bucket_id <= IDENTIFIER_SIZE); - for (i = 0; ((bucket_id > i) || (bucket_id + i) <= IDENTIFIER_SIZE) && i < JOIN_BUCKETS_QUERIES; i++) { + for (unsigned int i = 0; ((bucket_id > i) || (bucket_id + i) <= IDENTIFIER_SIZE) && i < JOIN_BUCKETS_QUERIES; i++) { if (bucket_id > i) { unsigned int id_in_bucket = get_id_in_prefix(id_, bucket_id - i); findNode(id_in_bucket, false); @@ -76,13 +75,14 @@ bool Node::join(unsigned int known_id) * @param id node we are querying * @param destination node we are trying to find. */ -void Node::sendFindNode(unsigned int id, unsigned int destination) +void Node::sendFindNode(unsigned int id, unsigned int destination) const { /* Gets the mailbox to send to */ simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id)); /* Build the task */ - Message* msg = new Message(id_, destination, simgrid::s4u::Mailbox::by_name(std::to_string(id_)), - simgrid::s4u::Host::current()->get_cname()); + + auto* msg = new Message(id_, destination, simgrid::s4u::Mailbox::by_name(std::to_string(id_)), + simgrid::s4u::Host::current()->get_cname()); /* Send the task */ mailbox->put_init(msg, 1)->detach(kademlia::destroy); @@ -93,12 +93,12 @@ void Node::sendFindNode(unsigned int id, unsigned int destination) * Sends to the best "KADEMLIA_ALPHA" nodes in the "node_list" array a "FIND_NODE" request, to ask them for their best * nodes */ -unsigned int Node::sendFindNodeToBest(Answer* node_list) +unsigned int Node::sendFindNodeToBest(const Answer* node_list) const { unsigned int i = 0; unsigned int j = 0; unsigned int destination = node_list->getDestinationId(); - for (auto node_to_query : node_list->nodes) { + for (auto const& node_to_query : node_list->getNodes()) { /* We need to have at most "KADEMLIA_ALPHA" requests each time, according to the protocol */ /* Gets the node we want to send the query to */ if (node_to_query.first != id_) { /* No need to query ourselves */ @@ -121,19 +121,19 @@ void Node::routingTableUpdate(unsigned int id) Bucket* bucket = table.findBucket(id); // check if the id is already in the bucket. - auto id_pos = std::find(bucket->nodes.begin(), bucket->nodes.end(), id); + auto id_pos = std::find(bucket->nodes_.begin(), bucket->nodes_.end(), id); - if (id_pos == bucket->nodes.end()) { + if (id_pos == bucket->nodes_.end()) { /* We check if the bucket is full or not. If it is, we evict an old element */ - if (bucket->nodes.size() >= BUCKET_SIZE) { - bucket->nodes.pop_back(); + if (bucket->nodes_.size() >= BUCKET_SIZE) { + bucket->nodes_.pop_back(); } - bucket->nodes.push_front(id); + bucket->nodes_.push_front(id); XBT_VERB("I'm adding to my routing table %08x", id); } else { // We push the element to the front - bucket->nodes.erase(id_pos); - bucket->nodes.push_front(id); + bucket->nodes_.erase(id_pos); + bucket->nodes_.push_front(id); XBT_VERB("I'm updating %08x", id); } } @@ -144,7 +144,7 @@ void Node::routingTableUpdate(unsigned int id) */ Answer* Node::findClosest(unsigned int destination_id) { - Answer* answer = new Answer(destination_id); + auto* answer = new Answer(destination_id); /* We find the corresponding bucket for the id */ const Bucket* bucket = table.findBucket(destination_id); int bucket_id = bucket->getId(); @@ -158,17 +158,16 @@ Answer* Node::findClosest(unsigned int destination_id) for (int i = 1; answer->getSize() < BUCKET_SIZE && ((bucket_id - i > 0) || (bucket_id + i < IDENTIFIER_SIZE)); i++) { /* We check the previous buckets */ if (bucket_id - i >= 0) { - const Bucket* bucket_p = &table.buckets[bucket_id - i]; + const Bucket* bucket_p = &table.getBucketAt(bucket_id - i); answer->addBucket(bucket_p); } /* We check the next buckets */ if (bucket_id + i <= IDENTIFIER_SIZE) { - const Bucket* bucket_n = &table.buckets[bucket_id + i]; + const Bucket* bucket_n = &table.getBucketAt(bucket_id + i); answer->addBucket(bucket_n); } } /* We trim the array to have only BUCKET_SIZE or less elements */ - std::sort(answer->nodes.begin(), answer->nodes.end(), sortbydistance); answer->trim(); return answer; @@ -206,18 +205,18 @@ bool Node::findNode(unsigned int id_to_find, bool count_in_stats) receive_comm = mailbox->get_async(&received_msg); if (receive_comm->test()) { - Message* msg = static_cast(received_msg); + const auto* msg = static_cast(received_msg); // Check if what we have received is what we are looking for. if (msg->answer_ && msg->answer_->getDestinationId() == id_to_find) { routingTableUpdate(msg->sender_id_); // Handle the answer - for (auto contact : node_list->nodes) + for (auto const& contact : node_list->getNodes()) routingTableUpdate(contact.first); answers++; nodes_added = node_list->merge(msg->answer_); XBT_DEBUG("Received an answer from %s (%s) with %zu nodes on it", msg->answer_to_->get_cname(), - msg->issuer_host_name_.c_str(), msg->answer_->nodes.size()); + msg->issuer_host_name_.c_str(), msg->answer_->getSize()); } else { if (msg->answer_) { routingTableUpdate(msg->sender_id_); @@ -262,25 +261,30 @@ bool Node::findNode(unsigned int id_to_find, bool count_in_stats) void Node::randomLookup() { unsigned int id_to_look = RANDOM_LOOKUP_NODE; // Totally random. - /* TODO: Use some pseudo-random generator like RngStream. */ + /* TODO: Use some pseudo-random generator. */ XBT_DEBUG("I'm doing a random lookup"); findNode(id_to_look, true); } /** @brief Handles the answer to an incoming "find_node" task */ -void Node::handleFindNode(Message* msg) +void Node::handleFindNode(const Message* msg) { routingTableUpdate(msg->sender_id_); XBT_VERB("Received a FIND_NODE from %s (%s), he's trying to find %08x", msg->answer_to_->get_cname(), msg->issuer_host_name_.c_str(), msg->destination_id_); // Building the answer to the request - Message* answer = + auto* answer = new Message(id_, msg->destination_id_, findClosest(msg->destination_id_), simgrid::s4u::Mailbox::by_name(std::to_string(id_)), simgrid::s4u::Host::current()->get_cname()); // Sending the answer msg->answer_to_->put_init(answer, 1)->detach(kademlia::destroy); } + +void Node::displaySuccessRate() const +{ + XBT_INFO("%u/%u FIND_NODE have succeeded", find_node_success, find_node_success + find_node_failed); } +} // namespace kademlia /**@brief Returns an identifier which is in a specific bucket of a routing table * @param id id of the routing table owner * @param prefix id of the bucket where we want that identifier to be @@ -290,7 +294,7 @@ unsigned int get_id_in_prefix(unsigned int id, unsigned int prefix) if (prefix == 0) { return 0; } else { - return (1U << ((unsigned int)(prefix - 1))) ^ id; + return (1U << (prefix - 1)) ^ id; } }