Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlgoubet2019-04-09 08:18:45 -0400
committerlgoubet2019-04-09 08:18:45 -0400
commitbe5bb041244737fc24fdc7e81222600a960a91b8 (patch)
treed61fecdad4173bcd53267da86b32367258f1ab61
parentbed7ff8930fb669d9edac8085508f5899a47d6cb (diff)
downloadorg.eclipse.emf.compare-be5bb041244737fc24fdc7e81222600a960a91b8.tar.gz
org.eclipse.emf.compare-be5bb041244737fc24fdc7e81222600a960a91b8.tar.xz
org.eclipse.emf.compare-be5bb041244737fc24fdc7e81222600a960a91b8.zip
Prevent OutOfMemoryErrors from the UI when switching CMV3.3.7M3
When comparing models that have very large single references (one reference containing 30k or more elements), computing the LCS will consume a huge amount of memory, repeatedly, only to display a placeholder for the insertion index if the user chooses to merge a given difference. This commit limits the number of object Change-Id: I4a18385090daf3d788c0f4a81faf470d526d4e42
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/provider/TreeMergeViewerItemContentProvider.java16
1 files changed, 16 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/provider/TreeMergeViewerItemContentProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/provider/TreeMergeViewerItemContentProvider.java
index bffbb816a..523eca58d 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/provider/TreeMergeViewerItemContentProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/provider/TreeMergeViewerItemContentProvider.java
@@ -81,6 +81,17 @@ import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
public class TreeMergeViewerItemContentProvider implements IMergeViewerItemContentProvider {
/**
+ * If the list on any one of the sides contains more elements than the given threshold, don't try and
+ * compute the insertion index for differences merging. On the one hand, showing insertion points in lists
+ * with so many elements wouldn't reallybe human readable, on the other hand, trying to compute insertion
+ * indices for too large lists will easily result in OutOfMemoryErrors. For example, if the left and right
+ * sides contain 60000 elements, we'll end up trying to instantiate an array with the following signature:
+ * "int[60000][60000]" to compute the LCS (see DiffUtils). Such an array would cost 13GB of memory as a
+ * conservative estimate.
+ */
+ private static final short LIST_SIZE_INSERTION_POINT_THRESHOLD = 10000;
+
+ /**
* {@inheritDoc}
*/
public boolean canHandle(Object object) {
@@ -300,6 +311,11 @@ public class TreeMergeViewerItemContentProvider implements IMergeViewerItemConte
List<Object> ancestorContent = getChildrenFromContentProvider(
getSideValue(parent, MergeViewerSide.ANCESTOR), adapterFactory);
+ if (sideContent.size() > LIST_SIZE_INSERTION_POINT_THRESHOLD
+ && oppositeContent.size() > LIST_SIZE_INSERTION_POINT_THRESHOLD) {
+ return new ArrayList<IMergeViewerItem>(values);
+ }
+
return createInsertionPoints(parent, sideContent, oppositeContent, ancestorContent, values,
differences, configuration);
}

Back to the top