X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/b024b9e443552c94609fc56a240cdb199a329853..5997f75835d50b618ea8f7030ff2f554b32350d9:/examples/s4u/app-bittorrent/s4u-peer.cpp diff --git a/examples/s4u/app-bittorrent/s4u-peer.cpp b/examples/s4u/app-bittorrent/s4u-peer.cpp index d36aae49e9..360bb203ac 100644 --- a/examples/s4u/app-bittorrent/s4u-peer.cpp +++ b/examples/s4u/app-bittorrent/s4u-peer.cpp @@ -33,35 +33,26 @@ Peer::Peer(std::vector args) try { id = std::stoi(args[1]); mailbox_ = simgrid::s4u::Mailbox::by_name(std::to_string(id)); - } catch (std::invalid_argument& ia) { - throw std::invalid_argument(std::string("Invalid ID:") + args[1].c_str()); + } catch (const std::invalid_argument&) { + throw std::invalid_argument("Invalid ID:" + args[1]); } try { deadline = std::stod(args[2]); - } catch (std::invalid_argument& ia) { - throw std::invalid_argument(std::string("Invalid deadline:") + args[2].c_str()); + } catch (const std::invalid_argument&) { + throw std::invalid_argument("Invalid deadline:" + args[2]); } xbt_assert(deadline > 0, "Wrong deadline supplied"); - stream = simgrid::s4u::this_actor::get_host()->extension()->getStream(); - if (args.size() == 4 && args[3] == "1") { bitfield_ = (1U << FILE_PIECES) - 1U; bitfield_blocks = (1ULL << (FILE_PIECES * PIECES_BLOCKS)) - 1ULL; } - pieces_count = new short[FILE_PIECES]{0}; + pieces_count.resize(FILE_PIECES); XBT_INFO("Hi, I'm joining the network with id %d", id); } -Peer::~Peer() -{ - for (auto const& peer : connected_peers) - delete peer.second; - delete[] pieces_count; -} - /** Peer main function */ void Peer::operator()() { @@ -85,13 +76,13 @@ void Peer::operator()() bool Peer::getPeersFromTracker() { - simgrid::s4u::MailboxPtr tracker_mailbox = simgrid::s4u::Mailbox::by_name(TRACKER_MAILBOX); + simgrid::s4u::Mailbox* tracker_mailbox = simgrid::s4u::Mailbox::by_name(TRACKER_MAILBOX); // Build the task to send to the tracker TrackerQuery* peer_request = new TrackerQuery(id, mailbox_); try { XBT_DEBUG("Sending a peer request to the tracker."); tracker_mailbox->put(peer_request, TRACKER_COMM_SIZE, GET_PEERS_TIMEOUT); - } catch (simgrid::TimeoutError& e) { + } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Timeout expired when requesting peers to tracker"); delete peer_request; return false; @@ -100,11 +91,11 @@ bool Peer::getPeersFromTracker() try { TrackerAnswer* answer = static_cast(mailbox_->get(GET_PEERS_TIMEOUT)); // Add the peers the tracker gave us to our peer list. - for (auto const& peer_id : *answer->getPeers()) + for (auto const& peer_id : answer->getPeers()) if (id != peer_id) - connected_peers[peer_id] = new Connection(peer_id); + connected_peers.emplace(peer_id, Connection(peer_id)); delete answer; - } catch (simgrid::TimeoutError& e) { + } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Timeout expired when requesting peers to tracker"); return false; } @@ -114,21 +105,21 @@ bool Peer::getPeersFromTracker() void Peer::sendHandshakeToAllPeers() { for (auto const& kv : connected_peers) { - Connection* remote_peer = kv.second; + const Connection& remote_peer = kv.second; Message* handshake = new Message(MESSAGE_HANDSHAKE, id, mailbox_); - remote_peer->mailbox_->put_init(handshake, MESSAGE_HANDSHAKE_SIZE)->detach(); - XBT_DEBUG("Sending a HANDSHAKE to %d", remote_peer->id); + remote_peer.mailbox_->put_init(handshake, MESSAGE_HANDSHAKE_SIZE)->detach(); + XBT_DEBUG("Sending a HANDSHAKE to %d", remote_peer.id); } } -void Peer::sendMessage(simgrid::s4u::MailboxPtr mailbox, e_message_type type, uint64_t size) +void Peer::sendMessage(simgrid::s4u::Mailbox* mailbox, e_message_type type, uint64_t size) { const char* type_names[6] = {"HANDSHAKE", "CHOKE", "UNCHOKE", "INTERESTED", "NOTINTERESTED", "CANCEL"}; XBT_DEBUG("Sending %s to %s", type_names[type], mailbox->get_cname()); mailbox->put_init(new Message(type, id, bitfield_, mailbox_), size)->detach(); } -void Peer::sendBitfield(simgrid::s4u::MailboxPtr mailbox) +void Peer::sendBitfield(simgrid::s4u::Mailbox* mailbox) { XBT_DEBUG("Sending a BITFIELD to %s", mailbox->get_cname()); mailbox @@ -137,7 +128,7 @@ void Peer::sendBitfield(simgrid::s4u::MailboxPtr mailbox) ->detach(); } -void Peer::sendPiece(simgrid::s4u::MailboxPtr mailbox, unsigned int piece, int block_index, int block_length) +void Peer::sendPiece(simgrid::s4u::Mailbox* mailbox, unsigned int piece, int block_index, int block_length) { xbt_assert(not hasNotPiece(piece), "Tried to send a unavailable piece."); XBT_DEBUG("Sending the PIECE %u (%d,%d) to %s", piece, block_index, block_length, mailbox->get_cname()); @@ -148,8 +139,8 @@ void Peer::sendHaveToAllPeers(unsigned int piece) { XBT_DEBUG("Sending HAVE message to all my peers"); for (auto const& kv : connected_peers) { - Connection* remote_peer = kv.second; - remote_peer->mailbox_->put_init(new Message(MESSAGE_HAVE, id, mailbox_, piece), MESSAGE_HAVE_SIZE)->detach(); + const Connection& remote_peer = kv.second; + remote_peer.mailbox_->put_init(new Message(MESSAGE_HAVE, id, mailbox_, piece), MESSAGE_HAVE_SIZE)->detach(); } } @@ -217,7 +208,7 @@ int Peer::nbInterestedPeers() { int nb = 0; for (auto const& kv : connected_peers) - if (kv.second->interested) + if (kv.second.interested) nb++; return nb; } @@ -298,7 +289,7 @@ void Peer::handleMessage() XBT_DEBUG("Received a %s message from %s", type_names[message->type], message->return_mailbox->get_cname()); auto known_peer = connected_peers.find(message->peer_id); - Connection* remote_peer = (known_peer == connected_peers.end()) ? nullptr : known_peer->second; + Connection* remote_peer = (known_peer == connected_peers.end()) ? nullptr : &known_peer->second; xbt_assert(remote_peer != nullptr || message->type == MESSAGE_HANDSHAKE, "The impossible did happened: A not-in-our-list peer sent us a message."); @@ -307,7 +298,7 @@ void Peer::handleMessage() // Check if the peer is in our connection list. if (remote_peer == nullptr) { XBT_DEBUG("This peer %d was unknown, answer to its handshake", message->peer_id); - connected_peers[message->peer_id] = new Connection(message->peer_id); + connected_peers.emplace(message->peer_id, Connection(message->peer_id)); sendMessage(message->return_mailbox, MESSAGE_HANDSHAKE, MESSAGE_HANDSHAKE_SIZE); } // Send our bitfield to the peer @@ -463,7 +454,8 @@ int Peer::selectPieceToDownload(Connection* remote_peer) xbt_assert(nb_interesting_pieces != 0); // get a random interesting piece - int random_piece_index = RngStream_RandInt(stream, 0, nb_interesting_pieces - 1); + std::uniform_int_distribution dist(0, nb_interesting_pieces - 1); + int random_piece_index = dist(generator); int current_index = 0; for (unsigned int i = 0; i < FILE_PIECES; i++) { if (hasNotPiece(i) && remote_peer->hasPiece(i)) { @@ -486,7 +478,8 @@ int Peer::selectPieceToDownload(Connection* remote_peer) nb_interesting_pieces++; xbt_assert(nb_interesting_pieces != 0); // get a random interesting piece - int random_piece_index = RngStream_RandInt(stream, 0, nb_interesting_pieces - 1); + std::uniform_int_distribution dist(0, nb_interesting_pieces - 1); + int random_piece_index = dist(generator); int current_index = 0; for (unsigned int i = 0; i < FILE_PIECES; i++) { if (hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) { @@ -517,7 +510,11 @@ int Peer::selectPieceToDownload(Connection* remote_peer) xbt_assert(nb_min_pieces != 0 || not isInterestedByFree(remote_peer)); // get a random rarest piece - int random_rarest_index = RngStream_RandInt(stream, 0, nb_min_pieces - 1); + int random_rarest_index = 0; + if (nb_min_pieces > 0) { + std::uniform_int_distribution dist(0, nb_min_pieces - 1); + random_rarest_index = dist(generator); + } for (unsigned int i = 0; i < FILE_PIECES; i++) if (pieces_count[i] == min && hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) { if (random_rarest_index == current_index) { @@ -551,13 +548,12 @@ void Peer::updateChokedPeers() /**If we are currently seeding, we unchoke the peer which has been unchoked the last time.*/ if (hasFinished()) { - Connection* remote_peer; double unchoke_time = simgrid::s4u::Engine::get_clock() + 1; - for (auto const& kv : connected_peers) { - remote_peer = kv.second; - if (remote_peer->last_unchoke < unchoke_time && remote_peer->interested && remote_peer->choked_upload) { - unchoke_time = remote_peer->last_unchoke; - chosen_peer = remote_peer; + for (auto& kv : connected_peers) { + Connection& remote_peer = kv.second; + if (remote_peer.last_unchoke < unchoke_time && remote_peer.interested && remote_peer.choked_upload) { + unchoke_time = remote_peer.last_unchoke; + chosen_peer = &remote_peer; } } } else { @@ -566,12 +562,11 @@ void Peer::updateChokedPeers() int j = 0; do { // We choose a random peer to unchoke. - std::unordered_map::iterator chosen_peer_it = connected_peers.begin(); - std::advance(chosen_peer_it, RngStream_RandInt(stream, 0, connected_peers.size() - 1)); - chosen_peer = chosen_peer_it->second; - if (chosen_peer == nullptr) - THROWF(unknown_error, 0, "A peer should have be selected at this point"); - else if (not chosen_peer->interested || not chosen_peer->choked_upload) + std::unordered_map::iterator chosen_peer_it = connected_peers.begin(); + std::uniform_int_distribution dist(0, connected_peers.size() - 1); + std::advance(chosen_peer_it, dist(generator)); + chosen_peer = &chosen_peer_it->second; + if (not chosen_peer->interested || not chosen_peer->choked_upload) chosen_peer = nullptr; else XBT_DEBUG("Nothing to do, keep going"); @@ -580,11 +575,11 @@ void Peer::updateChokedPeers() } else { // Use the "fastest download" policy. double fastest_speed = 0.0; - for (auto const& kv : connected_peers) { - Connection* remote_peer = kv.second; - if (remote_peer->peer_speed > fastest_speed && remote_peer->choked_upload && remote_peer->interested) { - chosen_peer = remote_peer; - fastest_speed = remote_peer->peer_speed; + for (auto& kv : connected_peers) { + Connection& remote_peer = kv.second; + if (remote_peer.peer_speed > fastest_speed && remote_peer.choked_upload && remote_peer.interested) { + fastest_speed = remote_peer.peer_speed; + chosen_peer = &remote_peer; } } } @@ -617,20 +612,20 @@ void Peer::updateChokedPeers() /** @brief Update "interested" state of peers: send "not interested" to peers that don't have any more pieces we want.*/ void Peer::updateInterestedAfterReceive() { - for (auto const& kv : connected_peers) { - Connection* remote_peer = kv.second; - if (remote_peer->am_interested) { + for (auto& kv : connected_peers) { + Connection& remote_peer = kv.second; + if (remote_peer.am_interested) { bool interested = false; // Check if the peer still has a piece we want. for (unsigned int i = 0; i < FILE_PIECES; i++) - if (hasNotPiece(i) && remote_peer->hasPiece(i)) { + if (hasNotPiece(i) && remote_peer.hasPiece(i)) { interested = true; break; } if (not interested) { // no more piece to download from connection - remote_peer->am_interested = false; - sendMessage(remote_peer->mailbox_, MESSAGE_NOTINTERESTED, MESSAGE_NOTINTERESTED_SIZE); + remote_peer.am_interested = false; + sendMessage(remote_peer.mailbox_, MESSAGE_NOTINTERESTED, MESSAGE_NOTINTERESTED_SIZE); } } }