From 0dae0a561bb1f5e6cf629dede15d1ee4bdf862e0 Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Fri, 1 Nov 2019 18:39:41 +0000 Subject: [PATCH] more accurate speed measurement. Makes a difference if MW is minimized for a long time --- .../core/download/DownloadSession.groovy | 18 +++++----------- .../muwire/core/download/Downloader.groovy | 21 ++++++++----------- .../core/download/DownloadSessionTest.groovy | 4 +++- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy b/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy index a36974a8..f48407f7 100644 --- a/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy +++ b/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy @@ -21,6 +21,7 @@ import java.nio.file.Files import java.nio.file.StandardOpenOption import java.security.MessageDigest import java.security.NoSuchAlgorithmException +import java.util.concurrent.atomic.AtomicLong import java.util.logging.Level @Log @@ -37,13 +38,12 @@ class DownloadSession { private final Set available private final MessageDigest digest - private long lastSpeedRead = System.currentTimeMillis() - private long dataSinceLastRead + private final AtomicLong dataSinceLastRead private MappedByteBuffer mapped DownloadSession(EventBus eventBus, String meB64, Pieces pieces, InfoHash infoHash, Endpoint endpoint, File file, - int pieceSize, long fileLength, Set available) { + int pieceSize, long fileLength, Set available, AtomicLong dataSinceLastRead) { this.eventBus = eventBus this.meB64 = meB64 this.pieces = pieces @@ -53,6 +53,7 @@ class DownloadSession { this.pieceSize = pieceSize this.fileLength = fileLength this.available = available + this.dataSinceLastRead = dataSinceLastRead try { digest = MessageDigest.getInstance("SHA-256") } catch (NoSuchAlgorithmException impossible) { @@ -190,7 +191,7 @@ class DownloadSession { throw new IOException() synchronized(this) { mapped.put(tmp, 0, read) - dataSinceLastRead += read + dataSinceLastRead.addAndGet(read) pieces.markPartial(piece, mapped.position()) } } @@ -222,13 +223,4 @@ class DownloadSession { return 0 mapped.position() } - - synchronized int speed() { - final long now = System.currentTimeMillis() - long interval = Math.max(1000, now - lastSpeedRead) - lastSpeedRead = now; - int rv = (int) (dataSinceLastRead * 1000.0 / interval) - dataSinceLastRead = 0 - rv - } } diff --git a/core/src/main/groovy/com/muwire/core/download/Downloader.groovy b/core/src/main/groovy/com/muwire/core/download/Downloader.groovy index e6d2ff7e..596db7cb 100644 --- a/core/src/main/groovy/com/muwire/core/download/Downloader.groovy +++ b/core/src/main/groovy/com/muwire/core/download/Downloader.groovy @@ -12,6 +12,7 @@ import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ExecutorService import java.util.concurrent.Executors import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicLong import java.util.logging.Level import com.muwire.core.Constants @@ -61,10 +62,11 @@ public class Downloader { private final AtomicBoolean eventFired = new AtomicBoolean() private boolean piecesFileClosed + private final AtomicLong dataSinceLastRead = new AtomicLong(0) + private volatile long lastSpeedRead = System.currentTimeMillis() private ArrayList speedArr = new ArrayList() private int speedPos = 0 private int speedAvg = 0 - private long timestamp = Instant.now().toEpochMilli() public Downloader(EventBus eventBus, DownloadManager downloadManager, Persona me, File file, long length, InfoHash infoHash, @@ -139,10 +141,11 @@ public class Downloader { public int speed() { int currSpeed = 0 if (getCurrentState() == DownloadState.DOWNLOADING) { - activeWorkers.values().each { - if (it.currentState == WorkerState.DOWNLOADING) - currSpeed += it.speed() - } + long dataRead = dataSinceLastRead.getAndSet(0) + long now = System.currentTimeMillis() + if (now > lastSpeedRead) + currSpeed = (int) (dataRead * 1000.0 / (now - lastSpeedRead)) + lastSpeedRead = now } if (speedArr.size() != downloadManager.muSettings.speedSmoothSeconds) { @@ -302,7 +305,7 @@ public class Downloader { boolean requestPerformed while(!pieces.isComplete()) { currentSession = new DownloadSession(eventBus, me.toBase64(), pieces, getInfoHash(), - endpoint, incompleteFile, pieceSize, length, available) + endpoint, incompleteFile, pieceSize, length, available, dataSinceLastRead) requestPerformed = currentSession.request() if (!requestPerformed) break @@ -339,12 +342,6 @@ public class Downloader { } } - int speed() { - if (currentSession == null) - return 0 - currentSession.speed() - } - void cancel() { downloadThread?.interrupt() } diff --git a/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy b/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy index 9f07dd4b..05f70104 100644 --- a/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy +++ b/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy @@ -2,6 +2,8 @@ package com.muwire.core.download import static org.junit.Assert.fail +import java.util.concurrent.atomic.AtomicLong + import org.junit.After import org.junit.Before import org.junit.Ignore @@ -76,7 +78,7 @@ class DownloadSessionTest { toUploader = new PipedOutputStream(fromDownloader) endpoint = new Endpoint(null, fromUploader, toUploader, null) - session = new DownloadSession(eventBus, "",pieces, infoHash, endpoint, target, pieceSize, size, available) + session = new DownloadSession(eventBus, "",pieces, infoHash, endpoint, target, pieceSize, size, available, new AtomicLong()) downloadThread = new Thread( { perform() } as Runnable) downloadThread.setDaemon(true) downloadThread.start()