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

View File

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

View File

@ -537,7 +537,14 @@ class PeerState
&& (lastRequest == null || lastRequest.piece != 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);
Request req = new Request(nextPiece, bs, 0, length);

View File

@ -473,7 +473,14 @@ public class Storage
if (!bitfield.get(piece))
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);
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
* i2psnark: Fix and enable generation of multifile torrents,

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
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 long BUILD = 2;
public final static long BUILD = 3;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);