Improve YangStoreService performance
[controller.git] / opendaylight / config / config-manager-facade-xml / src / main / java / org / opendaylight / controller / config / facade / xml / osgi / YangStoreService.java
index b6b1869937dda15dd99de854999c46b9167f5971..462d67bc001cca540ca3790d1b61fe140689c860 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.controller.config.facade.xml.osgi;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import java.lang.ref.SoftReference;
 import java.util.Collections;
@@ -18,13 +21,17 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicReference;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.config.util.capability.ModuleListener;
+import org.opendaylight.controller.config.util.capability.YangModuleCapability;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,6 +66,7 @@ public class YangStoreService implements YangStoreContext {
             new AtomicReference<>(new SoftReference<BindingRuntimeContext>(null));
 
     private final SchemaContextProvider schemaContextProvider;
+    private final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
 
     private final ExecutorService notificationExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
         @Override
@@ -69,17 +77,20 @@ public class YangStoreService implements YangStoreContext {
 
     private final Set<ModuleListener> listeners = Collections.synchronizedSet(new HashSet<ModuleListener>());
 
-    public YangStoreService(final SchemaContextProvider schemaContextProvider) {
+    public YangStoreService(final SchemaContextProvider schemaContextProvider,
+        final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
         this.schemaContextProvider = schemaContextProvider;
+        this.sourceProvider = sourceProvider;
     }
 
-    private synchronized YangStoreContext getYangStoreSnapshot() {
+    synchronized YangStoreContext getYangStoreSnapshot() {
         SoftReference<YangStoreSnapshot> r = ref.get();
         YangStoreSnapshot ret = r.get();
 
         while (ret == null) {
             // We need to be compute a new value
-            ret = new YangStoreSnapshot(schemaContextProvider.getSchemaContext(), refBindingContext.get().get());
+            // TODO sourceProvider is not a snapshot
+            ret = new YangStoreSnapshot(schemaContextProvider.getSchemaContext(), refBindingContext.get().get(), sourceProvider);
 
             if (!ref.compareAndSet(r, new SoftReference<>(ret))) {
                 LOG.debug("Concurrent refresh detected, recomputing snapshot");
@@ -95,6 +106,7 @@ public class YangStoreService implements YangStoreContext {
         return getYangStoreSnapshot();
     }
 
+    @Deprecated
     @Override
     public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
         return getYangStoreSnapshot().getModuleMXBeanEntryMap();
@@ -135,16 +147,25 @@ public class YangStoreService implements YangStoreContext {
         }
 
         this.listeners.add(listener);
-        listener.onCapabilitiesChanged(context.getModules(), Collections.<Module>emptySet());
+        listener.onCapabilitiesChanged(toCapabilities(context.getModules(), context), Collections.<Capability>emptySet());
 
         return new AutoCloseable() {
             @Override
-            public void close() throws Exception {
+            public void close() {
                 YangStoreService.this.listeners.remove(listener);
             }
         };
     }
 
+    private static Set<Capability> toCapabilities(final Set<Module> modules, final YangStoreContext current) {
+        return ImmutableSet.copyOf(Collections2.transform(modules, new Function<Module, Capability>() {
+            @Override
+            public Capability apply(final Module input) {
+                return new YangModuleCapability(input, current.getModuleSource(input));
+            }
+        }));
+    }
+
     private final class CapabilityChangeNotifier implements Runnable {
 
         private final YangStoreSnapshot previous;
@@ -157,14 +178,20 @@ public class YangStoreService implements YangStoreContext {
         public void run() {
             final YangStoreContext current = getYangStoreSnapshot();
 
-            if(!current.equals(previous)) {
-                final Set<Module> removed = Sets.difference(previous.getModules(), current.getModules());
-                final Set<Module> added = Sets.difference(current.getModules(), previous.getModules());
+            if (!current.equals(previous)) {
+                final Set<Module> prevModules = previous.getModules();
+                final Set<Module> currModules = current.getModules();
+                final Set<Module> removed = Sets.difference(prevModules, currModules);
+                final Set<Module> added = Sets.difference(currModules, prevModules);
+
+                final Set<Capability> addedCaps = toCapabilities(added, current);
+                final Set<Capability> removedCaps = toCapabilities(removed, current);
 
                 for (final ModuleListener listener : listeners) {
-                    listener.onCapabilitiesChanged(added, removed);
+                    listener.onCapabilitiesChanged(addedCaps, removedCaps);
                 }
             }
         }
+
     }
 }