jps model: cache role instances to optimize memory usage
authornik <Nikolay.Chashnikov@jetbrains.com>
Thu, 5 May 2016 10:45:26 +0000 (13:45 +0300)
committernik <Nikolay.Chashnikov@jetbrains.com>
Thu, 5 May 2016 10:45:26 +0000 (13:45 +0300)
jps/model-api/src/org/jetbrains/jps/model/ex/JpsElementChildRoleBase.java
jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java
jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkReferencesTableImpl.java

index 7150cb7708da527f8c49cf12fdfcceeab164474f..17036f1e9f80f2ff99030b77a332a83039bdd769 100644 (file)
@@ -25,7 +25,7 @@ public class JpsElementChildRoleBase<E extends JpsElement> extends JpsElementChi
   private String myDebugName;
 
   protected JpsElementChildRoleBase(String debugName) {
-    myDebugName = debugName.intern();
+    myDebugName = debugName;
   }
 
   @Override
index e2a4c50310040d0999501e319d1fd4291c977c2e..cdbb379c43c9302fa64d5465f4e138ce915e2344 100644 (file)
@@ -28,12 +28,17 @@ import org.jetbrains.jps.model.library.*;
 import org.jetbrains.jps.util.JpsPathUtil;
 
 import java.io.File;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
 
 /**
  * @author nik
  */
 public class JpsLibraryImpl<P extends JpsElement> extends JpsNamedCompositeElementBase<JpsLibraryImpl<P>> implements JpsTypedLibrary<P> {
+  private static final ConcurrentMap<JpsOrderRootType, JpsElementCollectionRole<JpsLibraryRoot>> ourRootRoles = ContainerUtil.newConcurrentMap();
   private final JpsLibraryType<P> myLibraryType;
 
   public JpsLibraryImpl(@NotNull String name, @NotNull JpsLibraryType<P> type, @NotNull P properties) {
@@ -103,7 +108,10 @@ public class JpsLibraryImpl<P extends JpsElement> extends JpsNamedCompositeEleme
   }
 
   private static JpsElementCollectionRole<JpsLibraryRoot> getRole(JpsOrderRootType type) {
-    return JpsElementCollectionRole.create(new JpsLibraryRootRole(type));
+    JpsElementCollectionRole<JpsLibraryRoot> role = ourRootRoles.get(type);
+    if (role != null) return role;
+    ourRootRoles.putIfAbsent(type, JpsElementCollectionRole.create(new JpsLibraryRootRole(type)));
+    return ourRootRoles.get(type);
   }
 
   @Override
index adf4bfb7314aee8b898cca00f6a31329e7287033..ad2a33ebdc07fe262d411c90028cd9f2972a4d8d 100644 (file)
@@ -15,6 +15,7 @@
  */
 package org.jetbrains.jps.model.module.impl;
 
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.jps.model.JpsElement;
@@ -25,11 +26,14 @@ import org.jetbrains.jps.model.library.sdk.JpsSdkReference;
 import org.jetbrains.jps.model.library.sdk.JpsSdkType;
 import org.jetbrains.jps.model.module.JpsSdkReferencesTable;
 
+import java.util.concurrent.ConcurrentMap;
+
 /**
  * @author nik
  */
 public class JpsSdkReferencesTableImpl extends JpsCompositeElementBase<JpsSdkReferencesTableImpl> implements JpsSdkReferencesTable {
   public static final JpsSdkReferencesTableRole ROLE = new JpsSdkReferencesTableRole();
+  private static final ConcurrentMap<JpsSdkType, JpsSdkReferenceRole> ourReferenceRoles = ContainerUtil.newConcurrentMap();
 
   public JpsSdkReferencesTableImpl() {
     super();
@@ -47,7 +51,7 @@ public class JpsSdkReferencesTableImpl extends JpsCompositeElementBase<JpsSdkRef
 
   @Override
   public <P extends JpsElement> void setSdkReference(@NotNull JpsSdkType<P> type, @Nullable JpsSdkReference<P> sdkReference) {
-    JpsSdkReferenceRole<P> role = new JpsSdkReferenceRole<P>(type);
+    JpsSdkReferenceRole<P> role = getSdkReferenceRole(type);
     if (sdkReference != null) {
       myContainer.setChild(role, sdkReference);
     }
@@ -58,7 +62,16 @@ public class JpsSdkReferencesTableImpl extends JpsCompositeElementBase<JpsSdkRef
 
   @Override
   public <P extends JpsElement> JpsSdkReference<P> getSdkReference(@NotNull JpsSdkType<P> type) {
-    return myContainer.getChild(new JpsSdkReferenceRole<P>(type));
+    return myContainer.getChild(getSdkReferenceRole(type));
+  }
+
+  @SuppressWarnings("unchecked")
+  @NotNull
+  private static <P extends JpsElement> JpsSdkReferenceRole<P> getSdkReferenceRole(@NotNull JpsSdkType<P> type) {
+    JpsSdkReferenceRole<P> role = ourReferenceRoles.get(type);
+    if (role != null) return role;
+    ourReferenceRoles.putIfAbsent(type, new JpsSdkReferenceRole<P>(type));
+    return ourReferenceRoles.get(type);
   }
 
   private static class JpsSdkReferencesTableRole extends JpsElementChildRoleBase<JpsSdkReferencesTable> implements JpsElementCreator<JpsSdkReferencesTable> {