X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-dom-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fcodec%2Fimpl%2FEnumerationCodec.java;h=076ff1935f135b9a014c5c7ff1347ec14cd17393;hb=1a2d7e719b78cd564fe37578cab270372628d096;hp=2e16b0c616c0144b0ceee188b6ae47f0d4b90388;hpb=984dfcd854a006724cbf0b20efc8bac6094bad48;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/EnumerationCodec.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/EnumerationCodec.java index 2e16b0c616..076ff1935f 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/EnumerationCodec.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/EnumerationCodec.java @@ -10,13 +10,16 @@ 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.ImmutableBiMap; import com.google.common.collect.Maps; import java.util.Arrays; import java.util.Map; import java.util.Set; -import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.dom.codec.impl.ValueTypeCodec.SchemaUnawareCodec; import org.opendaylight.yangtools.yang.binding.Enumeration; import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; @@ -26,19 +29,31 @@ import org.slf4j.LoggerFactory; final class EnumerationCodec extends ReflectionBasedCodec implements SchemaUnawareCodec { private static final Logger LOG = LoggerFactory.getLogger(EnumerationCodec.class); + /* + * 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 EnumerationCodec> CACHE = CacheBuilder.newBuilder().weakKeys() + .softValues().build(); private final ImmutableBiMap> nameToEnum; - EnumerationCodec(final Class> enumeration, final Map> nameToEnum) { + private EnumerationCodec(final Class> enumeration, final Map> nameToEnum) { super(enumeration); this.nameToEnum = ImmutableBiMap.copyOf(nameToEnum); } - static Callable loader(final Class returnType, final EnumTypeDefinition def) { - checkArgument(Enum.class.isAssignableFrom(returnType)); - @SuppressWarnings("unchecked") - final Class> enumType = (Class>) returnType; - return () -> { + static @NonNull EnumerationCodec of(final Class returnType, final EnumTypeDefinition def) + throws ExecutionException { + return CACHE.get(returnType, () -> { + final Class> enumType = castType(returnType); + final Map> mapping = Maps.uniqueIndex(Arrays.asList(enumType.getEnumConstants()), value -> { checkArgument(value instanceof Enumeration, @@ -61,7 +76,13 @@ final class EnumerationCodec extends ReflectionBasedCodec implements SchemaUnawa } return new EnumerationCodec(enumType, mapping); - }; + }); + } + + @SuppressWarnings("unchecked") + private static Class> castType(final Class returnType) { + checkArgument(Enum.class.isAssignableFrom(returnType)); + return (Class>) returnType; } @Override