/** * MapGenerator Sample Extensions */ package mycompany.map.modificator; import java.util.logging.Level; import java.util.logging.Logger; import org.w3c.dom.Element; import idea.map.generator.MapGenerator; import idea.map.matrix.AbstractMatrix; import idea.map.matrix.Matrixes; import idea.map.matrix.ResultMatrix; import idea.map.modificator.AbstractModificator; import idea.mapgen.util.StatisticsCollector; /** * Combine values from 3 input matrixes A, B and C * and store result to output matrix D, by following formula: * *D = (A + B) / C* * Usage: ** <Modificator class="mycompany.map.combinator.UserCombinator matrixA="xxx" ..."/> ** * * @author Lumir Vanek, vanek@idea-envi.cz * */ public class UserCombinator extends AbstractModificator { /** * Matrixes ID's to combine */ private final String matrixIdA; private final String matrixIdB; private final String matrixIdC; private final String matrixIdD; /** * Matrixes to combine */ private AbstractMatrix matrixA; private AbstractMatrix matrixB; private AbstractMatrix matrixC; /** * Result matrix */ private AbstractMatrix matrixD; /** * Constructor * * @param matrixA ID of matrix A * @param matrixB ID of matrix B * @param matrixC ID of matrix C * @param matrixD ID of matrix D */ public UserCombinator(String matrixA, String matrixB, String matrixC, String matrixD) { super(); matrixIdA = matrixA; matrixIdB = matrixB; matrixIdC = matrixC; matrixIdD = matrixD; } /** * XML Runset constructor, initialize yourself from given DOM element * * @param domElement DOM element */ public UserCombinator(Element domElement) { super(domElement); if(!domElement.hasAttribute("matrixA")) { throw new RuntimeException("Missing matrixA attribute for " + getXmlElementName()); } if(!domElement.hasAttribute("matrixB")) { throw new RuntimeException("Missing matrixB attribute for " + getXmlElementName()); } if(!domElement.hasAttribute("matrixC")) { throw new RuntimeException("Missing matrixC attribute for " + getXmlElementName()); } if(!domElement.hasAttribute("matrixD")) { throw new RuntimeException("Missing matrixD attribute for " + getXmlElementName()); } matrixIdA = domElement.getAttribute("matrixA"); matrixIdB = domElement.getAttribute("matrixB"); matrixIdC = domElement.getAttribute("matrixC"); matrixIdD = domElement.getAttribute("matrixD"); } /** * Combine 3 matrixes, specified in configuration, * create new matrix as result and put in to list * * @param matrixes Matrixes list to combine * @param collector The statistics collector */ public void modify(Matrixes matrixes, StatisticsCollector collector) { // Get matrixes A, B and C matrixA = matrixes.get(matrixIdA); if(matrixA == null) throw new RuntimeException("Matrix A not found in " + getXmlElementName()); matrixB = matrixes.get(matrixIdB); if(matrixB == null) throw new RuntimeException("Matrix B not found in " + getXmlElementName()); matrixC = matrixes.get(matrixIdC); if(matrixC == null) throw new RuntimeException("Matrix C not found in " + getXmlElementName()); // Create result matrix if(matrixes.containsKey(matrixIdD)) throw new RuntimeException("Matrix D in " + getXmlElementName() + " already exists"); matrixD = new ResultMatrix(matrixes, matrixIdD); // Combine matrixes if(matrixes.getRows() < getThreads()) { throw new RuntimeException("Matrixes rows number must be less than number of threads"); } try { float elapsedTime = runThreads(matrixes.getRows(), collector); matrixes.put(matrixIdD, matrixD); Logger.getLogger(MapGenerator.loggerName).fine("User Combination of matrixes " + matrixA.getId() + ", " + matrixB.getId() + ", " + matrixC.getId() + " -> " + matrixD.getId() + " finished in " + elapsedTime + " sec."); } catch(InterruptedException e) { Logger.getLogger(MapGenerator.loggerName).log(Level.SEVERE, "UserCombinationThread interrupted", e); throw new RuntimeException("UserCombinationThread interrupted"); } finally { this.matrixA = null; this.matrixB = null; this.matrixC = null; this.matrixD = null; } } /** * Create thread * * @param startRow First matrix row, computed by created thread * @param endRow Last matrix row, computed by created thread * @param nameAppendix Appendix for thread name * @return Thread, that make required work */ protected Runnable createThread(int startRow, int endRow, String nameAppendix) { return new UserCombinationThread("UserCombinationThread" + nameAppendix, matrixA, matrixB, matrixC, matrixD, startRow, endRow); } }