diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java index 3156cf497..d7f5d3988 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java @@ -341,29 +341,28 @@ public class Storage implements Closeable * @return number of bytes remaining; -1 if unknown file * @since 0.7.14 */ +/**** public long remaining(int fileIndex) { if (fileIndex < 0 || fileIndex >= _torrentFiles.size()) return -1; + if (complete()) + return 0; long bytes = 0; for (int i = 0; i < _torrentFiles.size(); i++) { TorrentFile tf = _torrentFiles.get(i); if (i == fileIndex) { - File f = tf.RAFfile; - if (complete()) - return 0; - int psz = piece_size; long start = bytes; long end = start + tf.length; - int pc = (int) (bytes / psz); + int pc = (int) (bytes / piece_size); long rv = 0; if (!bitfield.get(pc)) - rv = Math.min(psz - (start % psz), tf.length); - for (int j = pc + 1; (((long)j) * psz) < end && j < pieces; j++) { + rv = Math.min(piece_size - (start % piece_size), tf.length); + for (int j = pc + 1; (((long)j) * piece_size) < end && j < pieces; j++) { if (!bitfield.get(j)) { - if (((long)(j+1))*psz < end) - rv += psz; + if (((long)(j+1))*piece_size < end) + rv += piece_size; else - rv += end - (((long)j) * psz); + rv += end - (((long)j) * piece_size); } } return rv; @@ -372,6 +371,40 @@ public class Storage implements Closeable } return -1; } +****/ + + /** + * For efficiency, calculate remaining bytes for all files at once + * + * @return number of bytes remaining for each file, use indexOf() to get index for a file + * @since 0.9.23 + */ + public long[] remaining() { + long[] rv = new long[_torrentFiles.size()]; + if (complete()) + return rv; + long bytes = 0; + for (int i = 0; i < _torrentFiles.size(); i++) { + TorrentFile tf = _torrentFiles.get(i); + long start = bytes; + long end = start + tf.length; + int pc = (int) (bytes / piece_size); + long rvi = 0; + if (!bitfield.get(pc)) + rvi = Math.min(piece_size - (start % piece_size), tf.length); + for (int j = pc + 1; (((long)j) * piece_size) < end && j < pieces; j++) { + if (!bitfield.get(j)) { + if (((long)(j+1))*piece_size < end) + rvi += piece_size; + else + rvi += end - (((long)j) * piece_size); + } + } + rv[i] = rvi; + bytes += tf.length; + } + return rv; + } /** * @param fileIndex as obtained from indexOf @@ -455,9 +488,8 @@ public class Storage implements Closeable int file = 0; long pcEnd = -1; long fileEnd = _torrentFiles.get(0).length - 1; - int psz = piece_size; for (int i = 0; i < rv.length; i++) { - pcEnd += psz; + pcEnd += piece_size; int pri = _torrentFiles.get(file).priority; while (fileEnd <= pcEnd && file < _torrentFiles.size() - 1) { file++; diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 549ac435f..9d576f06e 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -2936,8 +2936,10 @@ public class I2PSnarkServlet extends BasicServlet { Storage storage = snark != null ? snark.getStorage() : null; List fileList = new ArrayList(ls.length); + // precompute remaining for all files for efficiency + long[] remainingArray = (storage != null) ? storage.remaining() : null; for (int i = 0; i < ls.length; i++) { - fileList.add(new Sorters.FileAndIndex(ls[i], storage)); + fileList.add(new Sorters.FileAndIndex(ls[i], storage, remainingArray)); } boolean showSort = fileList.size() > 1; diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/Sorters.java b/apps/i2psnark/java/src/org/klomp/snark/web/Sorters.java index 3b71cf3f1..0bf598fd9 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/Sorters.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/Sorters.java @@ -356,13 +356,14 @@ class Sorters { /** * @param storage may be null + * @param remaining precomputed, non-null iff storage is non-null */ - public FileAndIndex(File file, Storage storage) { + public FileAndIndex(File file, Storage storage, long[] remainingArray) { this.file = file; index = storage != null ? storage.indexOf(file) : -1; if (index >= 0) { isDirectory = false; - remaining = storage.remaining(index); + remaining = remainingArray[index]; priority = storage.getPriority(index); } else { isDirectory = file.isDirectory(); diff --git a/history.txt b/history.txt index 97cc89d69..fec2331ba 100644 --- a/history.txt +++ b/history.txt @@ -1,7 +1,21 @@ +2015-09-18 zzz + * EepGet: + - Send Accept-Encoding: gzip even when proxied + - Fix man page (ticket #1631) + * i2psnark: + - Don't display "Tracker Error" if torrent is stopped (ticket #1654) + - Improve directory listing efficiency (ticket #1079) + * i2ptunnel: + - Pass Accept-Encoding header through HTTP client and server proxies, + to allow end-to-end compression + - Don't do transparent response compression if response + Content-Encoding indicates it is already compressed + * Streaming: Move remaining timers from the context to streaming's SimpleTimer2 + 2015-09-17 zzz * i2psnark: - Store magnet parameters across restart (ticket #1485) - - Don't delete torrent config file after error on initial startup (ticket #1658) + - Don't delete torrent config file after error on initial startup (tickets #1575, #1658) 2015-09-16 zzz * Build: diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 4e28a2c8d..c10128fe6 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 5; + public final static long BUILD = 6; /** for example "-test" */ public final static String EXTRA = "";