package simulator; import java.util.Map; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import models.algebra.Constant; import models.algebra.Expression; import models.dataConstraintModel.Selector; import models.dataFlowModel.DataTransferChannel; public class ChannelState implements Cloneable { private DataTransferChannel channel; private ReferenceStructure referenceStructure; public ChannelState(DataTransferChannel channel) { this.channel = channel; } public DataTransferChannel getChannel() { return channel; } public Map<Expression, Expression> getDependingParamAndValues(List<Constant> channelValues) { if (referenceStructure == null) { return null; } return referenceStructure.getDependingParamAndValues(channelValues); } public List<List<Constant>> getDependedChannelSelectorValues(Expression dependingVariable, Expression itsValue) { if (referenceStructure == null) { return null; } Map<Expression, Expression> dependingVarToVal = new HashMap<>(); dependingVarToVal.put(dependingVariable, itsValue); return referenceStructure.getDependedChannelSelectorValues(dependingVarToVal); } public List<List<Constant>> getDependedChannelSelectorValues(Map<Expression, Expression> dependingVarToVal) { if (referenceStructure == null) { return null; } return referenceStructure.getDependedChannelSelectorValues(dependingVarToVal); } public void addDependingParamAndValue(List<Constant> channelValues, Expression dependingVariable, Expression itsValue) { if (referenceStructure == null) { referenceStructure = new ReferenceStructure(); } referenceStructure.addDependingParamAndValue(channelValues, dependingVariable, itsValue); } public Object clone() { ChannelState newChannelState = new ChannelState(channel); newChannelState.referenceStructure = (ReferenceStructure) referenceStructure.clone(); return newChannelState; } private static class ReferenceStructure implements Cloneable { private Map<Expression, Expression> dependingParamAndValues = null; private Map<Constant, ReferenceStructure> referenceStructure; public Map<Expression, Expression> getDependentParamAndValues() { return dependingParamAndValues; } public Map<Expression, Expression> getDependingParamAndValues(List<Constant> channelValues) { ReferenceStructure subStructure = this; for (Constant chVal: channelValues) { if (subStructure.getDependentParamAndValues() == null) { subStructure = subStructure.getReferenceStructure(chVal); } else { return null; } } return subStructure.getDependentParamAndValues(); } public List<List<Constant>> getDependedChannelSelectorValues(Map<Expression, Expression> dependingVarToVal) { List<List<Constant>> channelValuesList = new ArrayList<>(); if (dependingParamAndValues != null) { boolean doesMatch = true; for (Expression dependingVariable: dependingVarToVal.keySet()) { if (dependingParamAndValues.keySet().contains(dependingVariable)) { if (!dependingParamAndValues.get(dependingVariable).equals(dependingVarToVal.get(dependingVariable))) { doesMatch = false; } } } if (doesMatch) { List<List<Constant>> chValsList = new ArrayList<>(); chValsList.add(new ArrayList<>()); return chValsList; } else { return null; } } else { for (Constant chVal: referenceStructure.keySet()) { List<List<Constant>> chValsList = referenceStructure.get(chVal).getDependedChannelSelectorValues(dependingVarToVal); if (chValsList != null) { for (List<Constant> chVals: chValsList) { chVals.add(0, chVal); channelValuesList.add(chVals); } } } } return channelValuesList; } public void addDependingParamAndValue(Expression dependingVariable, Expression itsValue) { if (dependingParamAndValues == null) { dependingParamAndValues = new HashMap<>(); } dependingParamAndValues.put(dependingVariable, itsValue); } public void addDependingParamAndValue(List<Constant> channelValues, Expression dependingVariable, Expression itsValue) { ReferenceStructure subStructure = this; for (Constant chVal: channelValues) { if (subStructure.referenceStructure == null) { subStructure.referenceStructure = new HashMap<>(); } ReferenceStructure nextStructure = subStructure.referenceStructure.get(chVal); if (nextStructure == null) { nextStructure = new ReferenceStructure(); subStructure.referenceStructure.put(chVal, nextStructure); } subStructure = nextStructure; } subStructure.addDependingParamAndValue(dependingVariable, itsValue); } public ReferenceStructure getReferenceStructure(Constant channelParam) { return referenceStructure.get(channelParam); } public Object clone() { ReferenceStructure newReferenceStructure = new ReferenceStructure(); if (dependingParamAndValues != null) { newReferenceStructure.dependingParamAndValues = new HashMap<>(dependingParamAndValues); } if (referenceStructure != null) { newReferenceStructure.referenceStructure = new HashMap<>(); for (Map.Entry<Constant, ReferenceStructure> refEnt: referenceStructure.entrySet()) { newReferenceStructure.referenceStructure.put(refEnt.getKey(), (ReferenceStructure) refEnt.getValue().clone()); } } return newReferenceStructure; } } }