Repository: cxf Updated Branches: refs/heads/3.0.x-fixes 735178174 -> 58c15ecdf
[CXF-6227] Optimize conduit selection by making the address match faster Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/3013b681 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/3013b681 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/3013b681 Branch: refs/heads/3.0.x-fixes Commit: 3013b681ec60e670c5e862d34bb060fc2e3b0732 Parents: 7351781 Author: Alessio Soldano <asold...@redhat.com> Authored: Tue Feb 10 17:41:13 2015 +0100 Committer: Alessio Soldano <asold...@redhat.com> Committed: Tue Feb 10 17:45:49 2015 +0100 ---------------------------------------------------------------------- .../cxf/endpoint/AbstractConduitSelector.java | 60 ++++++++++++++++---- 1 file changed, 49 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/3013b681/core/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java b/core/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java index 7a3f989..7f1efb5 100644 --- a/core/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java +++ b/core/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java @@ -234,9 +234,7 @@ public abstract class AbstractConduitSelector implements ConduitSelector, Closea if (c != null) { return c; } - boolean full = MessageUtils.getContextualBoolean(message, - CONDUIT_COMPARE_FULL_URL, - false); + ContextualBooleanGetter cbg = new ContextualBooleanGetter(message); for (Conduit c2 : conduits) { if (c2.getTarget() == null || c2.getTarget().getAddress() == null @@ -253,14 +251,7 @@ public abstract class AbstractConduitSelector implements ConduitSelector, Closea actualAddress = messageAddress; } - if (!full) { - int idx = conduitAddress.indexOf(':'); - conduitAddress = idx == -1 ? "" : conduitAddress.substring(0, idx); - idx = actualAddress.indexOf(':'); - actualAddress = idx == -1 ? "" : actualAddress.substring(0, idx); - } - - if (conduitAddress.equalsIgnoreCase(actualAddress)) { + if (matchAddresses(conduitAddress, actualAddress, cbg)) { return c2; } } @@ -273,4 +264,51 @@ public abstract class AbstractConduitSelector implements ConduitSelector, Closea } return null; } + + private boolean matchAddresses(String conduitAddress, String actualAddress, ContextualBooleanGetter cbg) { + if (conduitAddress.length() == actualAddress.length()) { + //let's be optimistic and try full comparison first, regardless of CONDUIT_COMPARE_FULL_URL value, + //which can be expensive to fetch; as a matter of fact, anyway, if the addresses fully match, + //their hosts also match + if (conduitAddress.equalsIgnoreCase(actualAddress)) { + return true; + } else { + return cbg.isFullComparison() ? false : matchAddressSubstrings(conduitAddress, actualAddress); + } + } else { + return cbg.isFullComparison() ? false : matchAddressSubstrings(conduitAddress, actualAddress); + } + } + + //smart address substring comparison that tries to avoid building and comparing substrings unless strictly required + private boolean matchAddressSubstrings(String conduitAddress, String actualAddress) { + int idx = conduitAddress.indexOf(':'); + if (idx == actualAddress.indexOf(':')) { + if (idx <= 0) { + return true; + } + conduitAddress = conduitAddress.substring(0, idx); + actualAddress = actualAddress.substring(0, idx); + return conduitAddress.equalsIgnoreCase(actualAddress); + } else { + //no possible match as for sure the substrings before idx will be different + return false; + } + } + + private static final class ContextualBooleanGetter { + private Boolean value; + private final Message message; + + public ContextualBooleanGetter(Message message) { + this.message = message; + } + + public boolean isFullComparison() { + if (value == null) { + value = MessageUtils.getContextualBoolean(message, CONDUIT_COMPARE_FULL_URL, false); + } + return value; + } + } }