Skip to content

Commit 21d0feb

Browse files
committed
perf: replace recursion with iteration
1 parent 34cd443 commit 21d0feb

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/ProxyCompositeNode.java

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
package com.avaloq.tools.ddk.xtext.resource.persistence;
1212

1313
import java.io.IOException;
14+
import java.util.ArrayDeque;
1415
import java.util.ArrayList;
16+
import java.util.Deque;
1517
import java.util.List;
1618

1719
import org.eclipse.emf.common.notify.Adapter;
@@ -21,8 +23,9 @@
2123
import org.eclipse.emf.common.util.TreeIterator;
2224
import org.eclipse.emf.common.util.WrappedException;
2325
import org.eclipse.emf.ecore.EObject;
26+
import org.eclipse.emf.ecore.EStructuralFeature;
27+
import org.eclipse.emf.ecore.impl.EClassImpl;
2428
import org.eclipse.emf.ecore.resource.Resource;
25-
import org.eclipse.emf.ecore.util.EContentsEList.FeatureIterator;
2629
import org.eclipse.xtext.nodemodel.BidiIterable;
2730
import org.eclipse.xtext.nodemodel.BidiTreeIterable;
2831
import org.eclipse.xtext.nodemodel.BidiTreeIterator;
@@ -80,24 +83,45 @@ static void installProxyNodeModel(final Resource resource) {
8083
ProxyCompositeNode rootNode = installProxyNodeModel(root, idToEObjectMap);
8184
idToEObjectMap.trimToSize();
8285
rootNode.idToEObjectMap = idToEObjectMap;
83-
8486
if (resource instanceof XtextResource) {
8587
((XtextResource) resource).setParseResult(new ParseResult(root, rootNode, false));
8688
}
8789
}
8890

8991
private static ProxyCompositeNode installProxyNodeModel(final EObject eObject, final List<EObject> map) {
90-
ProxyCompositeNode result = new ProxyCompositeNode();
91-
eObject.eAdapters().add(result);
92+
Deque<EObject> deque = new ArrayDeque<>();
93+
deque.push(eObject);
94+
ProxyCompositeNode rootComposite = new ProxyCompositeNode();
95+
eObject.eAdapters().add(rootComposite);
9296
map.add(eObject);
9397

94-
for (FeatureIterator<EObject> it = (FeatureIterator<EObject>) eObject.eContents().iterator(); it.hasNext();) {
95-
EObject child = it.next();
96-
if (!it.feature().isTransient()) {
97-
installProxyNodeModel(child, map);
98+
while (!deque.isEmpty()) {
99+
EObject nextEObject = deque.pop();
100+
EStructuralFeature[] structuralFeatures = ((EClassImpl.FeatureSubsetSupplier) nextEObject.eClass().getEAllStructuralFeatures()).containments();
101+
if (structuralFeatures != null) {
102+
for (int i = structuralFeatures.length - 1; i >= 0; i--) {
103+
EStructuralFeature eStructuralFeature = structuralFeatures[i];
104+
if (!eStructuralFeature.isTransient()) {
105+
Object child = nextEObject.eGet(eStructuralFeature, false);
106+
if (child instanceof EObject singleChild) {
107+
singleChild.eAdapters().add(new ProxyCompositeNode());
108+
map.add(singleChild);
109+
deque.push(singleChild);
110+
} else if (child instanceof EList listChild) {
111+
for (int j = listChild.size() - 1; j >= 0; j--) {
112+
EObject singleChild = (EObject) listChild.get(j);
113+
singleChild.eAdapters().add(new ProxyCompositeNode());
114+
map.add(singleChild);
115+
deque.push(singleChild);
116+
}
117+
} else if (child != null) {
118+
throw new IllegalStateException("Unexpected class " + child.getClass()); //$NON-NLS-1$
119+
}
120+
}
121+
}
98122
}
99123
}
100-
return result;
124+
return rootComposite;
101125
}
102126

103127
/**

0 commit comments

Comments
 (0)