Skip to content

Commit 87e5ede

Browse files
committed
Reduce double map iteration of imported modules that need to be looked up in the heap everytime
1 parent a284eef commit 87e5ede

File tree

2 files changed

+58
-35
lines changed

2 files changed

+58
-35
lines changed

src/org/rascalmpl/interpreter/env/GlobalEnvironment.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,11 @@ public String toString(){
146146
}
147147

148148
public void removeModule(ModuleEnvironment env) {
149-
moduleEnvironment.remove(env.getName());
149+
var name = env.getName();
150+
moduleEnvironment.remove(name);
151+
for (var mod : moduleEnvironment.values()) {
152+
mod.deleteImport(name);
153+
}
150154
}
151155

152156
public void setModuleURI(String name, URI location) {

src/org/rascalmpl/interpreter/env/ModuleEnvironment.java

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121
import java.util.Collections;
2222
import java.util.HashMap;
2323
import java.util.HashSet;
24+
import java.util.Iterator;
2425
import java.util.LinkedHashSet;
2526
import java.util.LinkedList;
2627
import java.util.List;
2728
import java.util.Map;
29+
import java.util.Map.Entry;
30+
import java.util.Optional;
2831
import java.util.Set;
2932
import java.util.function.Predicate;
3033

@@ -67,7 +70,8 @@
6770
*/
6871
public class ModuleEnvironment extends Environment {
6972
protected final GlobalEnvironment heap;
70-
protected Set<String> importedModules;
73+
/** Map of imported modules to resolved ModuleEnvironments, will only be empty in case of a module was in a cycle or got reloaded and failed during the reload. use {@link #importedModulesResolved} to lazily resolve the modules. */
74+
protected Map<String, Optional<ModuleEnvironment>> importedModules;
7175
protected Set<String> extended;
7276
protected TypeStore typeStore;
7377
protected Set<IValue> productions;
@@ -87,7 +91,7 @@ public class ModuleEnvironment extends Environment {
8791
public ModuleEnvironment(String name, GlobalEnvironment heap) {
8892
super(ValueFactoryFactory.getValueFactory().sourceLocation(URIUtil.assumeCorrect("main", name, "")), name);
8993
this.heap = heap;
90-
this.importedModules = new HashSet<String>();
94+
this.importedModules = new HashMap<>();
9195
this.concreteSyntaxTypes = new HashMap<String, NonTerminalType>();
9296
this.productions = new HashSet<IValue>();
9397
this.generalKeywordParameters = new HashMap<Type,List<KeywordFormal>>();
@@ -122,7 +126,7 @@ protected ModuleEnvironment(ModuleEnvironment env) {
122126
@Override
123127
public void reset() {
124128
super.reset();
125-
this.importedModules = new HashSet<>();
129+
this.importedModules = new HashMap<>();
126130
this.concreteSyntaxTypes = new HashMap<>();
127131
this.typeStore = new TypeStore();
128132
this.productions = new HashSet<IValue>();
@@ -142,9 +146,9 @@ public void extend(ModuleEnvironment other) {
142146
// so that types become available
143147
if (other.importedModules != null) {
144148
if (this.importedModules == null) {
145-
this.importedModules = new HashSet<String>();
149+
this.importedModules = new HashMap<>();
146150
}
147-
this.importedModules.addAll(other.importedModules);
151+
this.importedModules.putAll(other.importedModules);
148152
}
149153

150154
if (other.concreteSyntaxTypes != null) {
@@ -294,7 +298,7 @@ public IMap getSyntaxDefinition() {
294298
result.put(VF.string(m), t);
295299
}else if(m.equals(getName())) { // This is the root scope.
296300
ISetWriter importWriter = VF.setWriter();
297-
for(String impname : importedModules){
301+
for(String impname : importedModules.keySet()){
298302
if(!done.contains(impname)) todo.add(impname);
299303

300304
importWriter.insert(VF.string(impname));
@@ -327,9 +331,13 @@ public boolean isModuleEnvironment() {
327331

328332
public void addImport(String name, ModuleEnvironment env) {
329333
assert heap.getModule(name).equals(env);
330-
importedModules.add(name);
334+
importedModules.put(name, Optional.ofNullable(env));
331335
typeStore.importStore(env.typeStore);
332336
}
337+
338+
void deleteImport(String name) {
339+
importedModules.computeIfPresent(name, (k, v) -> Optional.empty());
340+
}
333341

334342
public void addExtend(String name) {
335343
if (extended == null) {
@@ -356,7 +364,7 @@ public List<AbstractFunction> getTests() {
356364

357365
@Override
358366
public Set<String> getImports() {
359-
return Collections.unmodifiableSet(importedModules);
367+
return Collections.unmodifiableSet(importedModules.keySet());
360368
}
361369

362370
public Set<String> getImportsTransitive() {
@@ -384,11 +392,9 @@ public Set<String> getImportsTransitive() {
384392
}
385393

386394
public void unImport(String moduleName) {
387-
if (importedModules.remove(moduleName)) {
388-
ModuleEnvironment old = heap.getModule(moduleName);
389-
if (old != null) {
390-
typeStore.unimportStores(new TypeStore[] { old.getStore() });
391-
}
395+
var old = importedModules.remove(moduleName);
396+
if (old != null && old.isPresent()) {
397+
typeStore.unimportStores(old.get().getStore());
392398
}
393399
cachedGeneralKeywordParameters = null;
394400
}
@@ -447,6 +453,7 @@ public Result<IValue> getVariable(QualifiedName name) {
447453

448454
return getFrameVariable(cons);
449455
}
456+
450457

451458
@Override
452459
public void storeVariable(String name, Result<IValue> value) {
@@ -461,8 +468,7 @@ public void storeVariable(String name, Result<IValue> value) {
461468
super.storeVariable(name, value);
462469
}
463470
else {
464-
for (String i : importedModules) {
465-
ModuleEnvironment module = heap.getModule(i);
471+
for (ModuleEnvironment module : importedModulesResolved) {
466472
result = module.getLocalPublicVariable(name);
467473

468474
if (result != null) {
@@ -483,8 +489,7 @@ public org.rascalmpl.interpreter.result.Result<IValue> getSimpleVariable(String
483489
return var;
484490
}
485491

486-
for (String moduleName : importedModules) {
487-
ModuleEnvironment mod = getImport(moduleName);
492+
for (ModuleEnvironment mod : importedModulesResolved) {
488493

489494
if (mod != null) {
490495
var = mod.getLocalPublicVariable(name);
@@ -511,8 +516,7 @@ protected Map<String,Result<IValue>> getVariableDefiningEnvironment(String name)
511516
}
512517
}
513518

514-
for (String moduleName : importedModules) {
515-
ModuleEnvironment mod = getImport(moduleName);
519+
for (ModuleEnvironment mod : importedModulesResolved) {
516520
Result<IValue> r = null;
517521
if (mod != null && mod.variableEnvironment != null)
518522
r = mod.variableEnvironment.get(name);
@@ -529,8 +533,7 @@ protected Map<String,Result<IValue>> getVariableDefiningEnvironment(String name)
529533
public void getAllFunctions(String name, List<AbstractFunction> collection) {
530534
super.getAllFunctions(name, collection);
531535

532-
for (String moduleName : importedModules) {
533-
ModuleEnvironment mod = getImport(moduleName);
536+
for (ModuleEnvironment mod : importedModulesResolved) {
534537

535538
if (mod != null) {
536539
mod.getLocalPublicFunctions(name, collection);
@@ -542,8 +545,7 @@ public void getAllFunctions(String name, List<AbstractFunction> collection) {
542545
public void getAllFunctions(Type returnType, String name, List<AbstractFunction> collection) {
543546
super.getAllFunctions(returnType, name, collection);
544547

545-
for (String moduleName : importedModules) {
546-
ModuleEnvironment mod = getImport(moduleName);
548+
for (ModuleEnvironment mod : importedModulesResolved) {
547549

548550
if (mod != null) {
549551
mod.getLocalPublicFunctions(returnType, name, collection);
@@ -732,8 +734,7 @@ public Set<GenericKeywordParameters> lookupGenericKeywordParameters(Type adt) {
732734
result.add(new GenericKeywordParameters(this, list, getStore().getKeywordParameters(adt)));
733735
}
734736

735-
for (String moduleName : importedModules) {
736-
ModuleEnvironment mod = getImport(moduleName);
737+
for (ModuleEnvironment mod : importedModulesResolved) {
737738

738739
list = mod.generalKeywordParameters.get(adt);
739740
if (list != null) {
@@ -825,13 +826,33 @@ public String toString() {
825826

826827
@Override
827828
public ModuleEnvironment getImport(String moduleName) {
828-
if(importedModules.contains(moduleName)) {
829-
return heap.getModule(moduleName);
830-
}
831-
else {
832-
return null;
829+
var result = importedModules.computeIfPresent(moduleName,
830+
(m, c) -> c.isPresent() ? c : Optional.ofNullable(heap.getModule(m))
831+
);
832+
if (result == null || result.isEmpty()) {
833+
return null;
833834
}
835+
return result.get();
834836
}
837+
838+
private Iterable<ModuleEnvironment> importedModulesResolved =
839+
() -> new Iterator<ModuleEnvironment>() {
840+
Iterator<Entry<String, Optional<ModuleEnvironment>>> iterator = importedModules.entrySet().iterator();
841+
@Override
842+
public boolean hasNext() {
843+
return iterator.hasNext();
844+
}
845+
@Override
846+
public ModuleEnvironment next() {
847+
var entry = iterator.next();
848+
var result = entry.getValue();
849+
if (result.isEmpty()) {
850+
result = Optional.ofNullable(heap.getModule(entry.getKey()));
851+
entry.setValue(result);
852+
}
853+
return result.orElse(null);
854+
}
855+
};
835856

836857
@Override
837858
public void storeVariable(QualifiedName name, Result<IValue> result) {
@@ -870,8 +891,7 @@ public Type lookupConcreteSyntaxType(String name) {
870891
Type type = concreteSyntaxTypes.get(name);
871892

872893
if (type == null) {
873-
for (String i : importedModules) {
874-
ModuleEnvironment mod = getImport(i);
894+
for (ModuleEnvironment mod : importedModulesResolved) {
875895

876896
if (mod == null) {
877897
continue;
@@ -989,8 +1009,7 @@ protected Environment getFlagsEnvironment(String name) {
9891009
return env;
9901010
}
9911011

992-
for (String moduleName : importedModules) {
993-
ModuleEnvironment mod = getImport(moduleName);
1012+
for (ModuleEnvironment mod : importedModulesResolved) {
9941013
if(mod == null) {
9951014
throw new RuntimeException("getFlagsEnvironment");
9961015
}

0 commit comments

Comments
 (0)