Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package fr.inria.wimmics.coresetimer; import static fr.inria.corese.coresetimer.utils.VariousUtils.*; import fr.inria.edelweiss.kgram.core.Mappings; import fr.inria.edelweiss.kgtool.load.LoadException; import fr.inria.wimmics.coresetimer.Main.TestDescription; import java.io.File; import java.io.IOException; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.time.LocalDateTime; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; /** * * @author edemairy */ public class CoreseTimer { private final static Logger LOGGER = Logger.getLogger(CoreseTimer.class.getName()); public CoreseAdapter adapter; public String adapterName; private Mappings mappings; public enum Profile { DB, MEMORY }; private static String outputRoot; private Profile mode = Profile.MEMORY; private boolean initialized; private DescriptiveStatistics stats; private DescriptiveStatistics statsMemory; private TestDescription test; /** * * @param adapterName class name for the adapter to the version of * corese used. * @param runProfile kind of usage of corese (currently "db" or * "memory"). Used to classify the results and stats done. */ private CoreseTimer(TestDescription test) { this.adapterName = CoreseAdapter.class.getCanonicalName(); initialized = false; this.test = test; } static public CoreseTimer build(TestDescription test) { return new CoreseTimer(test); } public CoreseTimer setMode(Profile mode) { this.mode = mode; return this; } public CoreseTimer init() { switch (mode) { case DB: { System.setProperty("fr.inria.corese.factory", "fr.inria.corese.tinkerpop.Factory"); break; } case MEMORY: { System.setProperty("fr.inria.corese.factory", ""); break; } } ; // create output directory of the form ${OUTPUT_ROOT} outputRoot = getEnvWithDefault("OUTPUT_ROOT", "./"); outputRoot = ensureEndWith(outputRoot, "/"); outputRoot += mode; outputRoot = ensureEndWith(outputRoot, "/"); createDir(outputRoot, "rwxr-x---"); initialized = true; return this; } // public static String makeFileName(String prefix, String suffix, int nbInput, int nbQuery) { // return outputRoot + prefix + "input_" + nbInput + "_query_" + nbQuery + ".xml"; // } public CoreseTimer run() throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException, LoadException { LOGGER.entering(CoreseTimer.class.getName(), "run"); assert (initialized); // Loading the nq data in corese, then applying several times the query. LOGGER.log(Level.INFO, "beginning with input #{0}", test.getInput()); // require to have a brand new adapter for each new input set. adapter = (CoreseAdapter) Class.forName(adapterName).newInstance(); String inputFileName = ""; switch (mode) { case MEMORY: { inputFileName += test.getInput(); adapter.preProcessing(inputFileName, true); break; } case DB: { inputFileName += test.getInputDb(); System.setProperty("fr.inria.corese.tinkerpop.dbinput", inputFileName); adapter.preProcessing(inputFileName, false); break; } } String query = test.getRequest(); LOGGER.log(Level.INFO, "processing nbQuery #{0}", query); stats = new DescriptiveStatistics(); statsMemory = new DescriptiveStatistics(); int nbCycles = test.getMeasuredCycles() + test.getWarmupCycles(); boolean measured = true; for (int i = 0; i < nbCycles; i++) { LOGGER.log(Level.INFO, "iteration #{0}", i); System.gc(); final long startTime = System.currentTimeMillis(); LOGGER.log(Level.INFO, "before query"); ExecutorService executor = Executors.newSingleThreadExecutor(); Future<?> future = executor.submit(new Runnable() { @Override public void run() { adapter.execQuery(query); } }); try { future.get(1, TimeUnit.HOURS); measured = true; } catch (InterruptedException | TimeoutException e) { future.cancel(true); measured = false; LOGGER.log(Level.WARNING, "Terminated!"); } catch (ExecutionException ex) { Logger.getLogger(CoreseTimer.class.getName()).log(Level.SEVERE, null, ex); } executor.shutdownNow(); LOGGER.log(Level.INFO, "after query"); final long endTime = System.currentTimeMillis(); long delta = endTime - startTime; long memoryUsage = getMemoryUsage(); LOGGER.info(String.format("elapsed time = %d ms", delta)); LOGGER.info(String.format("used memory = %d bytes", memoryUsage)); if (i >= test.getWarmupCycles()) { if (!measured) { while (i < nbCycles) { stats.addValue(-100); statsMemory.addValue(memoryUsage); i++; } } else { stats.addValue(delta); statsMemory.addValue(memoryUsage); } } } adapter.saveResults(test.getOutputPath()); mappings = adapter.getMappings(); adapter.postProcessing(); LOGGER.exiting(CoreseTimer.class.getName(), "run"); return this; } public void writeResults() { adapter.saveResults(test.getOutputPath()); } public Mappings getMapping() { return mappings; } public DescriptiveStatistics getStats() { return stats; } public DescriptiveStatistics getStatsMemory() { return statsMemory; } private long getMemoryUsage() { long before = getGcCount(); System.gc(); while (getGcCount() == before) ; return getCurrentlyUsedMemory(); } private long getGcCount() { long sum = 0; for (GarbageCollectorMXBean b : ManagementFactory.getGarbageCollectorMXBeans()) { long count = b.getCollectionCount(); if (count != -1) { sum += count; } } return sum; } private long getCurrentlyUsedMemory() { return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed() + ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getUsed(); } public void writeStatistics() { Document doc = null; try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); doc = dBuilder.newDocument(); Element rootElement = doc.createElement("TestResult"); Element inputs = doc.createElement("Inputs"); Element inputFile = doc.createElement("Input"); Text inputFileText = doc.createTextNode(test.getInput()); inputFile.appendChild(inputFileText); Element request = doc.createElement("Request"); Text requestText = doc.createTextNode(test.getRequest()); request.appendChild(requestText); Element timestamp = doc.createElement("Timestamp"); Text timestampText = doc.createTextNode(LocalDateTime.now().toString()); timestamp.appendChild(timestampText); Element[] subElements = { inputFile, request, timestamp }; for (Element e : subElements) { inputs.appendChild(e); } Element outputs = doc.createElement("Statistics"); Element statsMemory = doc.createElement("CPU"); Text statsMemoryText = doc.createTextNode(getStats().toString()); statsMemory.appendChild(statsMemoryText); Element statsMemoryCoreseMem = doc.createElement("Memory"); Text statsMemoryCoreseMemText = doc.createTextNode(getStatsMemory().toString()); statsMemoryCoreseMem.appendChild(statsMemoryCoreseMemText); Element[] subElements2 = { statsMemory, statsMemoryCoreseMem }; for (Element e : subElements2) { outputs.appendChild(e); } rootElement.appendChild(inputs); rootElement.appendChild(outputs); doc.appendChild(rootElement); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(doc); StreamResult streamResult = new StreamResult(new File(test.getOutputPath())); transformer.transform(source, streamResult); LOGGER.log(Level.INFO, "Results were written in:", test.getOutputPath()); } catch (ParserConfigurationException | TransformerException ex) { LOGGER.log(Level.INFO, "Error when writing results:", ex.getMessage()); ex.printStackTrace(); } } }