more accurate speed measurement. Makes a difference if MW is minimized for a long time

This commit is contained in:
Zlatin Balevsky
2019-11-01 18:39:41 +00:00
parent 82eaafc2c3
commit 0dae0a561b
3 changed files with 17 additions and 26 deletions

View File

@@ -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<Integer> 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<Integer> available) {
int pieceSize, long fileLength, Set<Integer> 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
}
}

View File

@@ -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<Integer>()
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()
}

View File

@@ -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()