Skip to content

Commit b1b40b6

Browse files
committed
Avoid eager copying for ModuleFields#getMethods()
1 parent 6446234 commit b1b40b6

File tree

1 file changed

+39
-6
lines changed

1 file changed

+39
-6
lines changed

src/main/java/org/truffleruby/core/module/ModuleFields.java

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
import java.util.Deque;
1616
import java.util.HashMap;
1717
import java.util.HashSet;
18+
import java.util.Iterator;
1819
import java.util.List;
1920
import java.util.Map;
2021
import java.util.Map.Entry;
22+
import java.util.NoSuchElementException;
2123
import java.util.Set;
2224
import java.util.concurrent.ConcurrentHashMap;
2325
import java.util.concurrent.ConcurrentMap;
@@ -766,14 +768,45 @@ public RubyConstant getConstant(String name) {
766768
return constants.get(name);
767769
}
768770

769-
public Iterable<InternalMethod> getMethods() {
770-
List<InternalMethod> results = new ArrayList<>();
771-
for (MethodEntry methodEntry : methods.values()) {
772-
if (methodEntry.getMethod() != null) {
773-
results.add(methodEntry.getMethod());
771+
private static final class MethodsIterator implements Iterator<InternalMethod> {
772+
final Iterator<MethodEntry> methodEntries;
773+
InternalMethod nextElement;
774+
775+
MethodsIterator(Collection<MethodEntry> methodEntries) {
776+
this.methodEntries = methodEntries.iterator();
777+
computeNext();
778+
}
779+
780+
@Override
781+
public boolean hasNext() {
782+
return nextElement != null;
783+
}
784+
785+
@Override
786+
public InternalMethod next() {
787+
final InternalMethod element = nextElement;
788+
if (element == null) {
789+
throw new NoSuchElementException();
774790
}
791+
computeNext();
792+
return element;
775793
}
776-
return results;
794+
795+
private void computeNext() {
796+
if (methodEntries.hasNext()) {
797+
MethodEntry methodEntry = methodEntries.next();
798+
while (methodEntries.hasNext() && methodEntry.getMethod() == null) {
799+
methodEntry = methodEntries.next();
800+
}
801+
nextElement = methodEntry.getMethod();
802+
} else {
803+
nextElement = null;
804+
}
805+
}
806+
}
807+
808+
public Iterable<InternalMethod> getMethods() {
809+
return () -> new MethodsIterator(methods.values());
777810
}
778811

779812
public List<String> getMethodNames() {

0 commit comments

Comments
 (0)