app/core/DavPushStatistics.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "DavPushStatistics.h" | ||
| 2 | |||
| 3 | #include "data/CalendarModels.h" | ||
| 4 | #include "data/DavPushStore.h" | ||
| 5 | |||
| 6 | 857 | DavPushStatistics::DavPushStatistics(DavPushStore *store, std::function<qint64()> nowSeconds, QObject *parent) | |
| 7 |
1/1✓ Branch 8 → 9 taken 857 times.
|
857 | : QObject(parent), m_store(store), m_now(std::move(nowSeconds)) { |
| 8 |
1/1✓ Branch 9 → 10 taken 857 times.
|
857 | m_flush.setInterval(kFlushIntervalMs); |
| 9 |
1/1✓ Branch 10 → 11 taken 857 times.
|
857 | connect(&m_flush, &QTimer::timeout, this, &DavPushStatistics::flush); |
| 10 |
1/1✓ Branch 12 → 13 taken 857 times.
|
857 | m_flush.start(); |
| 11 | 857 | } | |
| 12 | |||
| 13 | 1713 | DavPushStatistics::~DavPushStatistics() { | |
| 14 | 857 | flush(); | |
| 15 | 1713 | } | |
| 16 | |||
| 17 | 202 | QString DavPushStatistics::accountScope(const QString &accountId) { | |
| 18 |
1/1✓ Branch 5 → 6 taken 202 times.
|
202 | return QStringLiteral("account:") + accountId; |
| 19 | } | ||
| 20 | |||
| 21 | 318 | QString DavPushStatistics::collectionScope(const QString &accountId, const QString &path) { | |
| 22 |
2/2✓ Branch 2 → 3 taken 318 times.
✓ Branch 6 → 7 taken 318 times.
|
636 | return QStringLiteral("collection:") + calendarSelectionKey(accountId, path); |
| 23 | } | ||
| 24 | |||
| 25 | 819 | void DavPushStatistics::count(const QString &scope, const QString &name, qint64 delta) { | |
| 26 | 819 | m_counts.append({scope, name, delta, m_now()}); | |
| 27 | 819 | emit changed(); | |
| 28 | 1638 | } | |
| 29 | |||
| 30 | 29 | void DavPushStatistics::latency(const QString &scope, const QString &kind, qint64 millis) { | |
| 31 | 29 | m_samples.append({scope, kind, millis, m_now()}); | |
| 32 | 29 | emit changed(); | |
| 33 | 58 | } | |
| 34 | |||
| 35 | 207 | void DavPushStatistics::event(const QString &scope, const QString &kind, const QString &detail) { | |
| 36 | 207 | m_events.append({scope, kind, detail, m_now()}); | |
| 37 | 207 | emit changed(); | |
| 38 | 414 | } | |
| 39 | |||
| 40 | // Runs on the GUI thread every 30 s: equal counters of the same hour are | ||
| 41 | // summed first and everything is written in one transaction (one commit; | ||
| 42 | // per-statement commits cost one fsync each and blocked the event loop | ||
| 43 | // for 100-300 ms under sustained push load). | ||
| 44 | 2547 | void DavPushStatistics::flush() { | |
| 45 |
4/7✓ Branch 2 → 3 taken 2547 times.
✗ Branch 2 → 5 not taken.
✓ Branch 3 → 4 taken 2547 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 2547 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 2547 times.
|
5059 | if (!m_store || !m_store->isOpen()) return; |
| 46 |
7/8✓ Branch 10 → 11 taken 2514 times.
✓ Branch 10 → 16 taken 33 times.
✓ Branch 12 → 13 taken 2514 times.
✗ Branch 12 → 16 not taken.
✓ Branch 14 → 15 taken 2512 times.
✓ Branch 14 → 16 taken 2 times.
✓ Branch 17 → 18 taken 2512 times.
✓ Branch 17 → 19 taken 35 times.
|
2547 | if (m_counts.isEmpty() && m_samples.isEmpty() && m_events.isEmpty()) return; |
| 47 | 35 | QList<PendingCount> merged; | |
| 48 | 35 | QHash<QString, qsizetype> index; // scope|name|hour -> position in merged | |
| 49 |
2/2✓ Branch 49 → 22 taken 817 times.
✓ Branch 49 → 50 taken 35 times.
|
852 | for (const auto &c : std::as_const(m_counts)) { |
| 50 |
5/5✓ Branch 23 → 24 taken 817 times.
✓ Branch 28 → 29 taken 817 times.
✓ Branch 29 → 30 taken 817 times.
✓ Branch 30 → 31 taken 817 times.
✓ Branch 31 → 32 taken 817 times.
|
817 | const QString key = c.scope + QLatin1Char('|') + c.name + QLatin1Char('|') + QString::number(c.at - c.at % 3600); |
| 51 | 817 | const auto found = index.constFind(key); | |
| 52 |
2/2✓ Branch 39 → 40 taken 549 times.
✓ Branch 39 → 43 taken 268 times.
|
817 | if (found != index.cend()) { |
| 53 |
1/1✓ Branch 41 → 42 taken 549 times.
|
549 | merged[*found].delta += c.delta; |
| 54 | } else { | ||
| 55 |
1/1✓ Branch 44 → 45 taken 268 times.
|
268 | index.insert(key, merged.size()); |
| 56 |
1/1✓ Branch 45 → 46 taken 268 times.
|
268 | merged.append(c); |
| 57 | } | ||
| 58 | 817 | } | |
| 59 |
1/1✓ Branch 50 → 51 taken 35 times.
|
35 | const bool transaction = m_store->beginTransaction(); |
| 60 |
3/3✓ Branch 55 → 56 taken 268 times.
✓ Branch 58 → 54 taken 268 times.
✓ Branch 58 → 59 taken 35 times.
|
303 | for (const auto &c : std::as_const(merged)) m_store->addCounter(c.scope, c.name, c.delta, c.at); |
| 61 |
3/3✓ Branch 63 → 64 taken 21 times.
✓ Branch 66 → 62 taken 21 times.
✓ Branch 66 → 67 taken 35 times.
|
56 | for (const auto &s : std::as_const(m_samples)) m_store->addLatency(s.scope, s.kind, s.millis, s.at); |
| 62 |
3/3✓ Branch 71 → 72 taken 204 times.
✓ Branch 74 → 70 taken 204 times.
✓ Branch 74 → 75 taken 35 times.
|
239 | for (const auto &e : std::as_const(m_events)) m_store->addEvent(e.scope, e.kind, e.detail, e.at); |
| 63 |
2/2✓ Branch 75 → 76 taken 35 times.
✓ Branch 76 → 77 taken 35 times.
|
35 | m_store->pruneHourly(m_now()); |
| 64 |
4/8✓ Branch 77 → 78 taken 35 times.
✗ Branch 77 → 81 not taken.
✓ Branch 78 → 79 taken 35 times.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 81 taken 35 times.
✗ Branch 82 → 83 not taken.
✓ Branch 82 → 84 taken 35 times.
✗ Branch 83 → 84 not taken.
|
35 | if (transaction && !m_store->commitTransaction()) m_store->rollbackTransaction(); |
| 65 |
1/1✓ Branch 84 → 85 taken 35 times.
|
35 | m_counts.clear(); |
| 66 |
1/1✓ Branch 85 → 86 taken 35 times.
|
35 | m_samples.clear(); |
| 67 |
1/1✓ Branch 86 → 87 taken 35 times.
|
35 | m_events.clear(); |
| 68 | 35 | } | |
| 69 | |||
| 70 | 152 | qint64 DavPushStatistics::counter(const QString &scope, const QString &name) const { | |
| 71 |
1/2✓ Branch 2 → 3 taken 152 times.
✗ Branch 2 → 5 not taken.
|
152 | qint64 value = m_store ? m_store->counter(scope, name) : 0; |
| 72 |
2/2✓ Branch 19 → 8 taken 730 times.
✓ Branch 19 → 20 taken 152 times.
|
882 | for (const auto &c : m_counts) |
| 73 |
6/6✓ Branch 10 → 11 taken 249 times.
✓ Branch 10 → 14 taken 481 times.
✓ Branch 12 → 13 taken 30 times.
✓ Branch 12 → 14 taken 219 times.
✓ Branch 15 → 16 taken 30 times.
✓ Branch 15 → 17 taken 700 times.
|
730 | if (c.scope == scope && c.name == name) value += c.delta; |
| 74 | 152 | return value; | |
| 75 | } | ||
| 76 | |||
| 77 | 32 | qint64 DavPushStatistics::periodSum(const QString &scope, const QString &name, qint64 sinceSeconds) const { | |
| 78 |
1/2✓ Branch 2 → 3 taken 32 times.
✗ Branch 2 → 5 not taken.
|
32 | qint64 value = m_store ? m_store->periodSum(scope, name, sinceSeconds) : 0; |
| 79 |
2/2✓ Branch 20 → 8 taken 64 times.
✓ Branch 20 → 21 taken 32 times.
|
96 | for (const auto &c : m_counts) |
| 80 |
7/8✓ Branch 10 → 11 taken 22 times.
✓ Branch 10 → 15 taken 42 times.
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 15 taken 20 times.
✓ Branch 13 → 14 taken 2 times.
✗ Branch 13 → 15 not taken.
✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 18 taken 62 times.
|
64 | if (c.scope == scope && c.name == name && c.at >= sinceSeconds - sinceSeconds % 3600) value += c.delta; |
| 81 | 32 | return value; | |
| 82 | } | ||
| 83 | |||
| 84 | 8 | QList<qint64> DavPushStatistics::latencies(const QString &scope, const QString &kind) const { | |
| 85 |
1/2✓ Branch 2 → 3 taken 8 times.
✗ Branch 2 → 4 not taken.
|
8 | QList<qint64> values = m_store ? m_store->latencies(scope, kind) : QList<qint64>(); |
| 86 |
2/2✓ Branch 18 → 7 taken 36 times.
✓ Branch 18 → 19 taken 8 times.
|
44 | for (const auto &s : m_samples) |
| 87 |
7/7✓ Branch 9 → 10 taken 20 times.
✓ Branch 9 → 13 taken 16 times.
✓ Branch 11 → 12 taken 12 times.
✓ Branch 11 → 13 taken 8 times.
✓ Branch 14 → 15 taken 12 times.
✓ Branch 14 → 16 taken 24 times.
✓ Branch 15 → 16 taken 12 times.
|
36 | if (s.scope == scope && s.kind == kind) values.append(s.millis); |
| 88 |
1/2✗ Branch 22 → 20 not taken.
✓ Branch 22 → 23 taken 8 times.
|
8 | while (values.size() > DavPushStore::kMaxLatencySamples) values.removeFirst(); |
| 89 | 8 | return values; | |
| 90 | ✗ | } | |
| 91 | |||
| 92 | 1 | bool DavPushStatistics::reset(const QString &scope) { | |
| 93 | 3 | m_counts.removeIf([&](const PendingCount &c) { return c.scope == scope; }); | |
| 94 | 9 | m_samples.removeIf([&](const PendingSample &s) { return s.scope == scope; }); | |
| 95 | 4 | m_events.removeIf([&](const PendingEvent &e) { return e.scope == scope; }); | |
| 96 |
2/4✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 10 not taken.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 10 not taken.
|
1 | const bool ok = m_store && m_store->resetStatistics(scope, m_now()); |
| 97 | 1 | emit changed(); | |
| 98 | 1 | return ok; | |
| 99 | } | ||
| 100 |