From 8a87df605b0e4f568753f15602c62d51f3f4bcf4 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 21 Jan 2007 00:35:09 +0000 Subject: [PATCH] 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. --- .../src/org/klomp/snark/PeerCheckerTask.java | 14 ++++++++++ .../org/klomp/snark/PeerConnectionOut.java | 2 +- .../src/org/klomp/snark/PeerCoordinator.java | 7 ++--- .../src/org/klomp/snark/PeerListener.java | 5 ++-- .../java/src/org/klomp/snark/Storage.java | 27 +++++++++++-------- history.txt | 8 +++++- .../src/net/i2p/router/RouterVersion.java | 4 +-- 7 files changed, 47 insertions(+), 20 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java index 150792e084..860a506045 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java @@ -127,6 +127,20 @@ class PeerCheckerTask extends TimerTask coordinator.uploaders--; 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 it.remove(); removed.add(peer); diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java index b1d1db1712..4c9ceae0ff 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java @@ -387,7 +387,7 @@ class PeerConnectionOut implements Runnable m.begin = begin; m.length = length; m.data = bytes; - m.off = begin; + m.off = 0; m.len = length; addMessage(m); } diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java index ea1a676875..51c3172749 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java @@ -338,6 +338,7 @@ public class PeerCoordinator implements PeerListener List interested = new LinkedList(); synchronized (peers) { int count = 0; + int unchokedCount = 0; Iterator it = peers.iterator(); while (it.hasNext()) { @@ -349,7 +350,7 @@ public class PeerCoordinator implements PeerListener if (uploaders < MAX_UPLOADERS) { if (!peer.isChoked()) - interested.add(0, peer); + interested.add(unchokedCount++, peer); else interested.add(peer); } @@ -485,14 +486,14 @@ public class PeerCoordinator implements PeerListener * Returns a byte array containing the requested piece or null of * the piece is unknown. */ - public byte[] gotRequest(Peer peer, int piece) + public byte[] gotRequest(Peer peer, int piece, int off, int len) { if (halted) return null; try { - return storage.getPiece(piece); + return storage.getPiece(piece, off, len); } catch (IOException ioe) { diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerListener.java b/apps/i2psnark/java/src/org/klomp/snark/PeerListener.java index 0cdc153d25..f505a41186 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerListener.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerListener.java @@ -107,11 +107,13 @@ public interface PeerListener * * @param peer the Peer that wants the piece. * @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 * 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. @@ -167,5 +169,4 @@ public interface PeerListener * @param peer the peer that is disconnecting */ void markUnrequested(Peer peer); - } diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java index c16fb878be..00117c807b 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java @@ -156,7 +156,7 @@ public class Storage byte[] piece = new byte[piece_size]; for (int i = 0; i < pieces; i++) { - int length = getUncheckedPiece(i, piece, 0); + int length = getUncheckedPiece(i, piece); digest.update(piece, 0, length); byte[] hash = digest.digest(); for (int j = 0; j < 20; j++) @@ -184,7 +184,7 @@ public class Storage byte[] piece = new byte[piece_size]; for (int i = 0; i < pieces; i++) { - int length = getUncheckedPiece(i, piece, 0); + int length = getUncheckedPiece(i, piece); digest.update(piece, 0, length); byte[] hash = digest.digest(); for (int j = 0; j < 20; j++) @@ -445,7 +445,7 @@ public class Storage byte[] piece = new byte[metainfo.getPieceLength(0)]; 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); 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. */ - public byte[] getPiece(int piece) throws IOException + public byte[] getPiece(int piece, int off, int len) throws IOException { if (!bitfield.get(piece)) return null; @@ -519,12 +519,12 @@ public class Storage //Catch a common place for OOMs esp. on 1MB pieces byte[] bs; try { - bs = new byte[metainfo.getPieceLength(piece)]; + bs = new byte[len]; } 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); + getUncheckedPiece(piece, bs, off, len); return bs; } @@ -617,15 +617,20 @@ public class Storage 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 { // XXX - copy/paste code from putPiece(). // 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; long raflen = lengths[i]; while (start > raflen) @@ -643,7 +648,7 @@ public class Storage synchronized(rafs[i]) { rafs[i].seek(start); - rafs[i].readFully(bs, off + read, len); + rafs[i].readFully(bs, read, len); } read += len; if (need - len > 0) diff --git a/history.txt b/history.txt index 2883a389f1..1122414d26 100644 --- a/history.txt +++ b/history.txt @@ -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 * Add new HTTP Proxy error message for non-http protocols diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 445eb5617e..8569cad3e5 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -15,9 +15,9 @@ import net.i2p.CoreVersion; * */ 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 long BUILD = 9; + public final static long BUILD = 10; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID);