From fdf3a46ad4d8a9802fd47f550c1468377ee238d9 Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Tue, 6 Oct 2020 20:28:00 +0100 Subject: [PATCH] rework the upload speed smoothing to persist across requests --- .../muwire/core/upload/ContentUploader.groovy | 2 +- .../core/upload/HashListUploader.groovy | 2 +- .../com/muwire/core/upload/Uploader.groovy | 37 ++---------------- .../com/muwire/gui/MainFrameModel.groovy | 39 ++++++++++++++++--- .../views/com/muwire/gui/MainFrameView.groovy | 2 +- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/upload/ContentUploader.groovy b/core/src/main/groovy/com/muwire/core/upload/ContentUploader.groovy index ca39d2ec..e8d051f7 100644 --- a/core/src/main/groovy/com/muwire/core/upload/ContentUploader.groovy +++ b/core/src/main/groovy/com/muwire/core/upload/ContentUploader.groovy @@ -69,9 +69,9 @@ class ContentUploader extends Uploader { int start = mapped.position() mapped.get(tmp, 0, Math.min(tmp.length, mapped.remaining())) read = mapped.position() - start - dataSinceLastRead += read } endpoint.getOutputStream().write(tmp, 0, read) + dataSinceLastRead.addAndGet(read) } done = true } finally { diff --git a/core/src/main/groovy/com/muwire/core/upload/HashListUploader.groovy b/core/src/main/groovy/com/muwire/core/upload/HashListUploader.groovy index cfa4d8da..35f869f9 100644 --- a/core/src/main/groovy/com/muwire/core/upload/HashListUploader.groovy +++ b/core/src/main/groovy/com/muwire/core/upload/HashListUploader.groovy @@ -32,9 +32,9 @@ class HashListUploader extends Uploader { int start = mapped.position() mapped.get(tmp, 0, Math.min(tmp.length, mapped.remaining())) read = mapped.position() - start - dataSinceLastRead += read } endpoint.getOutputStream().write(tmp, 0, read) + dataSinceLastRead.addAndGet(read) } endpoint.getOutputStream().flush() } diff --git a/core/src/main/groovy/com/muwire/core/upload/Uploader.groovy b/core/src/main/groovy/com/muwire/core/upload/Uploader.groovy index 20855107..e64c9027 100644 --- a/core/src/main/groovy/com/muwire/core/upload/Uploader.groovy +++ b/core/src/main/groovy/com/muwire/core/upload/Uploader.groovy @@ -5,6 +5,7 @@ import java.nio.channels.FileChannel import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.StandardOpenOption +import java.util.concurrent.atomic.AtomicInteger import com.muwire.core.Persona import com.muwire.core.connection.Endpoint @@ -13,12 +14,8 @@ abstract class Uploader { protected final Endpoint endpoint protected ByteBuffer mapped - private long lastSpeedRead - protected int dataSinceLastRead + protected final AtomicInteger dataSinceLastRead = new AtomicInteger() - private final ArrayList speedArr = [0,0,0,0,0] - private int speedPos, speedAvg - Uploader(Endpoint endpoint) { this.endpoint = endpoint } @@ -52,33 +49,7 @@ abstract class Uploader { abstract boolean isFeedEnabled(); abstract boolean isChatEnabled(); - synchronized int speed() { - final long now = System.currentTimeMillis() - long interval = Math.max(1000, now - lastSpeedRead) - lastSpeedRead = now; - int currSpeed = (int) (dataSinceLastRead * 1000.0d / interval) - dataSinceLastRead = 0 - - // normalize to speedArr.size - currSpeed /= speedArr.size() - - // compute new speedAvg and update speedArr - if ( speedArr[speedPos] > speedAvg ) { - speedAvg = 0 - } else { - speedAvg -= speedArr[speedPos] - } - speedAvg += currSpeed - speedArr[speedPos] = currSpeed - // this might be necessary due to rounding errors - if (speedAvg < 0) - speedAvg = 0 - - // rolling index over the speedArr - speedPos++ - if (speedPos >= speedArr.size()) - speedPos=0 - - speedAvg + int dataSinceLastRead() { + dataSinceLastRead.getAndSet(0) } } diff --git a/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy b/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy index 98d378e1..cb7e5875 100644 --- a/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy @@ -441,11 +441,9 @@ class MainFrameModel { return } } - if (wrapper != null) { - wrapper.uploader = e.uploader - wrapper.requests++ - wrapper.finished = false - } else + if (wrapper != null) + wrapper.updateUploader(e.uploader) + else uploads << new UploaderWrapper(uploader : e.uploader) updateTablePreservingSelection("uploads-table") view.refreshSharedFiles() @@ -678,6 +676,37 @@ class MainFrameModel { Uploader uploader int requests boolean finished + + private int[] speedArray = [] + private long lastSpeedRead = System.currentTimeMillis() + private int speedPos + + public int speed() { + + if (speedArray.length != core.muOptions.speedSmoothSeconds) { + speedArray = new int[core.muOptions.speedSmoothSeconds] + speedPos = 0 + } + + final long now = System.currentTimeMillis() + if (now < lastSpeedRead + 50) + return speedArray.average() + + int read = uploader.dataSinceLastRead() + int speed = (int) (1000.0d * read / (now - lastSpeedRead)) + lastSpeedRead = now + + speedArray[speedPos++] = speed + if (speedPos == speedArray.length) + speedPos = 0 + speedArray.average() + } + + void updateUploader(Uploader uploader) { + this.uploader = uploader + requests++ + finished = false + } } void onFeedLoadedEvent(FeedLoadedEvent e) { diff --git a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy index 7e7e190e..2773a0c4 100644 --- a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy @@ -385,7 +385,7 @@ class MainFrameView { "${totalSize} ($done/$pieces".toString() + trans("PIECES_SHORT")+ ")" }) closureColumn(header : trans("SPEED"), type : String, read : { row -> - int speed = row.uploader.speed() + int speed = row.speed() DataHelper.formatSize2Decimal(speed, false) + trans("B_SEC") }) }