Esempio n. 1
0
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);
}
Esempio n. 2
0
/* 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);
}
Esempio n. 3
0
/**
 * 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 {
Esempio n. 4
0
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);
    }
  }
}
Esempio n. 5
0
/** @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;
  }
}
Esempio n. 6
0
// 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));
	}
}
Esempio n. 7
0
	int random_int_below(int n) {
		return RngStream_RandInt(_stream, 0, n);
	}