/** * Starts requesting first chunk of next piece. Returns true if something has been added to the * requests, false otherwise. Caller should synchronize. */ private boolean requestNextPiece() { // Check that we already know what the other side has. if (bitfield != null) { // Check for adopting an orphaned partial piece PartialPiece pp = listener.getPartialPiece(peer, bitfield); if (pp != null) { // Double-check that r not already in outstandingRequests if (!getRequestedPieces().contains(Integer.valueOf(pp.getPiece()))) { Request r = pp.getRequest(); outstandingRequests.add(r); if (!choked) out.sendRequest(r); lastRequest = r; return true; } else { if (_log.shouldLog(Log.WARN)) _log.warn("Got dup from coord: " + pp); pp.release(); } } /** * ***** getPartialPiece() does it all now // Note that in addition to the bitfield, * PeerCoordinator uses // its request tracking and isRequesting() to determine // what piece * to give us next. int nextPiece = listener.wantPiece(peer, bitfield); if (nextPiece != -1 && * (lastRequest == null || lastRequest.getPiece() != nextPiece)) { if * (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " want piece " + nextPiece); // Fail safe to * make sure we are interested // When we transition into the end game we may not be * interested... if (!interesting) { if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " * transition to end game, setting interesting"); interesting = true; out.sendInterest(true); * } * * <p>int piece_length = metainfo.getPieceLength(nextPiece); //Catch a common place for OOMs * esp. on 1MB pieces byte[] bs; try { bs = new byte[piece_length]; } catch (OutOfMemoryError * oom) { _log.warn("Out of memory, can't request piece " + nextPiece, oom); return false; } * * <p>int length = Math.min(piece_length, PARTSIZE); Request req = new Request(nextPiece, bs, * 0, length); outstandingRequests.add(req); if (!choked) out.sendRequest(req); lastRequest = * req; return true; } else { if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " no more * pieces to request"); } ***** */ } // failsafe // However this is bad as it thrashes the peer when we change our mind // Ticket 691 cause here? if (outstandingRequests.isEmpty()) lastRequest = null; // If we are not in the end game, we may run out of things to request // because we are asking other peers. Set not-interesting now rather than // wait for those other requests to be satisfied via havePiece() if (interesting && lastRequest == null) { interesting = false; out.sendInterest(false); if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " nothing more to request, now uninteresting"); } return false; }
/** * @return good * @since 0.9.1 */ boolean checkPiece(PartialPiece pp) { int piece = pp.getPiece(); byte[] hash; try { hash = pp.getHash(); } catch (IOException ioe) { // Could be caused by closing a peer connnection // we don't want the exception to propagate through // to Storage.putPiece() _log.warn("Error checking", ioe); return false; } for (int i = 0; i < 20; i++) { if (hash[i] != piece_hashes[20 * piece + i]) return false; } return true; }