package org.yamcs.algorithms; import java.util.Collection; import java.util.HashMap; import java.util.List; import org.yamcs.Processor; import org.yamcs.parameter.ParameterValue; import org.yamcs.xtce.Algorithm; import org.yamcs.xtce.DataSource; import org.yamcs.xtce.Parameter; import org.yamcs.xtce.ParameterInstanceRef; /** * Algorithms for command verifiers must execute in parallel in different contexts - meaning that each algorithm will have * their own values for inputs referring to command specifics (e.g. command sequence count) * * That's why we associate to each AlgorithmEngine (which represents the instantiation of one algorithm) one of these AlgorithmExecutionContext. * * Currently it stores the historical values for parameters requiring that. * * Each execution context has a parent that stores the values which are not context specific. * * @author nm * */ public class AlgorithmExecutionContext { // For storing a window of previous parameter instances HashMap<Parameter,WindowBuffer> buffersByParam = new HashMap<Parameter,WindowBuffer>(); final AlgorithmExecutionContext parent; //all the algorithms that run in this context HashMap<Algorithm,AlgorithmExecutor> engineByAlgorithm=new HashMap<Algorithm,AlgorithmExecutor>(); //name used for debugging final String contextName; final Processor yproc; public AlgorithmExecutionContext(String contextName, AlgorithmExecutionContext parent, Processor proc) { this.contextName = contextName; this.parent = parent; this.yproc = proc; } public void enableBuffer(Parameter param, int lookbackSize) { if(parent==null || param.getDataSource()==DataSource.COMMAND || param.getDataSource()==DataSource.COMMAND_HISTORY) { if(buffersByParam.containsKey(param)) { WindowBuffer buf = buffersByParam.get(param); buf.expandIfNecessary(lookbackSize+1); } else { buffersByParam.put(param, new WindowBuffer(lookbackSize+1)); } } else { parent.enableBuffer(param, lookbackSize); } } public void updateHistoryWindows(List<ParameterValue> pvals) { for(ParameterValue pval:pvals) { if(buffersByParam.containsKey(pval.getParameter())) { buffersByParam.get(pval.getParameter()).update(pval); } else if(parent!=null){ parent.updateHistoryWindow(pval); } } } /** * * @return the processor in which this context is part of */ public Processor getProcessor() { return yproc; } private void updateHistoryWindow(ParameterValue pval) { if(buffersByParam.containsKey(pval.getParameter())) { buffersByParam.get(pval.getParameter()).update(pval); } } public ParameterValue getHistoricValue(ParameterInstanceRef pInstance) { WindowBuffer wb = buffersByParam.get(pInstance.getParameter()); if(wb!=null) { return wb.getHistoricValue(pInstance.getInstance()); } else if (parent!=null){ return parent.getHistoricValue(pInstance); } else { return null; } } public String getName() { return contextName; } public boolean containsAlgorithm(Algorithm algo) { return engineByAlgorithm.containsKey(algo); } public AlgorithmExecutor getExecutor(Algorithm algo) { return engineByAlgorithm.get(algo); } public void addAlgorithm(Algorithm algorithm, AlgorithmExecutor engine) { engineByAlgorithm.put(algorithm, engine); } public Collection<Algorithm> getAlgorithms() { return engineByAlgorithm.keySet(); } public AlgorithmExecutor remove(Algorithm algo) { return engineByAlgorithm.remove(algo); } }