controller/BodyRequestRegistry.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QHash> | ||
| 4 | #include <QList> | ||
| 5 | #include <QQueue> | ||
| 6 | |||
| 7 | #include <optional> | ||
| 8 | |||
| 9 | #include "data/MailRequest.h" | ||
| 10 | |||
| 11 | struct BodyConsumer { | ||
| 12 | BodyPurpose purpose = BodyPurpose::Display; | ||
| 13 | quint64 consumerId = 0; | ||
| 14 | quint64 displayGeneration = 0; | ||
| 15 | |||
| 16 | friend bool operator==(const BodyConsumer &, const BodyConsumer &) = default; | ||
| 17 | }; | ||
| 18 | |||
| 19 | struct BodyRequestTicket { | ||
| 20 | quint64 requestId = 0; | ||
| 21 | bool deduplicated = false; | ||
| 22 | }; | ||
| 23 | |||
| 24 | struct BodyRequestResolution { | ||
| 25 | BodyRequest request; | ||
| 26 | BodyResult result; | ||
| 27 | QList<BodyConsumer> consumers; | ||
| 28 | bool displayEligible = false; | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct BodyPrefetchStats { | ||
| 32 | quint64 requested = 0; | ||
| 33 | quint64 deduplicated = 0; | ||
| 34 | quint64 completed = 0; | ||
| 35 | quint64 cancelled = 0; | ||
| 36 | quint64 failed = 0; | ||
| 37 | }; | ||
| 38 | |||
| 39 | // Pure state machine for body work. Network dispatch and MIME/cache handling | ||
| 40 | // stay in MailController; this type owns correlation, deduplication, priority, | ||
| 41 | // and display-generation eligibility. | ||
| 42 | class BodyRequestRegistry { | ||
| 43 | public: | ||
| 44 | static constexpr qsizetype MaximumQueuedPrefetch = 4; | ||
| 45 | |||
| 46 | quint64 selectDisplay(const MailId &mailId); | ||
| 47 | void clearDisplaySelection(); | ||
| 48 | void invalidateFolder(const QString &accountId, qint64 folderId); | ||
| 49 | 24818 | [[nodiscard]] MailId selectedMailId() const { return m_selectedMailId; } | |
| 50 | 2192 | [[nodiscard]] quint64 displayGeneration() const { | |
| 51 | 2192 | return m_displayGeneration; | |
| 52 | } | ||
| 53 | |||
| 54 | BodyRequestTicket request(const MailId &mailId, const QString &folderPath, | ||
| 55 | BodyPurpose purpose, quint64 consumerId = 0); | ||
| 56 | // P90.9: the dispatcher asks whether a real queued prefetch would take | ||
| 57 | // the single transport slot. An empty queue is neither demand nor prefetch. | ||
| 58 | [[nodiscard]] bool nextDispatchIsPrefetch() const; | ||
| 59 | [[nodiscard]] bool hasQueuedDemand() const; | ||
| 60 | std::optional<BodyRequest> takeNextForDispatch(bool allowPrefetch = true); | ||
| 61 | std::optional<BodyRequestResolution> complete(const BodyResult &result); | ||
| 62 | [[nodiscard]] bool matchesResult(const BodyResult &result) const; | ||
| 63 | void removeConsumer(BodyPurpose purpose, quint64 consumerId); | ||
| 64 | |||
| 65 | [[nodiscard]] bool contains(const MailId &mailId) const; | ||
| 66 | [[nodiscard]] std::optional<MailId> mailIdForRequest(quint64 requestId) const; | ||
| 67 | // A prefetch can gain a display/tab consumer while it parses; writer | ||
| 68 | // priority follows the live consumers at enqueue time. | ||
| 69 | [[nodiscard]] bool hasDemandConsumer(quint64 requestId) const; | ||
| 70 | 1047 | [[nodiscard]] qsizetype pendingCount() const { return m_byId.size(); } | |
| 71 | [[nodiscard]] qsizetype queuedPrefetchCount() const; | ||
| 72 | 8 | [[nodiscard]] BodyPrefetchStats prefetchStats() const { | |
| 73 | 8 | return m_prefetchStats; | |
| 74 | } | ||
| 75 | |||
| 76 | private: | ||
| 77 | struct Entry { | ||
| 78 | BodyRequest request; | ||
| 79 | QList<BodyConsumer> consumers; | ||
| 80 | bool dispatched = false; | ||
| 81 | }; | ||
| 82 | |||
| 83 | static bool isDisplayConsumer(const BodyConsumer &consumer); | ||
| 84 | static bool sameConsumer(const BodyConsumer &left, const BodyConsumer &right); | ||
| 85 | void removeQueuedRequest(quint64 requestId); | ||
| 86 | void removeConsumers(BodyPurpose purpose, std::optional<quint64> consumerId); | ||
| 87 | |||
| 88 | quint64 m_nextRequestId = 1; | ||
| 89 | quint64 m_displayGeneration = 0; | ||
| 90 | MailId m_selectedMailId; | ||
| 91 | QHash<quint64, Entry> m_byId; | ||
| 92 | QHash<MailId, quint64> m_byMail; | ||
| 93 | QQueue<quint64> m_demandQueue; | ||
| 94 | QQueue<quint64> m_prefetchQueue; | ||
| 95 | BodyPrefetchStats m_prefetchStats; | ||
| 96 | }; | ||
| 97 |