You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2024/06/19 01:32:25 UTC

(activemq-artemis) branch main updated: ARTEMIS-4814 Make direct binding lookup time constant

This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new 166adf4bfb ARTEMIS-4814 Make direct binding lookup time constant
166adf4bfb is described below

commit 166adf4bfb7777e25a643bd4b7442f2a6a562341
Author: Josh Byster <jo...@imc.com>
AuthorDate: Tue Jun 11 22:10:54 2024 -0500

    ARTEMIS-4814 Make direct binding lookup time constant
    
    Currently, with 500K+ queues, the cleanup step of TempQueueCleanerUpper
    requires invoking WildcardAddressManager#getDirectBindings, which is
    O(k) in the number of queues.
    
    From method profiling, this can consume up to 95% of our CPU time when
    needing to clean up many of these.
    
    Add a new map to keep track of the direct bindings, and add a test
    assertion that fails if we don't properly remove it.
---
 .../core/postoffice/impl/SimpleAddressManager.java | 30 ++++++++++++++--------
 .../impl/WildcardAddressManagerUnitTest.java       |  3 +++
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/SimpleAddressManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/SimpleAddressManager.java
index 992cd475bc..77b4a5fae4 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/SimpleAddressManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/SimpleAddressManager.java
@@ -68,6 +68,8 @@ public class SimpleAddressManager implements AddressManager {
 
    private final ConcurrentMap<SimpleString, Pair<Binding, Address>> nameMap = new ConcurrentHashMap<>();
 
+   private final ConcurrentMap<SimpleString, Collection<Binding>> directBindingMap = new ConcurrentHashMap<>();
+
    private final BindingsFactory bindingsFactory;
 
    protected final MetricsManager metricsManager;
@@ -100,6 +102,11 @@ public class SimpleAddressManager implements AddressManager {
       if (nameMap.putIfAbsent(binding.getUniqueName(), bindingAddressPair) != null) {
          throw ActiveMQMessageBundle.BUNDLE.bindingAlreadyExists(binding);
       }
+      directBindingMap.compute(binding.getAddress(), (key, value) -> {
+         Collection<Binding> bindingList = value == null ? new ArrayList<>() : value;
+         bindingList.add(binding);
+         return bindingList;
+      });
 
       if (logger.isTraceEnabled()) {
          logger.trace("Adding binding {} with address = {}", binding, binding.getUniqueName(), new Exception("trace"));
@@ -116,7 +123,18 @@ public class SimpleAddressManager implements AddressManager {
          return null;
       }
 
-      removeBindingInternal(binding.getA().getAddress(), uniqueName);
+      SimpleString address = binding.getA().getAddress();
+      removeBindingInternal(address, uniqueName);
+      directBindingMap.compute(address, (key, value) -> {
+         if (value == null) {
+            return null;
+         }
+         value.remove(binding.getA());
+         if (value.isEmpty()) {
+            return null;
+         }
+         return value;
+      });
 
       return binding.getA();
    }
@@ -160,15 +178,7 @@ public class SimpleAddressManager implements AddressManager {
    @Override
    public Collection<Binding> getDirectBindings(final SimpleString address) throws Exception {
       SimpleString realAddress = CompositeAddress.extractAddressName(address);
-      Collection<Binding> bindings = new ArrayList<>();
-
-      nameMap.forEach((bindingUniqueName, bindingAddressPair) -> {
-         if (bindingAddressPair.getA().getAddress().equals(realAddress)) {
-            bindings.add(bindingAddressPair.getA());
-         }
-      });
-
-      return bindings;
+      return new ArrayList<>(directBindingMap.getOrDefault(realAddress, Collections.emptyList()));
    }
 
    @Override
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/WildcardAddressManagerUnitTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/WildcardAddressManagerUnitTest.java
index faf089829c..d381cf7d29 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/WildcardAddressManagerUnitTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/WildcardAddressManagerUnitTest.java
@@ -202,6 +202,7 @@ public class WildcardAddressManagerUnitTest extends ActiveMQTestBase {
 
       assertEquals(0, ad.getAddresses().size());
       assertEquals(0, ad.getBindings().count());
+      assertEquals(0, ad.getDirectBindings(SimpleString.of("Topic1.>")).size());
    }
 
    @Test
@@ -374,6 +375,8 @@ public class WildcardAddressManagerUnitTest extends ActiveMQTestBase {
                // publish again, read only
                ad.getBindingsForRoutingAddress(pubAddr);
 
+               ad.getDirectBindings(pubAddr);
+
             } catch (Exception e) {
                e.printStackTrace();
                oops.set(e);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@activemq.apache.org
For additional commands, e-mail: commits-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact