Commit a3d29f51446a7103a2101a21135c5f920aa73dc4
1 parent
4a16d48b
Fix unnecessary QoS packet creation
The extraneous creation would happen when multiple subscribes at different QoS levels happen.
Showing
3 changed files
with
10 additions
and
9 deletions
client.cpp
| @@ -251,14 +251,14 @@ void Client::writeMqttPacketAndBlameThisClient(PublishCopyFactory &copyFactory, | @@ -251,14 +251,14 @@ void Client::writeMqttPacketAndBlameThisClient(PublishCopyFactory &copyFactory, | ||
| 251 | 251 | ||
| 252 | MqttPacket *p = copyFactory.getOptimumPacket(max_qos, this->protocolVersion, topic_alias, skip_topic); | 252 | MqttPacket *p = copyFactory.getOptimumPacket(max_qos, this->protocolVersion, topic_alias, skip_topic); |
| 253 | 253 | ||
| 254 | - assert(p->getQos() <= max_qos); | 254 | + assert(static_cast<bool>(p->getQos()) == static_cast<bool>(max_qos)); |
| 255 | 255 | ||
| 256 | if (p->getQos() > 0) | 256 | if (p->getQos() > 0) |
| 257 | { | 257 | { |
| 258 | // This may change the packet ID and QoS of the incoming packet for each subscriber, but because we don't store that packet anywhere, | 258 | // This may change the packet ID and QoS of the incoming packet for each subscriber, but because we don't store that packet anywhere, |
| 259 | // that should be fine. | 259 | // that should be fine. |
| 260 | p->setPacketId(packet_id); | 260 | p->setPacketId(packet_id); |
| 261 | - p->setQos(max_qos); | 261 | + p->setQos(copyFactory.getEffectiveQos(max_qos)); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | writeMqttPacketAndBlameThisClient(*p); | 264 | writeMqttPacketAndBlameThisClient(*p); |
publishcopyfactory.cpp
| @@ -19,31 +19,32 @@ PublishCopyFactory::PublishCopyFactory(Publish *publish) : | @@ -19,31 +19,32 @@ PublishCopyFactory::PublishCopyFactory(Publish *publish) : | ||
| 19 | 19 | ||
| 20 | MqttPacket *PublishCopyFactory::getOptimumPacket(const char max_qos, const ProtocolVersion protocolVersion, uint16_t topic_alias, bool skip_topic) | 20 | MqttPacket *PublishCopyFactory::getOptimumPacket(const char max_qos, const ProtocolVersion protocolVersion, uint16_t topic_alias, bool skip_topic) |
| 21 | { | 21 | { |
| 22 | + const char actualQos = getEffectiveQos(max_qos); | ||
| 23 | + | ||
| 22 | if (packet) | 24 | if (packet) |
| 23 | { | 25 | { |
| 24 | if (protocolVersion >= ProtocolVersion::Mqtt5 && (packet->containsClientSpecificProperties() || topic_alias > 0)) | 26 | if (protocolVersion >= ProtocolVersion::Mqtt5 && (packet->containsClientSpecificProperties() || topic_alias > 0)) |
| 25 | { | 27 | { |
| 26 | Publish newPublish(packet->getPublishData()); | 28 | Publish newPublish(packet->getPublishData()); |
| 27 | - newPublish.qos = max_qos; | 29 | + newPublish.qos = actualQos; |
| 28 | newPublish.topicAlias = topic_alias; | 30 | newPublish.topicAlias = topic_alias; |
| 29 | newPublish.skipTopic = skip_topic; | 31 | newPublish.skipTopic = skip_topic; |
| 30 | this->oneShotPacket = std::make_unique<MqttPacket>(protocolVersion, newPublish); | 32 | this->oneShotPacket = std::make_unique<MqttPacket>(protocolVersion, newPublish); |
| 31 | return this->oneShotPacket.get(); | 33 | return this->oneShotPacket.get(); |
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | - if (packet->getProtocolVersion() == protocolVersion && orgQos == max_qos) | 36 | + if (packet->getProtocolVersion() == protocolVersion && static_cast<bool>(orgQos) == static_cast<bool>(actualQos)) |
| 35 | { | 37 | { |
| 36 | - assert(orgQos == packet->getQos()); | ||
| 37 | return packet; | 38 | return packet; |
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | - const int cache_key = (static_cast<uint8_t>(protocolVersion) * 10) + max_qos; | 41 | + const int cache_key = (static_cast<uint8_t>(protocolVersion) * 10) + actualQos; |
| 41 | std::unique_ptr<MqttPacket> &cachedPack = constructedPacketCache[cache_key]; | 42 | std::unique_ptr<MqttPacket> &cachedPack = constructedPacketCache[cache_key]; |
| 42 | 43 | ||
| 43 | if (!cachedPack) | 44 | if (!cachedPack) |
| 44 | { | 45 | { |
| 45 | Publish newPublish(packet->getPublishData()); | 46 | Publish newPublish(packet->getPublishData()); |
| 46 | - newPublish.qos = max_qos; | 47 | + newPublish.qos = actualQos; |
| 47 | cachedPack = std::make_unique<MqttPacket>(protocolVersion, newPublish); | 48 | cachedPack = std::make_unique<MqttPacket>(protocolVersion, newPublish); |
| 48 | } | 49 | } |
| 49 | 50 | ||
| @@ -53,7 +54,7 @@ MqttPacket *PublishCopyFactory::getOptimumPacket(const char max_qos, const Proto | @@ -53,7 +54,7 @@ MqttPacket *PublishCopyFactory::getOptimumPacket(const char max_qos, const Proto | ||
| 53 | // Getting an instance of a Publish object happens at least on retained messages, will messages and SYS topics. It's low traffic, anyway. | 54 | // Getting an instance of a Publish object happens at least on retained messages, will messages and SYS topics. It's low traffic, anyway. |
| 54 | assert(publish); | 55 | assert(publish); |
| 55 | 56 | ||
| 56 | - publish->qos = getEffectiveQos(max_qos); | 57 | + publish->qos = actualQos; |
| 57 | 58 | ||
| 58 | this->oneShotPacket = std::make_unique<MqttPacket>(protocolVersion, *publish); | 59 | this->oneShotPacket = std::make_unique<MqttPacket>(protocolVersion, *publish); |
| 59 | return this->oneShotPacket.get(); | 60 | return this->oneShotPacket.get(); |
publishcopyfactory.h
| @@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
| 11 | * @brief The PublishCopyFactory class is for managing copies of an incoming publish, including sometimes not making copies at all. | 11 | * @brief The PublishCopyFactory class is for managing copies of an incoming publish, including sometimes not making copies at all. |
| 12 | * | 12 | * |
| 13 | * The idea is that certain incoming packets can just be written to the receiving client as-is, without constructing a new one. We do have to change the bytes | 13 | * The idea is that certain incoming packets can just be written to the receiving client as-is, without constructing a new one. We do have to change the bytes |
| 14 | - * where the QoS is stored, so we keep track of the original. | 14 | + * where the QoS is stored, so we keep track of the original QoS. |
| 15 | * | 15 | * |
| 16 | * Ownership info: object of this type are never copied or transferred, so the internal pointers come from (near) the same scope these objects | 16 | * Ownership info: object of this type are never copied or transferred, so the internal pointers come from (near) the same scope these objects |
| 17 | * are created from. | 17 | * are created from. |