diff --git a/src/groups/mqb/mqbblp/mqbblp_queueengineutil.cpp b/src/groups/mqb/mqbblp/mqbblp_queueengineutil.cpp index 0dd4e3cb2..1f415ee93 100644 --- a/src/groups/mqb/mqbblp/mqbblp_queueengineutil.cpp +++ b/src/groups/mqb/mqbblp/mqbblp_queueengineutil.cpp @@ -637,6 +637,17 @@ QueueEngineUtil_AppsDeliveryContext::QueueEngineUtil_AppsDeliveryContext( , d_currentMessage(0) , d_queue_p(queue) , d_timeDelta() +, d_currentAppView_p(0) +, d_visitVisitor( + bdlf::BindUtil::bindS(allocator, + &QueueEngineUtil_AppsDeliveryContext::visit, + this, + bdlf::PlaceHolders::_1)) +, d_broadcastVisitor(bdlf::BindUtil::bindS( + allocator, + &QueueEngineUtil_AppsDeliveryContext::visitBroadcast, + this, + bdlf::PlaceHolders::_1)) { BSLS_ASSERT_SAFE(queue); } @@ -670,12 +681,7 @@ bool QueueEngineUtil_AppsDeliveryContext::processApp( if (d_queue_p->isDeliverAll()) { // collect all handles - app.routing()->iterateConsumers( - bdlf::BindUtil::bind( - &QueueEngineUtil_AppsDeliveryContext::visitBroadcast, - this, - bdlf::PlaceHolders::_1), - d_currentMessage); + app.routing()->iterateConsumers(d_broadcastVisitor, d_currentMessage); d_isReady = true; @@ -708,13 +714,13 @@ bool QueueEngineUtil_AppsDeliveryContext::processApp( // mapped file, which can delay the unmapping of files in case this // message has a huge TTL and there are no consumers for this message. - Routers::Result result = app.selectConsumer( - bdlf::BindUtil::bind(&QueueEngineUtil_AppsDeliveryContext::visit, - this, - bdlf::PlaceHolders::_1, - appView), - d_currentMessage, - ordinal); + d_currentAppView_p = &appView; + Routers::Result result = app.selectConsumer(d_visitVisitor, + d_currentMessage, + ordinal); + // Not really necessary, since we use this pointer only from + // `d_oneConsumerVisitor`, but keep it empty when not needed + d_currentAppView_p = NULL; if (result == Routers::e_SUCCESS) { // RootQueueEngine makes stat reports @@ -749,14 +755,16 @@ bool QueueEngineUtil_AppsDeliveryContext::processApp( } bool QueueEngineUtil_AppsDeliveryContext::visit( - const Routers::Subscription* subscription, - const mqbi::AppMessage& appView) + const Routers::Subscription* subscription) { BSLS_ASSERT_SAFE(subscription); + BSLS_ASSERT_SAFE( + d_currentAppView_p && + "`d_currentAppView_p` must be assigned before calling this function"); d_consumers[subscription->handle()].push_back( bmqp::SubQueueInfo(subscription->d_downstreamSubscriptionId, - appView.d_rdaInfo)); + d_currentAppView_p->d_rdaInfo)); return true; } diff --git a/src/groups/mqb/mqbblp/mqbblp_queueengineutil.h b/src/groups/mqb/mqbblp/mqbblp_queueengineutil.h index 7496a9a37..c6b0f95c7 100644 --- a/src/groups/mqb/mqbblp/mqbblp_queueengineutil.h +++ b/src/groups/mqb/mqbblp/mqbblp_queueengineutil.h @@ -603,10 +603,26 @@ struct QueueEngineUtil_AppsDeliveryContext { mqbi::StorageIterator* d_currentMessage; mqbi::Queue* d_queue_p; bsl::optional d_timeDelta; + + /// Mutable additional argument used in `visit()`, when it is called from + /// `d_visitVisitor` functor. + const mqbi::AppMessage* d_currentAppView_p; + + /// Cached functor to `QueueEngineUtil_AppsDeliveryContext::visit` + const Routers::Visitor d_visitVisitor; + + /// Cached functor to `QueueEngineUtil_AppsDeliveryContext::visitBroadcast` + const Routers::Visitor d_broadcastVisitor; + // Avoid reading the attributes if not necessary. Get timeDelta on demand. // See comment in `QueueEngineUtil_AppsDeliveryContext::processApp`. public: + // TRAITS + BSLMF_NESTED_TRAIT_DECLARATION(QueueEngineUtil_AppsDeliveryContext, + bslma::UsesBslmaAllocator) + + // CREATORS QueueEngineUtil_AppsDeliveryContext(mqbi::Queue* queue, bslma::Allocator* allocator); @@ -637,8 +653,7 @@ struct QueueEngineUtil_AppsDeliveryContext { bool processApp(QueueEngineUtil_AppState& app, unsigned int ordina); /// Collect and prepare data for the subsequent `deliverMessage` call. - bool visit(const Routers::Subscription* subscription, - const mqbi::AppMessage& appView); + bool visit(const Routers::Subscription* subscription); bool visitBroadcast(const Routers::Subscription* subscription); /// Deliver message to the previously processed handles.