From 523d333fa4f185aeb3eb3af505e0d9163849f11c Mon Sep 17 00:00:00 2001 From: jarvis2f <137974272+jarvis2f@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:05:54 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20Update=20`SpeedPoint`=20rec?= =?UTF-8?q?ords=20to=20streamline=20parameters=20and=20optimize=20download?= =?UTF-8?q?=20progress=20update=20logic.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/telegram/files/AvgSpeed.java | 11 ++- .../java/telegram/files/TelegramVerticle.java | 2 +- .../java/telegram/files/AvgSpeedTest.java | 76 +++++++++---------- 3 files changed, 46 insertions(+), 43 deletions(-) diff --git a/api/src/main/java/telegram/files/AvgSpeed.java b/api/src/main/java/telegram/files/AvgSpeed.java index 331df2e..9f9679f 100644 --- a/api/src/main/java/telegram/files/AvgSpeed.java +++ b/api/src/main/java/telegram/files/AvgSpeed.java @@ -20,7 +20,7 @@ public class AvgSpeed { /** * @param speed Speed since last point */ - record SpeedPoint(long totalSize, long downloadedSize, long speed) { + record SpeedPoint(long downloadedSize, long speed) { } public AvgSpeed() { @@ -42,7 +42,10 @@ public class AvgSpeed { /** * Update download progress */ - public void update(long totalSize, long downloadedSize, long timestamp) { + public void update(long downloadedSize, long timestamp) { + if (downloadedSize <= 0) { + return; + } // Calculate speed since last point long speed = calculateSpeed(downloadedSize, timestamp); @@ -58,11 +61,11 @@ public class AvgSpeed { } // Add new speed point - speedPoints.put(timestamp, new SpeedPoint(totalSize, downloadedSize, speed)); + speedPoints.put(timestamp, new SpeedPoint(downloadedSize, speed)); // Remove old points outside the interval long cutoffTime = timestamp - interval * 1000L; // Convert interval to milliseconds - speedPoints.headMap(cutoffTime).clear(); + speedPoints.headMap(cutoffTime); } private long calculateSpeed(long downloadedSize, long timestamp) { diff --git a/api/src/main/java/telegram/files/TelegramVerticle.java b/api/src/main/java/telegram/files/TelegramVerticle.java index d48e4dc..d94a3c8 100644 --- a/api/src/main/java/telegram/files/TelegramVerticle.java +++ b/api/src/main/java/telegram/files/TelegramVerticle.java @@ -680,7 +680,7 @@ public class TelegramVerticle extends AbstractVerticle { private void onFileDownloadsUpdated(TdApi.UpdateFileDownloads updateFileDownloads) { log.trace("[%s] Receive file downloads update: %s".formatted(getRootId(), updateFileDownloads)); - avgSpeed.update(updateFileDownloads.totalSize, updateFileDownloads.downloadedSize, System.currentTimeMillis()); + avgSpeed.update(updateFileDownloads.downloadedSize, System.currentTimeMillis()); sendHttpEvent(EventPayload.build(EventPayload.TYPE_FILE_DOWNLOAD, updateFileDownloads)); } diff --git a/api/src/test/java/telegram/files/AvgSpeedTest.java b/api/src/test/java/telegram/files/AvgSpeedTest.java index a930f2d..7596a4f 100644 --- a/api/src/test/java/telegram/files/AvgSpeedTest.java +++ b/api/src/test/java/telegram/files/AvgSpeedTest.java @@ -30,11 +30,11 @@ class AvgSpeedTest { void testConstantSpeed() { // Simulate constant download speed of 100 bytes per second long baseTime = System.currentTimeMillis(); - long totalSize = 1000; - avgSpeed.update(totalSize, 0L, baseTime); - avgSpeed.update(totalSize, 1000L, baseTime + 10000); // 100 bytes/sec for 10 seconds - avgSpeed.update(totalSize, 2000L, baseTime + 20000); // 100 bytes/sec for another 10 seconds + + avgSpeed.update(0L, baseTime); + avgSpeed.update(1000L, baseTime + 10000); // 100 bytes/sec for 10 seconds + avgSpeed.update(2000L, baseTime + 20000); // 100 bytes/sec for another 10 seconds AvgSpeed.SpeedStats stats = avgSpeed.getSpeedStats(); assertEquals(100, stats.avgSpeed(), 1.0, "Average speed should be 100 bytes/sec"); @@ -43,17 +43,17 @@ class AvgSpeedTest { @Test void testSpeedWithPause() { long baseTime = System.currentTimeMillis(); - long totalSize = 1000; + // Download at 100 bytes/sec - avgSpeed.update(totalSize, 0L, baseTime); - avgSpeed.update(totalSize, 1000L, baseTime + 10000); // 100 bytes/sec + avgSpeed.update(0L, baseTime); + avgSpeed.update(1000L, baseTime + 10000); // 100 bytes/sec // Pause for 10 seconds - avgSpeed.update(totalSize, 1000L, baseTime + 20000); + avgSpeed.update(1000L, baseTime + 20000); // Resume at 100 bytes/sec - avgSpeed.update(totalSize, 2000L, baseTime + 30000); + avgSpeed.update(2000L, baseTime + 30000); // Average speed should be: 2000 bytes / 30 seconds = 66.67 bytes/sec assertEquals(67, avgSpeed.getSpeed(), 1.0, @@ -63,15 +63,15 @@ class AvgSpeedTest { @Test void testDownloadRestart() { long baseTime = System.currentTimeMillis(); - long totalSize = 1000; + // Initial download - avgSpeed.update(totalSize, 0L, baseTime); - avgSpeed.update(totalSize, 1000L, baseTime + 10000); // 100 bytes/sec + avgSpeed.update(0L, baseTime); + avgSpeed.update(1000L, baseTime + 10000); // 100 bytes/sec // Restart download - avgSpeed.update(totalSize, 0L, baseTime + 15000); - avgSpeed.update(totalSize, 500L, baseTime + 20000); // 100 bytes/sec after restart + avgSpeed.update(0L, baseTime + 15000); + avgSpeed.update(500L, baseTime + 20000); // 100 bytes/sec after restart AvgSpeed.SpeedStats stats = avgSpeed.getSpeedStats(); assertTrue(stats.maxSpeed() >= 100, @@ -81,12 +81,12 @@ class AvgSpeedTest { @Test void testSpeedFluctuation() { long baseTime = System.currentTimeMillis(); - long totalSize = 1000; - avgSpeed.update(totalSize, 0L, baseTime); - avgSpeed.update(totalSize, 500L, baseTime + 5000); // 100 bytes/sec - avgSpeed.update(totalSize, 2500L, baseTime + 10000); // 400 bytes/sec - avgSpeed.update(totalSize, 3000L, baseTime + 15000); // 100 bytes/sec + + avgSpeed.update(0L, baseTime); + avgSpeed.update(500L, baseTime + 5000); // 100 bytes/sec + avgSpeed.update(2500L, baseTime + 10000); // 400 bytes/sec + avgSpeed.update(3000L, baseTime + 15000); // 100 bytes/sec AvgSpeed.SpeedStats stats = avgSpeed.getSpeedStats(); assertTrue(stats.maxSpeed() >= 300, @@ -98,13 +98,13 @@ class AvgSpeedTest { @Test void testDataSmoothing() { long baseTime = System.currentTimeMillis(); - long totalSize = 1000; - avgSpeed.update(totalSize, 0L, baseTime); - avgSpeed.update(totalSize, 1000L, baseTime + 10000); // 100 bytes/sec - avgSpeed.update(totalSize, 2000L, baseTime + 20000); // 100 bytes/sec - avgSpeed.update(totalSize, 7000L, baseTime + 30000); // 500 bytes/sec (spike) - avgSpeed.update(totalSize, 8000L, baseTime + 40000); // 100 bytes/sec + + avgSpeed.update(0L, baseTime); + avgSpeed.update(1000L, baseTime + 10000); // 100 bytes/sec + avgSpeed.update(2000L, baseTime + 20000); // 100 bytes/sec + avgSpeed.update(7000L, baseTime + 30000); // 500 bytes/sec (spike) + avgSpeed.update(8000L, baseTime + 40000); // 100 bytes/sec AvgSpeed.SpeedStats stats = avgSpeed.getSpeedStats(); assertTrue(stats.avgSpeed() < 300, @@ -114,15 +114,15 @@ class AvgSpeedTest { @Test void testOldDataRemoval() { long baseTime = System.currentTimeMillis(); - long totalSize = 1000; + // Add initial points - avgSpeed.update(totalSize, 0L, baseTime); - avgSpeed.update(totalSize, 1000L, baseTime + 10000); // 100 bytes/sec + avgSpeed.update(0L, baseTime); + avgSpeed.update(1000L, baseTime + 10000); // 100 bytes/sec // Add point beyond interval // Note: Need to move forward by interval milliseconds plus a buffer - avgSpeed.update(totalSize, 2000L, baseTime + (TEST_INTERVAL * 1000L) + 20000); + avgSpeed.update(2000L, baseTime + (TEST_INTERVAL * 1000L) + 20000); long speed = avgSpeed.getSpeed(); assertTrue(speed < 50, @@ -132,13 +132,13 @@ class AvgSpeedTest { @Test void testMedianCalculation() { long baseTime = System.currentTimeMillis(); - long totalSize = 1000; + // Create a sequence of very distinct speeds for clear median - avgSpeed.update(totalSize, 0L, baseTime); - avgSpeed.update(totalSize, 1000L, baseTime + 5000); // 200 bytes/sec - avgSpeed.update(totalSize, 1500L, baseTime + 10000); // 100 bytes/sec - avgSpeed.update(totalSize, 3500L, baseTime + 15000); // 400 bytes/sec + avgSpeed.update(0L, baseTime); + avgSpeed.update(1000L, baseTime + 5000); // 200 bytes/sec + avgSpeed.update(1500L, baseTime + 10000); // 100 bytes/sec + avgSpeed.update(3500L, baseTime + 15000); // 400 bytes/sec long medianSpeed = avgSpeed.getMedianSpeed(); assertTrue(medianSpeed >= 100 && medianSpeed <= 400, @@ -150,14 +150,14 @@ class AvgSpeedTest { long baseTime = System.currentTimeMillis(); // Test with zero time difference - avgSpeed.update(1000L, 0L, baseTime); - avgSpeed.update(1000L, 100L, baseTime); + avgSpeed.update(0L, baseTime); + avgSpeed.update(100L, baseTime); assertEquals(0, avgSpeed.getSpeed(), "Speed should be 0 when time difference is 0"); // Test with large downloads - avgSpeed.update(1000000L, 0L, baseTime + 1000); - avgSpeed.update(1000000L, 500000L, baseTime + 6000); // 100,000 bytes/sec + avgSpeed.update(0L, baseTime + 1000); + avgSpeed.update(500000L, baseTime + 6000); // 100,000 bytes/sec assertTrue(avgSpeed.getSpeed() > 0, "Speed should be calculated correctly with large numbers"); }