From b02da25e1e87bc0ad4db83a0a556a7d622cc5d09 Mon Sep 17 00:00:00 2001 From: Giovanny Rodriguez Date: Thu, 2 Apr 2026 18:08:46 -0500 Subject: [PATCH] Add KDoc documentation to Cache averaging algorithm Document the exponential moving average used in calculate(), the cache depth strategy in size() based on scan speed thresholds, the eviction logic in add(), and the purpose of CacheResult. No logic changes. --- .../vrem/wifianalyzer/wifi/scanner/Cache.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/app/src/main/kotlin/com/vrem/wifianalyzer/wifi/scanner/Cache.kt b/app/src/main/kotlin/com/vrem/wifianalyzer/wifi/scanner/Cache.kt index 72ba39b81..739c31e24 100644 --- a/app/src/main/kotlin/com/vrem/wifianalyzer/wifi/scanner/Cache.kt +++ b/app/src/main/kotlin/com/vrem/wifianalyzer/wifi/scanner/Cache.kt @@ -23,6 +23,11 @@ import com.vrem.annotation.OpenClass import com.vrem.util.ssid import com.vrem.wifianalyzer.MainContext +/** + * Holds a [ScanResult] alongside the computed signal level average + * for that access point across cached scans. + */ + internal class CacheResult( val scanResult: ScanResult, val average: Int, @@ -38,6 +43,11 @@ internal class Cache { private val scanResults: ArrayDeque> = ArrayDeque(MAXIMUM) private var count: Int = COUNT_MIN var wifiInfo: WifiInfo? = null + + /** + * Returns one [CacheResult] per unique access point (keyed by BSSID + SSID), + * with the signal level averaged across all scans currently in the cache. + */ fun scanResults(): List = combineCache() @@ -47,6 +57,13 @@ internal class Cache { }.values .toList() + /** + * Adds a new scan batch to the front of the cache (most recent first). + * Evicts the oldest batch when the cache exceeds [size]. + * Also advances the internal [count] cycle used by [calculate] when + * screen size is unavailable. + */ + fun add(scanResults: List) { count = if (count >= MAXIMUM * FACTOR) COUNT_MIN else count + 1 val size = size() @@ -60,6 +77,16 @@ internal class Cache { fun last(): List = scanResults.last() + /** + * Returns the number of scan batches to retain in the cache. + * When screen size is available, the cache depth is determined by scan speed: + * - scanSpeed < 2 → [MAXIMUM] (4 batches) + * - scanSpeed < 5 → [MAXIMUM] - 1 (3 batches) + * - scanSpeed < 10 → [MAXIMUM] - 2 (2 batches) + * - else → [MINIMUM] (1 batch, effectively no caching) + * When cache is disabled or screen size is unavailable, returns [MINIMUM]. + */ + fun size(): Int = if (sizeAvailable) { val settings = MainContext.INSTANCE.settings @@ -79,6 +106,16 @@ internal class Cache { MINIMUM } + /** + * Computes the signal level average for an access point across cached scans + * using an exponential moving average: `(previous + current) / 2`. + * This weights recent scans more heavily than older ones. + * + * When screen size is unavailable (e.g. small screen or restricted mode), + * applies an additional penalty based on the internal scan [count] cycle + * to further reduce perceived signal strength, clamped to [-100, 0] dBm. + */ + private fun calculate( first: Boolean, element: ScanResult,