ARTEMIS-4450 Caching hasLocal boolean on bindings to avoid transversing the maps on every call
This commit is contained in:
parent
4db39520f2
commit
42be518deb
|
@ -63,7 +63,5 @@ public interface Bindings extends UnproposalListener {
|
|||
|
||||
int size();
|
||||
|
||||
default boolean contains(Class clazz) {
|
||||
return false;
|
||||
}
|
||||
boolean hasLocalBinding();
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.apache.activemq.artemis.utils.CompositeAddress;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public final class BindingsImpl implements Bindings {
|
||||
|
@ -86,7 +87,12 @@ public final class BindingsImpl implements Bindings {
|
|||
/**
|
||||
* This has a version about adds and removes
|
||||
*/
|
||||
private final AtomicInteger version = new AtomicInteger(sequenceVersion.incrementAndGet());
|
||||
private volatile int version;
|
||||
|
||||
private static final AtomicIntegerFieldUpdater<BindingsImpl> VERSION_UPDATER = AtomicIntegerFieldUpdater
|
||||
.newUpdater(BindingsImpl.class, "version");
|
||||
|
||||
private volatile boolean hasLocal;
|
||||
|
||||
public BindingsImpl(final SimpleString name, final GroupingHandler groupingHandler, StorageManager storageManager) {
|
||||
this.groupingHandler = groupingHandler;
|
||||
|
@ -157,7 +163,19 @@ public final class BindingsImpl implements Bindings {
|
|||
}
|
||||
|
||||
private void updated() {
|
||||
version.set(sequenceVersion.incrementAndGet());
|
||||
VERSION_UPDATER.set(this, sequenceVersion.incrementAndGet());
|
||||
checkBindingsIdMap();
|
||||
}
|
||||
|
||||
private void checkBinding(Long bindingID, Binding binding) {
|
||||
if (binding instanceof LocalQueueBinding) {
|
||||
hasLocal = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkBindingsIdMap() {
|
||||
hasLocal = false;
|
||||
bindingsIdMap.forEach(this::checkBinding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -201,14 +219,8 @@ public final class BindingsImpl implements Bindings {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Class clazz) {
|
||||
for (Binding binding : getBindings()) {
|
||||
if (clazz.isInstance(binding)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
public boolean hasLocalBinding() {
|
||||
return hasLocal;
|
||||
}
|
||||
|
||||
|
||||
|
@ -296,7 +308,7 @@ public final class BindingsImpl implements Bindings {
|
|||
private void route(final Message message,
|
||||
final RoutingContext context,
|
||||
final boolean groupRouting) throws Exception {
|
||||
final int currentVersion = version.get();
|
||||
final int currentVersion = VERSION_UPDATER.get(this);
|
||||
final boolean reusableContext = context.isReusable(message, currentVersion);
|
||||
|
||||
if (!reusableContext) {
|
||||
|
|
|
@ -1269,7 +1269,7 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
|
|||
|
||||
Bindings simpleRoute(SimpleString address, RoutingContext context, Message message, AddressInfo addressInfo) throws Exception {
|
||||
Bindings bindings = addressManager.getBindingsForRoutingAddress(address);
|
||||
if ((bindings == null || !bindings.contains(LocalQueueBinding.class)) && context.getServerSession() != null) {
|
||||
if ((bindings == null || !bindings.hasLocalBinding()) && context.getServerSession() != null) {
|
||||
AutoCreateResult autoCreateResult = context.getServerSession().checkAutoCreate(new QueueConfiguration(address).setRoutingType(context.getRoutingType()));
|
||||
if (autoCreateResult == AutoCreateResult.NOT_FOUND) {
|
||||
ActiveMQException e = ActiveMQMessageBundle.BUNDLE.addressDoesNotExist(address);
|
||||
|
|
|
@ -64,7 +64,6 @@ import org.apache.activemq.artemis.core.postoffice.Bindings;
|
|||
import org.apache.activemq.artemis.core.postoffice.PostOffice;
|
||||
import org.apache.activemq.artemis.core.postoffice.QueueBinding;
|
||||
import org.apache.activemq.artemis.core.postoffice.RoutingStatus;
|
||||
import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding;
|
||||
import org.apache.activemq.artemis.core.protocol.core.CoreRemotingConnection;
|
||||
import org.apache.activemq.artemis.core.remoting.CertificateUtil;
|
||||
import org.apache.activemq.artemis.core.remoting.CloseListener;
|
||||
|
@ -1826,7 +1825,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
|
|||
if (server.locateQueue(unPrefixedQueue) == null) {
|
||||
// The queue doesn't exist.
|
||||
Bindings bindings = server.getPostOffice().lookupBindingsForAddress(unPrefixedAddress);
|
||||
if (bindings != null && bindings.contains(LocalQueueBinding.class) && !queueConfig.isFqqn()) {
|
||||
if (bindings != null && bindings.hasLocalBinding() && !queueConfig.isFqqn()) {
|
||||
// The address has another queue with a different name, which is fine. Just ignore it.
|
||||
result = AutoCreateResult.EXISTED;
|
||||
} else if (addressSettings.isAutoCreateQueues() || queueConfig.isTemporary()) {
|
||||
|
|
|
@ -493,6 +493,11 @@ public class WildcardAddressManagerUnitTest extends ActiveMQTestBase {
|
|||
this.name = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocalBinding() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Binding> getBindings() {
|
||||
return bindings.values();
|
||||
|
|
Loading…
Reference in New Issue