i2psnark: Improve directory listing efficiency (ticket #1079)

This commit is contained in:
zzz
2015-09-18 22:54:32 +00:00
parent b8a909c4cc
commit 462c882f4e
5 changed files with 66 additions and 17 deletions

View File

@ -341,29 +341,28 @@ public class Storage implements Closeable
* @return number of bytes remaining; -1 if unknown file * @return number of bytes remaining; -1 if unknown file
* @since 0.7.14 * @since 0.7.14
*/ */
/****
public long remaining(int fileIndex) { public long remaining(int fileIndex) {
if (fileIndex < 0 || fileIndex >= _torrentFiles.size()) if (fileIndex < 0 || fileIndex >= _torrentFiles.size())
return -1; return -1;
if (complete())
return 0;
long bytes = 0; long bytes = 0;
for (int i = 0; i < _torrentFiles.size(); i++) { for (int i = 0; i < _torrentFiles.size(); i++) {
TorrentFile tf = _torrentFiles.get(i); TorrentFile tf = _torrentFiles.get(i);
if (i == fileIndex) { if (i == fileIndex) {
File f = tf.RAFfile;
if (complete())
return 0;
int psz = piece_size;
long start = bytes; long start = bytes;
long end = start + tf.length; long end = start + tf.length;
int pc = (int) (bytes / psz); int pc = (int) (bytes / piece_size);
long rv = 0; long rv = 0;
if (!bitfield.get(pc)) if (!bitfield.get(pc))
rv = Math.min(psz - (start % psz), tf.length); rv = Math.min(piece_size - (start % piece_size), tf.length);
for (int j = pc + 1; (((long)j) * psz) < end && j < pieces; j++) { for (int j = pc + 1; (((long)j) * piece_size) < end && j < pieces; j++) {
if (!bitfield.get(j)) { if (!bitfield.get(j)) {
if (((long)(j+1))*psz < end) if (((long)(j+1))*piece_size < end)
rv += psz; rv += piece_size;
else else
rv += end - (((long)j) * psz); rv += end - (((long)j) * piece_size);
} }
} }
return rv; return rv;
@ -372,6 +371,40 @@ public class Storage implements Closeable
} }
return -1; 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 * @param fileIndex as obtained from indexOf
@ -455,9 +488,8 @@ public class Storage implements Closeable
int file = 0; int file = 0;
long pcEnd = -1; long pcEnd = -1;
long fileEnd = _torrentFiles.get(0).length - 1; long fileEnd = _torrentFiles.get(0).length - 1;
int psz = piece_size;
for (int i = 0; i < rv.length; i++) { for (int i = 0; i < rv.length; i++) {
pcEnd += psz; pcEnd += piece_size;
int pri = _torrentFiles.get(file).priority; int pri = _torrentFiles.get(file).priority;
while (fileEnd <= pcEnd && file < _torrentFiles.size() - 1) { while (fileEnd <= pcEnd && file < _torrentFiles.size() - 1) {
file++; file++;

View File

@ -2936,8 +2936,10 @@ public class I2PSnarkServlet extends BasicServlet {
Storage storage = snark != null ? snark.getStorage() : null; Storage storage = snark != null ? snark.getStorage() : null;
List<Sorters.FileAndIndex> fileList = new ArrayList<Sorters.FileAndIndex>(ls.length); List<Sorters.FileAndIndex> fileList = new ArrayList<Sorters.FileAndIndex>(ls.length);
// precompute remaining for all files for efficiency
long[] remainingArray = (storage != null) ? storage.remaining() : null;
for (int i = 0; i < ls.length; i++) { 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; boolean showSort = fileList.size() > 1;

View File

@ -356,13 +356,14 @@ class Sorters {
/** /**
* @param storage may be null * @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; this.file = file;
index = storage != null ? storage.indexOf(file) : -1; index = storage != null ? storage.indexOf(file) : -1;
if (index >= 0) { if (index >= 0) {
isDirectory = false; isDirectory = false;
remaining = storage.remaining(index); remaining = remainingArray[index];
priority = storage.getPriority(index); priority = storage.getPriority(index);
} else { } else {
isDirectory = file.isDirectory(); isDirectory = file.isDirectory();

View File

@ -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 2015-09-17 zzz
* i2psnark: * i2psnark:
- Store magnet parameters across restart (ticket #1485) - 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 2015-09-16 zzz
* Build: * Build:

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 5; public final static long BUILD = 6;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";