X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/1a64ca4c11a1eb7ba2ecd102f877ac571486a034..9afa0d0db01da2ae64e48fb594cc87c186dde192:/examples/cpp/dht-kademlia/node.cpp diff --git a/examples/cpp/dht-kademlia/node.cpp b/examples/cpp/dht-kademlia/node.cpp index 8ffc0c15e7..68d56ebd08 100644 --- a/examples/cpp/dht-kademlia/node.cpp +++ b/examples/cpp/dht-kademlia/node.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. 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. */ @@ -7,6 +7,7 @@ #include "routing_table.hpp" XBT_LOG_NEW_DEFAULT_CATEGORY(kademlia_node, "Messages specific for this example"); +namespace sg4 = simgrid::s4u; namespace kademlia { static void destroy(void* message) @@ -15,6 +16,19 @@ static void destroy(void* message) delete msg; } +/** + * Try to asynchronously get a new message from given mailbox. Return null if none available. + */ +Message* Node::receive(sg4::Mailbox* mailbox) +{ + if (receive_comm == nullptr) + receive_comm = mailbox->get_async(&received_msg); + if (not receive_comm->test()) + return nullptr; + receive_comm = nullptr; + return received_msg; +} + /** * @brief Tries to join the network * @param known_id id of the node I know in the network. @@ -30,25 +44,21 @@ bool Node::join(unsigned int known_id) /* First step: Send a "FIND_NODE" request to the node we know */ sendFindNode(known_id, id_); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_)); + sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id_)); do { - if (receive_comm == nullptr) - receive_comm = mailbox->get_async(&received_msg); - if (receive_comm->test()) { + if (Message* msg = receive(mailbox)) { XBT_DEBUG("Received an answer from the node I know."); got_answer = true; // retrieve the node list and ping them. - const Answer* node_list = received_msg->answer_.get(); - if (node_list) { - for (auto const& contact : node_list->getNodes()) - routingTableUpdate(contact.first); + if (const Answer* node_list = msg->answer_.get()) { + for (auto const& [contact, _] : node_list->getNodes()) + routingTableUpdate(contact); } else { - handleFindNode(received_msg); + handleFindNode(msg); } - delete received_msg; - receive_comm = nullptr; + delete msg; } else - simgrid::s4u::this_actor::sleep_for(1); + sg4::this_actor::sleep_for(1); } while (not got_answer); /* Second step: Send a FIND_NODE to a random node in buckets */ @@ -74,11 +84,11 @@ bool Node::join(unsigned int known_id) 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)); + sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id)); /* Build the task */ - auto* 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, sg4::Mailbox::by_name(std::to_string(id_)), sg4::Host::current()->get_cname()); /* Send the task */ mailbox->put_init(msg, 1)->detach(kademlia::destroy); @@ -94,11 +104,11 @@ 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 const& node_to_query : node_list->getNodes()) { + 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 */ - sendFindNode(node_to_query.first, destination); + if (node_to_query != id_) { /* No need to query ourselves */ + sendFindNode(node_to_query, destination); j++; } i++; @@ -178,7 +188,7 @@ bool Node::findNode(unsigned int id_to_find, bool count_in_stats) unsigned int answers; bool destination_found = false; unsigned int nodes_added = 0; - double global_timeout = simgrid::s4u::Engine::get_clock() + FIND_NODE_GLOBAL_TIMEOUT; + double global_timeout = sg4::Engine::get_clock() + FIND_NODE_GLOBAL_TIMEOUT; unsigned int steps = 0; /* First we build a list of who we already know */ @@ -191,47 +201,43 @@ bool Node::findNode(unsigned int id_to_find, bool count_in_stats) answers = 0; queries = sendFindNodeToBest(node_list.get()); nodes_added = 0; - double timeout = simgrid::s4u::Engine::get_clock() + FIND_NODE_TIMEOUT; + double timeout = sg4::Engine::get_clock() + FIND_NODE_TIMEOUT; steps++; - double time_beginreceive = simgrid::s4u::Engine::get_clock(); + double time_beginreceive = sg4::Engine::get_clock(); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_)); + sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id_)); do { - if (receive_comm == nullptr) - receive_comm = mailbox->get_async(&received_msg); - - if (receive_comm->test()) { + if (Message* msg = receive(mailbox)) { // Check if what we have received is what we are looking for. - if (received_msg->answer_ && received_msg->answer_->getDestinationId() == id_to_find) { - routingTableUpdate(received_msg->sender_id_); + if (msg->answer_ && msg->answer_->getDestinationId() == id_to_find) { + routingTableUpdate(msg->sender_id_); // Handle the answer - for (auto const& contact : node_list->getNodes()) - routingTableUpdate(contact.first); + for (auto const& [contact, _] : node_list->getNodes()) + routingTableUpdate(contact); answers++; - nodes_added = node_list->merge(received_msg->answer_.get()); - XBT_DEBUG("Received an answer from %s (%s) with %zu nodes on it", received_msg->answer_to_->get_cname(), - received_msg->issuer_host_name_.c_str(), received_msg->answer_->getSize()); + nodes_added = node_list->merge(msg->answer_.get()); + 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_->getSize()); } else { - if (received_msg->answer_) { - routingTableUpdate(received_msg->sender_id_); + if (msg->answer_) { + routingTableUpdate(msg->sender_id_); XBT_DEBUG("Received a wrong answer for a FIND_NODE"); } else { - handleFindNode(received_msg); + handleFindNode(msg); } // Update the timeout if we didn't have our answer - timeout += simgrid::s4u::Engine::get_clock() - time_beginreceive; - time_beginreceive = simgrid::s4u::Engine::get_clock(); + timeout += sg4::Engine::get_clock() - time_beginreceive; + time_beginreceive = sg4::Engine::get_clock(); } - delete received_msg; - receive_comm = nullptr; + delete msg; } else { - simgrid::s4u::this_actor::sleep_for(1); + sg4::this_actor::sleep_for(1); } - } while (simgrid::s4u::Engine::get_clock() < timeout && answers < queries); + } while (sg4::Engine::get_clock() < timeout && answers < queries); destination_found = node_list->destinationFound(); - } while (not destination_found && (nodes_added > 0 || answers == 0) && - simgrid::s4u::Engine::get_clock() < global_timeout && steps < MAX_STEPS); + } while (not destination_found && (nodes_added > 0 || answers == 0) && sg4::Engine::get_clock() < global_timeout && + steps < MAX_STEPS); if (destination_found) { if (count_in_stats) @@ -266,9 +272,8 @@ void Node::handleFindNode(const Message* msg) 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 - 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()); + auto* answer = new Message(id_, msg->destination_id_, findClosest(msg->destination_id_), + sg4::Mailbox::by_name(std::to_string(id_)), sg4::Host::current()->get_cname()); // Sending the answer msg->answer_to_->put_init(answer, 1)->detach(kademlia::destroy); } @@ -301,7 +306,7 @@ unsigned int get_node_prefix(unsigned int id, unsigned int nb_bits) unsigned int size = sizeof(unsigned int) * 8; for (unsigned int j = 0; j < size; j++) { if (((id >> (size - 1 - j)) & 0x1) != 0) { - return nb_bits - (j); + return nb_bits - j; } } return 0;