* under the terms of the license (GNU LGPL) which comes with this package. */
#include <algorithm>
+#include <array>
#include <climits>
#include "s4u-peer.hpp"
constexpr double SLEEP_DURATION = 1.0;
#define BITS_TO_BYTES(x) (((x) / 8 + (x) % 8) ? 1 : 0)
+constexpr std::array<const char*, 10> message_type_names{
+ {"HANDSHAKE", "CHOKE", "UNCHOKE", "INTERESTED", "NOTINTERESTED", "HAVE", "BITFIELD", "REQUEST", "PIECE", "CANCEL"}};
+
Peer::Peer(std::vector<std::string> args)
{
// Check arguments
} catch (const std::invalid_argument&) {
throw std::invalid_argument("Invalid ID:" + args[1]);
}
+ random.set_seed(id);
try {
deadline = std::stod(args[2]);
{
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_);
+ auto* 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);
}
try {
- TrackerAnswer* answer = static_cast<TrackerAnswer*>(mailbox_->get(GET_PEERS_TIMEOUT));
+ auto* answer = static_cast<TrackerAnswer*>(mailbox_->get(GET_PEERS_TIMEOUT));
// Add the peers the tracker gave us to our peer list.
for (auto const& peer_id : answer->getPeers())
if (id != peer_id)
{
for (auto const& kv : connected_peers) {
const Connection& remote_peer = kv.second;
- Message* handshake = new Message(MESSAGE_HANDSHAKE, id, mailbox_);
+ auto* 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);
}
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());
+ XBT_DEBUG("Sending %s to %s", message_type_names.at(type), mailbox->get_cname());
mailbox->put_init(new Message(type, id, bitfield_, mailbox_), size)->detach();
}
xbt_assert(remote_peer->hasPiece(piece));
int block_index = getFirstMissingBlockFrom(piece);
if (block_index != -1) {
- int block_length = std::min(BLOCKS_REQUESTED, PIECES_BLOCKS - block_index);
+ int block_length = static_cast<int>(std::min(BLOCKS_REQUESTED, PIECES_BLOCKS - block_index));
XBT_DEBUG("Sending a REQUEST to %s for piece %u (%d,%d)", remote_peer->mailbox_->get_cname(), piece, block_index,
block_length);
remote_peer->mailbox_
}
}
-std::string Peer::getStatus()
+std::string Peer::getStatus() const
{
std::string res;
for (unsigned i = 0; i < FILE_PIECES; i++)
return res;
}
-bool Peer::hasFinished()
+bool Peer::hasFinished() const
{
return bitfield_ == (1U << FILE_PIECES) - 1U;
}
pieces_count[i]++;
}
-unsigned int Peer::countPieces(unsigned int bitfield)
+unsigned int Peer::countPieces(unsigned int bitfield) const
{
unsigned int count = 0U;
unsigned int n = bitfield;
return count;
}
-int Peer::nbInterestedPeers()
+int Peer::nbInterestedPeers() const
{
int nb = 0;
for (auto const& kv : connected_peers)
void Peer::handleMessage()
{
- const char* type_names[10] = {"HANDSHAKE", "CHOKE", "UNCHOKE", "INTERESTED", "NOTINTERESTED",
- "HAVE", "BITFIELD", "REQUEST", "PIECE", "CANCEL"};
-
- XBT_DEBUG("Received a %s message from %s", type_names[message->type], message->return_mailbox->get_cname());
+ XBT_DEBUG("Received a %s message from %s", message_type_names.at(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;
xbt_assert(nb_interesting_pieces != 0);
// get a random interesting piece
- int random_piece_index = simgrid::xbt::random::uniform_int(0, nb_interesting_pieces - 1);
+ int random_piece_index = random.uniform_int(0, nb_interesting_pieces - 1);
int current_index = 0;
for (unsigned int i = 0; i < FILE_PIECES; i++) {
if (remotePeerHasMissingPiece(remote_peer, i)) {
nb_interesting_pieces++;
xbt_assert(nb_interesting_pieces != 0);
// get a random interesting piece
- int random_piece_index = simgrid::xbt::random::uniform_int(0, nb_interesting_pieces - 1);
+ int random_piece_index = random.uniform_int(0, nb_interesting_pieces - 1);
int current_index = 0;
for (unsigned int i = 0; i < FILE_PIECES; i++) {
if (remotePeerHasMissingPiece(remote_peer, i) && isNotDownloadingPiece(i)) {
// get a random rarest piece
int random_rarest_index = 0;
if (nb_min_pieces > 0) {
- random_rarest_index = simgrid::xbt::random::uniform_int(0, nb_min_pieces - 1);
+ random_rarest_index = random.uniform_int(0, nb_min_pieces - 1);
}
for (unsigned int i = 0; i < FILE_PIECES; i++)
if (pieces_count[i] == min && remotePeerHasMissingPiece(remote_peer, i) && isNotDownloadingPiece(i)) {
int j = 0;
do {
// We choose a random peer to unchoke.
- std::unordered_map<int, Connection>::iterator chosen_peer_it = connected_peers.begin();
- std::advance(chosen_peer_it, simgrid::xbt::random::uniform_int(0, connected_peers.size() - 1));
+ auto chosen_peer_it = connected_peers.begin();
+ std::advance(chosen_peer_it, random.uniform_int(0, static_cast<int>(connected_peers.size() - 1)));
chosen_peer = &chosen_peer_it->second;
if (not chosen_peer->interested || not chosen_peer->choked_upload)
chosen_peer = nullptr;
bitfield_blocks |= (1ULL << static_cast<unsigned int>(piece * PIECES_BLOCKS + i));
}
-bool Peer::hasCompletedPiece(unsigned int piece)
+bool Peer::hasCompletedPiece(unsigned int piece) const
{
for (unsigned int i = 0; i < PIECES_BLOCKS; i++)
if (not(bitfield_blocks & 1ULL << (piece * PIECES_BLOCKS + i)))
return true;
}
-int Peer::getFirstMissingBlockFrom(int piece)
+int Peer::getFirstMissingBlockFrom(int piece) const
{
for (unsigned int i = 0; i < PIECES_BLOCKS; i++)
if (not(bitfield_blocks & 1ULL << (piece * PIECES_BLOCKS + i)))
}
/** Returns a piece that is partially downloaded and stored by the remote peer if any -1 otherwise. */
-int Peer::partiallyDownloadedPiece(const Connection* remote_peer)
+int Peer::partiallyDownloadedPiece(const Connection* remote_peer) const
{
for (unsigned int i = 0; i < FILE_PIECES; i++)
if (remotePeerHasMissingPiece(remote_peer, i) && isNotDownloadingPiece(i) && getFirstMissingBlockFrom(i) > 0)