diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java index ba62cf6274eda6ab8be34d9aa50c8418d9e0ab4a..c8fd37970818610133167005f9d62c7262f09c88 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java @@ -745,6 +745,18 @@ public class Snark return storage != null && storage.isChecking(); } + /** + * If checking is in progress, return completion 0-100, + * else return 100. + * @since 0.9.23 + */ + public double getCheckingProgress() { + if (storage != null && storage.isChecking()) + return storage.getCheckingProgress(); + else + return 100.0d; + } + /** * Disk allocation (ballooning) in progress. * @since 0.9.3 diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java index 6d73ed658697a1a657aaf4cf3228eb3c60ecbab5..7d80aa291a9ddc7443a6b5a3c1bf2d7ccc653e4e 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java @@ -73,6 +73,7 @@ public class Storage implements Closeable private boolean changed; private volatile boolean _isChecking; private final AtomicInteger _allocateCount = new AtomicInteger(); + private final AtomicInteger _checkProgress = new AtomicInteger(); /** The default piece size. */ private static final int DEFAULT_PIECE_SIZE = 256*1024; @@ -311,6 +312,18 @@ public class Storage implements Closeable return _isChecking; } + /** + * If checking is in progress, return completion 0-100, + * else return 100. + * @since 0.9.23 + */ + public double getCheckingProgress() { + if (_isChecking) + return _checkProgress.get() / (double) pieces; + else + return 100.0d; + } + /** * Disk allocation (ballooning) in progress. * Always false on Windows. @@ -869,6 +882,7 @@ public class Storage implements Closeable private void locked_checkCreateFiles(boolean recheck) throws IOException { + _checkProgress.set(0); // Whether we are resuming or not, // if any of the files already exists we assume we are resuming. boolean resume = false; @@ -885,13 +899,16 @@ public class Storage implements Closeable // Make sure all files are available and of correct length // The files should all exist as they have been created with zero length by createFilesFromNames() + long lengthProgress = 0; for (TorrentFile tf : _torrentFiles) { long length = tf.RAFfile.length(); + lengthProgress += tf.length; if(tf.RAFfile.exists() && length == tf.length) { if (listener != null) listener.storageAllocated(this, length); + _checkProgress.set(0); resume = true; // XXX Could dynamicly check } else if (length == 0) { @@ -903,6 +920,8 @@ public class Storage implements Closeable tf.closeRAF(); } catch (IOException ioe) {} } + if (!resume) + _checkProgress.set((int) (pieces * lengthProgress / total_length)); } else { String msg = "File '" + tf.name + "' exists, but has wrong length (expected " + tf.length + " but found " + length + ") - repairing corruption"; @@ -911,6 +930,7 @@ public class Storage implements Closeable _log.error(msg); changed = true; resume = true; + _checkProgress.set(0); _probablyComplete = false; // to force RW synchronized(tf) { RandomAccessFile raf = tf.checkRAF(); @@ -931,6 +951,7 @@ public class Storage implements Closeable long pieceEnd = 0; for (int i = 0; i < pieces; i++) { + _checkProgress.set(i); int length = getUncheckedPiece(i, piece); boolean correctHash = metainfo.checkPiece(i, piece, 0, length); // close as we go so we don't run out of file descriptors @@ -957,6 +978,7 @@ public class Storage implements Closeable } } + _checkProgress.set(pieces); _probablyComplete = complete(); // close all the files so we don't end up with a zillion open ones; // we will reopen as needed 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 2368c7536f72d99078b7e008a8a5241a0755fcd7..f59ae0bdc9e7de6f255afb08000f5106600c0947 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -1471,7 +1471,8 @@ public class I2PSnarkServlet extends BasicServlet { String statusString; if (snark.isChecking()) { statusString = toThemeImg("stalled", "", _("Checking")) + "</td>" + - "<td class=\"snarkTorrentStatus\">" + _("Checking"); + "<td class=\"snarkTorrentStatus\">" + _("Checking") + ' ' + + (new DecimalFormat("0.00%")).format(snark.getCheckingProgress()); } else if (snark.isAllocating()) { statusString = toThemeImg("stalled", "", _("Allocating")) + "</td>" + "<td class=\"snarkTorrentStatus\">" + _("Allocating"); @@ -2924,8 +2925,9 @@ public class I2PSnarkServlet extends BasicServlet { buf.append("<tr><td>"); toThemeImg(buf, "file"); if (snark.isChecking()) { - buf.append(" <b>").append(_("Checking")).append("…</b> ") - .append("<a href=\"").append(base).append("\">") + buf.append(" <b>").append(_("Checking")).append("… ") + .append((new DecimalFormat("0.00%")).format(snark.getCheckingProgress())) + .append(" <a href=\"").append(base).append("\">") .append(_("Refresh page for results")).append("</a>"); } else if (snark.isStarting()) { buf.append(" <b>").append(_("Starting")).append("…</b>");