Search in sources :

Example 31 with PEPeer

use of com.biglybt.core.peer.PEPeer in project BiglyBT by BiglySoftware.

the class DownloadingUnchoker method getImmediateUnchokes.

@Override
public ArrayList<PEPeer> getImmediateUnchokes(int max_to_unchoke, ArrayList<PEPeer> all_peers) {
    ArrayList<PEPeer> to_unchoke = new ArrayList<>();
    // count all the currently unchoked peers
    int num_unchoked = 0;
    for (int i = 0; i < all_peers.size(); i++) {
        PEPeer peer = 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++) {
            PEPeer peer = UnchokerUtil.getNextOptimisticPeer(all_peers, true, true);
            // no more new unchokes avail
            if (peer == null)
                break;
            to_unchoke.add(peer);
            peer.setOptimisticUnchoke(true);
        }
    }
    return to_unchoke;
}
Also used : PEPeer(com.biglybt.core.peer.PEPeer) ArrayList(java.util.ArrayList)

Example 32 with PEPeer

use of com.biglybt.core.peer.PEPeer in project BiglyBT by BiglySoftware.

the class SeedingUnchoker method getImmediateUnchokes.

@Override
public ArrayList<PEPeer> getImmediateUnchokes(int max_to_unchoke, ArrayList<PEPeer> all_peers) {
    int peer_count = all_peers.size();
    if (max_to_unchoke > peer_count) {
        max_to_unchoke = peer_count;
    }
    // count all the currently unchoked peers
    int num_unchoked = 0;
    for (int i = 0; i < all_peers.size(); i++) {
        PEPeer peer = all_peers.get(i);
        if (!peer.isChokedByMe())
            num_unchoked++;
    }
    // if not enough unchokes
    int needed = max_to_unchoke - num_unchoked;
    if (needed > 0) {
        ArrayList<PEPeer> to_unchoke = UnchokerUtil.getNextOptimisticPeers(all_peers, false, false, needed);
        if (to_unchoke == null) {
            return (new ArrayList<>(0));
        }
        for (int i = 0; i < to_unchoke.size(); i++) {
            to_unchoke.get(i).setOptimisticUnchoke(true);
        }
        return (to_unchoke);
    } else {
        return (new ArrayList<>(0));
    }
}
Also used : PEPeer(com.biglybt.core.peer.PEPeer)

Example 33 with PEPeer

use of com.biglybt.core.peer.PEPeer in project BiglyBT by BiglySoftware.

the class SeedingUnchoker method calculateUnchokes.

@Override
public void calculateUnchokes(int max_to_unchoke, ArrayList<PEPeer> all_peers, boolean force_refresh, boolean check_priority_connections, boolean do_high_latency_peers) {
    // one optimistic unchoke for every 5 upload slots
    int max_optimistic = ((max_to_unchoke - 1) / 5) + 1;
    // get all the currently unchoked peers
    for (int i = 0; i < all_peers.size(); i++) {
        PEPeer peer = all_peers.get(i);
        if (!peer.isChokedByMe()) {
            if (UnchokerUtil.isUnchokable(peer, false)) {
                unchokes.add(peer);
            } else {
                // should be immediately choked
                chokes.add(peer);
            }
        }
    }
    // if too many unchokes
    while (unchokes.size() > max_to_unchoke) {
        chokes.add(unchokes.remove(unchokes.size() - 1));
    }
    // we only recalculate the uploads when we're forced to refresh the optimistic unchokes
    if (force_refresh) {
        // we need to make room for new opt unchokes by finding the "worst" peers
        ArrayList<PEPeer> peers_ordered_by_rate = new ArrayList<>();
        ArrayList<PEPeer> peers_ordered_by_uploaded = new ArrayList<>();
        // 0-initialized
        long[] rates = new long[unchokes.size()];
        // 0-initialized
        long[] uploaded = new long[rates.length];
        // calculate factor rankings
        for (int i = 0; i < unchokes.size(); i++) {
            PEPeer peer = unchokes.get(i);
            long rate = peer.getStats().getDataSendRate();
            if (rate > 256) {
                // filter out really slow peers
                // calculate reverse order by our upload rate to them
                UnchokerUtil.updateLargestValueFirstSort(rate, rates, peer, peers_ordered_by_rate, 0);
                // calculate order by the total number of bytes we've uploaded to them
                UnchokerUtil.updateLargestValueFirstSort(peer.getStats().getTotalDataBytesSent(), uploaded, peer, peers_ordered_by_uploaded, 0);
            }
        }
        // we want higher rates at the end
        Collections.reverse(peers_ordered_by_rate);
        ArrayList<PEPeer> peers_ordered_by_rank = new ArrayList<>();
        long[] ranks = new long[peers_ordered_by_rate.size()];
        Arrays.fill(ranks, Long.MIN_VALUE);
        // combine factor rankings to get best
        for (int i = 0; i < unchokes.size(); i++) {
            PEPeer peer = unchokes.get(i);
            // "better" peers have high indexes (toward the end of each list)
            long rate_factor = peers_ordered_by_rate.indexOf(peer);
            long uploaded_factor = peers_ordered_by_uploaded.indexOf(peer);
            // wasn't downloading fast enough, skip add so it will be choked automatically
            if (rate_factor == -1)
                continue;
            long rank_factor = rate_factor + uploaded_factor;
            UnchokerUtil.updateLargestValueFirstSort(rank_factor, ranks, peer, peers_ordered_by_rank, 0);
        }
        // make space for new optimistic unchokes
        while (peers_ordered_by_rank.size() > max_to_unchoke - max_optimistic) {
            peers_ordered_by_rank.remove(peers_ordered_by_rank.size() - 1);
        }
        // update choke list with drops and unchoke list with optimistic unchokes
        ArrayList<PEPeer> to_unchoke = new ArrayList<>();
        for (Iterator<PEPeer> it = unchokes.iterator(); it.hasNext(); ) {
            PEPeer peer = it.next();
            peer.setOptimisticUnchoke(false);
            if (!peers_ordered_by_rank.contains(peer)) {
                // should be choked
                // we assume that any/all chokes are to be replace by optimistics
                PEPeer optimistic_peer = UnchokerUtil.getNextOptimisticPeer(all_peers, false, false);
                if (optimistic_peer != null) {
                    // only choke if we've got a peer to replace it with
                    chokes.add(peer);
                    it.remove();
                    to_unchoke.add(optimistic_peer);
                    optimistic_peer.setOptimisticUnchoke(true);
                }
            }
        }
        for (int i = 0; i < to_unchoke.size(); i++) {
            unchokes.add(to_unchoke.get(i));
        }
    }
    if (check_priority_connections) {
        // add priority peers preferentially, leaving room for 1 non-priority peer for every 5 upload slots
        setPriorityUnchokes(max_to_unchoke - max_optimistic, all_peers);
    }
    if (do_high_latency_peers) {
        UnchokerUtil.doHighLatencyPeers(chokes, unchokes, false);
    }
}
Also used : PEPeer(com.biglybt.core.peer.PEPeer) ArrayList(java.util.ArrayList)

Example 34 with PEPeer

use of com.biglybt.core.peer.PEPeer in project BiglyBT by BiglySoftware.

the class SeedingUnchoker method setPriorityUnchokes.

private void setPriorityUnchokes(int max_priority, ArrayList<PEPeer> all_peers) {
    // don't bother trying to replace peers in an empty list
    if (unchokes.isEmpty())
        return;
    ArrayList<PEPeer> priority_peers = new ArrayList<>();
    for (int i = 0; i < all_peers.size(); i++) {
        PEPeer peer = all_peers.get(i);
        if (peer.isPriorityConnection() && UnchokerUtil.isUnchokable(peer, true)) {
            priority_peers.add(peer);
        }
    }
    // we want to give all connected priority peers an equal chance if there are more than max_priority allowed
    Collections.shuffle(priority_peers);
    int num_unchoked = 0;
    int num_non_priority_to_retain = priority_unchoke_retention_count;
    int max = max_priority > unchokes.size() ? unchokes.size() : max_priority;
    while (num_unchoked < max && !priority_peers.isEmpty()) {
        // go through unchoke list and replace non-buddy peers with buddy ones
        // pop peer from front of unchoke list
        PEPeer peer = unchokes.remove(0);
        if (priority_peers.remove(peer)) {
            // peer is already in the priority list
            // so insert priority peer back into list at the end
            unchokes.add(peer);
        } else {
            if (num_non_priority_to_retain-- > 0) {
                // retain if permitted
                unchokes.add(peer);
            }
            // get next buddy
            PEPeer buddy = priority_peers.remove(priority_peers.size() - 1);
            // just in case
            chokes.remove(buddy);
            // add priority to back of list
            unchokes.add(buddy);
        }
        num_unchoked++;
    }
}
Also used : PEPeer(com.biglybt.core.peer.PEPeer) ArrayList(java.util.ArrayList)

Example 35 with PEPeer

use of com.biglybt.core.peer.PEPeer in project BiglyBT by BiglySoftware.

the class UnchokerUtil method getNextOptimisticPeers.

public static ArrayList<PEPeer> getNextOptimisticPeers(ArrayList<PEPeer> all_peers, boolean factor_reciprocated, boolean allow_snubbed, int num_needed) {
    // find all potential optimistic peers
    ArrayList<PEPeer> optimistics = new ArrayList<>();
    for (int i = 0; i < all_peers.size(); i++) {
        PEPeer peer = all_peers.get(i);
        if (isUnchokable(peer, false) && peer.isChokedByMe()) {
            optimistics.add(peer);
        }
    }
    if (optimistics.isEmpty() && allow_snubbed) {
        // try again, allowing snubbed peers as last resort
        for (int i = 0; i < all_peers.size(); i++) {
            PEPeer peer = all_peers.get(i);
            if (isUnchokable(peer, true) && peer.isChokedByMe()) {
                optimistics.add(peer);
            }
        }
    }
    // no unchokable peers avail
    if (optimistics.isEmpty())
        return null;
    // factor in peer reciprocation ratio when picking optimistic peers
    ArrayList<PEPeer> result = new ArrayList<>(optimistics.size());
    if (factor_reciprocated) {
        ArrayList<PEPeerTransport> ratioed_peers = new ArrayList<>(optimistics.size());
        long[] ratios = new long[optimistics.size()];
        Arrays.fill(ratios, Long.MIN_VALUE);
        // order by upload ratio
        for (int i = 0; i < optimistics.size(); i++) {
            PEPeer peer = optimistics.get(i);
            // score of >0 means we've uploaded more, <0 means we've downloaded more
            long score = peer.getStats().getTotalDataBytesSent() - peer.getStats().getTotalDataBytesReceived();
            // higher value = worse score
            UnchokerUtil.updateLargestValueFirstSort(score, ratios, peer, ratioed_peers, 0);
        }
        for (int i = 0; i < num_needed && ratioed_peers.size() > 0; i++) {
            // map to sorted list using a logistic curve
            double factor = 1F / (0.8 + 0.2 * Math.pow(RandomUtils.nextFloat(), -1));
            int pos = (int) (factor * ratioed_peers.size());
            result.add(ratioed_peers.remove(pos));
        }
    } else {
        for (int i = 0; i < num_needed && optimistics.size() > 0; i++) {
            int rand_pos = new Random().nextInt(optimistics.size());
            result.add(optimistics.remove(rand_pos));
        }
    }
    return (result);
// TODO:
// in downloading mode, we would be better off optimistically unchoking just peers we are interested in ourselves,
// as they could potentially reciprocate. however, new peers have no pieces to share, and are not interesting to
// us, and would never be unchoked, and thus would never get any data.
// we could use a deterministic method for new peers to get their very first piece from us
}
Also used : PEPeer(com.biglybt.core.peer.PEPeer) PEPeerTransport(com.biglybt.core.peer.impl.PEPeerTransport)

Aggregations

PEPeer (com.biglybt.core.peer.PEPeer)84 PEPeerManager (com.biglybt.core.peer.PEPeerManager)18 DownloadManager (com.biglybt.core.download.DownloadManager)11 ArrayList (java.util.ArrayList)11 DiskManagerFileInfo (com.biglybt.core.disk.DiskManagerFileInfo)5 AERunnable (com.biglybt.core.util.AERunnable)5 PEPiece (com.biglybt.core.peer.PEPiece)4 List (java.util.List)4 Image (org.eclipse.swt.graphics.Image)4 DiskManager (com.biglybt.core.disk.DiskManager)3 GlobalManager (com.biglybt.core.global.GlobalManager)3 PEPeerStats (com.biglybt.core.peer.PEPeerStats)3 PEPeerTransport (com.biglybt.core.peer.impl.PEPeerTransport)3 TOTorrent (com.biglybt.core.torrent.TOTorrent)3 Point (org.eclipse.swt.graphics.Point)3 DiskManagerPiece (com.biglybt.core.disk.DiskManagerPiece)2 DownloadManagerPeerListener (com.biglybt.core.download.DownloadManagerPeerListener)2 PiecePicker (com.biglybt.core.peermanager.piecepicker.PiecePicker)2 BitFlags (com.biglybt.core.peermanager.piecepicker.util.BitFlags)2 Tag (com.biglybt.core.tag.Tag)2