]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java
Use query caching previous to multi-query-thread to retain performance
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / CodeGen.java
1 package org.simantics.db.impl.query;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.UnsupportedEncodingException;
6 import java.net.MalformedURLException;
7 import java.net.URL;
8 import java.net.URLDecoder;
9
10 import org.simantics.utils.FileUtils;
11
12 public class CodeGen {
13
14         int indent = 4;
15
16         String[] signatureR1RelationInfo = { "int r", "r", "keyR", "long", "InternalProcedure<RelationInfo>", "entry.id" };
17         String[] signatureR1Bytes = { "int r", "r", "keyR", "long", "InternalProcedure<byte[]>", "entry.id" };
18         String[] signatureR1IntSet = { "int r", "r", "keyR", "long", "InternalProcedure<IntSet>", "entry.id" };
19         String[] signatureR1IP = { "int r", "r", "keyR", "long", "IntProcedure", "entry.id" };
20         String[] signatureR2IP = { "int r1, int r2", "r1,r2", "keyR2", "long", "IntProcedure", "entry.id" };
21         String[] signatureR2TIP = { "int r1, int r2", "r1,r2", "keyR2", "long", "TripleIntProcedure", "entry.id" };
22         String[] signatureID1 = { "String id", "id", "keyID", "String", "InternalProcedure<Integer>", "entry.id" };
23         String[] signatureID2 = { "String id", "id", "keyID", "String", "InternalProcedure<TObjectIntHashMap<String>>", "entry.id" };
24         String[] signatureChildMap = { "int r", "r", "keyR", "long", "InternalProcedure<ObjectResourceIdMap<String>>", "entry.id" };
25         String[] signatureRead = { "Read<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
26         String[] signatureAsyncRead = { "AsyncRead<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
27         String[] signatureMultiRead = { "MultiRead<?> r", "r", "id", "long", "SyncMultiProcedure", "entry.request" };
28         String[] signatureAsyncMultiRead = { "AsyncMultiRead<?> r", "r", "id", "long", "AsyncMultiProcedure", "entry.request" };
29         String[] signatureExternalRead = { "ExternalRead<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
30
31         private void line(StringBuilder content, String line) {
32                 for(int i=0;i<indent;i++)
33                         content.append(" ");
34                 content.append(line);
35                 content.append("\n");
36         }
37
38     public void generateQuery(StringBuilder content, String clazz, String[] signature, boolean runnerShortcut, boolean genReturn) {
39                 generateGetOrCreate(content, clazz, signature);
40                 generateRemove(content, clazz, signature);
41                 generateRunner(content, clazz, signature, runnerShortcut, genReturn);
42         }
43
44         public void generateRunner(StringBuilder content, String clazz, String[] signature, boolean shortcut, boolean genReturn) {
45
46                 line(content, "public static " + (genReturn ? "Object" : "void") + " runner" + clazz + "(ReadGraphImpl graph, " + signature[0] + ", CacheEntry parent, ListenerBase listener, final " + signature[4] + " procedure) throws DatabaseException {");
47                 line(content, "    QueryCache cache  = graph.processor.cache;");
48                 if(shortcut) {
49                         line(content, "    if(parent == null && listener == null && !cache.shouldCache(graph.processor, " + signature[1] + ")) {");
50                         line(content, "        if (SINGLE) {");
51                         line(content, "            " + clazz + " e = cache.peek" + clazz + "(" + signature[1] + ");");
52                         line(content, "            if (e != null && e.isReady()) {");
53                         line(content, "                " + (genReturn ? "return " : "") + "e.performFromCache(graph, procedure);");
54                         if(!genReturn) line(content, "                return;");
55                         line(content, "            }");
56                         line(content, "        }");
57                         line(content, "        " + (genReturn ? "return " : "") + clazz + ".computeForEach(graph, " + signature[1] + ", null, procedure);");
58                         if(!genReturn) line(content, "        return;");
59                         line(content, "    }");
60                 }
61                 line(content, "    " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(graph, " + signature[1] + ");");
62                 line(content, "    " + signature[4] + " procedure_ = procedure != null ? procedure : emptyProcedure" + clazz + ";");
63                 line(content, "    ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);");
64                 line(content, "    if(entry.isReady()) " + (genReturn ? "return " : "") + "entry.performFromCache(graph, procedure_);");
65                 line(content, "    else {");
66                 line(content, "      assert(entry.isPending());");
67                 if(shortcut) line(content, "      " + (genReturn ? "Object result = " : "") + clazz + ".computeForEach(graph, " + signature[1] + ", entry, procedure_);");
68                 else line(content, "      entry.compute(graph, procedure_);"); 
69                 line(content, "      if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());");
70                 if(genReturn) line(content, "      return result;");
71                 line(content, "    }");
72                 line(content, "}");
73                 line(content, "");
74
75         String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1);
76
77                 line(content, "private " + clazz + " peek" + clazz + "(" + signature[0] + ") {");
78                 line(content, "    synchronized(" + lower +"Map) {");
79                 line(content, "        return (" + clazz + ") " + lower + "Map.get(" + signature[1] + ");");
80                 line(content, "    }");
81                 line(content, "}");
82                 line(content, "");
83         }
84
85         public void generateRemove(StringBuilder content, String clazz, String[] signature) {
86
87                 String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1);
88
89                 line(content, "void remove(" + clazz + " entry) {");
90                 line(content, "    synchronized(" + lower + "Map) {");
91                 line(content, "        " + lower + "Map.remove(" + signature[5] + ");");
92                 line(content, "    }");
93                 line(content, "}");
94                 line(content, "");
95
96         }
97
98         public void generateGetOrCreate(StringBuilder content, String clazz, String[] signature) {
99
100                 String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1);
101
102                 line(content, "" + clazz + " getOrCreate" + clazz + "(ReadGraphImpl graph, " + signature[0] + ") throws DatabaseException {");
103                 line(content, "    " + clazz + " existing = null;");
104                 line(content, "    synchronized(" + lower + "Map) {");
105                 line(content, "        existing = (" + clazz + ")" + lower + "Map.get(" + signature[1] + ");");
106                 line(content, "        if(existing == null) {");
107                 line(content, "            existing = new " + clazz + "(" + signature[1] + ");");
108                 line(content, "            existing.clearResult(querySupport);");
109                 line(content, "            existing.setPending();");
110                 line(content, "            " + lower + "Map.put(" + signature[2] + "(" + signature[1] + "), existing);");
111                 line(content, "            size++;");
112                 line(content, "            return existing;");
113                 line(content, "        }");
114                 line(content, "        if(existing.requiresComputation()) {");
115                 line(content, "            existing.setPending();");
116                 line(content, "            return existing;");
117                 line(content, "        }");
118                 line(content, "    }");
119                 line(content, "    if(existing.isPending()) waitPending(graph, existing);");
120                 line(content, "    return existing;");
121                 line(content, "}");
122                 line(content, "");
123
124         }
125
126         public void generate() {
127
128                 URL classLocation = CodeGen.class.getResource(".");
129                 if (classLocation != null) {
130                         if (classLocation.getProtocol().equals("file")) {
131                                 try {
132                                         URL resource = new URL(classLocation, ".");
133                                         File path = new File(URLDecoder.decode(resource.getPath(), "UTF-8"));
134                                         String target = path.getAbsolutePath().replace("\\", "/");
135                                         target = target.replace("/bin/", "/src/") + "/QueryCache.java";
136                                         System.err.println("target=" + target);
137                                         File source = new File(target);
138                                         StringBuilder content = new StringBuilder();
139                                         content.append("package org.simantics.db.impl.query;\n");
140                                         content.append("\n");
141
142                                         content.append("import org.simantics.db.ObjectResourceIdMap;\n");
143                                         content.append("import org.simantics.db.RelationInfo;\n");
144                                         content.append("import org.simantics.db.common.utils.Logger;\n");
145                                         content.append("import org.simantics.db.exception.DatabaseException;\n");
146                                         content.append("import org.simantics.db.impl.graph.ReadGraphImpl;\n");
147                                         content.append("import org.simantics.db.impl.procedure.InternalProcedure;\n");
148                                         content.append("import org.simantics.db.impl.query.QueryProcessor.SessionTask;\n");
149                                         content.append("import org.simantics.db.procedure.AsyncMultiProcedure;\n");
150                                         content.append("import org.simantics.db.procedure.AsyncProcedure;\n");
151                                         content.append("import org.simantics.db.procedure.ListenerBase;\n");
152                                         content.append("import org.simantics.db.procedure.SyncMultiProcedure;\n");
153                                         content.append("import org.simantics.db.request.AsyncMultiRead;\n");
154                                         content.append("import org.simantics.db.request.AsyncRead;\n");
155                                         content.append("import org.simantics.db.request.ExternalRead;\n");
156                                         content.append("import org.simantics.db.request.MultiRead;\n");
157                                         content.append("import org.simantics.db.request.Read;\n");
158                                         content.append("\n");
159
160                                         content.append("public class QueryCache extends QueryCacheBase {\n");
161                                         content.append("\n");
162                                         
163                                         line(content, "private static final boolean SINGLE = true;");
164                                         content.append("\n");
165                                         
166                                         line(content,"public QueryCache(QuerySupport querySupport, int threads) {");
167                                         line(content,"    super(querySupport, threads);");
168                                         line(content,"}");
169                                         content.append("\n");
170
171                                         generateQuery(content, "Objects", signatureR2IP, true, false);
172                                         generateQuery(content, "Statements", signatureR2TIP, true, false);
173                                         generateQuery(content, "DirectObjects", signatureR2IP, true, false);
174                                         generateQuery(content, "RelationInfoQuery", signatureR1RelationInfo, true, false);
175                                         generateQuery(content, "URIToResource", signatureID1, true, false);
176                                         generateQuery(content, "ValueQuery", signatureR1Bytes, true, false);
177                                         generateQuery(content, "OrderedSet", signatureR1IP, true, false);
178                                         generateQuery(content, "PrincipalTypes", signatureR1IP, true, false);
179                                         generateQuery(content, "DirectPredicates", signatureR1IntSet, true, false);
180                                         generateQuery(content, "Predicates", signatureR1IntSet, true, false);
181                                         generateQuery(content, "ReadEntry", signatureRead, true, true);
182                                         generateQuery(content, "AsyncReadEntry", signatureAsyncRead, true, true);
183                                         generateQuery(content, "Types", signatureR1IntSet, true, false);
184                                         generateQuery(content, "ChildMap", signatureChildMap, true, false);
185                                         generateQuery(content, "TypeHierarchy", signatureR1IntSet, true, false);
186                                         generateQuery(content, "SuperTypes", signatureR1IntSet, true, false);
187                                         generateQuery(content, "SuperRelations", signatureR1IntSet, true, false);
188
189                                         generateQuery(content, "AssertedPredicates", signatureR1IP, false, false);
190                                         generateQuery(content, "AssertedStatements", signatureR2TIP, false, false);
191                                         generateQuery(content, "DirectSuperRelations", signatureR1IP, false, false);
192                                         generateQuery(content, "MultiReadEntry", signatureMultiRead, false, false);
193                                         generateQuery(content, "AsyncMultiReadEntry", signatureAsyncMultiRead, false, false);
194                                         generateQuery(content, "ExternalReadEntry", signatureExternalRead, false, false);
195                                         content.append("}\n");
196                                         FileUtils.writeFile(source, content.toString().getBytes());
197                                 } catch (MalformedURLException e) {
198                                         e.printStackTrace();
199                                 } catch (UnsupportedEncodingException e) {
200                                         e.printStackTrace();
201                                 } catch (IOException e) {
202                                         e.printStackTrace();
203                                 }
204                         }
205                 }
206
207         }
208
209         public static void main(String[] args) {
210                 new CodeGen().generate();
211         }
212
213 }