예제 #1
0
  public ArrayList getImmediateUnchokes(int max_to_unchoke, ArrayList all_peers) {
    ArrayList to_unchoke = new ArrayList();

    // count all the currently unchoked peers
    int num_unchoked = 0;
    for (int i = 0; i < all_peers.size(); i++) {
      PEPeerTransport peer = (PEPeerTransport) all_peers.get(i);
      if (!peer.isChokedByMe()) num_unchoked++;
    }

    // if not enough unchokes
    int needed = max_to_unchoke - num_unchoked;
    if (needed > 0) {
      for (int i = 0; i < needed; i++) {
        PEPeerTransport peer = UnchokerUtil.getNextOptimisticPeer(all_peers, true, true);
        if (peer == null) break; // no more new unchokes avail
        to_unchoke.add(peer);
        peer.setOptimisticUnchoke(true);
      }
    }

    return to_unchoke;
  }
예제 #2
0
  public void calculateUnchokes(
      int max_to_unchoke, ArrayList all_peers, boolean force_refresh, boolean check_buddies) {
    int max_optimistic =
        ((max_to_unchoke - 1) / 10) + 1; // one optimistic unchoke for every 10 upload slots

    ArrayList optimistic_unchokes = new ArrayList();
    ArrayList best_peers = new ArrayList();
    long[] bests =
        new long[max_to_unchoke]; // ensure we never pick more slots than allowed to unchoke

    // get all the currently unchoked peers
    for (int i = 0; i < all_peers.size(); i++) {
      PEPeerTransport peer = (PEPeerTransport) all_peers.get(i);

      if (!peer.isChokedByMe()) {
        if (UnchokerUtil.isUnchokable(peer, true)) {
          unchokes.add(peer);
          if (peer.isOptimisticUnchoke()) {
            optimistic_unchokes.add(peer);
          }
        } else { // should be immediately choked
          chokes.add(peer);
        }
      }
    }

    if (!force_refresh) { // ensure current optimistic unchokes remain unchoked
      for (int i = 0; i < optimistic_unchokes.size(); i++) {
        PEPeerTransport peer = (PEPeerTransport) optimistic_unchokes.get(i);

        if (i < max_optimistic) {
          best_peers.add(peer); // add them to the front of the "best" list
        } else { // too many optimistics
          peer.setOptimisticUnchoke(false);
        }
      }
    }

    // fill slots with peers who we are currently downloading the fastest from
    int start_pos = best_peers.size();
    for (int i = 0; i < all_peers.size(); i++) {
      PEPeerTransport peer = (PEPeerTransport) all_peers.get(i);

      if (peer.isInteresting()
          && UnchokerUtil.isUnchokable(peer, false)
          && !best_peers.contains(peer)) { // viable peer found
        long rate = peer.getStats().getSmoothDataReceiveRate();
        if (rate > 256) { // filter out really slow peers
          UnchokerUtil.updateLargestValueFirstSort(rate, bests, peer, best_peers, start_pos);
        }
      }
    }

    // if we havent yet picked enough slots
    if (best_peers.size() < max_to_unchoke) {
      start_pos = best_peers.size();

      // fill the remaining slots with peers that we have downloaded from in the past
      for (int i = 0; i < all_peers.size(); i++) {
        PEPeerTransport peer = (PEPeerTransport) all_peers.get(i);

        if (peer.isInteresting()
            && UnchokerUtil.isUnchokable(peer, false)
            && !best_peers.contains(peer)) { // viable peer found
          long uploaded_ratio =
              peer.getStats().getTotalDataBytesSent()
                  / (peer.getStats().getTotalDataBytesReceived() + (DiskManager.BLOCK_SIZE - 1));
          // make sure we haven't already uploaded several times as much data as they've sent us
          if (uploaded_ratio < 3) {
            UnchokerUtil.updateLargestValueFirstSort(
                peer.getStats().getTotalDataBytesReceived(), bests, peer, best_peers, start_pos);
          }
        }
      }
    }

    if (force_refresh) {
      // make space for new optimistic unchokes
      while (best_peers.size() > max_to_unchoke - max_optimistic) {
        best_peers.remove(best_peers.size() - 1);
      }
    }

    // if we still have remaining slots
    while (best_peers.size() < max_to_unchoke) {
      PEPeerTransport peer =
          UnchokerUtil.getNextOptimisticPeer(all_peers, true, true); // just pick one optimistically
      if (peer == null) break; // no more new unchokes avail

      if (!best_peers.contains(peer)) {
        best_peers.add(peer);
        peer.setOptimisticUnchoke(true);
      } else {
        // we're here because the given optimistic peer is already "best", but is choked still,
        // which means it will continually get picked by the getNextOptimisticPeer() method,
        // and we'll loop forever if there are no other peers to choose from
        peer.sendUnChoke(); // send unchoke immediately, so it won't get picked optimistically
        // anymore
        // all_peers.remove( peer );  //remove from all_peers list, so it won't get picked
        // optimistically anymore    //TODO
      }
    }

    // update chokes
    for (Iterator it = unchokes.iterator(); it.hasNext(); ) {
      PEPeerTransport peer = (PEPeerTransport) it.next();

      if (!best_peers.contains(peer)) { // should be choked
        if (best_peers.size()
            < max_to_unchoke) { // but there are still slots needed (no optimistics avail), so don't
          // bother choking them
          best_peers.add(peer);
        } else {
          chokes.add(peer);
          it.remove();
        }
      }
    }

    // update unchokes
    for (int i = 0; i < best_peers.size(); i++) {
      PEPeerTransport peer = (PEPeerTransport) best_peers.get(i);

      if (!unchokes.contains(peer)) {
        unchokes.add(peer);
      }
    }
  }