2007-01-20 zzz

* i2psnark: More choking rotation tweaks
    * Improve performance by not reading in the whole
      piece from disk for each request. A huge memory savings
      on 1MB torrents with many peers.
This commit is contained in:
zzz
2007-01-21 00:35:09 +00:00
committed by zzz
parent 8ca085bceb
commit 8a87df605b
7 changed files with 47 additions and 20 deletions

View File

@ -127,6 +127,20 @@ class PeerCheckerTask extends TimerTask
coordinator.uploaders--; coordinator.uploaders--;
removedCount++; removedCount++;
// Put it at the back of the list
it.remove();
removed.add(peer);
}
else if (!peer.isInteresting() && !coordinator.completed())
{
// If they aren't interesting make someone else a downloader
if (Snark.debug >= Snark.DEBUG)
Snark.debug("Choke uninteresting peer: " + peer, Snark.DEBUG);
peer.setChoking(true);
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);

View File

@ -387,7 +387,7 @@ class PeerConnectionOut implements Runnable
m.begin = begin; m.begin = begin;
m.length = length; m.length = length;
m.data = bytes; m.data = bytes;
m.off = begin; m.off = 0;
m.len = length; m.len = length;
addMessage(m); addMessage(m);
} }

View File

@ -338,6 +338,7 @@ public class PeerCoordinator implements PeerListener
List interested = new LinkedList(); List interested = new LinkedList();
synchronized (peers) { synchronized (peers) {
int count = 0; int count = 0;
int unchokedCount = 0;
Iterator it = peers.iterator(); Iterator it = peers.iterator();
while (it.hasNext()) while (it.hasNext())
{ {
@ -349,7 +350,7 @@ public class PeerCoordinator implements PeerListener
if (uploaders < MAX_UPLOADERS) if (uploaders < MAX_UPLOADERS)
{ {
if (!peer.isChoked()) if (!peer.isChoked())
interested.add(0, peer); interested.add(unchokedCount++, peer);
else else
interested.add(peer); interested.add(peer);
} }
@ -485,14 +486,14 @@ public class PeerCoordinator implements PeerListener
* Returns a byte array containing the requested piece or null of * Returns a byte array containing the requested piece or null of
* the piece is unknown. * the piece is unknown.
*/ */
public byte[] gotRequest(Peer peer, int piece) public byte[] gotRequest(Peer peer, int piece, int off, int len)
{ {
if (halted) if (halted)
return null; return null;
try try
{ {
return storage.getPiece(piece); return storage.getPiece(piece, off, len);
} }
catch (IOException ioe) catch (IOException ioe)
{ {

View File

@ -107,11 +107,13 @@ public interface PeerListener
* *
* @param peer the Peer that wants the piece. * @param peer the Peer that wants the piece.
* @param piece the piece number requested. * @param piece the piece number requested.
* @param off byte offset into the piece.
* @param len length of the chunk requested.
* *
* @return a byte array containing the piece or null when the piece * @return a byte array containing the piece or null when the piece
* is not available (which is a protocol error). * is not available (which is a protocol error).
*/ */
byte[] gotRequest(Peer peer, int piece); byte[] gotRequest(Peer peer, int piece, int off, int len);
/** /**
* Called when a (partial) piece has been downloaded from the peer. * Called when a (partial) piece has been downloaded from the peer.
@ -167,5 +169,4 @@ public interface PeerListener
* @param peer the peer that is disconnecting * @param peer the peer that is disconnecting
*/ */
void markUnrequested(Peer peer); void markUnrequested(Peer peer);
} }

View File

@ -156,7 +156,7 @@ public class Storage
byte[] piece = new byte[piece_size]; byte[] piece = new byte[piece_size];
for (int i = 0; i < pieces; i++) for (int i = 0; i < pieces; i++)
{ {
int length = getUncheckedPiece(i, piece, 0); int length = getUncheckedPiece(i, piece);
digest.update(piece, 0, length); digest.update(piece, 0, length);
byte[] hash = digest.digest(); byte[] hash = digest.digest();
for (int j = 0; j < 20; j++) for (int j = 0; j < 20; j++)
@ -184,7 +184,7 @@ public class Storage
byte[] piece = new byte[piece_size]; byte[] piece = new byte[piece_size];
for (int i = 0; i < pieces; i++) for (int i = 0; i < pieces; i++)
{ {
int length = getUncheckedPiece(i, piece, 0); int length = getUncheckedPiece(i, piece);
digest.update(piece, 0, length); digest.update(piece, 0, length);
byte[] hash = digest.digest(); byte[] hash = digest.digest();
for (int j = 0; j < 20; j++) for (int j = 0; j < 20; j++)
@ -445,7 +445,7 @@ public class Storage
byte[] piece = new byte[metainfo.getPieceLength(0)]; byte[] piece = new byte[metainfo.getPieceLength(0)];
for (int i = 0; i < pieces; i++) for (int i = 0; i < pieces; i++)
{ {
int length = getUncheckedPiece(i, piece, 0); int length = getUncheckedPiece(i, piece);
boolean correctHash = metainfo.checkPiece(i, piece, 0, length); boolean correctHash = metainfo.checkPiece(i, piece, 0, length);
if (correctHash) if (correctHash)
{ {
@ -508,10 +508,10 @@ public class Storage
} }
/** /**
* Returns a byte array containing the requested piece or null if * Returns a byte array containing a portion of the requested piece or null if
* the storage doesn't contain the piece yet. * the storage doesn't contain the piece yet.
*/ */
public byte[] getPiece(int piece) throws IOException public byte[] getPiece(int piece, int off, int len) throws IOException
{ {
if (!bitfield.get(piece)) if (!bitfield.get(piece))
return null; return null;
@ -519,12 +519,12 @@ public class Storage
//Catch a common place for OOMs esp. on 1MB pieces //Catch a common place for OOMs esp. on 1MB pieces
byte[] bs; byte[] bs;
try { try {
bs = new byte[metainfo.getPieceLength(piece)]; bs = new byte[len];
} catch (OutOfMemoryError oom) { } catch (OutOfMemoryError oom) {
I2PSnarkUtil.instance().debug("Out of memory, can't honor request for piece " + piece, Snark.WARNING, oom); I2PSnarkUtil.instance().debug("Out of memory, can't honor request for piece " + piece, Snark.WARNING, oom);
return null; return null;
} }
getUncheckedPiece(piece, bs, 0); getUncheckedPiece(piece, bs, off, len);
return bs; return bs;
} }
@ -617,15 +617,20 @@ public class Storage
return true; return true;
} }
private int getUncheckedPiece(int piece, byte[] bs, int off) private int getUncheckedPiece(int piece, byte[] bs)
throws IOException
{
return getUncheckedPiece(piece, bs, 0, metainfo.getPieceLength(piece));
}
private int getUncheckedPiece(int piece, byte[] bs, int off, int length)
throws IOException throws IOException
{ {
// XXX - copy/paste code from putPiece(). // XXX - copy/paste code from putPiece().
// Early typecast, avoid possibly overflowing a temp integer // Early typecast, avoid possibly overflowing a temp integer
long start = (long) piece * (long) metainfo.getPieceLength(0); long start = ((long) piece * (long) metainfo.getPieceLength(0)) + off;
int length = metainfo.getPieceLength(piece);
int i = 0; int i = 0;
long raflen = lengths[i]; long raflen = lengths[i];
while (start > raflen) while (start > raflen)
@ -643,7 +648,7 @@ public class Storage
synchronized(rafs[i]) synchronized(rafs[i])
{ {
rafs[i].seek(start); rafs[i].seek(start);
rafs[i].readFully(bs, off + read, len); rafs[i].readFully(bs, read, len);
} }
read += len; read += len;
if (need - len > 0) if (need - len > 0)

View File

@ -1,4 +1,10 @@
$Id: history.txt,v 1.540 2007-01-17 00:13:28 zzz Exp $ $Id: history.txt,v 1.541 2007-01-17 20:42:14 zzz Exp $
2007-01-20 zzz
* i2psnark: More choking rotation tweaks
* Improve performance by not reading in the whole
piece from disk for each request. A huge memory savings
on 1MB torrents with many peers.
2007-01-17 zzz 2007-01-17 zzz
* Add new HTTP Proxy error message for non-http protocols * Add new HTTP Proxy error message for non-http protocols

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
* *
*/ */
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.475 $ $Date: 2007-01-17 00:13:27 $"; public final static String ID = "$Revision: 1.476 $ $Date: 2007-01-17 20:42:13 $";
public final static String VERSION = "0.6.1.26"; public final static String VERSION = "0.6.1.26";
public final static long BUILD = 9; public final static long BUILD = 10;
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);