From 28046f05f7a58f14883bd463859dcb6cd875729e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 4 Oct 2026 16:14:10 +0200 Subject: [PATCH] test(measurements): group the hourly-mean fake once instead of per day The in-memory day-aggregate fake re-filtered every row for every day, converting each timestamp to the profile timezone again, so a 1000-day series took about five seconds and the graded pulse-status test hit its timeout. It now groups by day and segment in one pass (4.8 s to 85 ms). --- .../__tests__/fake-day-aggregates.ts | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/lib/measurements/__tests__/fake-day-aggregates.ts b/src/lib/measurements/__tests__/fake-day-aggregates.ts index dd17f37ef..9e2503dd0 100644 --- a/src/lib/measurements/__tests__/fake-day-aggregates.ts +++ b/src/lib/measurements/__tests__/fake-day-aggregates.ts @@ -81,22 +81,31 @@ export async function fakeReadDayAggregates( // Mirror the SQL's hourly-mean day: the mean of the (day, segment)'s local // hours' means. const starts = opts.segmentStarts ?? []; + // Group once by (day, segment) with the fold's own filters, so a long + // series stays linear instead of re-filtering every row per day. + const membersByKey = new Map< + string, + Array<{ measuredAt: Date; value: number }> + >(); + for (const r of rows) { + const t = r.measuredAt.getTime(); + if (t < opts.since.getTime()) continue; + if (opts.until && t > opts.until.getTime()) continue; + if ( + opts.valueRange && + (r.value < opts.valueRange.min || r.value > opts.valueRange.max) + ) { + continue; + } + const key = `${userDayKey(r.measuredAt, opts.timeZone)}|${ + starts.filter((st) => t < st.getTime()).length + }`; + const list = membersByKey.get(key); + if (list) list.push(r); + else membersByKey.set(key, [r]); + } return days.map((d) => { - const members = rows.filter((r) => { - const t = r.measuredAt.getTime(); - if (t < opts.since.getTime()) return false; - if (opts.until && t > opts.until.getTime()) return false; - if ( - opts.valueRange && - (r.value < opts.valueRange.min || r.value > opts.valueRange.max) - ) { - return false; - } - return ( - userDayKey(r.measuredAt, opts.timeZone) === d.day && - starts.filter((s) => t < s.getTime()).length === d.segment - ); - }); + const members = membersByKey.get(`${d.day}|${d.segment}`) ?? []; const dayMean = dayValue(opts.type, members, opts.timeZone); return dayMean === null ? d : { ...d, dayMean }; });