JNIEXPORT jint JNICALL Java_org_simgrid_msg_RngStream_randInt(JNIEnv *env, jobject jrngstream, jint i, jint j) { RngStream rngstream = jrngstream_to_native(env, jrngstream); if (!rngstream) return 0; return (jint)RngStream_RandInt(rngstream, (int)i, (int)j); }
/* Performs a find successor request to a random id */ void Node::randomLookup() { int res = id_; int random_index = RngStream_RandInt(stream, 0, nb_bits - 1); int random_id = fingers_[random_index]; XBT_DEBUG("Making a lookup request for id %d", random_id); if (random_id != id_) res = findSuccessor(random_id); XBT_DEBUG("The successor of node %d is %d", random_id, res); }
/** * Tracker main function * @param argc number of arguments * @param argv arguments */ int tracker(int argc, char *argv[]) { int i; RngStream stream = (RngStream) MSG_host_get_property_value(MSG_host_self(), "stream"); //Checking arguments xbt_assert(argc == 2, "Wrong number of arguments for the tracker."); //Retrieving end time double deadline = atof(argv[1]); xbt_assert(deadline > 0, "Wrong deadline supplied"); //Building peers array xbt_dynar_t peers_list = xbt_dynar_new(sizeof(int), NULL); XBT_INFO("Tracker launched."); msg_comm_t comm_received = NULL; msg_task_t task_received = NULL; while (MSG_get_clock() < deadline) { if (comm_received == NULL) { comm_received = MSG_task_irecv(&task_received, TRACKER_MAILBOX); } if (MSG_comm_test(comm_received)) { //Check for correct status if (MSG_comm_get_status(comm_received) == MSG_OK) { //Retrieve the data sent by the peer. tracker_task_data_t data = MSG_task_get_data(task_received); //Add the peer to our peer list. if (!is_in_list(peers_list, data->peer_id)) { xbt_dynar_push_as(peers_list, int, data->peer_id); } //Sending peers to the peer int next_peer; int peers_length = xbt_dynar_length(peers_list); for (i = 0; i < MAXIMUM_PAIRS && i < peers_length; i++) { do { next_peer = xbt_dynar_get_as(peers_list, RngStream_RandInt(stream, 0, peers_length - 1), int); } while (is_in_list(data->peers, next_peer)); xbt_dynar_push_as(data->peers, int, next_peer); } //setting the interval data->interval = TRACKER_QUERY_INTERVAL; //sending the task back to the peer. MSG_task_dsend(task_received, data->mailbox, task_free); //destroy the communication. } MSG_comm_destroy(comm_received); comm_received = NULL; task_received = NULL; } else {
void Peer::updateChokedPeers() { if (nbInterestedPeers() == 0) return; XBT_DEBUG("(%d) update_choked peers %zu active peers", id, active_peers.size()); // update the current round round_ = (round_ + 1) % 3; Connection* chosen_peer = nullptr; // select first active peer and remove it from the set Connection* choked_peer; if (active_peers.empty()) { choked_peer = nullptr; } else { choked_peer = *active_peers.begin(); active_peers.erase(choked_peer); } /**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; } } } else { // Random optimistic unchoking if (round_ == 0) { 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, 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) chosen_peer = nullptr; else XBT_DEBUG("Nothing to do, keep going"); j++; } while (chosen_peer == nullptr && j < MAXIMUM_PEERS); } 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; } } } } if (chosen_peer != nullptr) XBT_DEBUG("(%d) update_choked peers unchoked (%d) ; int (%d) ; choked (%d) ", id, chosen_peer->id, chosen_peer->interested, chosen_peer->choked_upload); if (choked_peer != chosen_peer) { if (choked_peer != nullptr) { xbt_assert(not choked_peer->choked_upload, "Tries to choked a choked peer"); choked_peer->choked_upload = true; updateActivePeersSet(choked_peer); XBT_DEBUG("(%d) Sending a CHOKE to %d", id, choked_peer->id); sendMessage(choked_peer->mailbox_, MESSAGE_CHOKE, MESSAGE_CHOKE_SIZE); } if (chosen_peer != nullptr) { xbt_assert((chosen_peer->choked_upload), "Tries to unchoked an unchoked peer"); chosen_peer->choked_upload = false; active_peers.insert(chosen_peer); chosen_peer->last_unchoke = simgrid::s4u::Engine::get_clock(); XBT_DEBUG("(%d) Sending a UNCHOKE to %d", id, chosen_peer->id); updateActivePeersSet(chosen_peer); sendMessage(chosen_peer->mailbox_, MESSAGE_UNCHOKE, MESSAGE_UNCHOKE_SIZE); } } }
/** @brief Return the piece to be downloaded * There are two cases (as described in "Bittorrent Architecture Protocol", Ryan Toole : * If a piece is partially downloaded, this piece will be selected prioritarily * If the peer has strictly less than 4 pieces, he chooses a piece at random. * If the peer has more than pieces, he downloads the pieces that are the less replicated (rarest policy). * If all pieces have been downloaded or requested, we select a random requested piece (endgame mode). * @param remote_peer: information about the connection * @return the piece to download if possible. -1 otherwise */ int Peer::selectPieceToDownload(Connection* remote_peer) { int piece = partiallyDownloadedPiece(remote_peer); // strict priority policy if (piece != -1) return piece; // end game mode if (countPieces(current_pieces) >= (FILE_PIECES - countPieces(bitfield_)) && isInterestedBy(remote_peer)) { #if ENABLE_END_GAME_MODE == 0 return -1; #endif int nb_interesting_pieces = 0; // compute the number of interesting pieces for (unsigned int i = 0; i < FILE_PIECES; i++) if (hasNotPiece(i) && remote_peer->hasPiece(i)) 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); int current_index = 0; for (unsigned int i = 0; i < FILE_PIECES; i++) { if (hasNotPiece(i) && remote_peer->hasPiece(i)) { if (random_piece_index == current_index) { piece = i; break; } current_index++; } } xbt_assert(piece != -1); return piece; } // Random first policy if (countPieces(bitfield_) < 4 && isInterestedByFree(remote_peer)) { int nb_interesting_pieces = 0; // compute the number of interesting pieces for (unsigned int i = 0; i < FILE_PIECES; i++) if (hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) 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); int current_index = 0; for (unsigned int i = 0; i < FILE_PIECES; i++) { if (hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) { if (random_piece_index == current_index) { piece = i; break; } current_index++; } } xbt_assert(piece != -1); return piece; } else { // Rarest first policy short min = SHRT_MAX; int nb_min_pieces = 0; int current_index = 0; // compute the smallest number of copies of available pieces for (unsigned int i = 0; i < FILE_PIECES; i++) { if (pieces_count[i] < min && hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) min = pieces_count[i]; } xbt_assert(min != SHRT_MAX || not isInterestedByFree(remote_peer)); // compute the number of rarest pieces for (unsigned int i = 0; i < FILE_PIECES; i++) if (pieces_count[i] == min && hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) nb_min_pieces++; 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); 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) { piece = i; break; } current_index++; } xbt_assert(piece != -1 || not isInterestedByFree(remote_peer)); return piece; } }
// Performs one iteration of the primal process void primal_run (primal_t *primal) { instance_t *inst = primal->inst; solution_t *s = primal->sol; int i, w, n, aspiration, n_best, n_free, n_diver; double best_gain; check_solution(inst, s); //% Algorithm 1 Step 4 (cont'd) // Perform moves to conform with the improving partial solution for (i = 0; i < inst->n; i++) if (primal->improving_partial_x[i] != -1 && primal->tabu[i] != INFINITY) { primal->tabu[i] = INFINITY; if (s->x[i] != primal->improving_partial_x[i]) { solution_flip(inst, s, i); check_solution(inst, s); ++primal->n_moves; if (s->total_cost < primal->best_z) { primal->n_moves_at_last_improvement = primal->n_moves; primal->best_z = s->total_cost; memcpy(primal->best_x, s->x, inst->n * sizeof(int)); } } } // Perturb tabu state using the guiding solution if (primal->n_moves_at_last_improvement + inst->request_period < primal->n_moves) { primal->n_moves_at_last_improvement = primal->n_moves; for (i = 0; i < inst->n; i++) if (primal->tabu[i] != INFINITY && s->x[i] == primal->guiding_x[i]) primal->tabu[i] = ((double) primal->n_moves) + primal->tabu_length; } // Analyze search state //% Algorithm 1 step 1 for (aspiration = 0, best_gain = -INFINITY, n_best = n_free = n_diver = 0, i = 0; i < inst->n; i++) if (primal->tabu[i] == INFINITY) { assert(s->x[i] == primal->improving_partial_x[i]); } else { ++n_free; // count the number of unfixed locations if ((primal->n_moves == 0 || (s->total_cost - s->flip_gain[i] <= primal->best_z - bound_eps)) && s->flip_gain[i] != INFINITY) aspiration = 1; // aspiration criterion is satisfied if ((double) primal->n_moves > primal->tabu[i] || aspiration) { ++n_diver; // count the number of non-tabu locations if (s->flip_gain[i] > best_gain + bound_eps && best_gain != INFINITY) n_best = 1, best_gain = s->flip_gain[i]; // store the best location to perform a move on else if (fabs(s->flip_gain[i] - best_gain) < 2.0 * bound_eps || (s->flip_gain[i] == INFINITY && best_gain == INFINITY)) ++n_best; // count the number of best locations } } // Select the 1OPT move to perform w = -1; if (best_gain <= bound_eps) { // if there exist no improving moves if (n_free == 0) { // if there exist no moves //% Algorithm 1 step 1(d) return; } if (n_diver == 0) { // if there exist no non-tabu moves // select one location at random //% Algorithm 1 step 1(c) n = RngStream_RandInt(primal->rng, 0, n_free - 1); for (i = 0; i < inst->n && w == -1; i++) if (primal->tabu[i] != INFINITY && n-- <= 0) w = i; } else { // there exist non-tabu moves // select one location at random //% Algorithm 1 step 1(b) n = RngStream_RandInt(primal->rng, 0, n_diver - 1); for (i = 0; i < inst->n && w == -1; i++) if (((double) primal->n_moves > primal->tabu[i] || aspiration) && n-- <= 0) w = i; } } else { // there exists at least one improving move // select one of the best at random //% Algorithm 1 step 1(a) assert(n_best > 0); n = RngStream_RandInt(primal->rng, 0, n_best - 1); for (w = -1, i = 0; i < inst->n && w == -1; i++) if (((double) primal->n_moves > primal->tabu[i] || aspiration) && (fabs(s->flip_gain[i] - best_gain) < 2.0 * bound_eps || (s->flip_gain[i] == INFINITY && best_gain == INFINITY)) && n-- <= 0) w = i; } // check that in all cases we have found something assert(w >= 0); assert(w < inst->n); assert(primal->tabu[w] != INFINITY); // Update search state //% Algorithm 1 step 2 tabu_tenure(primal, w, (s->flip_gain[w] > bound_eps)); //% Algorithm 1 step 3(a,b,c) solution_flip(inst, s, w); check_solution(inst, s); //% Algorithm 1 step 3(d) if (s->total_cost < primal->best_z) { // Update best known solution primal->n_moves_at_last_improvement = primal->n_moves; primal->best_z = s->total_cost; memcpy(primal->best_x, s->x, inst->n * sizeof(int)); } }
int random_int_below(int n) { return RngStream_RandInt(_stream, 0, n); }