Commit 0877d253 authored by Victor Marsault's avatar Victor Marsault

Streamlining of outbridge package

parent da3844dd
......@@ -85,6 +85,17 @@
<build>
<plugins>
<!-- ## File to exclude (dev-only) ######################################### -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/uk/ac/ed/cyphsem/cli/Executor.java</exclude>
<exclude>**/uk/ac/ed/cyphsem/outbridge/InterpreterComparator.java</exclude>
</excludes>
</configuration>
</plugin>
<!-- ## Execution ######################################################### -->
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
......
......@@ -30,10 +30,11 @@ import uk.ac.ed.cyphsem.table.*;
import uk.ac.ed.cyphsem.utils.*;
import java.io.IOException;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
......@@ -131,28 +132,28 @@ public class Utils {
// }
// }
public static String readFile(String path)
throws IOException {
return readFile(new File(path));
}
public static String readFile(File f)
throws IOException {
return readFile(f, StandardCharsets.UTF_8);
}
public static String readFile(String path, Charset encoding)
throws IOException
{
return readFile(new File(path), encoding);
}
public static String readFile(File f, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(f.toPath());
return new String(encoded, encoding);
}
// public static String readFile(String path)
// throws IOException {
// return readFile(new File(path));
// }
//
// public static String readFile(File f)
// throws IOException {
// return readFile(f, StandardCharsets.UTF_8);
// }
//
// public static String readFile(String path, Charset encoding)
// throws IOException
// {
// return readFile(new File(path), encoding);
// }
//
// public static String readFile(File f, Charset encoding)
// throws IOException
// {
// byte[] encoded = Files.readAllBytes(f.toPath());
// return new String(encoded, encoding);
// }
public static <E,F> List<F> map (List<E> input, Function<? super E,F> f) {
return input.stream().map(e -> f.apply(e)).collect(Collectors.toList());
......@@ -272,4 +273,23 @@ public class Utils {
return false;
return true;
}
/** Functions creating a temporary file with given extension and containing given content
* @param content Content of the file
* @param ext Extension of the created file
* @return A temporary file containing the given content.
***/
public static Path tmpFileOfString(String content, String ext) {
Path file = null ;
try {
file = Files.createTempFile("CyphSem_",ext);
Files.write(file, content.getBytes());
}
catch (IOException e) {
throw new RuntimeException("Problem writing to temporary file "+file+".",e);
}
return file;
}
}
/* CyphSem
Copyright (c) 2018,2019 Victor Marsault
This file is part of CyphSem.
CyphSem is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CyphSem is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CyphSem. If not, see <https://www.gnu.org/licenses/>. */
package uk.ac.ed.cyphsem.exception;
import uk.ac.ed.cyphsem.outbridge.Interpreter;
/** Exception launched when a result is asked from an {@link Interpreter} and the result is not entirely computed.
*/
public class ComputationOngoingException extends Exception {
public ComputationOngoingException() {}
public ComputationOngoingException (String e) { super(e); }
}
......@@ -19,15 +19,20 @@
package uk.ac.ed.cyphsem.outbridge;
import java.io.File;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import uk.ac.ed.cyphsem.Interruptor;
import uk.ac.ed.cyphsem.exception.InterpretingException;
import uk.ac.ed.cyphsem.exception.UndefinedNameException;
import uk.ac.ed.cyphsem.exception.UnspecifiedBehaviourException;
import uk.ac.ed.cyphsem.datamodel.graph.Graph;
import uk.ac.ed.cyphsem.exception.*;
import uk.ac.ed.cyphsem.datamodel.graph.Graph;
import uk.ac.ed.cyphsem.language.query.QueryData;
import uk.ac.ed.cyphsem.language.parser.Parser;
import uk.ac.ed.cyphsem.exception.AnTLRException;
......@@ -35,59 +40,69 @@ import uk.ac.ed.cyphsem.language.query.Query;
import uk.ac.ed.cyphsem.table.Table;
/** Class implementing the Cypher Interpreter native to CyphSem.
* @see Interpreters#CYPHSEM
***/
public class CyphSemInterpreter implements Interpreter {
public class CyphSemInterpreter extends Interpreter.AbstractHelper implements Interpreter {
Graph graph;
protected long lastRunTime;
// Boolean interrupted = false;
/** Stored input graph */
Graph graph = null;
/** Stored input query */
Query query = null;
/** Interruptor of the query execution currently run (if any). Never {@code null}. */
Interruptor interruptor = new Interruptor();
/** The resut of currently run query-execution, when it will be available. */
Future<QueryData> futureResult = null;
public CyphSemInterpreter() { }
public CyphSemInterpreter(Graph graph) { this.graph = graph; }
public CyphSemInterpreter(Interpreter other) { this(other.getGraph()); }
public CyphSemInterpreter(Graph graph) { inputGraph(graph); }
@Override
public void load(File database) { }
@Override
public void load(String str) { }
@Override
public void loadFrom(Interpreter i) { this.graph = i.getGraph(); }
@Override
public Graph getGraph() { return graph; }
public void setGraph(Graph graph) { this.graph = graph; }
@Override
public Table run(String statement) throws InterpretingException, InterruptedException {
try {
lastRunTime = -System.nanoTime();
Query query = Parser.queryOf(statement);
Table result = query.execute(graph, interruptor).table();
lastRunTime += System.nanoTime();
return result;
} catch (UndefinedNameException e) {
throw new InterpretingException(e);
} catch (UnspecifiedBehaviourException e) {
throw new InterpretingException(e);
} catch (AnTLRException e) {
throw new InterpretingException(e.getCause());
}
public void inputGraph(Graph g) { graph = g; }
@Override
public void inputQuery(Query q) { query= q; }
@Override
public Graph outputGraph()
throws InterruptedException, ExecutionException, ComputationOngoingException
{
if (futureResult.isDone())
return futureResult.get().graph();
else
throw new ComputationOngoingException();
}
@Override
public Table outputTable()
throws InterruptedException, ExecutionException, ComputationOngoingException
{
if (futureResult.isDone())
return futureResult.get().table();
else
throw new ComputationOngoingException();
}
@Override
public long getLastRunTime() {
return lastRunTime;
public void run() {
interruptor = new Interruptor();
Callable<QueryData> runnable = new Callable<QueryData> () {
public QueryData call() throws InterruptedException {
return query.execute(graph, interruptor);
}
};
ExecutorService exe = Executors.newSingleThreadExecutor();
futureResult = exe.submit(runnable);
}
@Override
public void close() { }
@Override
public void interrupt() { interruptor.interrupt(); }
public void interrupt() { interruptor.interrupt(); }
/**{@inheritDoc}
* Implemtentation in {@link CyphSemInterpreter} does nothing.
***/
@Override
public void close() { }
}
/* CyphSem
Copyright (c) 2018,2019 Victor Marsault
This file is part of CyphSem.
CyphSem is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CyphSem is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CyphSem. If not, see <https://www.gnu.org/licenses/>. */
package uk.ac.ed.cyphsem.outbridge;
import java.io.File;
import uk.ac.ed.cyphsem.Interruptor;
import uk.ac.ed.cyphsem.exception.InterpretingException;
import uk.ac.ed.cyphsem.exception.UndefinedNameException;
import uk.ac.ed.cyphsem.exception.UnspecifiedBehaviourException;
import uk.ac.ed.cyphsem.datamodel.graph.Graph;
import uk.ac.ed.cyphsem.language.parser.Parser;
import uk.ac.ed.cyphsem.exception.AnTLRException;
import uk.ac.ed.cyphsem.language.query.Query;
import uk.ac.ed.cyphsem.table.Table;
public class CyphSemInterpreter extends Interpreter.AbstractHelper implements Interpreter {
Graph graph;
protected long lastRunTime;
// Boolean interrupted = false;
Interruptor interruptor = new Interruptor();
public CyphSemInterpreter() { }
public CyphSemInterpreter(Graph graph) { this.graph = graph; }
public CyphSemInterpreter(Interpreter other) { this(other.getGraph()); }
@Override
public void load(File database) { }
@Override
public void load(String str) { }
@Override
public void loadFrom(Interpreter i) { this.graph = i.getGraph(); }
@Override
public Graph getGraph() { return graph; }
public void setGraph(Graph graph) { this.graph = graph; }
@Override
public Table run(String statement) throws InterpretingException, InterruptedException {
try {
lastRunTime = -System.nanoTime();
Query query = Parser.queryOf(statement);
Table result = query.execute(graph, interruptor).table();
lastRunTime += System.nanoTime();
return result;
} catch (UndefinedNameException e) {
throw new InterpretingException(e);
} catch (UnspecifiedBehaviourException e) {
throw new InterpretingException(e);
} catch (AnTLRException e) {
throw new InterpretingException(e.getCause());
}
}
@Override
public long getLastRunTime() {
return lastRunTime;
}
@Override
public void close() { }
@Override
public void interrupt() { interruptor.interrupt(); }
}
/* CyphSem
Copyright (c) 2018,2019 Victor Marsault
This file is part of CyphSem.
CyphSem is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CyphSem is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CyphSem. If not, see <https://www.gnu.org/licenses/>. */
package uk.ac.ed.cyphsem.outbridge;
import java.io.File;
import java.io.IOException;
import uk.ac.ed.cyphsem.exception.ConversionException;
import uk.ac.ed.cyphsem.exception.InterpretingException;
import uk.ac.ed.cyphsem.datamodel.graph.Graph;
import uk.ac.ed.cyphsem.table.Table;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.ExecutionException;
import uk.ac.ed.cyphsem.Utils;
import uk.ac.ed.cyphsem.exception.UnreachableStatementError;
public interface Interpreter extends AutoCloseable {
public void load(File database) throws InterpretingException ;
public void load(String str) throws InterpretingException ;
public Graph getGraph();
public Table run(String statement) throws InterpretingException, InterruptedException ;
public abstract Table run(String statement, long timeout)
throws InterpretingException, TimeoutException ;
public long getLastRunTime();
@Override
public void close();
public void interrupt();
public void loadFrom(Interpreter i) throws InterpretingException ;
public abstract class AbstractHelper implements Interpreter {
@Override
public void load(File database) throws InterpretingException {
try { load(uk.ac.ed.cyphsem.Utils.readFile(database)); }
catch (IOException e) { throw new ConversionException(e); }
}
@Override
public abstract void load(String str) throws InterpretingException ;
@Override
public abstract void loadFrom(Interpreter i) throws InterpretingException ;
@Override
public abstract Graph getGraph();
@Override
public abstract Table run(String statement) throws InterpretingException, InterruptedException ;
@Override
public Table run(String statement, long timeout)
throws InterpretingException, TimeoutException
{
uk.ac.ed.cyphsem.table.Table result = null;
Callable<uk.ac.ed.cyphsem.table.Table> callable = new Callable<uk.ac.ed.cyphsem.table.Table> () {
public uk.ac.ed.cyphsem.table.Table call() throws InterpretingException, InterruptedException {
return run(statement);
}
};
ExecutorService exe = Executors.newSingleThreadExecutor();
Future<uk.ac.ed.cyphsem.table.Table> futureResult = exe.submit(callable);
try {
result = futureResult.get(timeout, TimeUnit.MILLISECONDS);
exe.shutdownNow();
} catch (TimeoutException e) {
exe.shutdownNow();
interrupt();
throw e;
} catch (InterruptedException e) {
exe.shutdownNow();
throw new UnreachableStatementError();
} catch (ExecutionException e) {
// System.out.println(e);
exe.shutdownNow();
Throwable thr = e.getCause();
if (thr instanceof InterpretingException)
throw ((InterpretingException) thr);
else
throw new InterpretingException(e);
}
return result;
}
@Override
public void close() { }
@Override
public void interrupt() { }
}
}
......@@ -38,7 +38,7 @@ public class InterpreterComparator {
public static class Comparison {
// public List<Integer> failedWithExceptions;
public List<InterpretingException> exceptions;
public List<ExecutionException> exceptions;
public List<List<Integer>> succeeded = new LinkedList<List<Integer>>();
public List<Table> tables = new LinkedList<Table>();
......@@ -127,7 +127,7 @@ public class InterpreterComparator {
List<Interpreter> interpreters = makeInterpreters();
for (int i=0; i<interpreters.size(); i++) {
try { result.addSuccess(i, interpreters.get(i).run(statement, timeout) ); }
catch (InterpretingException e) { result.addExceptionFails(i,e); }
catch (ExecutionException e) { result.addExceptionFails(i,e); }
catch (TimeoutException e) { result.addTimeoutFails(i); }
interpreters.get(i).close();
}
......
......@@ -18,56 +18,56 @@
package uk.ac.ed.cyphsem.outbridge;
import uk.ac.ed.cyphsem.exception.InterpretingException;
import uk.ac.ed.cyphsem.exception.*;
import java.io.File;
import java.util.concurrent.ExecutionException;
import java.lang.InterruptedException;
import uk.ac.ed.cyphsem.datamodel.graph.Graph;
import uk.ac.ed.cyphsem.language.query.Query;
import uk.ac.ed.cyphsem.table.Table;
import java.util.concurrent.TimeoutException;
/** This enum registers instance of different {@link Intepreter}'s for easier use.
* Note that they won't inconditionally work; for instance, {@link #NEO4J} will only work if Neo4j service is correcly started and set up.
***/
public enum Interpreters implements Interpreter {
CYPHSEM(new CyphSemInterpreter()),
NEOCOM(new NeoComInterpreter());
CYPHSEM(new CyphSemInterpreter())
// ,NEO4J(new NeoComInterpreter())
;
Interpreter boxedInterpreter;
private Interpreters(Interpreter i) { boxedInterpreter = i; }
@Override
public void load(File database) throws InterpretingException
{ boxedInterpreter.load(database); }
@Override
public void load(String str) throws InterpretingException
{ boxedInterpreter.load(str); }
public void inputGraph(Graph g) { boxedInterpreter.inputGraph(g); }
@Override
public Graph getGraph() { return boxedInterpreter.getGraph(); }
public void inputQuery(Query q) { boxedInterpreter.inputQuery(q); }
@Override
public Table run(String statement) throws InterpretingException, InterruptedException
{ return boxedInterpreter.run(statement); }
public Graph outputGraph()
throws InterruptedException, ExecutionException, ComputationOngoingException
{
return boxedInterpreter.outputGraph();
}
@Override
public Table run(String statement, long timeout)
throws InterpretingException, TimeoutException
{ return boxedInterpreter.run(statement, timeout); }
@Override
public void close() { boxedInterpreter.close(); }
public Table outputTable()
throws InterruptedException, ExecutionException, ComputationOngoingException
{ return boxedInterpreter.outputTable(); }
@Override
public long getLastRunTime() { return boxedInterpreter.getLastRunTime(); }
public void interrupt() { boxedInterpreter.interrupt(); }
@Override
public void interrupt() { boxedInterpreter.interrupt(); }
public void run() { boxedInterpreter.run(); }
@Override
public void loadFrom(Interpreter i) throws InterpretingException
{ boxedInterpreter.loadFrom(i); }
public void close() { boxedInterpreter.close(); }
}
This diff is collapsed.
/* CyphSem
Copyright (c) 2018,2019 Victor Marsault
This file is part of CyphSem.
CyphSem is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CyphSem is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CyphSem. If not, see <https://www.gnu.org/licenses/>. */
package uk.ac.ed.cyphsem.outbridge;
import uk.ac.ed.cyphsem.Utils;
import uk.ac.ed.cyphsem.utils.StringOf;
import uk.ac.ed.cyphsem.exception.*;
import uk.ac.ed.cyphsem.language.query.Query;
import uk.ac.ed.cyphsem.language.parser.Parser;
import uk.ac.ed.cyphsem.table.*;
import uk.ac.ed.cyphsem.datamodel.graph.*;
import uk.ac.ed.cyphsem.datamodel.value.*;