From 8453c34bfc0ac8bc82bf031682f326f7a2f8a5dc Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 30 May 2012 15:21:37 +0000 Subject: [PATCH] Improve rarest-first behavior by not favoring a partial piece held by multiple peers when requesting from a seed --- .../src/org/klomp/snark/PeerCoordinator.java | 18 +++++++++++++++--- .../java/src/org/klomp/snark/Piece.java | 9 +++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java index 01260f183..abb7d1d7c 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java @@ -1146,10 +1146,18 @@ class PeerCoordinator implements PeerListener PartialPiece pp = iter.next(); int savedPiece = pp.getPiece(); if (havePieces.get(savedPiece)) { - iter.remove(); // this is just a double-check, it should be in there + boolean skipped = false; for(Piece piece : wantedPieces) { if (piece.getId() == savedPiece) { + if (peer.isCompleted() && piece.getPeerCount() > 1) { + // Try to preserve rarest-first when we have only one seeder + // by not preferring a partial piece that others have too + // from a seeder + skipped = true; + break; + } + iter.remove(); piece.setRequested(peer, true); if (_log.shouldLog(Log.INFO)) { _log.info("Restoring orphaned partial piece " + pp + @@ -1158,8 +1166,12 @@ class PeerCoordinator implements PeerListener return pp; } } - if (_log.shouldLog(Log.WARN)) - _log.warn("Partial piece " + pp + " NOT in wantedPieces??"); + if (_log.shouldLog(Log.WARN)) { + if (skipped) + _log.warn("Partial piece " + pp + " with multiple peers skipped for seeder"); + else + _log.warn("Partial piece " + pp + " NOT in wantedPieces??"); + } } } if (_log.shouldLog(Log.WARN) && !partialPieces.isEmpty()) diff --git a/apps/i2psnark/java/src/org/klomp/snark/Piece.java b/apps/i2psnark/java/src/org/klomp/snark/Piece.java index dd48508a9..a9822640b 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Piece.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Piece.java @@ -57,6 +57,15 @@ class Piece implements Comparable { /** caller must synchronize */ public boolean removePeer(Peer peer) { return this.peers.remove(peer.getPeerID()); } + /** + * How many peers have this piece? + * Caller must synchronize + * @since 0.9.1 + */ + public int getPeerCount() { + return this.peers.size(); + } + /** caller must synchronize */ public boolean isRequested() { return this.requests != null && !this.requests.isEmpty();