Migrate ModuleInfo cache to BindingReflections 72/82672/3
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 23 Jun 2019 21:54:34 +0000 (23:54 +0200)
committerRobert Varga <nite@hq.sk>
Sun, 23 Jun 2019 22:57:53 +0000 (22:57 +0000)
Reflections are using a cache already, so adding another one does
not really hurt. This allows code reuse between our test suite
and downstreams.

JIRA: MDSAL-418
Change-Id: Id4474a0754f33b880afaff333279969f947df494
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/AbstractSchemaAwareTest.java
binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java

index 1c558b33b7a3d34674f6c2b9dbc4057881ff3941..8d01ed15c253c1d63d7b38a4a0badca5c0a3d61e 100644 (file)
@@ -19,13 +19,6 @@ import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public abstract class AbstractSchemaAwareTest {
-    private static final LoadingCache<ClassLoader, Set<YangModuleInfo>> MODULE_INFO_CACHE = CacheBuilder.newBuilder()
-            .weakKeys().weakValues().build(new CacheLoader<ClassLoader, Set<YangModuleInfo>>() {
-                @Override
-                public Set<YangModuleInfo> load(final ClassLoader key) {
-                    return BindingReflections.loadModuleInfos(key);
-                }
-            });
     private static final LoadingCache<Set<YangModuleInfo>, SchemaContext> SCHEMA_CONTEXT_CACHE =
             CacheBuilder.newBuilder().weakValues().build(new CacheLoader<Set<YangModuleInfo>, SchemaContext>() {
                 @Override
@@ -42,7 +35,7 @@ public abstract class AbstractSchemaAwareTest {
     }
 
     protected Set<YangModuleInfo> getModuleInfos() throws Exception {
-        return MODULE_INFO_CACHE.getUnchecked(Thread.currentThread().getContextClassLoader());
+        return BindingReflections.cacheModuleInfos(Thread.currentThread().getContextClassLoader());
     }
 
     protected SchemaContext getSchemaContext() throws Exception {
index 5875f17b91a3e5e5464e7ce160a8e71763c95e62..ed9070f278e2a90e19c1dc6ee8a3ea127eb0f302 100644 (file)
@@ -29,6 +29,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.ServiceLoader;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -68,6 +69,15 @@ public final class BindingReflections {
             .expireAfterAccess(EXPIRATION_TIME, TimeUnit.SECONDS)
             .build(new ClassToQNameLoader());
 
+    private static final LoadingCache<ClassLoader, ImmutableSet<YangModuleInfo>> MODULE_INFO_CACHE =
+            CacheBuilder.newBuilder().weakKeys().weakValues().build(
+                new CacheLoader<ClassLoader, ImmutableSet<YangModuleInfo>>() {
+                    @Override
+                    public ImmutableSet<YangModuleInfo> load(final ClassLoader key) {
+                        return loadModuleInfos(key);
+                    }
+                });
+
     private BindingReflections() {
         throw new UnsupportedOperationException("Utility class.");
     }
@@ -331,9 +341,10 @@ public final class BindingReflections {
      * When {@link YangModuleInfo} is available, all dependencies are recursively collected into returning set by
      * collecting results of {@link YangModuleInfo#getImportedModules()}.
      *
-     * @param loader
-     *            Classloader for which {@link YangModuleInfo} should be
-     *            retrieved.
+     * <p>
+     * Consider using {@link #cacheModuleInfos(ClassLoader)} if the classloader is known to be immutable.
+     *
+     * @param loader Classloader for which {@link YangModuleInfo} should be retrieved.
      * @return Set of {@link YangModuleInfo} available for supplied classloader.
      */
     public static ImmutableSet<YangModuleInfo> loadModuleInfos(final ClassLoader loader) {
@@ -348,6 +359,27 @@ public final class BindingReflections {
         return moduleInfoSet.build();
     }
 
+    /**
+     * Loads {@link YangModuleInfo} instances available on supplied {@link ClassLoader}, assuming the set of available
+     * information does not change. Subsequent accesses may return cached values.
+     *
+     * <p>
+     * {@link YangModuleInfo} are discovered using {@link ServiceLoader} for {@link YangModelBindingProvider}.
+     * {@link YangModelBindingProvider} are simple classes which holds only pointers to actual instance
+     * {@link YangModuleInfo}.
+     *
+     * <p>
+     * When {@link YangModuleInfo} is available, all dependencies are recursively collected into returning set by
+     * collecting results of {@link YangModuleInfo#getImportedModules()}.
+     *
+     * @param loader Class loader for which {@link YangModuleInfo} should be retrieved.
+     * @return Set of {@link YangModuleInfo} available for supplied classloader.
+     */
+    @Beta
+    public static ImmutableSet<YangModuleInfo> cacheModuleInfos(final ClassLoader loader) throws ExecutionException {
+        return MODULE_INFO_CACHE.get(loader);
+    }
+
     private static void collectYangModuleInfo(final YangModuleInfo moduleInfo,
             final Builder<YangModuleInfo> moduleInfoSet) {
         moduleInfoSet.add(moduleInfo);