3.3 KiB
3.3 KiB
Спецификация 02: HrSampleStore — буфер пульса (чистый JVM)
Источники: Ф-3.2 (текущее значение + линия последнего подхода), module_reqs разд. 1 (буфер, устаревание >10 с, решение 4 — только память). Единица 2.
1. Интерфейс
class HrSampleStore {
fun add(bpm: Int, atMs: Long) // сэмпл транспортом
fun current(nowMs: Long, staleAfterMs: Long = 10_000): Int?
fun average(fromMs: Long, toMs: Long): Int? // среднее за окно
fun series(fromMs: Long, toMs: Long): List<Pair<Long, Int>> // (atMs, bpm)
fun clear() // сброс (новая тренировка)
val lastSampleAtMs: Long?
}
- время — абсолютные миллисекунды (
System.currentTimeMillis()передаётся вызывающим; в тестах — фикссированные значения); - хранение: весь список сэмплов сессии (
ArrayList<Pair<Long, Int>>) — при 1 Гц и 3-часовой тренировке ~10⁴ записей, деградации памяти нет; среднее считается инкрементально по окну проходом (список короткий), без накопления суммы всей сессии; current: последний сэмпл, еслиnowMs − atMs ≤ staleAfterMs, иначеnull(прочерк, «нет данных»);average: арифметическоеInt(округление вниз) по сэмплам окна[fromMs, toMs]; пусто →null;toMsобычно «сейчас»;series— сэмплы окна в порядке поступления (линия последнего подхода:fromMs = время последнего logSet, толщина линии — один сэмпл = одна точка);- значения bpm вне 30–250 в буфер не попадают (отфильтрованы
парсером, спец 01 §3 — двойная защита:
addтоже игнорирует вне диапазона).
2. Связь с тренировкой
- окно средней — от старта тренировки (
workout.startedAt) до финиша; сэмплы вне окна (канал работал до старта — экран «Допуск») в среднее не входят; clear()вызывается фасадом приunbindпосле финишированной тренировки; между тренировками буфер накапливается только при открытом экране «Допуск» (для «взять с часов», спец 03 §4).
3. Тесты (pure JVM)
- фильтрация диапазона при
add; current: свежий / устаревший (10 001 мс) / пустой буфер;average: пусто → null; одно значение; окно вырезает сэмплы до/после; округление вниз (127,5 → 127);series: порядок и граница окна включительно;clearобнуляет всё.