2007-03-08 zzz
* i2psnark changes to improve upload performance: * Implement total uploader limit (10) * Don't timeout non-piece messages out * Change chunk size to 32K (was 64K) * Change request limit to 64K (was 256K) * i2psnark: Disconnect from seeds when complete
This commit is contained in:
@ -507,6 +507,21 @@ public class Peer implements Comparable
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if a peer is a seeder
|
||||
* Quite inefficient - a byte lookup table or counter in Bitfield would be much better
|
||||
*/
|
||||
public boolean isCompleted()
|
||||
{
|
||||
PeerState s = state;
|
||||
if (s == null || s.bitfield == null)
|
||||
return false;
|
||||
for (int i = 0; i < s.bitfield.size(); i++)
|
||||
if (!s.bitfield.get(i))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push the total uploaded/downloaded onto a RATE_DEPTH deep stack
|
||||
*/
|
||||
|
@ -41,6 +41,17 @@ class PeerCheckerTask extends TimerTask
|
||||
{
|
||||
synchronized(coordinator.peers)
|
||||
{
|
||||
Iterator it = coordinator.peers.iterator();
|
||||
if ((!it.hasNext()) || coordinator.halted()) {
|
||||
coordinator.peerCount = 0;
|
||||
coordinator.interestedAndChoking = 0;
|
||||
coordinator.setRateHistory(0, 0);
|
||||
coordinator.uploaders = 0;
|
||||
if (coordinator.halted())
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate total uploading and worst downloader.
|
||||
long worstdownload = Long.MAX_VALUE;
|
||||
Peer worstDownloader = null;
|
||||
@ -56,8 +67,7 @@ class PeerCheckerTask extends TimerTask
|
||||
// Keep track of peers we remove now,
|
||||
// we will add them back to the end of the list.
|
||||
List removed = new ArrayList();
|
||||
|
||||
Iterator it = coordinator.peers.iterator();
|
||||
int uploadLimit = coordinator.allowedUploaders();
|
||||
while (it.hasNext())
|
||||
{
|
||||
Peer peer = (Peer)it.next();
|
||||
@ -100,8 +110,9 @@ class PeerCheckerTask extends TimerTask
|
||||
// If we are at our max uploaders and we have lots of other
|
||||
// interested peers try to make some room.
|
||||
// (Note use of coordinator.uploaders)
|
||||
if (coordinator.uploaders >= PeerCoordinator.MAX_UPLOADERS
|
||||
&& coordinator.interestedAndChoking > 0
|
||||
if (((coordinator.uploaders == uploadLimit
|
||||
&& coordinator.interestedAndChoking > 0)
|
||||
|| coordinator.uploaders > uploadLimit)
|
||||
&& !peer.isChoking())
|
||||
{
|
||||
// Check if it still wants pieces from us.
|
||||
@ -186,8 +197,9 @@ class PeerCheckerTask extends TimerTask
|
||||
coordinator.uploaders = uploaders;
|
||||
|
||||
// Remove the worst downloader if needed. (uploader if seeding)
|
||||
if (uploaders >= PeerCoordinator.MAX_UPLOADERS
|
||||
&& coordinator.interestedAndChoking > 0
|
||||
if (((uploaders == uploadLimit
|
||||
&& coordinator.interestedAndChoking > 0)
|
||||
|| uploaders > uploadLimit)
|
||||
&& worstDownloader != null)
|
||||
{
|
||||
if (Snark.debug >= Snark.DEBUG)
|
||||
@ -216,8 +228,5 @@ class PeerCheckerTask extends TimerTask
|
||||
coordinator.setRateHistory(uploaded, downloaded);
|
||||
|
||||
}
|
||||
if (coordinator.halted()) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,10 +208,12 @@ class PeerConnectionOut implements Runnable
|
||||
/**
|
||||
* Adds a message to the sendQueue and notifies the method waiting
|
||||
* on the sendQueue to change.
|
||||
* If a PIECE message only, add a timeout.
|
||||
*/
|
||||
private void addMessage(Message m)
|
||||
{
|
||||
SimpleTimer.getInstance().addEvent(new RemoveTooSlow(m), SEND_TIMEOUT);
|
||||
if (m.type == Message.PIECE)
|
||||
SimpleTimer.getInstance().addEvent(new RemoveTooSlow(m), SEND_TIMEOUT);
|
||||
synchronized(sendQueue)
|
||||
{
|
||||
sendQueue.add(m);
|
||||
|
@ -170,7 +170,7 @@ public class PeerCoordinator implements PeerListener
|
||||
setRate(down, downloaded_old);
|
||||
}
|
||||
|
||||
private void setRate(long val, long array[])
|
||||
private static void setRate(long val, long array[])
|
||||
{
|
||||
synchronized(array) {
|
||||
for (int i = RATE_DEPTH-1; i > 0; i--)
|
||||
@ -352,6 +352,7 @@ public class PeerCoordinator implements PeerListener
|
||||
synchronized (peers) {
|
||||
int count = 0;
|
||||
int unchokedCount = 0;
|
||||
int maxUploaders = allowedUploaders();
|
||||
Iterator it = peers.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
@ -360,7 +361,7 @@ public class PeerCoordinator implements PeerListener
|
||||
if (peer.isChoking() && peer.isInterested())
|
||||
{
|
||||
count++;
|
||||
if (uploaders < MAX_UPLOADERS)
|
||||
if (uploaders < maxUploaders)
|
||||
{
|
||||
if (!peer.isChoked())
|
||||
interested.add(unchokedCount++, peer);
|
||||
@ -370,7 +371,7 @@ public class PeerCoordinator implements PeerListener
|
||||
}
|
||||
}
|
||||
|
||||
while (uploaders < MAX_UPLOADERS && interested.size() > 0)
|
||||
while (uploaders < maxUploaders && interested.size() > 0)
|
||||
{
|
||||
Peer peer = (Peer)interested.remove(0);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -586,14 +587,27 @@ public class PeerCoordinator implements PeerListener
|
||||
}
|
||||
|
||||
// Announce to the world we have it!
|
||||
// Disconnect from other seeders when we get the last piece
|
||||
synchronized(peers)
|
||||
{
|
||||
List toDisconnect = new ArrayList();
|
||||
Iterator it = peers.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
Peer p = (Peer)it.next();
|
||||
if (p.isConnected())
|
||||
p.have(piece);
|
||||
{
|
||||
if (completed() && p.isCompleted())
|
||||
toDisconnect.add(p);
|
||||
else
|
||||
p.have(piece);
|
||||
}
|
||||
}
|
||||
it = toDisconnect.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
Peer p = (Peer)it.next();
|
||||
p.disconnect(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -615,7 +629,7 @@ public class PeerCoordinator implements PeerListener
|
||||
{
|
||||
synchronized(peers)
|
||||
{
|
||||
if (uploaders < MAX_UPLOADERS)
|
||||
if (uploaders < allowedUploaders())
|
||||
{
|
||||
if(peer.isChoking())
|
||||
{
|
||||
@ -783,5 +797,20 @@ public class PeerCoordinator implements PeerListener
|
||||
for (int i = 0; arr[i] >= 0; i++)
|
||||
markUnrequestedIfOnlyOne(peer, arr[i]);
|
||||
}
|
||||
|
||||
/** Return number of allowed uploaders for this torrent.
|
||||
** Check with Snark to see if we are over the total upload limit.
|
||||
*/
|
||||
public int allowedUploaders()
|
||||
{
|
||||
if (Snark.overUploadLimit(uploaders)) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Over limit, uploaders was: " + uploaders);
|
||||
return uploaders - 1;
|
||||
} else if (uploaders < MAX_UPLOADERS)
|
||||
return uploaders + 1;
|
||||
else
|
||||
return MAX_UPLOADERS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,8 @@ class PeerState
|
||||
private boolean resend = false;
|
||||
|
||||
private final static int MAX_PIPELINE = 2;
|
||||
private final static int PARTSIZE = 64*1024; // default was 16K, i2p-bt uses 64KB
|
||||
private final static int PARTSIZE = 32*1024; // Snark was 16K, i2p-bt uses 64KB
|
||||
private final static int MAX_PARTSIZE = 64*1024; // Don't let anybody request more than this
|
||||
|
||||
PeerState(Peer peer, PeerListener listener, MetaInfo metainfo,
|
||||
PeerConnectionIn in, PeerConnectionOut out)
|
||||
@ -173,7 +174,7 @@ class PeerState
|
||||
|| begin < 0
|
||||
|| begin > metainfo.getPieceLength(piece)
|
||||
|| length <= 0
|
||||
|| length > 4*PARTSIZE)
|
||||
|| length > MAX_PARTSIZE)
|
||||
{
|
||||
// XXX - Protocol error -> disconnect?
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
|
@ -287,7 +287,7 @@ public class Snark
|
||||
/*
|
||||
* Don't start a tunnel if the torrent isn't going to be started.
|
||||
* If we are starting,
|
||||
* startTorrent() will call trackerclient.start() which will force a connect.
|
||||
* startTorrent() will force a connect.
|
||||
*
|
||||
boolean ok = I2PSnarkUtil.instance().connect();
|
||||
if (!ok) fatal("Unable to connect to I2P");
|
||||
@ -368,6 +368,9 @@ public class Snark
|
||||
activity = "Checking storage";
|
||||
storage = new Storage(meta, slistener);
|
||||
storage.check(rootDataDir);
|
||||
// have to figure out when to reopen
|
||||
// if (!start)
|
||||
// storage.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
@ -751,4 +754,22 @@ public class Snark
|
||||
public interface CompleteListener {
|
||||
public void torrentComplete(Snark snark);
|
||||
}
|
||||
|
||||
/** Maintain a total uploader cap
|
||||
** This should be configurable
|
||||
*/
|
||||
private final static int MAX_TOTAL_UPLOADERS = 10;
|
||||
public static boolean overUploadLimit(int uploaders) {
|
||||
PeerCoordinatorSet coordinators = PeerCoordinatorSet.instance();
|
||||
if (coordinators == null || uploaders <= 0)
|
||||
return false;
|
||||
int totalUploaders = 0;
|
||||
for (Iterator iter = coordinators.iterator(); iter.hasNext(); ) {
|
||||
PeerCoordinator c = (PeerCoordinator)iter.next();
|
||||
if (!c.halted())
|
||||
totalUploaders += c.uploaders;
|
||||
}
|
||||
Snark.debug("Total uploaders: " + totalUploaders, Snark.DEBUG);
|
||||
return totalUploaders > MAX_TOTAL_UPLOADERS;
|
||||
}
|
||||
}
|
||||
|
13
history.txt
13
history.txt
@ -1,4 +1,15 @@
|
||||
$Id: history.txt,v 1.555 2007-03-03 15:30:52 zzz Exp $
|
||||
$Id: history.txt,v 1.556 2007-03-07 00:11:46 zzz Exp $
|
||||
|
||||
2007-03-08 zzz
|
||||
* i2psnark changes to improve upload performance:
|
||||
* Implement total uploader limit (10)
|
||||
* Don't timeout non-piece messages out
|
||||
* Change chunk size to 32K (was 64K)
|
||||
* Change request limit to 64K (was 256K)
|
||||
* i2psnark: Disconnect from seeds when complete
|
||||
|
||||
2007-03-07 zzz
|
||||
* Remove dynamic router keys from config.jsp
|
||||
|
||||
2007-03-07 zzz
|
||||
* Streaming lib changes to improve upstream performance during congestion:
|
||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.491 $ $Date: 2007-03-03 15:30:52 $";
|
||||
public final static String ID = "$Revision: 1.492 $ $Date: 2007-03-07 00:11:45 $";
|
||||
public final static String VERSION = "0.6.1.27";
|
||||
public final static long BUILD = 5;
|
||||
public final static long BUILD = 6;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
Reference in New Issue
Block a user