Skip to content

Commit adf7b5f

Browse files
committed
Use ImmutableSet for GeneSet when deserializing to save memory.
1 parent 3a4147c commit adf7b5f

File tree

6 files changed

+57
-11
lines changed

6 files changed

+57
-11
lines changed

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/CyActivator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import org.baderlab.csplugins.enrichmentmap.ApplicationModule.Headless;
66
import org.baderlab.csplugins.enrichmentmap.actions.OpenEnrichmentMapAction;
7+
import org.baderlab.csplugins.enrichmentmap.actions.ShowEnrichmentMapDialogAction;
78
import org.baderlab.csplugins.enrichmentmap.commands.BuildEnrichmentMapTuneableTaskFactory;
89
import org.baderlab.csplugins.enrichmentmap.commands.EnrichmentMapGSEACommandHandlerTaskFactory;
910
import org.baderlab.csplugins.enrichmentmap.model.EnrichmentMapManager;
@@ -106,6 +107,10 @@ public void shutDown() {
106107
// Close the legend panel
107108
LegendPanelMediator legendPanelMediator = injector.getInstance(LegendPanelMediator.class);
108109
legendPanelMediator.hideDialog();
110+
111+
// Dispose the creation dialog, or else lots of memory leaks.
112+
ShowEnrichmentMapDialogAction dialogAction = injector.getInstance(ShowEnrichmentMapDialogAction.class);
113+
dialogAction.dispose();
109114
}
110115
} finally {
111116
super.shutDown();

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/actions/ShowEnrichmentMapDialogAction.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@
33
import java.awt.event.ActionEvent;
44

55
import javax.swing.AbstractAction;
6+
import javax.swing.JFrame;
67

78
import org.baderlab.csplugins.enrichmentmap.view.creation.CreationDialogParameters;
89
import org.baderlab.csplugins.enrichmentmap.view.util.CardDialog;
9-
import org.cytoscape.application.swing.CySwingApplication;
10+
import org.baderlab.csplugins.enrichmentmap.view.util.SwingUtil;
1011

1112
import com.google.inject.Inject;
1213
import com.google.inject.Provider;
14+
import com.google.inject.Singleton;
1315

1416
@SuppressWarnings("serial")
17+
@Singleton
1518
public class ShowEnrichmentMapDialogAction extends AbstractAction {
1619

1720
@Inject private Provider<CreationDialogParameters> dialogParametersProvider;
18-
@Inject private CySwingApplication application;
21+
@Inject private Provider<JFrame> jframeProvider;
1922

2023
private CardDialog masterMapDialog;
2124

@@ -27,9 +30,17 @@ public ShowEnrichmentMapDialogAction() {
2730
public void actionPerformed(ActionEvent e) {
2831
if (masterMapDialog == null) {
2932
CreationDialogParameters params = dialogParametersProvider.get();
30-
masterMapDialog = new CardDialog(application.getJFrame(), params);
33+
masterMapDialog = new CardDialog(jframeProvider.get(), params);
3134
}
32-
3335
masterMapDialog.open();
3436
}
37+
38+
39+
public void dispose() {
40+
if(masterMapDialog != null) {
41+
SwingUtil.invokeOnEDTAndWait(() -> {
42+
masterMapDialog.dispose();
43+
});
44+
}
45+
}
3546
}

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/model/GeneSet.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ public class GeneSet {
5353

5454
private final String name;
5555
private final String description;
56-
private final Set<Integer> genes;
56+
// ImmutableSet uses less memory than a HashSet, also this forces GSON to deserialize using ImmutableSet.
57+
private final ImmutableSet<Integer> genes;
5758
private final Optional<String> source;
5859

5960
public GeneSet(String name, String description, Set<Integer> genes) {
6061
this.name = name;
6162
this.description = description;
62-
this.genes = genes;
63+
this.genes = ImmutableSet.copyOf(genes);
6364

6465
String[] name_tokens = name.split("%");
6566
if(name_tokens.length > 1)

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/model/SetOfGeneSets.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,15 @@ public class SetOfGeneSets {
1313
//name of results (ie. Dataset1 or name specified by user)
1414
private String name;
1515

16-
//the set of genesets
17-
// Hash Key = name of gene set
18-
// Hash Value = Gene set
19-
private Map<String, GeneSet> geneSets;
16+
/**
17+
* The set of genesets
18+
* Hash Key = name of gene set
19+
* Hash Value = Gene set
20+
*
21+
* Note: Must declare the type as HashMap because it forces GSON to deserialize using
22+
* an actual HashMap, otherwise it wants to use a LinkedTreeMap which uses much more memory.
23+
*/
24+
private HashMap<String, GeneSet> geneSets;
2025

2126
//filename
2227
private String filename;
@@ -48,7 +53,7 @@ public SetOfGeneSets(String ds, HashMap<String, String> props) {
4853
* the genes found in the expression file.
4954
*/
5055
public void filterGeneSets(Set<Integer> datasetGenes) {
51-
Map<String, GeneSet> filteredGenesets = new HashMap<>();
56+
HashMap<String, GeneSet> filteredGenesets = new HashMap<>();
5257

5358
//iterate through each geneset and filter each one
5459
for (String geneSetName : geneSets.keySet()) {

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/model/io/ModelSerializer.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515

1616
import com.google.common.collect.BiMap;
1717
import com.google.common.collect.HashBiMap;
18+
import com.google.common.collect.ImmutableSet;
1819
import com.google.gson.Gson;
1920
import com.google.gson.GsonBuilder;
21+
import com.google.gson.JsonArray;
2022
import com.google.gson.JsonDeserializationContext;
2123
import com.google.gson.JsonDeserializer;
2224
import com.google.gson.JsonElement;
@@ -25,6 +27,7 @@
2527
import com.google.gson.JsonPrimitive;
2628
import com.google.gson.JsonSerializationContext;
2729
import com.google.gson.JsonSerializer;
30+
import com.google.gson.reflect.TypeToken;
2831

2932
public class ModelSerializer {
3033

@@ -44,10 +47,13 @@ public static String serialize(EnrichmentMap map) {
4447

4548

4649
public static EnrichmentMap deserialize(String json) {
50+
Type immutableIntSetType = new TypeToken<ImmutableSet<Integer>>() {}.getType();
51+
4752
Gson gson = new GsonBuilder()
4853
.registerTypeAdapter(BiMap.class, new BiMapAdapter())
4954
.registerTypeHierarchyAdapter(Path.class, new PathAdapter())
5055
.registerTypeAdapter(EnrichmentResult.class, new EnrichmentResultAdapter())
56+
.registerTypeAdapter(immutableIntSetType, new ImmutableIntSetAdapter())
5157
.create();
5258

5359
try {
@@ -76,6 +82,19 @@ public BiMap<Integer,String> deserialize(JsonElement json, Type type, JsonDeseri
7682
}
7783
}
7884

85+
private static class ImmutableIntSetAdapter implements JsonDeserializer<ImmutableSet<Integer>> {
86+
@Override
87+
public ImmutableSet<Integer> deserialize(JsonElement json, Type type, JsonDeserializationContext context) {
88+
ImmutableSet.Builder<Integer> builder = ImmutableSet.builder();
89+
JsonArray array = (JsonArray) json;
90+
for(JsonElement element : array) {
91+
int gene = element.getAsInt();
92+
builder.add(gene);
93+
}
94+
return builder.build();
95+
}
96+
}
97+
7998
private static class PathAdapter implements JsonDeserializer<Path>, JsonSerializer<Path> {
8099
@Override
81100
public Path deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) {

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/view/util/CardDialog.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ public void open() {
5454
dialog.setVisible(true);
5555
}
5656

57+
public void dispose() {
58+
dialog.setVisible(false);
59+
dialog.dispose();
60+
}
61+
5762
public boolean isVisible() {
5863
return dialog != null && dialog.isVisible();
5964
}

0 commit comments

Comments
 (0)