import java.net.URL;
import java.net.URLDecoder;
+import org.simantics.db.ObjectResourceIdMap;
import org.simantics.utils.FileUtils;
public class CodeGen {
String[] signatureR2TIP = { "int r1, int r2", "r1,r2", "keyR2", "long", "TripleIntProcedure", "entry.id" };
String[] signatureID1 = { "String id", "id", "keyID", "String", "InternalProcedure<Integer>", "entry.id" };
String[] signatureID2 = { "String id", "id", "keyID", "String", "InternalProcedure<TObjectIntHashMap<String>>", "entry.id" };
+ String[] signatureChildMap = { "int r", "r", "keyR", "long", "InternalProcedure<ObjectResourceIdMap<String>>", "entry.id" };
String[] signatureRead = { "Read<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
String[] signatureAsyncRead = { "AsyncRead<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
String[] signatureMultiRead = { "MultiRead<?> r", "r", "id", "long", "AsyncMultiProcedure", "entry.request" };
content.append("\n");
}
- public void generateQuery(StringBuilder content, String clazz, String[] signature, boolean runnerShortcut) {
- generateGetOrCreate(content, clazz, signature);
+ public void generateQuery(StringBuilder content, String clazz, String[] signature, boolean runnerShortcut, boolean genAsync) {
+ generateGetOrCreate(content, clazz, signature, genAsync);
generateRemove(content, clazz, signature);
- generateRunner(content, clazz, signature, runnerShortcut);
+ generateRunner(content, clazz, signature, runnerShortcut, genAsync);
}
- public void generateRunner(StringBuilder content, String clazz, String[] signature, boolean shortcut) {
+ public void generateRunner(StringBuilder content, String clazz, String[] signature, boolean shortcut, boolean genAsync) {
- line(content, "public static void runner" + clazz + "(ReadGraphImpl graph, " + signature[0] + ", CacheEntry parent, ListenerBase listener, " + signature[4] + " procedure) throws DatabaseException {");
+ line(content, "public static void runner" + clazz + "(ReadGraphImpl graph, " + signature[0] + ", CacheEntry parent, ListenerBase listener, final " + signature[4] + " procedure" + (genAsync ? ", boolean isSync" : "") + ") throws DatabaseException {");
+ line(content, " QueryCache cache = graph.processor.cache;");
if(shortcut) {
- line(content, " if(parent == null && listener == null) {");
+ line(content, " if(parent == null && listener == null && !cache.shouldCache(graph.processor, " + signature[1] + ")) {");
line(content, " " + clazz + ".computeForEach(graph, " + signature[1] + ", null, procedure);");
line(content, " return;");
line(content, " }");
}
- line(content, " QueryCache cache = graph.processor.cache;");
- line(content, " if(procedure == null) procedure = emptyProcedure" + clazz + ";");
- line(content, " " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(" + signature[1] + ");");
- line(content, " ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false);");
- line(content, " if(entry.isReady()) entry.performFromCache(graph, procedure);");
+ line(content, " " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(" + signature[1] + (genAsync ? ", isSync" : "") + ");");
+ if(genAsync) {
+ line(content, " if(entry == null) {");
+ line(content, " graph.processor.schedule(Integer.MIN_VALUE, new SessionTask(r, graph.processor.THREAD_MASK+1, -1) {");
+ line(content, " @Override");
+ line(content, " public void run(int thread) {");
+ line(content, " try {");
+ line(content, " assert(!isSync);");
+ line(content, " runner" + clazz + "(graph, r, parent, listener, procedure, isSync);");
+ line(content, " } catch (DatabaseException e) {");
+ line(content, " Logger.defaultLogError(e);");
+ line(content, " }");
+ line(content, " }");
+ line(content, " });");
+ line(content, " return;");
+ line(content, " }");
+ }
+ line(content, " " + signature[4] + " procedure_ = procedure != null ? procedure : emptyProcedure" + clazz + ";");
+ line(content, " ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);");
+ line(content, " if(entry.isReady()) entry.performFromCache(graph, procedure_);");
line(content, " else {");
- if(shortcut) line(content, " " + clazz + ".computeForEach(graph, " + signature[1] + ", entry, procedure);");
- else line(content, " entry.compute(graph, procedure);");
+ line(content, " assert(entry.isPending());");
+ if(shortcut) line(content, " " + clazz + ".computeForEach(graph, " + signature[1] + ", entry, procedure_);");
+ else line(content, " entry.compute(graph, procedure_);");
line(content, " if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());");
line(content, " }");
line(content, "}");
}
- public void generateGetOrCreate(StringBuilder content, String clazz, String[] signature) {
+ public void generateGetOrCreate(StringBuilder content, String clazz, String[] signature, boolean genAsync) {
String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1);
- line(content, "" + clazz + " getOrCreate" + clazz + "(" + signature[0] + ") throws DatabaseException {");
+ line(content, "" + clazz + " getOrCreate" + clazz + "(" + signature[0] + (genAsync ? ", boolean isSync" : "") + ") throws DatabaseException {");
line(content, " " + clazz + " existing = null;");
line(content, " synchronized(" + lower + "Map) {");
line(content, " existing = (" + clazz + ")" + lower + "Map.get(" + signature[1] + ");");
line(content, " existing.clearResult(querySupport);");
line(content, " existing.setPending();");
line(content, " " + lower + "Map.put(" + signature[2] + "(" + signature[1] + "), existing);");
+ line(content, " size++;");
line(content, " return existing;");
line(content, " }");
line(content, " if(existing.requiresComputation()) {");
line(content, " return existing;");
line(content, " }");
line(content, " }");
- line(content, " if(existing.isPending()) waitPending(existing);");
+ if(genAsync) {
+ line(content, " if(existing.isPending()) {");
+ line(content, " if(isSync) waitPending(existing);");
+ line(content, " else return null;");
+ line(content, " }");
+ } else {
+ line(content, " if(existing.isPending()) waitPending(existing);");
+ }
line(content, " return existing;");
line(content, "}");
line(content, "");
StringBuilder content = new StringBuilder();
content.append("package org.simantics.db.impl.query;\n");
content.append("\n");
+
+ content.append("import org.simantics.db.ObjectResourceIdMap;\n");
content.append("import org.simantics.db.RelationInfo;\n");
+ content.append("import org.simantics.db.common.utils.Logger;\n");
content.append("import org.simantics.db.exception.DatabaseException;\n");
content.append("import org.simantics.db.impl.graph.ReadGraphImpl;\n");
content.append("import org.simantics.db.impl.procedure.InternalProcedure;\n");
+ content.append("import org.simantics.db.impl.query.QueryProcessor.SessionTask;\n");
content.append("import org.simantics.db.procedure.AsyncMultiProcedure;\n");
content.append("import org.simantics.db.procedure.AsyncProcedure;\n");
content.append("import org.simantics.db.procedure.ListenerBase;\n");
line(content,"}");
content.append("\n");
- generateQuery(content, "Objects", signatureR2IP, true);
- generateQuery(content, "Statements", signatureR2TIP, true);
- generateQuery(content, "DirectObjects", signatureR2IP, true);
- generateQuery(content, "RelationInfoQuery", signatureR1RelationInfo, true);
- generateQuery(content, "URIToResource", signatureID1, true);
- generateQuery(content, "ValueQuery", signatureR1Bytes, true);
- generateQuery(content, "OrderedSet", signatureR1IP, true);
- generateQuery(content, "PrincipalTypes", signatureR1IP, true);
- generateQuery(content, "DirectPredicates", signatureR1IntSet, true);
- generateQuery(content, "Predicates", signatureR1IntSet, true);
- generateQuery(content, "ReadEntry", signatureRead, true);
- generateQuery(content, "AsyncReadEntry", signatureAsyncRead, true);
- generateQuery(content, "Types", signatureR1IntSet, true);
- generateQuery(content, "NamespaceIndex", signatureID2, true);
+ generateQuery(content, "Objects", signatureR2IP, true, false);
+ generateQuery(content, "Statements", signatureR2TIP, true, false);
+ generateQuery(content, "DirectObjects", signatureR2IP, true, false);
+ generateQuery(content, "RelationInfoQuery", signatureR1RelationInfo, true, false);
+ generateQuery(content, "URIToResource", signatureID1, true, false);
+ generateQuery(content, "ValueQuery", signatureR1Bytes, true, false);
+ generateQuery(content, "OrderedSet", signatureR1IP, true, false);
+ generateQuery(content, "PrincipalTypes", signatureR1IP, true, false);
+ generateQuery(content, "DirectPredicates", signatureR1IntSet, true, false);
+ generateQuery(content, "Predicates", signatureR1IntSet, true, false);
+ generateQuery(content, "ReadEntry", signatureRead, true, true);
+ generateQuery(content, "AsyncReadEntry", signatureAsyncRead, true, true);
+ generateQuery(content, "Types", signatureR1IntSet, true, false);
+ //generateQuery(content, "NamespaceIndex", signatureID2, true);
+ generateQuery(content, "ChildMap", signatureChildMap, true, false);
- generateQuery(content, "AssertedStatements", signatureR2TIP, false);
- generateQuery(content, "AssertedPredicates", signatureR1IP, false);
- generateQuery(content, "DirectSuperRelations", signatureR1IP, false);
- generateQuery(content, "SuperTypes", signatureR1IntSet, false);
- generateQuery(content, "TypeHierarchy", signatureR1IntSet, false);
- generateQuery(content, "SuperRelations", signatureR1IntSet, false);
- generateQuery(content, "MultiReadEntry", signatureMultiRead, false);
- generateQuery(content, "AsyncMultiReadEntry", signatureAsyncMultiRead, false);
- generateQuery(content, "ExternalReadEntry", signatureExternalRead, false);
+ generateQuery(content, "AssertedStatements", signatureR2TIP, false, false);
+ generateQuery(content, "AssertedPredicates", signatureR1IP, false, false);
+ generateQuery(content, "DirectSuperRelations", signatureR1IP, false, false);
+ generateQuery(content, "SuperTypes", signatureR1IntSet, false, false);
+ generateQuery(content, "TypeHierarchy", signatureR1IntSet, false, false);
+ generateQuery(content, "SuperRelations", signatureR1IntSet, false, false);
+ generateQuery(content, "MultiReadEntry", signatureMultiRead, false, false);
+ generateQuery(content, "AsyncMultiReadEntry", signatureAsyncMultiRead, false, false);
+ generateQuery(content, "ExternalReadEntry", signatureExternalRead, false, false);
content.append("}\n");
FileUtils.writeFile(source, content.toString().getBytes());
} catch (MalformedURLException e) {