2007-01-14 zzz

* i2psnark: Improvements for torrents with > 4 leechers:
      choke based on upload rate when seeding, and
      be smarter and fairer about rotating choked peers.
    * Handle two common i2psnark OOM situations rather
      than shutting down the whole thing.
    * Fix reporting to tracker of remaining bytes for
      torrents > 4GB (but ByteMonsoon still has a bug)
This commit is contained in:
zzz
2007-01-14 19:49:33 +00:00
committed by zzz
parent 61b3f21f69
commit 53ba6c2a64
6 changed files with 59 additions and 30 deletions

View File

@ -48,10 +48,7 @@ class PeerCheckerTask extends TimerTask
int peers = 0; int peers = 0;
int uploaders = 0; int uploaders = 0;
int downloaders = 0; int downloaders = 0;
int interested = 0; int removedCount = 0;
int interesting = 0;
int choking = 0;
int choked = 0;
long uploaded = 0; long uploaded = 0;
long downloaded = 0; long downloaded = 0;
@ -80,14 +77,6 @@ class PeerCheckerTask extends TimerTask
uploaders++; uploaders++;
if (!peer.isChoked() && peer.isInteresting()) if (!peer.isChoked() && peer.isInteresting())
downloaders++; downloaders++;
if (peer.isInterested())
interested++;
if (peer.isInteresting())
interesting++;
if (peer.isChoking())
choking++;
if (peer.isChoked())
choked++;
long upload = peer.getUploaded(); long upload = peer.getUploaded();
uploaded += upload; uploaded += upload;
@ -111,7 +100,7 @@ class PeerCheckerTask extends TimerTask
// interested peers try to make some room. // interested peers try to make some room.
// (Note use of coordinator.uploaders) // (Note use of coordinator.uploaders)
if (coordinator.uploaders >= PeerCoordinator.MAX_UPLOADERS if (coordinator.uploaders >= PeerCoordinator.MAX_UPLOADERS
&& interested > PeerCoordinator.MAX_UPLOADERS && coordinator.interestedAndChoking > 0
&& !peer.isChoking()) && !peer.isChoking())
{ {
// Check if it still wants pieces from us. // Check if it still wants pieces from us.
@ -128,7 +117,7 @@ class PeerCheckerTask extends TimerTask
it.remove(); it.remove();
removed.add(peer); removed.add(peer);
} }
else if (peer.isChoked()) else if (peer.isInteresting() && peer.isChoked())
{ {
// If they are choking us make someone else a downloader // If they are choking us make someone else a downloader
if (Snark.debug >= Snark.DEBUG) if (Snark.debug >= Snark.DEBUG)
@ -136,6 +125,7 @@ class PeerCheckerTask extends TimerTask
peer.setChoking(true); peer.setChoking(true);
uploaders--; uploaders--;
coordinator.uploaders--; coordinator.uploaders--;
removedCount++;
// Put it at the back of the list // Put it at the back of the list
it.remove(); it.remove();
@ -152,17 +142,25 @@ class PeerCheckerTask extends TimerTask
peer.setChoking(true); peer.setChoking(true);
uploaders--; uploaders--;
coordinator.uploaders--; coordinator.uploaders--;
removedCount++;
// Put it at the back of the list // Put it at the back of the list
it.remove(); it.remove();
removed.add(peer); removed.add(peer);
} }
else if (!peer.isChoking() && download < worstdownload) else if (peer.isInteresting() && !peer.isChoked() &&
download < worstdownload)
{ {
// Make sure download is good if we are uploading // Make sure download is good if we are uploading
worstdownload = download; worstdownload = download;
worstDownloader = peer; worstDownloader = peer;
} }
else if (upload < worstdownload && coordinator.completed())
{
// Make sure upload is good if we are seeding
worstdownload = upload;
worstDownloader = peer;
}
} }
peer.retransmitRequests(); peer.retransmitRequests();
peer.keepAlive(); peer.keepAlive();
@ -172,9 +170,9 @@ class PeerCheckerTask extends TimerTask
// (can shift a bit by disconnecting peers) // (can shift a bit by disconnecting peers)
coordinator.uploaders = uploaders; coordinator.uploaders = uploaders;
// Remove the worst downloader if needed. // Remove the worst downloader if needed. (uploader if seeding)
if (uploaders >= PeerCoordinator.MAX_UPLOADERS if (uploaders >= PeerCoordinator.MAX_UPLOADERS
&& interested > PeerCoordinator.MAX_UPLOADERS && coordinator.interestedAndChoking > 0
&& worstDownloader != null) && worstDownloader != null)
{ {
if (Snark.debug >= Snark.DEBUG) if (Snark.debug >= Snark.DEBUG)
@ -183,6 +181,7 @@ class PeerCheckerTask extends TimerTask
worstDownloader.setChoking(true); worstDownloader.setChoking(true);
coordinator.uploaders--; coordinator.uploaders--;
removedCount++;
// Put it at the back of the list // Put it at the back of the list
coordinator.peers.remove(worstDownloader); coordinator.peers.remove(worstDownloader);
@ -196,6 +195,7 @@ class PeerCheckerTask extends TimerTask
// Put peers back at the end of the list that we removed earlier. // Put peers back at the end of the list that we removed earlier.
coordinator.peers.addAll(removed); coordinator.peers.addAll(removed);
coordinator.peerCount = coordinator.peers.size(); coordinator.peerCount = coordinator.peers.size();
coordinator.interestedAndChoking += removedCount;
// store the rates // store the rates
coordinator.setRateHistory(uploaded, downloaded); coordinator.setRateHistory(uploaded, downloaded);

View File

@ -44,6 +44,7 @@ public class PeerCoordinator implements PeerListener
// Approximation of the number of current uploaders. // Approximation of the number of current uploaders.
// Resynced by PeerChecker once in a while. // Resynced by PeerChecker once in a while.
int uploaders = 0; int uploaders = 0;
int interestedAndChoking = 0;
// final static int MAX_DOWNLOADERS = MAX_CONNECTIONS; // final static int MAX_DOWNLOADERS = MAX_CONNECTIONS;
// int downloaders = 0; // int downloaders = 0;
@ -132,7 +133,7 @@ public class PeerCoordinator implements PeerListener
public long getLeft() public long getLeft()
{ {
// XXX - Only an approximation. // XXX - Only an approximation.
return storage.needed() * metainfo.getPieceLength(0); return ((long) storage.needed()) * metainfo.getPieceLength(0);
} }
/** /**
@ -336,14 +337,16 @@ public class PeerCoordinator implements PeerListener
// other peer that are interested, but are choking us. // other peer that are interested, but are choking us.
List interested = new LinkedList(); List interested = new LinkedList();
synchronized (peers) { synchronized (peers) {
int count = 0;
Iterator it = peers.iterator(); Iterator it = peers.iterator();
while (it.hasNext()) while (it.hasNext())
{ {
Peer peer = (Peer)it.next(); Peer peer = (Peer)it.next();
boolean remove = false; boolean remove = false;
if (uploaders < MAX_UPLOADERS if (peer.isChoking() && peer.isInterested())
&& peer.isChoking() {
&& peer.isInterested()) count++;
if (uploaders < MAX_UPLOADERS)
{ {
if (!peer.isChoked()) if (!peer.isChoked())
interested.add(0, peer); interested.add(0, peer);
@ -351,6 +354,7 @@ public class PeerCoordinator implements PeerListener
interested.add(peer); interested.add(peer);
} }
} }
}
while (uploaders < MAX_UPLOADERS && interested.size() > 0) while (uploaders < MAX_UPLOADERS && interested.size() > 0)
{ {
@ -359,11 +363,13 @@ public class PeerCoordinator implements PeerListener
_log.debug("Unchoke: " + peer); _log.debug("Unchoke: " + peer);
peer.setChoking(false); peer.setChoking(false);
uploaders++; uploaders++;
count--;
// Put peer back at the end of the list. // Put peer back at the end of the list.
peers.remove(peer); peers.remove(peer);
peers.add(peer); peers.add(peer);
peerCount = peers.size(); peerCount = peers.size();
} }
interestedAndChoking = count;
} }
} }

View File

@ -537,7 +537,14 @@ class PeerState
&& (lastRequest == null || lastRequest.piece != nextPiece)) && (lastRequest == null || lastRequest.piece != nextPiece))
{ {
int piece_length = metainfo.getPieceLength(nextPiece); int piece_length = metainfo.getPieceLength(nextPiece);
byte[] bs = new byte[piece_length]; //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;
}
int length = Math.min(piece_length, PARTSIZE); int length = Math.min(piece_length, PARTSIZE);
Request req = new Request(nextPiece, bs, 0, length); Request req = new Request(nextPiece, bs, 0, length);

View File

@ -473,7 +473,14 @@ public class Storage
if (!bitfield.get(piece)) if (!bitfield.get(piece))
return null; return null;
byte[] bs = new byte[metainfo.getPieceLength(piece)]; //Catch a common place for OOMs esp. on 1MB pieces
byte[] bs;
try {
bs = new byte[metainfo.getPieceLength(piece)];
} catch (OutOfMemoryError oom) {
I2PSnarkUtil.instance().debug("Out of memory, can't honor request for piece " + piece, Snark.WARNING, oom);
return null;
}
getUncheckedPiece(piece, bs, 0); getUncheckedPiece(piece, bs, 0);
return bs; return bs;
} }

View File

@ -1,4 +1,13 @@
$Id: history.txt,v 1.533 2006-10-29 14:29:50 complication Exp $ $Id: history.txt,v 1.534 2006-11-09 20:44:36 zzz Exp $
2007-01-14 zzz
* i2psnark: Improvements for torrents with > 4 leechers:
choke based on upload rate when seeding, and
be smarter and fairer about rotating choked peers.
* Handle two common i2psnark OOM situations rather
than shutting down the whole thing.
* Fix reporting to tracker of remaining bytes for
torrents > 4GB (but ByteMonsoon still has a bug)
2006-10-29 zzz 2006-10-29 zzz
* i2psnark: Fix and enable generation of multifile torrents, * i2psnark: Fix and enable generation of multifile torrents,

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
* *
*/ */
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.468 $ $Date: 2006-10-29 14:29:53 $"; public final static String ID = "$Revision: 1.469 $ $Date: 2006-11-09 20:44:35 $";
public final static String VERSION = "0.6.1.26"; public final static String VERSION = "0.6.1.26";
public final static long BUILD = 2; public final static long BUILD = 3;
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID); System.out.println("Router ID: " + RouterVersion.ID);