Files
School/Anul 2/Semestrul 1/Metode avansate de programare/Interpretor/Controllers/Controller.java
T
2024-08-31 12:07:21 +03:00

105 lines
4.2 KiB
Java

package Controllers;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import Exceptions.BaseException;
import Models.Program.ProgramState;
import Models.Values.IValue;
import Models.Values.ReferenceValue;
import Repositories.IRepository;
public class Controller {
private IRepository repository;
private boolean displayFlag;
private ExecutorService executor;
public Controller(IRepository repository, boolean displayFlag) {
this.repository = repository;
this.displayFlag = displayFlag;
}
public List<ProgramState> removeCompletedPrograms(List<ProgramState> programStates) {
return programStates.stream().filter(p -> p.isNotCompleted()).collect(Collectors.toList());
}
public void oneStepForAllProgramStates(List<ProgramState> programStates) {
programStates.forEach(programState -> {
try{
repository.logProgramStateExecution(programState);
}
catch(BaseException e){
System.out.println(e.getMessage());
}
});
List<Callable<ProgramState>> callList = programStates.stream().map((ProgramState p) -> (Callable<ProgramState>)(() -> {
try{
return p.oneStep();
}
catch(BaseException e){
System.out.println(e.getMessage());
}
return null;
})).filter(c -> c != null).collect(Collectors.toList());
List<ProgramState> newProgramStates = new ArrayList<ProgramState>();
try{
newProgramStates = executor.invokeAll(callList).stream().map(future -> {
try {
return future.get();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}).filter(p -> p != null).collect(Collectors.toList());
}
catch(InterruptedException e){
System.out.println(e.getMessage());
}
programStates.addAll(newProgramStates);
programStates.forEach(programState -> {
try{
repository.logProgramStateExecution(programState);
}
catch(BaseException e){
System.out.println(e.getMessage());
}
});
repository.setProgramStates(programStates);
}
public void allSteps() {
executor = Executors.newFixedThreadPool(2);
List<ProgramState> programStates = removeCompletedPrograms(repository.getProgramStates());
while(programStates.size() > 0){
programStates.get(0).getHeap().setContent(this.garbageCollector(this.getAddressesFromSymbolTable(programStates.stream().map(programState -> programState.getSymbolTable().getContent()).collect(Collectors.toList()), programStates.get(0).getHeap().getContent()), programStates.get(0).getHeap().getContent()));
oneStepForAllProgramStates(programStates);
programStates = removeCompletedPrograms(repository.getProgramStates());
}
executor.shutdownNow();
repository.setProgramStates(programStates);
}
public Hashtable<Integer, IValue> garbageCollector(Set<Integer> symbolTable, Hashtable<Integer, IValue> heap) {
return heap.entrySet().stream().filter(e -> symbolTable.contains(e.getKey()))
.collect(Hashtable::new, (m, e) -> m.put(e.getKey(), e.getValue()), Hashtable::putAll);
}
public Set<Integer> getAddressesFromSymbolTable(List<Collection<IValue>> symbolTablesValues, Hashtable<Integer, IValue> heap) {
return symbolTablesValues.stream().flatMap(Collection::stream).filter(v -> v instanceof ReferenceValue)
.flatMap(v -> Stream.iterate(((ReferenceValue) v).getAddress(), Objects::nonNull, addr -> {
var value = heap.get(addr);
return value instanceof ReferenceValue ? ((ReferenceValue) value).getAddress() : null;
})).distinct().collect(Collectors.toSet());
}
}