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:
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user