forked from I2P_Developers/i2p.i2p
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 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
|
* Push the total uploaded/downloaded onto a RATE_DEPTH deep stack
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +41,17 @@ class PeerCheckerTask extends TimerTask
|
|||||||
{
|
{
|
||||||
synchronized(coordinator.peers)
|
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.
|
// Calculate total uploading and worst downloader.
|
||||||
long worstdownload = Long.MAX_VALUE;
|
long worstdownload = Long.MAX_VALUE;
|
||||||
Peer worstDownloader = null;
|
Peer worstDownloader = null;
|
||||||
@ -56,8 +67,7 @@ class PeerCheckerTask extends TimerTask
|
|||||||
// Keep track of peers we remove now,
|
// Keep track of peers we remove now,
|
||||||
// we will add them back to the end of the list.
|
// we will add them back to the end of the list.
|
||||||
List removed = new ArrayList();
|
List removed = new ArrayList();
|
||||||
|
int uploadLimit = coordinator.allowedUploaders();
|
||||||
Iterator it = coordinator.peers.iterator();
|
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
Peer peer = (Peer)it.next();
|
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
|
// If we are at our max uploaders and we have lots of other
|
||||||
// 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 == uploadLimit
|
||||||
&& coordinator.interestedAndChoking > 0
|
&& coordinator.interestedAndChoking > 0)
|
||||||
|
|| coordinator.uploaders > uploadLimit)
|
||||||
&& !peer.isChoking())
|
&& !peer.isChoking())
|
||||||
{
|
{
|
||||||
// Check if it still wants pieces from us.
|
// Check if it still wants pieces from us.
|
||||||
@ -186,8 +197,9 @@ class PeerCheckerTask extends TimerTask
|
|||||||
coordinator.uploaders = uploaders;
|
coordinator.uploaders = uploaders;
|
||||||
|
|
||||||
// Remove the worst downloader if needed. (uploader if seeding)
|
// Remove the worst downloader if needed. (uploader if seeding)
|
||||||
if (uploaders >= PeerCoordinator.MAX_UPLOADERS
|
if (((uploaders == uploadLimit
|
||||||
&& coordinator.interestedAndChoking > 0
|
&& coordinator.interestedAndChoking > 0)
|
||||||
|
|| uploaders > uploadLimit)
|
||||||
&& worstDownloader != null)
|
&& worstDownloader != null)
|
||||||
{
|
{
|
||||||
if (Snark.debug >= Snark.DEBUG)
|
if (Snark.debug >= Snark.DEBUG)
|
||||||
@ -216,8 +228,5 @@ class PeerCheckerTask extends TimerTask
|
|||||||
coordinator.setRateHistory(uploaded, downloaded);
|
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
|
* Adds a message to the sendQueue and notifies the method waiting
|
||||||
* on the sendQueue to change.
|
* on the sendQueue to change.
|
||||||
|
* If a PIECE message only, add a timeout.
|
||||||
*/
|
*/
|
||||||
private void addMessage(Message m)
|
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)
|
synchronized(sendQueue)
|
||||||
{
|
{
|
||||||
sendQueue.add(m);
|
sendQueue.add(m);
|
||||||
|
@ -170,7 +170,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
setRate(down, downloaded_old);
|
setRate(down, downloaded_old);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRate(long val, long array[])
|
private static void setRate(long val, long array[])
|
||||||
{
|
{
|
||||||
synchronized(array) {
|
synchronized(array) {
|
||||||
for (int i = RATE_DEPTH-1; i > 0; i--)
|
for (int i = RATE_DEPTH-1; i > 0; i--)
|
||||||
@ -352,6 +352,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
synchronized (peers) {
|
synchronized (peers) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int unchokedCount = 0;
|
int unchokedCount = 0;
|
||||||
|
int maxUploaders = allowedUploaders();
|
||||||
Iterator it = peers.iterator();
|
Iterator it = peers.iterator();
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
@ -360,7 +361,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
if (peer.isChoking() && peer.isInterested())
|
if (peer.isChoking() && peer.isInterested())
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if (uploaders < MAX_UPLOADERS)
|
if (uploaders < maxUploaders)
|
||||||
{
|
{
|
||||||
if (!peer.isChoked())
|
if (!peer.isChoked())
|
||||||
interested.add(unchokedCount++, peer);
|
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);
|
Peer peer = (Peer)interested.remove(0);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
@ -586,14 +587,27 @@ public class PeerCoordinator implements PeerListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Announce to the world we have it!
|
// Announce to the world we have it!
|
||||||
|
// Disconnect from other seeders when we get the last piece
|
||||||
synchronized(peers)
|
synchronized(peers)
|
||||||
{
|
{
|
||||||
|
List toDisconnect = new ArrayList();
|
||||||
Iterator it = peers.iterator();
|
Iterator it = peers.iterator();
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
Peer p = (Peer)it.next();
|
Peer p = (Peer)it.next();
|
||||||
if (p.isConnected())
|
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)
|
synchronized(peers)
|
||||||
{
|
{
|
||||||
if (uploaders < MAX_UPLOADERS)
|
if (uploaders < allowedUploaders())
|
||||||
{
|
{
|
||||||
if(peer.isChoking())
|
if(peer.isChoking())
|
||||||
{
|
{
|
||||||
@ -783,5 +797,20 @@ public class PeerCoordinator implements PeerListener
|
|||||||
for (int i = 0; arr[i] >= 0; i++)
|
for (int i = 0; arr[i] >= 0; i++)
|
||||||
markUnrequestedIfOnlyOne(peer, arr[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 boolean resend = false;
|
||||||
|
|
||||||
private final static int MAX_PIPELINE = 2;
|
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,
|
PeerState(Peer peer, PeerListener listener, MetaInfo metainfo,
|
||||||
PeerConnectionIn in, PeerConnectionOut out)
|
PeerConnectionIn in, PeerConnectionOut out)
|
||||||
@ -173,7 +174,7 @@ class PeerState
|
|||||||
|| begin < 0
|
|| begin < 0
|
||||||
|| begin > metainfo.getPieceLength(piece)
|
|| begin > metainfo.getPieceLength(piece)
|
||||||
|| length <= 0
|
|| length <= 0
|
||||||
|| length > 4*PARTSIZE)
|
|| length > MAX_PARTSIZE)
|
||||||
{
|
{
|
||||||
// XXX - Protocol error -> disconnect?
|
// XXX - Protocol error -> disconnect?
|
||||||
if (_log.shouldLog(Log.WARN))
|
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.
|
* Don't start a tunnel if the torrent isn't going to be started.
|
||||||
* If we are starting,
|
* If we are starting,
|
||||||
* startTorrent() will call trackerclient.start() which will force a connect.
|
* startTorrent() will force a connect.
|
||||||
*
|
*
|
||||||
boolean ok = I2PSnarkUtil.instance().connect();
|
boolean ok = I2PSnarkUtil.instance().connect();
|
||||||
if (!ok) fatal("Unable to connect to I2P");
|
if (!ok) fatal("Unable to connect to I2P");
|
||||||
@ -368,6 +368,9 @@ public class Snark
|
|||||||
activity = "Checking storage";
|
activity = "Checking storage";
|
||||||
storage = new Storage(meta, slistener);
|
storage = new Storage(meta, slistener);
|
||||||
storage.check(rootDataDir);
|
storage.check(rootDataDir);
|
||||||
|
// have to figure out when to reopen
|
||||||
|
// if (!start)
|
||||||
|
// storage.close();
|
||||||
}
|
}
|
||||||
catch (IOException ioe)
|
catch (IOException ioe)
|
||||||
{
|
{
|
||||||
@ -751,4 +754,22 @@ public class Snark
|
|||||||
public interface CompleteListener {
|
public interface CompleteListener {
|
||||||
public void torrentComplete(Snark snark);
|
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
|
2007-03-07 zzz
|
||||||
* Streaming lib changes to improve upstream performance during congestion:
|
* Streaming lib changes to improve upstream performance during congestion:
|
||||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
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 String VERSION = "0.6.1.27";
|
||||||
public final static long BUILD = 5;
|
public final static long BUILD = 6;
|
||||||
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);
|
||||||
|
Reference in New Issue
Block a user