ModelSequence.java

package edu.udel.cis.vsl.tass.model.IF;

import java.util.LinkedHashSet;
import java.util.Set;

public class ModelSequence {

	private ModelIF[] models;

	private int[] modelIndices;

	private ProcessIF[] globalProcessArray;

	private Set<ProcessIF> globalProcessSet;

	/**
	 * The global indices of all processes arranged in 2-d array. First index is
	 * model index, second is pid. The value at that point is the global index
	 * of the process in that model with that pid.
	 */
	private int[][] modelProcessArray;

	public ModelSequence(ModelIF[] models) {
		int maxModelId = -1;
		int numModels = models.length;
		int totalNumProcs = 0;
		int counter = 0;

		this.models = models;
		for (int i = 0; i < numModels; i++) {
			ModelIF model = models[i];
			int modelId = model.id();

			assert model != null;
			if (modelId > maxModelId)
				maxModelId = modelId;
		}
		modelIndices = new int[maxModelId + 1];
		for (int i = 0; i <= maxModelId; i++)
			modelIndices[i] = -1;
		for (int i = 0; i < numModels; i++) {
			int id = models[i].id();

			assert modelIndices[id] == -1;
			modelIndices[id] = i;
		}
		modelProcessArray = new int[numModels][];
		globalProcessSet = new LinkedHashSet<ProcessIF>();
		counter = 0;
		for (int i = 0; i < numModels; i++) {
			ModelIF model = models[i];
			int numProcs = model.numProcs();

			modelProcessArray[i] = new int[numProcs];
			for (int j = 0; j < numProcs; j++) {
				ProcessIF process = model.process(j);

				modelProcessArray[i][j] = counter;
				counter++;
				globalProcessSet.add(process);
			}
			totalNumProcs += numProcs;
		}
		globalProcessArray = new ProcessIF[totalNumProcs];
		counter = 0;
		for (int i = 0; i < numModels; i++) {
			ModelIF model = models[i];
			int numProcs = model.numProcs();

			for (int j = 0; j < numProcs; j++) {
				globalProcessArray[counter] = model.process(j);
				counter++;
			}
		}
	}

	public ModelSequence(ModelIF model) {
		this(new ModelIF[] { model });
	}

	public ModelSequence(ModelIF spec, ModelIF impl) {
		this(new ModelIF[] { spec, impl });
	}

	public ModelIF[] models() {
		return models;
	}

	public ModelIF modelWithId(int id) {
		return models[modelIndices[id]];
	}

	public ModelIF modelWithIndex(int index) {
		return models[index];
	}

	public int indexOf(ModelIF model) {
		return modelIndices[model.id()];
	}

	public int numModels() {
		return models.length;
	}

	public Set<ProcessIF> allProcesses() {
		return globalProcessSet;
	}

	public int totalNumProcs() {
		return globalProcessArray.length;
	}

	public int globalIndexOfProcess(ProcessIF process) {
		return modelProcessArray[indexOf(process.model())][process.pid()];
	}

	public ProcessIF processOfGlobalIndex(int index) {
		return globalProcessArray[index];
	}

}