/** * Choose which of the connected peers should be unchoked and authorized to upload from this * client. A peer gets unchoked if it is not interested, or if it is interested and has one of the * 5 highest download rate among the interested peers. \r\n Every 3 times this method is called, * calls the optimisticUnchoke method, which unchoke a peer no matter its download rate, in a try * to find a better source */ private synchronized void unchokePeers() { synchronized (this.task) { int nbNotInterested = 0; int nbDownloaders = 0; int nbChoked = 0; this.unchoken.clear(); List<Peer> l = new LinkedList<Peer>(this.peerList.values()); if (!this.isComplete()) Collections.sort(l, new DLRateComparator()); else Collections.sort(l, new ULRateComparator()); downloadRate = 0; for (Iterator it = l.iterator(); it.hasNext(); ) { Peer p = (Peer) it.next(); if (p.getDLRate(false) > 0) { downloadRate += p.getDLRate(true) / (1024 * 10); // System.out.println(p + " rate: " + // p.getDLRate(true) / (1024 * 10) + // "ko/s"); } DownloadTask dt = this.task.get(p.toString()); if (nbDownloaders < 5 && dt != null) { if (!p.isInterested()) { this.unchoken.put(p.toString(), p); if (p.isChoked()) dt.ms.addMessageToQueue(new Message_PP(PeerProtocol.UNCHOKE)); p.setChoked(false); while (this.unchokeList.remove(p)) ; nbNotInterested++; } else if (p.isChoked()) { this.unchoken.put(p.toString(), p); dt.ms.addMessageToQueue(new Message_PP(PeerProtocol.UNCHOKE)); p.setChoked(false); while (this.unchokeList.remove(p)) ; nbDownloaders++; } } else { if (!p.isChoked()) { dt.ms.addMessageToQueue(new Message_PP(PeerProtocol.CHOKE)); p.setChoked(true); } if (!this.unchokeList.contains(p)) this.unchokeList.add(p); nbChoked++; } p = null; dt = null; } } this.lastUnchoking = System.currentTimeMillis(); if (this.optimisticUnchoke-- == 0) { this.optimisticUnchoke(); this.optimisticUnchoke = 3; } }
private synchronized void optimisticUnchoke() { if (!this.unchokeList.isEmpty()) { Peer p = null; do { p = (Peer) this.unchokeList.remove(0); synchronized (this.task) { DownloadTask dt = this.task.get(p.toString()); if (dt != null) { dt.ms.addMessageToQueue(new Message_PP(PeerProtocol.UNCHOKE)); p.setChoked(false); this.unchoken.put(p.toString(), p); System.out.println(p + " optimistically unchoken..."); } else p = null; dt = null; } } while ((p == null) && (!this.unchokeList.isEmpty())); p = null; } }