From 7cbf466b9b5995971409f1579be5b52edd65744d Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Wed, 7 Oct 2020 07:51:45 +0100 Subject: [PATCH] move bandwidth smoothing logic in its own class, use it in uploader --- .../muwire/clilanterna/UploadsModel.groovy | 34 +++++------ .../muwire/core/util/BandwidthCounter.java | 57 +++++++++++++++++++ .../com/muwire/gui/MainFrameModel.groovy | 28 +++------ .../java/com/muwire/webui/UploadManager.java | 41 +++++-------- 4 files changed, 92 insertions(+), 68 deletions(-) create mode 100644 core/src/main/java/com/muwire/core/util/BandwidthCounter.java diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsModel.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsModel.groovy index db30b93f..29b87fd3 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsModel.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsModel.groovy @@ -7,6 +7,7 @@ import com.muwire.core.Core import com.muwire.core.upload.UploadEvent import com.muwire.core.upload.UploadFinishedEvent import com.muwire.core.upload.Uploader +import com.muwire.core.util.BandwidthCounter import net.i2p.data.DataHelper @@ -43,8 +44,7 @@ class UploadsModel { } } if (found != null) { - found.uploader = e.uploader - found.finished = false + found.updateUploader(e.uploader) } else uploaders << new UploaderWrapper(uploader : e.uploader) } @@ -99,9 +99,7 @@ class UploadsModel { Uploader uploader boolean finished - private int [] speedArray = [] - private long lastSpeedRead = System.currentTimeMillis() - private int speedPos + private BandwidthCounter bwCounter = new BandwidthCounter(0); @Override public String toString() { @@ -112,23 +110,17 @@ class UploadsModel { if (finished) return 0 - if (speedArray.length != core.muOptions.speedSmoothSeconds) { - speedArray = new int[core.muOptions.speedSmoothSeconds] - speedPos = 0 - } + if (bwCounter.getMemory() != core.muOptions.speedSmoothSeconds) + bwCounter = new BandwidthCounter(core.muOptions.speedSmoothSeconds) - 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() + bwCounter.read(uploader.dataSinceLastRead()) + bwCounter.average() + } + + void updateUploader(Uploader e) { + bwCounter.read(uploader.dataSinceLastRead()) + this.uploader = uploader + finished = false } } } diff --git a/core/src/main/java/com/muwire/core/util/BandwidthCounter.java b/core/src/main/java/com/muwire/core/util/BandwidthCounter.java new file mode 100644 index 00000000..b29d7a86 --- /dev/null +++ b/core/src/main/java/com/muwire/core/util/BandwidthCounter.java @@ -0,0 +1,57 @@ +package com.muwire.core.util; + +import java.util.Arrays; + +/** + * A bandwidth counter that uses SMA. + * @author zab + * + */ +public class BandwidthCounter { + + private final int memory; + private final int[] data; + private final long[] timestamps; + + private int index; + + public BandwidthCounter(int memory) { + this.memory = memory; + this.data = new int[memory]; + this.timestamps = new long[memory]; + Arrays.fill(timestamps, System.currentTimeMillis()); + } + + public int getMemory() { + return memory; + } + + public void read(int read) { + if (memory < 1) + throw new IllegalStateException(); + + data[index] = read; + timestamps[index] = System.currentTimeMillis(); + + index++; + if (index == memory) + index = 0; + } + + private int lastIndex() { + if (index == 0) + return memory - 1; + return index - 1; + } + + public int average() { + int total = 0; + for (int read : data) + total += read; + long delta = timestamps[lastIndex()] - timestamps[index]; + if (delta == 0) + delta = 1; + return (int) (total * 1000.0 / delta); + } + +} diff --git a/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy b/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy index 20e72a65..d4ee7147 100644 --- a/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy @@ -57,6 +57,7 @@ import com.muwire.core.update.UpdateDownloadedEvent import com.muwire.core.upload.UploadEvent import com.muwire.core.upload.UploadFinishedEvent import com.muwire.core.upload.Uploader +import com.muwire.core.util.BandwidthCounter import griffon.core.GriffonApplication import griffon.core.artifact.GriffonModel @@ -677,35 +678,22 @@ class MainFrameModel { int requests boolean finished - private int[] speedArray = [] - private long lastSpeedRead = System.currentTimeMillis() - private int speedPos + private BandwidthCounter bwCounter = new BandwidthCounter(0) public int speed() { if (finished) return 0 - - 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() + if (bwCounter.getMemory() != core.muOptions.speedSmoothSeconds) + bwCounter = new BandwidthCounter(core.muOptions.speedSmoothSeconds) + + bwCounter.read(uploader.dataSinceLastRead()) + bwCounter.average() } void updateUploader(Uploader uploader) { + bwCounter.read(this.uploader.dataSinceLastRead()) this.uploader = uploader requests++ finished = false diff --git a/webui/src/main/java/com/muwire/webui/UploadManager.java b/webui/src/main/java/com/muwire/webui/UploadManager.java index bea81aeb..ed41e08d 100644 --- a/webui/src/main/java/com/muwire/webui/UploadManager.java +++ b/webui/src/main/java/com/muwire/webui/UploadManager.java @@ -9,6 +9,7 @@ import com.muwire.core.Core; import com.muwire.core.upload.UploadEvent; import com.muwire.core.upload.UploadFinishedEvent; import com.muwire.core.upload.Uploader; +import com.muwire.core.util.BandwidthCounter; public class UploadManager { @@ -34,9 +35,7 @@ public class UploadManager { } } if (wrapper != null) { - wrapper.uploader = e.getUploader(); - wrapper.requests++; - wrapper.finished = false; + wrapper.updateUploader(e.getUploader()); } else { wrapper = new UploaderWrapper(); wrapper.uploader = e.getUploader(); @@ -73,9 +72,7 @@ public class UploadManager { private volatile int requests; private volatile boolean finished; - private volatile int[] speedArray = new int[0]; - private volatile int speedPos; - private volatile long lastSpeedRead = System.currentTimeMillis(); + private volatile BandwidthCounter bwCounter = new BandwidthCounter(0); public Uploader getUploader() { return uploader; @@ -90,31 +87,21 @@ public class UploadManager { } public int speed() { + if (finished) + return 0; - if (speedArray.length != core.getMuOptions().getSpeedSmoothSeconds()) { - speedArray = new int[core.getMuOptions().getSpeedSmoothSeconds()]; - speedPos = 0; - } + if (bwCounter.getMemory() != core.getMuOptions().getSpeedSmoothSeconds()) + bwCounter = new BandwidthCounter(core.getMuOptions().getSpeedSmoothSeconds()); - final long now = System.currentTimeMillis(); - if (now < lastSpeedRead + 50) - return speedAverage(); - - int read = uploader.dataSinceLastRead(); - int speed = (int) (1000.0d * read / (now - lastSpeedRead)); - lastSpeedRead = now; - - speedArray[speedPos++] = speed; - if (speedPos == speedArray.length) - speedPos = 0; - return speedAverage(); + bwCounter.read(uploader.dataSinceLastRead()); + return bwCounter.average(); } - private int speedAverage() { - int total = 0; - for (int reading : speedArray) - total += reading; - return total / speedArray.length; + void updateUploader(Uploader uploader) { + bwCounter.read(this.uploader.dataSinceLastRead()); + this.uploader = uploader; + requests++; + finished = false; } } }