X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=binding%2Fmdsal-binding-dom-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fcodec%2Fimpl%2FBitsCodec.java;h=9a4238e9dcb9d891cac7002c9bb319395edc070b;hb=c4d4ec8b44becb12d2ea0c2a2be8f24994c2b58d;hp=340ad77f37e01aa14f61713cc94dc8f63e3efe90;hpb=8eccd3361817a9b116798cc054ded188ad1d8958;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BitsCodec.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BitsCodec.java index 340ad77f37..9a4238e9dc 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BitsCodec.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BitsCodec.java @@ -10,6 +10,8 @@ package org.opendaylight.mdsal.binding.dom.codec.impl; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import java.lang.invoke.MethodHandle; @@ -25,13 +27,25 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; -import java.util.concurrent.Callable; -import org.opendaylight.mdsal.binding.dom.codec.impl.ValueTypeCodec.SchemaUnawareCodec; +import java.util.concurrent.ExecutionException; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.spec.naming.BindingMapping; import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit; final class BitsCodec extends ReflectionBasedCodec implements SchemaUnawareCodec { + /* + * Use identity comparison for keys and allow classes to be GCd themselves. + * + * Since codecs can (and typically do) hold a direct or indirect strong reference to the class, they need to be also + * accessed via reference. Using a weak reference could be problematic, because the codec would quite often be only + * weakly reachable. We therefore use a soft reference, whose implementation guidance is suitable to our use case: + * + * "Virtual machine implementations are, however, encouraged to bias against clearing recently-created or + * recently-used soft references." + */ + private static final Cache, @NonNull BitsCodec> CACHE = CacheBuilder.newBuilder().weakKeys().softValues() + .build(); private static final MethodType CONSTRUCTOR_INVOKE_TYPE = MethodType.methodType(Object.class, Boolean[].class); // Ordered by position @@ -48,8 +62,9 @@ final class BitsCodec extends ReflectionBasedCodec implements SchemaUnawareCodec this.getters = ImmutableMap.copyOf(getters); } - static Callable loader(final Class returnType, final BitsTypeDefinition rootType) { - return () -> { + static @NonNull BitsCodec of(final Class returnType, final BitsTypeDefinition rootType) + throws ExecutionException { + return CACHE.get(returnType, () -> { final Map getters = new LinkedHashMap<>(); final Set ctorArgs = new TreeSet<>(); @@ -69,7 +84,7 @@ final class BitsCodec extends ReflectionBasedCodec implements SchemaUnawareCodec final MethodHandle ctor = MethodHandles.publicLookup().unreflectConstructor(constructor) .asSpreader(Boolean[].class, ctorArgs.size()).asType(CONSTRUCTOR_INVOKE_TYPE); return new BitsCodec(returnType, ctor, ctorArgs, getters); - }; + }); } @Override