package won.matcher.rescal.service; import org.la4j.matrix.SparseMatrix; import org.la4j.matrix.functor.MatrixProcedure; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import won.matcher.rescal.config.RescalMatcherConfig; import won.matcher.service.common.event.BulkHintEvent; import won.matcher.service.common.event.HintEvent; import won.matcher.utils.tensor.TensorMatchingData; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; /** * Used to read a hint matrix mtx file and create (bulk) hint event objects from it. * <p> * User: hfriedrich * Date: 23.06.2015 */ @Component public class HintReader { private static final Logger log = LoggerFactory.getLogger(HintReader.class); @Autowired private RescalMatcherConfig config; public BulkHintEvent readHints(TensorMatchingData matchingData) throws IOException { // read the header file ArrayList<String> needHeaders = new ArrayList<>(); FileInputStream fis = new FileInputStream(config.getExecutionDirectory() + "/" + TensorMatchingData.HEADERS_FILE); BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8")); String line = null; int i = 0; while ((line = br.readLine()) != null) { if (line.startsWith(TensorMatchingData.NEED_PREFIX)) { String originalHeaderEntry = line.substring(TensorMatchingData.NEED_PREFIX.length()); needHeaders.add(i, originalHeaderEntry); } i++; } br.close(); // read the hint matrix (supposed to contain new hints only, without the connection entries) fis = new FileInputStream(config.getExecutionDirectory() + "/output/hints.mtx"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis, "UTF-8")); StringBuffer stringBuffer = new StringBuffer(); while ((line = bufferedReader.readLine()) != null) { if (line.startsWith("%%MatrixMarket")) { if (!line.contains("row-major") || !line.contains("column-major")) { stringBuffer.append(line).append(" row-major\n"); } else { stringBuffer.append(line).append("\n"); } } else if (!line.startsWith("%")) { stringBuffer.append(line).append("\n"); } } String hintMatrixString = stringBuffer.toString(); SparseMatrix hintMatrix; try { hintMatrix = SparseMatrix.fromMatrixMarket(hintMatrixString); } catch (Exception e) { // IllegalArgumentException can occur here if we have no needs and thus now hints, catch this case and return // null to indicate no hints were found log.warn("Cannot load hint matrix file. This can happen if no hints were created"); log.debug("Exception was: ", e); return null; } // create the hint events and return them in one bulk hint object BulkHintEventMatrixProcedure hintProcedure = new BulkHintEventMatrixProcedure(needHeaders, matchingData); hintMatrix.eachNonZero(hintProcedure); return hintProcedure.getBulkHintEvent(); } private class BulkHintEventMatrixProcedure implements MatrixProcedure { private BulkHintEvent hints; private ArrayList<String> needUris; private TensorMatchingData matchingData; public BulkHintEventMatrixProcedure(ArrayList<String> needUris, TensorMatchingData matchingData) { hints = new BulkHintEvent(); this.needUris = needUris; this.matchingData = matchingData; } @Override public void apply(final int i, final int j, final double value) { String needUri1 = needUris.get(i); String needUri2 = needUris.get(j); if (needUri1 != null && needUri2 != null) { // wonNodeUri must have been set as attribute before to be able to read it here String fromWonNodeUri = matchingData.getFirstAttributeOfNeed(needUri1, "wonNodeUri"); String toWonNodeUri = matchingData.getFirstAttributeOfNeed(needUri2, "wonNodeUri"); HintEvent hint = new HintEvent(fromWonNodeUri, needUri1, toWonNodeUri, needUri2, config.getPublicMatcherUri(), value); hints.addHintEvent(hint); } } public BulkHintEvent getBulkHintEvent() { return hints; } } }