performance/BackgroundPerformanceTracker.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "performance/BackgroundPerformanceTracker.h" | ||
| 2 | |||
| 3 | #include <QApplication> | ||
| 4 | #include <QDir> | ||
| 5 | #include <QEvent> | ||
| 6 | #include <QFile> | ||
| 7 | #include <QFileInfo> | ||
| 8 | #include <QJsonDocument> | ||
| 9 | #include <QJsonObject> | ||
| 10 | #include <QSet> | ||
| 11 | #include <QTimer> | ||
| 12 | #include <QWidget> | ||
| 13 | |||
| 14 | #include <algorithm> | ||
| 15 | |||
| 16 | namespace MailJD::Performance { | ||
| 17 | |||
| 18 | namespace { | ||
| 19 | constexpr auto RowMetric = "realtime.server_to_row.v1"; | ||
| 20 | constexpr auto BadgeMetric = "realtime.server_to_badge.v1"; | ||
| 21 | constexpr auto NotificationMetric = "realtime.server_to_notification.v1"; | ||
| 22 | constexpr auto SettledMetric = "realtime.server_to_settled.v1"; | ||
| 23 | constexpr auto AnchorFileName = "realtime-anchor.json"; | ||
| 24 | constexpr auto SyncMetric = "sync.total.v1"; | ||
| 25 | constexpr auto ThroughputMetric = "sync.items_per_second.v1"; | ||
| 26 | constexpr auto MaintenanceMetric = "maintenance.total.v1"; | ||
| 27 | constexpr auto ShutdownMetric = "shutdown.input_to_durable_terminal.v1"; | ||
| 28 | constexpr auto ContentionBackgroundMetric = | ||
| 29 | "contention.background_throughput.v1"; | ||
| 30 | constexpr auto ContentionStallMetric = "contention.event_loop_stall.v1"; | ||
| 31 | constexpr auto ContentionBusyMetric = "contention.sqlite_busy.v1"; | ||
| 32 | constexpr int EventLoopProbeIntervalMs = 50; | ||
| 33 | constexpr qint64 MaximumAnchorAgeNs = 15LL * 60LL * 1000LL * 1000LL * 1000LL; | ||
| 34 | |||
| 35 | const QSet<QString> AllowedAnchorFields = { | ||
| 36 | QStringLiteral("schema_version"), | ||
| 37 | QStringLiteral("run_id"), | ||
| 38 | QStringLiteral("scenario"), | ||
| 39 | QStringLiteral("server_accepted_monotonic_ns"), | ||
| 40 | QStringLiteral("item_count"), | ||
| 41 | }; | ||
| 42 | } // namespace | ||
| 43 | |||
| 44 | 3003 | BackgroundPerformanceTracker &BackgroundPerformanceTracker::instance() { | |
| 45 |
4/7✓ Branch 2 → 3 taken 25 times.
✓ Branch 2 → 8 taken 2978 times.
✓ Branch 4 → 5 taken 25 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 25 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
|
3003 | static BackgroundPerformanceTracker tracker; |
| 46 | 3003 | return tracker; | |
| 47 | } | ||
| 48 | |||
| 49 | 25 | BackgroundPerformanceTracker::BackgroundPerformanceTracker(QObject *parent) | |
| 50 |
1/1✓ Branch 12 → 13 taken 25 times.
|
25 | : QObject(parent) { |
| 51 |
1/1✓ Branch 13 → 14 taken 25 times.
|
25 | m_eventLoopProbe.setTimerType(Qt::PreciseTimer); |
| 52 |
1/1✓ Branch 14 → 15 taken 25 times.
|
25 | m_eventLoopProbe.setInterval(EventLoopProbeIntervalMs); |
| 53 | 25 | connect(&m_eventLoopProbe, &QTimer::timeout, this, | |
| 54 |
1/1✓ Branch 15 → 16 taken 25 times.
|
25 | &BackgroundPerformanceTracker::probeEventLoop); |
| 55 | 25 | } | |
| 56 | |||
| 57 | 27 | bool BackgroundPerformanceTracker::isRealtimeActive() const { | |
| 58 |
4/4✓ Branch 2 → 3 taken 27 times.
✓ Branch 3 → 4 taken 27 times.
✓ Branch 4 → 5 taken 25 times.
✓ Branch 4 → 13 taken 2 times.
|
77 | return PerformanceTrace::instance().isEnabled() && |
| 59 |
5/7✓ Branch 5 → 6 taken 25 times.
✓ Branch 6 → 7 taken 25 times.
✓ Branch 10 → 11 taken 25 times.
✓ Branch 11 → 12 taken 23 times.
✓ Branch 11 → 13 taken 2 times.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 32 not taken.
|
77 | PerformanceTrace::instance().selectedScenario().startsWith( |
| 60 |
6/10✓ Branch 14 → 15 taken 25 times.
✓ Branch 14 → 16 taken 2 times.
✓ Branch 16 → 17 taken 25 times.
✓ Branch 16 → 18 taken 2 times.
✓ Branch 18 → 19 taken 25 times.
✓ Branch 18 → 20 taken 2 times.
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 24 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 28 not taken.
|
79 | QStringLiteral("REALTIME.")); |
| 61 | } | ||
| 62 | |||
| 63 | 10 | void BackgroundPerformanceTracker::ensureEventFilterInstalled() { | |
| 64 |
5/6✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 6 taken 9 times.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 11 taken 9 times.
|
10 | if (!m_eventFilterInstalled && qApp) { |
| 65 | 1 | qApp->installEventFilter(this); | |
| 66 | 1 | m_eventFilterInstalled = true; | |
| 67 | } | ||
| 68 | 10 | } | |
| 69 | |||
| 70 | 3 | void BackgroundPerformanceTracker::watchMailViewport(QWidget *viewport) { | |
| 71 | 3 | m_mailViewport = viewport; | |
| 72 |
1/2✓ Branch 4 → 5 taken 3 times.
✗ Branch 4 → 6 not taken.
|
3 | if (isRealtimeActive()) |
| 73 | 3 | ensureEventFilterInstalled(); | |
| 74 | 3 | } | |
| 75 | |||
| 76 | 3 | void BackgroundPerformanceTracker::watchBadgeViewport(QWidget *viewport) { | |
| 77 | 3 | m_badgeViewport = viewport; | |
| 78 |
1/2✓ Branch 4 → 5 taken 3 times.
✗ Branch 4 → 6 not taken.
|
3 | if (isRealtimeActive()) |
| 79 | 3 | ensureEventFilterInstalled(); | |
| 80 | 3 | } | |
| 81 | |||
| 82 | 28 | void BackgroundPerformanceTracker::reset() { | |
| 83 |
4/8✓ Branch 3 → 4 taken 28 times.
✗ Branch 3 → 10 not taken.
✓ Branch 5 → 6 taken 28 times.
✗ Branch 5 → 10 not taken.
✓ Branch 7 → 8 taken 28 times.
✗ Branch 7 → 10 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 28 times.
|
56 | if (m_row.isValid() || m_badge.isValid() || m_notification.isValid() || |
| 84 |
1/2✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 28 times.
|
28 | m_settled.isValid()) |
| 85 | ✗ | failAll(Outcome::Cancelled); | |
| 86 | 28 | m_scenario.clear(); | |
| 87 | 28 | m_expectedCount = 0; | |
| 88 | 28 | m_fetchedCount = 0; | |
| 89 | 28 | m_appendedCount = 0; | |
| 90 | 28 | m_notificationCount = 0; | |
| 91 | 28 | m_repaintCount = 0; | |
| 92 | 28 | m_rowPaintPending = false; | |
| 93 | 28 | m_badgePaintPending = false; | |
| 94 | 28 | m_rowPainted = false; | |
| 95 | 28 | m_badgePainted = false; | |
| 96 | 28 | m_notificationAccepted = false; | |
| 97 | 28 | m_settleScheduled = false; | |
| 98 | 28 | ++m_generation; | |
| 99 | 28 | resetBackground(); | |
| 100 | 28 | } | |
| 101 | |||
| 102 | 1537 | bool BackgroundPerformanceTracker::isBackgroundActive() const { | |
| 103 |
4/4✓ Branch 2 → 3 taken 1537 times.
✓ Branch 3 → 4 taken 1537 times.
✓ Branch 4 → 5 taken 1496 times.
✓ Branch 4 → 6 taken 41 times.
|
1537 | if (!PerformanceTrace::instance().isEnabled()) |
| 104 | 1496 | return false; | |
| 105 |
2/2✓ Branch 6 → 7 taken 41 times.
✓ Branch 7 → 8 taken 41 times.
|
41 | const QString selected = PerformanceTrace::instance().selectedScenario(); |
| 106 |
4/9✓ Branch 11 → 12 taken 41 times.
✓ Branch 12 → 13 taken 17 times.
✓ Branch 12 → 18 taken 24 times.
✓ Branch 26 → 27 taken 41 times.
✗ Branch 26 → 28 not taken.
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 45 not taken.
|
140 | return selected.startsWith(QStringLiteral("SYNC_MAINT.")) || |
| 107 |
8/13✓ Branch 16 → 17 taken 17 times.
✓ Branch 17 → 18 taken 2 times.
✓ Branch 17 → 19 taken 15 times.
✓ Branch 20 → 21 taken 17 times.
✓ Branch 20 → 22 taken 24 times.
✓ Branch 22 → 23 taken 17 times.
✓ Branch 22 → 24 taken 24 times.
✓ Branch 24 → 25 taken 41 times.
✗ Branch 24 → 26 not taken.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 33 not taken.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 37 not taken.
|
58 | selected.startsWith(QStringLiteral("CONTENTION.")); |
| 108 | 41 | } | |
| 109 | |||
| 110 | 1537 | bool BackgroundPerformanceTracker::selectedOperationMatches( | |
| 111 | const QStringList &operations) const { | ||
| 112 |
3/3✓ Branch 2 → 3 taken 1537 times.
✓ Branch 3 → 4 taken 1511 times.
✓ Branch 3 → 5 taken 26 times.
|
1537 | if (!isBackgroundActive()) |
| 113 | 1511 | return false; | |
| 114 |
2/2✓ Branch 5 → 6 taken 26 times.
✓ Branch 6 → 7 taken 26 times.
|
26 | const QString selected = PerformanceTrace::instance().selectedScenario(); |
| 115 |
1/1✓ Branch 9 → 10 taken 26 times.
|
26 | return std::any_of(operations.cbegin(), operations.cend(), |
| 116 | 34 | [&selected](const QString &operation) { | |
| 117 |
1/1✓ Branch 10 → 11 taken 34 times.
|
136 | return selected.contains(QStringLiteral(".") + |
| 118 |
1/1✓ Branch 8 → 9 taken 34 times.
|
68 | operation + |
| 119 |
1/1✓ Branch 9 → 10 taken 34 times.
|
136 | QStringLiteral(".")); |
| 120 | 26 | }); | |
| 121 | 26 | } | |
| 122 | |||
| 123 | 1537 | void BackgroundPerformanceTracker::beginBackground( | |
| 124 | const QStringList &operations, qint64 startNs, qint64 itemCount, | ||
| 125 | qint64 byteCount) { | ||
| 126 |
8/8✓ Branch 2 → 3 taken 1537 times.
✓ Branch 3 → 4 taken 24 times.
✓ Branch 3 → 6 taken 1513 times.
✓ Branch 4 → 5 taken 24 times.
✓ Branch 5 → 6 taken 9 times.
✓ Branch 5 → 7 taken 15 times.
✓ Branch 8 → 9 taken 1522 times.
✓ Branch 8 → 10 taken 15 times.
|
1537 | if (!selectedOperationMatches(operations) || m_background.isValid()) |
| 127 | 1522 | return; | |
| 128 |
2/2✓ Branch 10 → 11 taken 15 times.
✓ Branch 11 → 12 taken 15 times.
|
15 | const QString scenario = PerformanceTrace::instance().selectedScenario(); |
| 129 |
1/1✓ Branch 15 → 16 taken 15 times.
|
15 | const QString operation = scenario.section(QLatin1Char('.'), 1, 1); |
| 130 |
3/3✓ Branch 19 → 20 taken 15 times.
✓ Branch 22 → 23 taken 2 times.
✓ Branch 22 → 28 taken 13 times.
|
15 | if (scenario.startsWith(QStringLiteral("CONTENTION."))) { |
| 131 |
1/1✓ Branch 24 → 25 taken 2 times.
|
2 | m_backgroundMetric = QString::fromLatin1(ContentionBackgroundMetric); |
| 132 |
3/3✓ Branch 31 → 32 taken 13 times.
✓ Branch 34 → 35 taken 1 time.
✓ Branch 34 → 40 taken 12 times.
|
13 | } else if (operation.startsWith(QStringLiteral("shutdown_"))) { |
| 133 |
1/1✓ Branch 36 → 37 taken 1 time.
|
1 | m_backgroundMetric = QString::fromLatin1(ShutdownMetric); |
| 134 |
5/6✓ Branch 49 → 50 taken 10 times.
✓ Branch 49 → 75 taken 1 time.
✓ Branch 103 → 104 taken 12 times.
✗ Branch 103 → 105 not taken.
✓ Branch 105 → 106 taken 7 times.
✓ Branch 105 → 111 taken 5 times.
|
35 | } else if (operation == QStringLiteral("fts_rebuild") || |
| 135 |
5/6✓ Branch 54 → 55 taken 9 times.
✓ Branch 54 → 75 taken 1 time.
✓ Branch 99 → 100 taken 11 times.
✓ Branch 99 → 101 taken 1 time.
✓ Branch 101 → 102 taken 12 times.
✗ Branch 101 → 103 not taken.
|
33 | operation == QStringLiteral("fts_incremental") || |
| 136 |
6/6✓ Branch 59 → 60 taken 8 times.
✓ Branch 59 → 75 taken 1 time.
✓ Branch 95 → 96 taken 10 times.
✓ Branch 95 → 97 taken 2 times.
✓ Branch 97 → 98 taken 11 times.
✓ Branch 97 → 99 taken 1 time.
|
31 | operation == QStringLiteral("predictor_initial") || |
| 137 |
6/6✓ Branch 64 → 65 taken 7 times.
✓ Branch 64 → 75 taken 1 time.
✓ Branch 91 → 92 taken 9 times.
✓ Branch 91 → 93 taken 3 times.
✓ Branch 93 → 94 taken 10 times.
✓ Branch 93 → 95 taken 2 times.
|
29 | operation == QStringLiteral("predictor_incremental") || |
| 138 |
6/6✓ Branch 69 → 70 taken 6 times.
✓ Branch 69 → 75 taken 1 time.
✓ Branch 87 → 88 taken 8 times.
✓ Branch 87 → 89 taken 4 times.
✓ Branch 89 → 90 taken 9 times.
✓ Branch 89 → 91 taken 3 times.
|
27 | operation == QStringLiteral("migration") || |
| 139 |
8/8✓ Branch 44 → 45 taken 11 times.
✓ Branch 44 → 75 taken 1 time.
✓ Branch 74 → 75 taken 1 time.
✓ Branch 74 → 76 taken 5 times.
✓ Branch 83 → 84 taken 7 times.
✓ Branch 83 → 85 taken 5 times.
✓ Branch 85 → 86 taken 8 times.
✓ Branch 85 → 87 taken 4 times.
|
54 | operation == QStringLiteral("wal_checkpoint") || |
| 140 |
6/6✓ Branch 77 → 78 taken 6 times.
✓ Branch 77 → 79 taken 6 times.
✓ Branch 79 → 80 taken 6 times.
✓ Branch 79 → 81 taken 6 times.
✓ Branch 81 → 82 taken 7 times.
✓ Branch 81 → 83 taken 5 times.
|
18 | operation == QStringLiteral("payload_eviction")) { |
| 141 |
1/1✓ Branch 107 → 108 taken 7 times.
|
7 | m_backgroundMetric = QString::fromLatin1(MaintenanceMetric); |
| 142 | } else { | ||
| 143 |
1/1✓ Branch 112 → 113 taken 5 times.
|
5 | m_backgroundMetric = QString::fromLatin1(SyncMetric); |
| 144 | } | ||
| 145 | 15 | m_backgroundStartedNs = | |
| 146 |
3/3✓ Branch 116 → 117 taken 6 times.
✓ Branch 116 → 119 taken 9 times.
✓ Branch 117 → 118 taken 6 times.
|
15 | startNs >= 0 ? startNs : PerformanceTrace::monotonicNowNs(); |
| 147 | 15 | m_backgroundItems = 0; | |
| 148 | 15 | m_backgroundBytes = 0; | |
| 149 | 15 | m_sqliteBusyNs = 0; | |
| 150 | 15 | m_maxEventLoopDelayNs = 0; | |
| 151 | 15 | m_backgroundClients = 0; | |
| 152 | 15 | m_finishedBackgroundClients = 0; | |
| 153 | 15 | m_backgroundFailed = false; | |
| 154 | 15 | m_backgroundQueueClosed = false; | |
| 155 |
1/1✓ Branch 120 → 121 taken 15 times.
|
30 | m_background = PerformanceTrace::instance().startMetric( |
| 156 |
1/1✓ Branch 121 → 122 taken 15 times.
|
15 | scenario, m_backgroundMetric, m_backgroundStartedNs, itemCount, |
| 157 | 15 | byteCount); | |
| 158 |
1/1✓ Branch 127 → 128 taken 15 times.
|
30 | m_background.startPhase(QStringLiteral("background_work")); |
| 159 |
3/3✓ Branch 133 → 134 taken 15 times.
✓ Branch 136 → 137 taken 13 times.
✓ Branch 136 → 185 taken 2 times.
|
15 | if (scenario.startsWith(QStringLiteral("SYNC_MAINT."))) { |
| 160 | 65 | for (const QString &metric : {QString::fromLatin1(SyncMetric), | |
| 161 | 13 | QString::fromLatin1(ThroughputMetric), | |
| 162 | 13 | QString::fromLatin1(MaintenanceMetric), | |
| 163 |
6/10✓ Branch 138 → 139 taken 13 times.
✓ Branch 140 → 141 taken 13 times.
✓ Branch 142 → 143 taken 13 times.
✓ Branch 144 → 145 taken 13 times.
✓ Branch 177 → 148 taken 52 times.
✓ Branch 177 → 178 taken 13 times.
✗ Branch 230 → 231 not taken.
✗ Branch 230 → 234 not taken.
✗ Branch 232 → 233 not taken.
✗ Branch 232 → 234 not taken.
|
130 | QString::fromLatin1(ShutdownMetric)}) { |
| 164 |
4/4✓ Branch 149 → 150 taken 39 times.
✓ Branch 149 → 158 taken 13 times.
✓ Branch 153 → 154 taken 15 times.
✓ Branch 153 → 159 taken 24 times.
|
106 | if (metric == m_backgroundMetric || |
| 165 |
5/7✓ Branch 151 → 152 taken 39 times.
✓ Branch 157 → 158 taken 5 times.
✓ Branch 157 → 159 taken 10 times.
✓ Branch 164 → 165 taken 18 times.
✓ Branch 164 → 166 taken 34 times.
✗ Branch 240 → 241 not taken.
✗ Branch 240 → 242 not taken.
|
106 | (m_backgroundMetric == QString::fromLatin1(SyncMetric) && |
| 166 |
5/7✓ Branch 155 → 156 taken 15 times.
✓ Branch 160 → 161 taken 15 times.
✓ Branch 160 → 162 taken 37 times.
✓ Branch 162 → 163 taken 39 times.
✓ Branch 162 → 164 taken 13 times.
✗ Branch 235 → 236 not taken.
✗ Branch 235 → 237 not taken.
|
67 | metric == QString::fromLatin1(ThroughputMetric))) |
| 167 | 18 | continue; | |
| 168 |
2/2✓ Branch 166 → 167 taken 34 times.
✓ Branch 171 → 172 taken 34 times.
|
68 | PerformanceTrace::instance().markProcessEvent( |
| 169 |
1/1✓ Branch 170 → 171 taken 34 times.
|
68 | scenario, metric + QStringLiteral(".inapplicable")); |
| 170 | 65 | } | |
| 171 | } | ||
| 172 | 15 | m_probeExpectedNs = m_backgroundStartedNs + | |
| 173 | static_cast<qint64>(EventLoopProbeIntervalMs) * 1000000; | ||
| 174 |
1/1✓ Branch 185 → 186 taken 15 times.
|
15 | m_eventLoopProbe.start(); |
| 175 | 15 | } | |
| 176 | |||
| 177 | 2194 | void BackgroundPerformanceTracker::backgroundPhaseStarted( | |
| 178 | const QString &phase) { | ||
| 179 |
2/2✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 2191 times.
|
2194 | if (m_background.isValid()) |
| 180 | 3 | m_background.startPhase(phase); | |
| 181 | 2194 | } | |
| 182 | |||
| 183 | 1432 | void BackgroundPerformanceTracker::backgroundPhaseFinished(const QString &phase, | |
| 184 | qint64 itemCount, | ||
| 185 | qint64 byteCount) { | ||
| 186 |
2/2✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 1429 times.
|
1432 | if (m_background.isValid()) |
| 187 | 3 | m_background.endPhase(phase, itemCount, byteCount); | |
| 188 | 1432 | } | |
| 189 | |||
| 190 | 775 | void BackgroundPerformanceTracker::addBackgroundWork(qint64 itemCount, | |
| 191 | qint64 byteCount) { | ||
| 192 |
2/2✓ Branch 3 → 4 taken 764 times.
✓ Branch 3 → 5 taken 11 times.
|
775 | if (!m_background.isValid()) |
| 193 | 764 | return; | |
| 194 | 11 | m_backgroundItems += std::max<qint64>(0, itemCount); | |
| 195 | 11 | m_backgroundBytes += std::max<qint64>(0, byteCount); | |
| 196 | } | ||
| 197 | |||
| 198 | 4 | void BackgroundPerformanceTracker::backgroundClientQueued() { | |
| 199 |
5/6✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 6 taken 2 times.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 6 not taken.
✓ Branch 7 → 8 taken 2 times.
✓ Branch 7 → 9 taken 2 times.
|
4 | if (m_background.isValid() && !m_backgroundQueueClosed) |
| 200 | 2 | ++m_backgroundClients; | |
| 201 | 4 | } | |
| 202 | |||
| 203 | 3 | void BackgroundPerformanceTracker::backgroundQueueClosed() { | |
| 204 |
2/2✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 2 times.
|
3 | if (!m_background.isValid()) |
| 205 | 1 | return; | |
| 206 | 2 | m_backgroundQueueClosed = true; | |
| 207 |
2/2✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 13 taken 1 time.
|
2 | if (m_backgroundClients == 0) { |
| 208 |
1/1✓ Branch 9 → 10 taken 1 time.
|
1 | backgroundPhaseFinished(QStringLiteral("dav_sync")); |
| 209 | 1 | backgroundFinished(false); | |
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | 2 | void BackgroundPerformanceTracker::backgroundClientFailed() { | |
| 214 |
2/2✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 1 time.
|
2 | if (m_background.isValid()) |
| 215 | 1 | m_backgroundFailed = true; | |
| 216 | 2 | } | |
| 217 | |||
| 218 | 4 | void BackgroundPerformanceTracker::backgroundClientFinished() { | |
| 219 |
2/2✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 5 taken 2 times.
|
4 | if (!m_background.isValid()) |
| 220 | 2 | return; | |
| 221 | 2 | ++m_finishedBackgroundClients; | |
| 222 |
1/2✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 14 not taken.
|
2 | if (m_backgroundQueueClosed && |
| 223 |
2/2✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 14 taken 1 time.
|
2 | m_finishedBackgroundClients >= m_backgroundClients) { |
| 224 |
1/1✓ Branch 10 → 11 taken 1 time.
|
1 | backgroundPhaseFinished(QStringLiteral("dav_sync")); |
| 225 | 1 | backgroundFinished(!m_backgroundFailed); | |
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | 2 | void BackgroundPerformanceTracker::addSqliteBusyTime(qint64 durationNs) { | |
| 230 |
1/2✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 6 not taken.
|
2 | if (m_background.isValid()) |
| 231 | 2 | m_sqliteBusyNs += std::max<qint64>(0, durationNs); | |
| 232 | 2 | } | |
| 233 | |||
| 234 | 1 | void BackgroundPerformanceTracker::probeEventLoop() { | |
| 235 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 1 time.
|
1 | if (!m_background.isValid()) { |
| 236 | ✗ | m_eventLoopProbe.stop(); | |
| 237 | ✗ | return; | |
| 238 | } | ||
| 239 | 1 | const qint64 now = PerformanceTrace::monotonicNowNs(); | |
| 240 | 3 | m_maxEventLoopDelayNs = std::max( | |
| 241 | 1 | m_maxEventLoopDelayNs, std::max<qint64>(0, now - m_probeExpectedNs)); | |
| 242 | 1 | m_probeExpectedNs = | |
| 243 | 1 | now + static_cast<qint64>(EventLoopProbeIntervalMs) * 1000000; | |
| 244 | } | ||
| 245 | |||
| 246 | 769 | void BackgroundPerformanceTracker::backgroundFinished(bool success) { | |
| 247 |
3/3✓ Branch 2 → 3 taken 769 times.
✓ Branch 3 → 4 taken 755 times.
✓ Branch 3 → 5 taken 14 times.
|
769 | if (!m_background.isValid()) |
| 248 | 755 | return; | |
| 249 |
1/1✓ Branch 5 → 6 taken 14 times.
|
14 | m_eventLoopProbe.stop(); |
| 250 |
2/2✓ Branch 6 → 7 taken 14 times.
✓ Branch 7 → 8 taken 14 times.
|
14 | const QString scenario = PerformanceTrace::instance().selectedScenario(); |
| 251 | 14 | const qint64 totalNs = std::max<qint64>( | |
| 252 |
1/1✓ Branch 8 → 9 taken 14 times.
|
14 | 0, PerformanceTrace::monotonicNowNs() - m_backgroundStartedNs); |
| 253 |
1/1✓ Branch 13 → 14 taken 14 times.
|
28 | m_background.endPhase(QStringLiteral("background_work"), m_backgroundItems, |
| 254 | m_backgroundBytes); | ||
| 255 |
8/13✓ Branch 19 → 20 taken 14 times.
✓ Branch 20 → 21 taken 12 times.
✓ Branch 20 → 26 taken 2 times.
✓ Branch 24 → 25 taken 4 times.
✓ Branch 24 → 26 taken 8 times.
✓ Branch 31 → 32 taken 14 times.
✗ Branch 31 → 33 not taken.
✓ Branch 33 → 34 taken 4 times.
✓ Branch 33 → 40 taken 10 times.
✗ Branch 81 → 82 not taken.
✗ Branch 81 → 83 not taken.
✗ Branch 85 → 86 not taken.
✗ Branch 85 → 87 not taken.
|
54 | if (scenario.startsWith(QStringLiteral("SYNC_MAINT.")) && |
| 256 |
4/7✓ Branch 22 → 23 taken 12 times.
✓ Branch 27 → 28 taken 12 times.
✓ Branch 27 → 29 taken 2 times.
✓ Branch 29 → 30 taken 14 times.
✗ Branch 29 → 31 not taken.
✗ Branch 76 → 77 not taken.
✗ Branch 76 → 78 not taken.
|
26 | m_backgroundMetric == QString::fromLatin1(SyncMetric)) { |
| 257 |
2/2✓ Branch 34 → 35 taken 4 times.
✓ Branch 37 → 38 taken 4 times.
|
8 | PerformanceTrace::instance().markProcessEvent( |
| 258 |
1/1✓ Branch 36 → 37 taken 4 times.
|
8 | scenario, QString::fromLatin1(ThroughputMetric), -1, totalNs, |
| 259 | m_backgroundItems, m_backgroundBytes); | ||
| 260 | } | ||
| 261 |
3/3✓ Branch 43 → 44 taken 14 times.
✓ Branch 46 → 47 taken 2 times.
✓ Branch 46 → 58 taken 12 times.
|
14 | if (scenario.startsWith(QStringLiteral("CONTENTION."))) { |
| 262 |
2/2✓ Branch 47 → 48 taken 2 times.
✓ Branch 50 → 51 taken 2 times.
|
4 | PerformanceTrace::instance().markProcessEvent( |
| 263 |
1/1✓ Branch 49 → 50 taken 2 times.
|
4 | scenario, QString::fromLatin1(ContentionStallMetric), -1, |
| 264 | m_maxEventLoopDelayNs); | ||
| 265 |
2/2✓ Branch 52 → 53 taken 2 times.
✓ Branch 55 → 56 taken 2 times.
|
4 | PerformanceTrace::instance().markProcessEvent( |
| 266 |
1/1✓ Branch 54 → 55 taken 2 times.
|
4 | scenario, QString::fromLatin1(ContentionBusyMetric), -1, |
| 267 | m_sqliteBusyNs); | ||
| 268 | } | ||
| 269 |
3/3✓ Branch 58 → 59 taken 7 times.
✓ Branch 58 → 60 taken 7 times.
✓ Branch 61 → 62 taken 14 times.
|
14 | m_background.finish(success ? Outcome::Success : Outcome::Failed, |
| 270 | m_backgroundItems, m_backgroundBytes); | ||
| 271 | 14 | m_background = {}; | |
| 272 | 14 | m_backgroundMetric.clear(); | |
| 273 | 14 | m_backgroundStartedNs = 0; | |
| 274 | 14 | } | |
| 275 | |||
| 276 | 28 | void BackgroundPerformanceTracker::resetBackground() { | |
| 277 | 28 | m_eventLoopProbe.stop(); | |
| 278 |
2/2✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 27 times.
|
28 | if (m_background.isValid()) |
| 279 | 1 | m_background.finish(Outcome::Cancelled, m_backgroundItems, | |
| 280 | m_backgroundBytes); | ||
| 281 | 28 | m_background = {}; | |
| 282 | 28 | m_backgroundMetric.clear(); | |
| 283 | 28 | m_backgroundStartedNs = 0; | |
| 284 | 28 | m_backgroundItems = 0; | |
| 285 | 28 | m_backgroundBytes = 0; | |
| 286 | 28 | m_sqliteBusyNs = 0; | |
| 287 | 28 | m_probeExpectedNs = 0; | |
| 288 | 28 | m_maxEventLoopDelayNs = 0; | |
| 289 | 28 | m_backgroundClients = 0; | |
| 290 | 28 | m_finishedBackgroundClients = 0; | |
| 291 | 28 | m_backgroundFailed = false; | |
| 292 | 28 | m_backgroundQueueClosed = false; | |
| 293 | 28 | } | |
| 294 | |||
| 295 | 13 | bool BackgroundPerformanceTracker::beginFromAnchor(int observedCount) { | |
| 296 |
1/1✓ Branch 2 → 3 taken 13 times.
|
13 | auto &trace = PerformanceTrace::instance(); |
| 297 |
2/2✓ Branch 3 → 4 taken 13 times.
✓ Branch 4 → 5 taken 13 times.
|
13 | const QFileInfo traceInfo(trace.outputPath()); |
| 298 |
4/4✓ Branch 6 → 7 taken 13 times.
✓ Branch 8 → 9 taken 13 times.
✓ Branch 9 → 10 taken 13 times.
✓ Branch 10 → 11 taken 13 times.
|
13 | QFile file(traceInfo.dir().filePath(QString::fromLatin1(AnchorFileName))); |
| 299 |
3/3✓ Branch 15 → 16 taken 13 times.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 26 taken 12 times.
|
13 | if (!file.open(QIODevice::ReadOnly)) { |
| 300 |
2/2✓ Branch 20 → 21 taken 1 time.
✓ Branch 21 → 22 taken 1 time.
|
1 | trace.markProcessEvent(trace.selectedScenario(), |
| 301 | 2 | QStringLiteral("realtime.anchor_missing")); | |
| 302 | 1 | return false; | |
| 303 | } | ||
| 304 | 12 | QJsonParseError parseError; | |
| 305 | const QJsonDocument document = | ||
| 306 |
2/2✓ Branch 26 → 27 taken 12 times.
✓ Branch 27 → 28 taken 12 times.
|
12 | QJsonDocument::fromJson(file.readAll(), &parseError); |
| 307 |
7/7✓ Branch 29 → 30 taken 11 times.
✓ Branch 29 → 32 taken 1 time.
✓ Branch 30 → 31 taken 11 times.
✓ Branch 31 → 32 taken 1 time.
✓ Branch 31 → 33 taken 10 times.
✓ Branch 34 → 35 taken 2 times.
✓ Branch 34 → 44 taken 10 times.
|
12 | if (parseError.error != QJsonParseError::NoError || !document.isObject()) { |
| 308 |
2/2✓ Branch 38 → 39 taken 2 times.
✓ Branch 39 → 40 taken 2 times.
|
2 | trace.markProcessEvent(trace.selectedScenario(), |
| 309 | 4 | QStringLiteral("realtime.anchor_invalid")); | |
| 310 | 2 | return false; | |
| 311 | } | ||
| 312 |
1/1✓ Branch 44 → 45 taken 10 times.
|
10 | const QJsonObject object = document.object(); |
| 313 |
5/5✓ Branch 45 → 46 taken 10 times.
✓ Branch 46 → 47 taken 10 times.
✓ Branch 47 → 48 taken 10 times.
✓ Branch 63 → 49 taken 47 times.
✓ Branch 63 → 64 taken 9 times.
|
56 | for (const QString &key : object.keys()) { |
| 314 |
2/2✓ Branch 51 → 52 taken 1 time.
✓ Branch 51 → 61 taken 46 times.
|
47 | if (!AllowedAnchorFields.contains(key)) { |
| 315 |
2/2✓ Branch 55 → 56 taken 1 time.
✓ Branch 56 → 57 taken 1 time.
|
1 | trace.markProcessEvent(trace.selectedScenario(), |
| 316 | 2 | QStringLiteral("realtime.anchor_unsafe")); | |
| 317 | 1 | return false; | |
| 318 | } | ||
| 319 | 10 | } | |
| 320 | const qint64 acceptedNs = | ||
| 321 |
1/1✓ Branch 71 → 73 taken 9 times.
|
18 | object.value(QStringLiteral("server_accepted_monotonic_ns")) |
| 322 |
1/1✓ Branch 73 → 74 taken 9 times.
|
18 | .toVariant() |
| 323 |
1/1✓ Branch 74 → 75 taken 9 times.
|
9 | .toLongLong(); |
| 324 |
2/2✓ Branch 82 → 83 taken 9 times.
✓ Branch 83 → 84 taken 9 times.
|
9 | const int itemCount = object.value(QStringLiteral("item_count")).toInt(-1); |
| 325 |
1/1✓ Branch 87 → 88 taken 9 times.
|
9 | const qint64 now = PerformanceTrace::monotonicNowNs(); |
| 326 | const bool valid = | ||
| 327 |
5/13✓ Branch 91 → 92 taken 9 times.
✓ Branch 102 → 103 taken 7 times.
✓ Branch 102 → 117 taken 1 time.
✓ Branch 142 → 143 taken 9 times.
✗ Branch 142 → 144 not taken.
✓ Branch 144 → 145 taken 9 times.
✗ Branch 144 → 146 not taken.
✗ Branch 276 → 277 not taken.
✗ Branch 276 → 278 not taken.
✗ Branch 280 → 281 not taken.
✗ Branch 280 → 282 not taken.
✗ Branch 284 → 285 not taken.
✗ Branch 284 → 286 not taken.
|
34 | object.value(QStringLiteral("schema_version")).toInt() == 1 && |
| 328 |
8/16✓ Branch 99 → 100 taken 8 times.
✓ Branch 100 → 101 taken 8 times.
✓ Branch 130 → 131 taken 8 times.
✓ Branch 130 → 132 taken 1 time.
✓ Branch 132 → 133 taken 8 times.
✓ Branch 132 → 134 taken 1 time.
✓ Branch 134 → 135 taken 8 times.
✓ Branch 134 → 136 taken 1 time.
✗ Branch 252 → 253 not taken.
✗ Branch 252 → 254 not taken.
✗ Branch 256 → 257 not taken.
✗ Branch 256 → 258 not taken.
✗ Branch 260 → 261 not taken.
✗ Branch 260 → 262 not taken.
✗ Branch 264 → 265 not taken.
✗ Branch 264 → 266 not taken.
|
17 | object.value(QStringLiteral("run_id")).toString() == |
| 329 |
9/14✓ Branch 94 → 95 taken 8 times.
✓ Branch 95 → 96 taken 8 times.
✓ Branch 110 → 111 taken 6 times.
✓ Branch 110 → 117 taken 1 time.
✓ Branch 136 → 137 taken 8 times.
✓ Branch 136 → 138 taken 1 time.
✓ Branch 138 → 139 taken 8 times.
✓ Branch 138 → 140 taken 1 time.
✓ Branch 140 → 141 taken 9 times.
✗ Branch 140 → 142 not taken.
✗ Branch 268 → 269 not taken.
✗ Branch 268 → 270 not taken.
✗ Branch 272 → 273 not taken.
✗ Branch 272 → 274 not taken.
|
31 | traceInfo.dir().dirName() && |
| 330 |
8/16✓ Branch 107 → 108 taken 7 times.
✓ Branch 108 → 109 taken 7 times.
✓ Branch 120 → 121 taken 7 times.
✓ Branch 120 → 122 taken 2 times.
✓ Branch 122 → 123 taken 7 times.
✓ Branch 122 → 124 taken 2 times.
✓ Branch 124 → 125 taken 7 times.
✓ Branch 124 → 126 taken 2 times.
✗ Branch 232 → 233 not taken.
✗ Branch 232 → 234 not taken.
✗ Branch 236 → 237 not taken.
✗ Branch 236 → 238 not taken.
✗ Branch 240 → 241 not taken.
✗ Branch 240 → 242 not taken.
✗ Branch 244 → 245 not taken.
✗ Branch 244 → 246 not taken.
|
16 | object.value(QStringLiteral("scenario")).toString() == |
| 331 |
7/9✓ Branch 103 → 104 taken 7 times.
✓ Branch 111 → 112 taken 5 times.
✓ Branch 111 → 117 taken 1 time.
✓ Branch 126 → 127 taken 7 times.
✓ Branch 126 → 128 taken 2 times.
✓ Branch 128 → 129 taken 8 times.
✓ Branch 128 → 130 taken 1 time.
✗ Branch 248 → 249 not taken.
✗ Branch 248 → 250 not taken.
|
22 | trace.selectedScenario() && |
| 332 |
2/2✓ Branch 112 → 113 taken 4 times.
✓ Branch 112 → 117 taken 1 time.
|
5 | acceptedNs > 0 && acceptedNs <= now && |
| 333 |
9/9✓ Branch 92 → 93 taken 9 times.
✓ Branch 93 → 94 taken 8 times.
✓ Branch 93 → 117 taken 1 time.
✓ Branch 113 → 114 taken 3 times.
✓ Branch 113 → 117 taken 1 time.
✓ Branch 114 → 115 taken 2 times.
✓ Branch 114 → 117 taken 1 time.
✓ Branch 115 → 116 taken 1 time.
✓ Branch 115 → 117 taken 1 time.
|
26 | now - acceptedNs <= MaximumAnchorAgeNs && itemCount > 0 && |
| 334 |
2/2✓ Branch 118 → 119 taken 7 times.
✓ Branch 118 → 120 taken 2 times.
|
9 | itemCount == observedCount; |
| 335 |
2/2✓ Branch 146 → 147 taken 8 times.
✓ Branch 146 → 156 taken 1 time.
|
9 | if (!valid) { |
| 336 |
2/2✓ Branch 150 → 151 taken 8 times.
✓ Branch 151 → 152 taken 8 times.
|
8 | trace.markProcessEvent(trace.selectedScenario(), |
| 337 | 16 | QStringLiteral("realtime.anchor_mismatch")); | |
| 338 | 8 | return false; | |
| 339 | } | ||
| 340 |
1/1✓ Branch 156 → 157 taken 1 time.
|
1 | beginRealtimeDelivery(acceptedNs, itemCount); |
| 341 | 1 | return true; | |
| 342 | 13 | } | |
| 343 | |||
| 344 | 14 | void BackgroundPerformanceTracker::idleDeliveryObserved(int newCount) { | |
| 345 |
2/2✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 13 times.
|
14 | if (!isRealtimeActive()) |
| 346 | 1 | return; | |
| 347 |
4/8✓ Branch 6 → 7 taken 13 times.
✗ Branch 6 → 13 not taken.
✓ Branch 8 → 9 taken 13 times.
✗ Branch 8 → 13 not taken.
✓ Branch 10 → 11 taken 13 times.
✗ Branch 10 → 13 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 13 times.
|
26 | if (m_row.isValid() || m_badge.isValid() || m_notification.isValid() || |
| 348 |
1/2✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 13 times.
|
13 | m_settled.isValid()) { |
| 349 | ✗ | failAll(Outcome::Cancelled); | |
| 350 | } | ||
| 351 |
2/2✓ Branch 18 → 19 taken 12 times.
✓ Branch 18 → 20 taken 1 time.
|
13 | if (!beginFromAnchor(newCount)) |
| 352 | 12 | return; | |
| 353 |
1/1✓ Branch 23 → 24 taken 1 time.
|
2 | m_row.mark(QStringLiteral("client_idle_observed"), newCount); |
| 354 |
1/1✓ Branch 29 → 30 taken 1 time.
|
2 | m_badge.mark(QStringLiteral("client_idle_observed"), newCount); |
| 355 |
1/1✓ Branch 35 → 36 taken 1 time.
|
2 | m_notification.mark(QStringLiteral("client_idle_observed"), newCount); |
| 356 |
1/1✓ Branch 41 → 42 taken 1 time.
|
2 | m_settled.mark(QStringLiteral("client_idle_observed"), newCount); |
| 357 | } | ||
| 358 | |||
| 359 | 7 | void BackgroundPerformanceTracker::beginRealtimeDelivery( | |
| 360 | qint64 serverAcceptedNs, int expectedCount) { | ||
| 361 |
6/8✓ Branch 3 → 4 taken 4 times.
✓ Branch 3 → 6 taken 3 times.
✓ Branch 4 → 5 taken 4 times.
✗ Branch 4 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 4 times.
✓ Branch 8 → 9 taken 3 times.
✓ Branch 8 → 10 taken 4 times.
|
7 | if (!isRealtimeActive() || serverAcceptedNs <= 0 || expectedCount <= 0) |
| 362 | 3 | return; | |
| 363 | 4 | reset(); | |
| 364 | 4 | ensureEventFilterInstalled(); | |
| 365 |
2/2✓ Branch 12 → 13 taken 4 times.
✓ Branch 13 → 14 taken 4 times.
|
4 | m_scenario = PerformanceTrace::instance().selectedScenario(); |
| 366 | 4 | m_expectedCount = expectedCount; | |
| 367 |
1/1✓ Branch 16 → 17 taken 4 times.
|
8 | m_row = PerformanceTrace::instance().startMetric( |
| 368 |
2/2✓ Branch 18 → 19 taken 4 times.
✓ Branch 19 → 20 taken 4 times.
|
8 | m_scenario, QString::fromLatin1(RowMetric), serverAcceptedNs, |
| 369 | 4 | expectedCount); | |
| 370 |
1/1✓ Branch 23 → 24 taken 4 times.
|
8 | m_badge = PerformanceTrace::instance().startMetric( |
| 371 |
2/2✓ Branch 25 → 26 taken 4 times.
✓ Branch 26 → 27 taken 4 times.
|
8 | m_scenario, QString::fromLatin1(BadgeMetric), serverAcceptedNs, |
| 372 | 4 | expectedCount); | |
| 373 |
1/1✓ Branch 30 → 31 taken 4 times.
|
8 | m_notification = PerformanceTrace::instance().startMetric( |
| 374 |
2/2✓ Branch 32 → 33 taken 4 times.
✓ Branch 33 → 34 taken 4 times.
|
8 | m_scenario, QString::fromLatin1(NotificationMetric), serverAcceptedNs, |
| 375 | 4 | expectedCount); | |
| 376 |
1/1✓ Branch 37 → 38 taken 4 times.
|
8 | m_settled = PerformanceTrace::instance().startMetric( |
| 377 |
2/2✓ Branch 39 → 40 taken 4 times.
✓ Branch 40 → 41 taken 4 times.
|
8 | m_scenario, QString::fromLatin1(SettledMetric), serverAcceptedNs, |
| 378 | 4 | expectedCount); | |
| 379 | 4 | for (const Operation &operation : | |
| 380 |
2/2✓ Branch 64 → 51 taken 16 times.
✓ Branch 64 → 65 taken 4 times.
|
40 | {m_row, m_badge, m_notification, m_settled}) { |
| 381 |
1/1✓ Branch 54 → 55 taken 16 times.
|
32 | operation.mark(QStringLiteral("server_accepted"), expectedCount); |
| 382 |
1/1✓ Branch 60 → 61 taken 16 times.
|
32 | operation.startPhase(QStringLiteral("protocol_and_header_fetch"), |
| 383 | expectedCount); | ||
| 384 | 20 | } | |
| 385 | } | ||
| 386 | |||
| 387 | 20 | void BackgroundPerformanceTracker::headersCommitted(int fetchedCount, | |
| 388 | int appendedCount) { | ||
| 389 |
8/8✓ Branch 3 → 4 taken 7 times.
✓ Branch 3 → 6 taken 13 times.
✓ Branch 4 → 5 taken 6 times.
✓ Branch 4 → 6 taken 1 time.
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 5 times.
✓ Branch 8 → 9 taken 15 times.
✓ Branch 8 → 10 taken 5 times.
|
20 | if (!m_row.isValid() || fetchedCount <= 0 || appendedCount < 0) |
| 390 | 15 | return; | |
| 391 | 5 | m_fetchedCount += fetchedCount; | |
| 392 | 5 | m_appendedCount += appendedCount; | |
| 393 |
2/4✓ Branch 10 → 11 taken 5 times.
✗ Branch 10 → 13 not taken.
✓ Branch 11 → 12 taken 5 times.
✗ Branch 11 → 13 not taken.
|
5 | if (m_fetchedCount > m_expectedCount || m_appendedCount > m_expectedCount || |
| 394 |
2/2✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 15 taken 4 times.
|
5 | m_fetchedCount != m_appendedCount) { |
| 395 | 1 | failAll(Outcome::Failed); | |
| 396 | 1 | return; | |
| 397 | } | ||
| 398 |
2/2✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 17 taken 3 times.
|
4 | if (m_fetchedCount < m_expectedCount) |
| 399 | 1 | return; | |
| 400 | 3 | for (const Operation &operation : | |
| 401 |
2/2✓ Branch 37 → 24 taken 12 times.
✓ Branch 37 → 38 taken 3 times.
|
30 | {m_row, m_badge, m_notification, m_settled}) { |
| 402 |
1/1✓ Branch 27 → 28 taken 12 times.
|
12 | operation.endPhase(QStringLiteral("protocol_and_header_fetch"), |
| 403 | 12 | m_fetchedCount); | |
| 404 |
1/1✓ Branch 33 → 34 taken 12 times.
|
24 | operation.mark(QStringLiteral("headers_committed"), m_fetchedCount); |
| 405 | 15 | } | |
| 406 |
1/1✓ Branch 47 → 48 taken 3 times.
|
6 | m_row.startPhase(QStringLiteral("row_paint")); |
| 407 |
1/1✓ Branch 53 → 54 taken 3 times.
|
6 | m_settled.startPhase(QStringLiteral("visible_settle")); |
| 408 | 3 | m_rowPaintPending = true; | |
| 409 |
2/2✓ Branch 57 → 58 taken 2 times.
✓ Branch 57 → 60 taken 1 time.
|
3 | if (m_mailViewport) |
| 410 | 2 | m_mailViewport->update(); | |
| 411 | } | ||
| 412 | |||
| 413 | 7 | void BackgroundPerformanceTracker::badgeCommitted() { | |
| 414 |
2/2✓ Branch 4 → 5 taken 4 times.
✓ Branch 4 → 7 taken 2 times.
|
13 | if (!m_badge.isValid() || m_fetchedCount != m_expectedCount || |
| 415 |
7/8✓ Branch 3 → 4 taken 6 times.
✓ Branch 3 → 7 taken 1 time.
✓ Branch 5 → 6 taken 3 times.
✓ Branch 5 → 7 taken 1 time.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 3 times.
✓ Branch 9 → 10 taken 4 times.
✓ Branch 9 → 11 taken 3 times.
|
13 | m_badgePaintPending || m_badgePainted) |
| 416 | 4 | return; | |
| 417 |
1/1✓ Branch 14 → 15 taken 3 times.
|
6 | m_badge.startPhase(QStringLiteral("badge_paint")); |
| 418 | 3 | m_badgePaintPending = true; | |
| 419 |
2/2✓ Branch 18 → 19 taken 2 times.
✓ Branch 18 → 21 taken 1 time.
|
3 | if (m_badgeViewport) |
| 420 | 2 | m_badgeViewport->update(); | |
| 421 | } | ||
| 422 | |||
| 423 | 7 | void BackgroundPerformanceTracker::notificationCommitted(int representedCount, | |
| 424 | bool accepted) { | ||
| 425 |
6/6✓ Branch 3 → 4 taken 5 times.
✓ Branch 3 → 5 taken 2 times.
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 4 times.
✓ Branch 7 → 8 taken 3 times.
✓ Branch 7 → 9 taken 4 times.
|
7 | if (!m_notification.isValid() || representedCount <= 0) |
| 426 | 3 | return; | |
| 427 |
1/2✗ Branch 9 → 10 not taken.
✓ Branch 9 → 12 taken 4 times.
|
4 | if (!accepted) { |
| 428 | ✗ | failAll(Outcome::Failed); | |
| 429 | ✗ | return; | |
| 430 | } | ||
| 431 | 4 | m_notificationCount += representedCount; | |
| 432 |
2/2✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 15 taken 3 times.
|
4 | if (m_notificationCount > m_expectedCount) { |
| 433 | 1 | failAll(Outcome::Failed); | |
| 434 | 1 | return; | |
| 435 | } | ||
| 436 |
2/2✓ Branch 15 → 16 taken 2 times.
✓ Branch 15 → 27 taken 1 time.
|
3 | if (m_notificationCount == m_expectedCount) { |
| 437 |
1/1✓ Branch 19 → 20 taken 2 times.
|
2 | m_notification.mark(QStringLiteral("notification_service_accepted"), |
| 438 | 2 | m_notificationCount); | |
| 439 | 2 | m_notification.finish(Outcome::Success, m_expectedCount); | |
| 440 | 2 | m_notification = {}; | |
| 441 | 2 | m_notificationAccepted = true; | |
| 442 | 2 | maybeScheduleSettled(); | |
| 443 | } | ||
| 444 | } | ||
| 445 | |||
| 446 | ✗ | void BackgroundPerformanceTracker::failRealtimeDelivery() { | |
| 447 | ✗ | failAll(Outcome::Failed); | |
| 448 | ✗ | } | |
| 449 | |||
| 450 | 2 | void BackgroundPerformanceTracker::failAll(Outcome outcome) { | |
| 451 |
2/2✓ Branch 11 → 4 taken 8 times.
✓ Branch 11 → 12 taken 2 times.
|
10 | for (Operation *operation : {&m_row, &m_badge, &m_notification, &m_settled}) { |
| 452 |
3/3✓ Branch 4 → 5 taken 8 times.
✓ Branch 5 → 6 taken 6 times.
✓ Branch 5 → 7 taken 2 times.
|
8 | if (operation->isValid()) |
| 453 |
1/1✓ Branch 6 → 7 taken 6 times.
|
6 | operation->finish(outcome, m_expectedCount); |
| 454 | 8 | *operation = {}; | |
| 455 | } | ||
| 456 | 2 | m_rowPaintPending = false; | |
| 457 | 2 | m_badgePaintPending = false; | |
| 458 | 2 | m_settleScheduled = false; | |
| 459 | 2 | ++m_generation; | |
| 460 | 2 | } | |
| 461 | |||
| 462 | 8 | void BackgroundPerformanceTracker::maybeScheduleSettled() { | |
| 463 |
3/4✓ Branch 4 → 5 taken 8 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 6 times.
✓ Branch 5 → 8 taken 2 times.
|
16 | if (!m_settled.isValid() || m_settleScheduled || !m_rowPainted || |
| 464 |
7/8✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 8 not taken.
✓ Branch 6 → 7 taken 3 times.
✓ Branch 6 → 8 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 9 taken 2 times.
✓ Branch 10 → 11 taken 6 times.
✓ Branch 10 → 12 taken 2 times.
|
16 | !m_badgePainted || !m_notificationAccepted) |
| 465 | 6 | return; | |
| 466 | 2 | m_settleScheduled = true; | |
| 467 | 2 | const quint64 generation = ++m_generation; | |
| 468 |
1/1✓ Branch 12 → 13 taken 2 times.
|
2 | QTimer::singleShot(100, this, [this, generation]() { |
| 469 |
3/6✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 5 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 2 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 2 times.
|
2 | if (!m_settled.isValid() || generation != m_generation) |
| 470 | ✗ | return; | |
| 471 |
1/1✓ Branch 12 → 13 taken 2 times.
|
4 | m_settled.endPhase(QStringLiteral("visible_settle"), m_repaintCount); |
| 472 |
1/1✓ Branch 18 → 19 taken 2 times.
|
4 | m_settled.mark(QStringLiteral("settled_event_loop_turn"), m_repaintCount); |
| 473 | 2 | m_settled.finish(Outcome::Success, m_expectedCount); | |
| 474 | 2 | m_settled = {}; | |
| 475 | 2 | m_settleScheduled = false; | |
| 476 | }); | ||
| 477 | } | ||
| 478 | |||
| 479 | 40 | bool BackgroundPerformanceTracker::eventFilter(QObject *watched, | |
| 480 | QEvent *event) { | ||
| 481 |
2/2✓ Branch 3 → 4 taken 7 times.
✓ Branch 3 → 42 taken 33 times.
|
40 | if (event->type() == QEvent::Paint) { |
| 482 |
6/8✓ Branch 5 → 6 taken 3 times.
✓ Branch 5 → 10 taken 4 times.
✓ Branch 6 → 7 taken 3 times.
✗ Branch 6 → 10 not taken.
✓ Branch 8 → 9 taken 3 times.
✗ Branch 8 → 10 not taken.
✓ Branch 11 → 12 taken 3 times.
✓ Branch 11 → 23 taken 4 times.
|
7 | if (watched == m_mailViewport && m_rowPaintPending && m_row.isValid()) { |
| 483 | 3 | ++m_repaintCount; | |
| 484 |
1/1✓ Branch 15 → 16 taken 3 times.
|
6 | m_row.endPhase(QStringLiteral("row_paint"), m_expectedCount); |
| 485 | 3 | m_row.finish(Outcome::Success, m_expectedCount); | |
| 486 | 3 | m_row = {}; | |
| 487 | 3 | m_rowPaintPending = false; | |
| 488 | 3 | m_rowPainted = true; | |
| 489 | 3 | maybeScheduleSettled(); | |
| 490 | } | ||
| 491 |
5/6✓ Branch 24 → 25 taken 3 times.
✓ Branch 24 → 29 taken 4 times.
✓ Branch 25 → 26 taken 3 times.
✗ Branch 25 → 29 not taken.
✓ Branch 30 → 31 taken 3 times.
✓ Branch 30 → 42 taken 4 times.
|
10 | if (watched == m_badgeViewport && m_badgePaintPending && |
| 492 |
1/2✓ Branch 27 → 28 taken 3 times.
✗ Branch 27 → 29 not taken.
|
3 | m_badge.isValid()) { |
| 493 | 3 | ++m_repaintCount; | |
| 494 |
1/1✓ Branch 34 → 35 taken 3 times.
|
6 | m_badge.endPhase(QStringLiteral("badge_paint"), m_expectedCount); |
| 495 | 3 | m_badge.finish(Outcome::Success, m_expectedCount); | |
| 496 | 3 | m_badge = {}; | |
| 497 | 3 | m_badgePaintPending = false; | |
| 498 | 3 | m_badgePainted = true; | |
| 499 | 3 | maybeScheduleSettled(); | |
| 500 | } | ||
| 501 | } | ||
| 502 | 40 | return QObject::eventFilter(watched, event); | |
| 503 | } | ||
| 504 | |||
| 505 | } // namespace MailJD::Performance | ||
| 506 |