Skip to content

Commit a0c0a58

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

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

91+
@SuppressWarnings("unchecked")
8992
private static ProxyCompositeNode installProxyNodeModel(final EObject eObject, final List<EObject> map) {
90-
ProxyCompositeNode result = new ProxyCompositeNode();
91-
eObject.eAdapters().add(result);
93+
Deque<EObject> deque = new ArrayDeque<>();
94+
deque.push(eObject);
95+
ProxyCompositeNode rootComposite = new ProxyCompositeNode();
96+
eObject.eAdapters().add(rootComposite);
9297
map.add(eObject);
9398

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);
99+
while (!deque.isEmpty()) {
100+
EObject nextEObject = deque.pop();
101+
EStructuralFeature[] structuralFeatures = ((EClassImpl.FeatureSubsetSupplier) nextEObject.eClass().getEAllStructuralFeatures()).containments();
102+
if (structuralFeatures != null) {
103+
for (int i = structuralFeatures.length - 1; i >= 0; i--) {
104+
EStructuralFeature eStructuralFeature = structuralFeatures[i];
105+
if (!eStructuralFeature.isTransient() && nextEObject.eIsSet(eStructuralFeature)) {
106+
if (eStructuralFeature.isMany()) {
107+
EList<EObject> listChild = (EList<EObject>) nextEObject.eGet(eStructuralFeature);
108+
for (int j = listChild.size() - 1; j >= 0; j--) {
109+
EObject singleChild = listChild.get(j);
110+
singleChild.eAdapters().add(new ProxyCompositeNode());
111+
map.add(singleChild);
112+
deque.push(singleChild);
113+
}
114+
} else {
115+
EObject singleChild = (EObject) nextEObject.eGet(eStructuralFeature);
116+
singleChild.eAdapters().add(new ProxyCompositeNode());
117+
map.add(singleChild);
118+
deque.push(singleChild);
119+
}
120+
}
121+
}
98122
}
99123
}
100-
return result;
124+
return rootComposite;
101125
}
102126

103127
/**

0 commit comments

Comments
 (0)