From: Robert Varga Date: Tue, 13 Nov 2018 14:13:41 +0000 (+0100) Subject: Cache mismatched augmentations X-Git-Tag: release/oxygen-sr4~9 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=50d8a3a7566d720ed20e7d2c0d841540d0cb5456;hp=56674bdd6082dd749a85986ad620f8a275f21ca5;p=mdsal.git Cache mismatched augmentations Address a FIXME around caching of mismatched augmentations, as it seems openflowplugin is doing this on purpose. The cache is expected to be needed infrequently in terms of associated objects as well as modified infrequently, hence we use a space-efficient ImmutableMap. JIRA: MDSAL-388 Change-Id: Id86d8c713ee1014d9d4867558032ba3ccd51fc45 Signed-off-by: Robert Varga (cherry picked from commit c44477a41ca49f9fddf92b56a129f915741de5c7) --- diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java index 5ef8844075..637585a950 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java @@ -11,6 +11,7 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableSortedMap; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -74,6 +75,8 @@ abstract class DataObjectCodecContext(); private final ConcurrentMap, DataContainerCodecPrototype> byStreamAugmented = new ConcurrentHashMap<>(); + private volatile ImmutableMap, DataContainerCodecPrototype> mismatchedAugmented = ImmutableMap.of(); + DataObjectCodecContext(final DataContainerCodecPrototype prototype) { super(prototype); @@ -281,25 +284,46 @@ abstract class DataObjectCodecContext mismatched = mismatchedAugmented.get(childClass); + if (mismatched != null) { + return mismatched; + } + @SuppressWarnings("rawtypes") final Class augTarget = BindingReflections.findAugmentationTarget((Class) childClass); if (getBindingClass().equals(augTarget)) { for (final DataContainerCodecPrototype realChild : byStreamAugmented.values()) { if (Augmentation.class.isAssignableFrom(realChild.getBindingClass()) && BindingReflections.isSubstitutionFor(childClass, realChild.getBindingClass())) { - return realChild; + return cacheMismatched(childClass, realChild); } } } return null; } + private synchronized DataContainerCodecPrototype cacheMismatched(final Class childClass, + final DataContainerCodecPrototype prototype) { + // Original access was unsynchronized, we need to perform additional checking + final ImmutableMap, DataContainerCodecPrototype> local = mismatchedAugmented; + final DataContainerCodecPrototype existing = local.get(childClass); + if (existing != null) { + return existing; + } + + final Builder, DataContainerCodecPrototype> builder = ImmutableMap.builderWithExpectedSize( + local.size() + 1); + builder.putAll(local); + builder.put(childClass, prototype); + + mismatchedAugmented = builder.build(); + return prototype; + } + private DataContainerCodecPrototype getAugmentationPrototype(final Type value) { final ClassLoadingStrategy loader = factory().getRuntimeContext().getStrategy(); @SuppressWarnings("rawtypes")