]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java
Merge commit 'b9450ae'
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / DirectQuerySupportImpl.java
1 package fi.vtt.simantics.procore.internal;\r
2 \r
3 import org.simantics.db.AsyncReadGraph;\r
4 import org.simantics.db.DirectStatements;\r
5 import org.simantics.db.ReadGraph;\r
6 import org.simantics.db.RelationInfo;\r
7 import org.simantics.db.Resource;\r
8 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;\r
9 import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;\r
10 import org.simantics.db.exception.DatabaseException;\r
11 import org.simantics.db.impl.ClusterI;\r
12 import org.simantics.db.impl.ClusterI.ClusterTypeEnum;\r
13 import org.simantics.db.impl.ForEachObjectContextProcedure;\r
14 import org.simantics.db.impl.ForEachObjectProcedure;\r
15 import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;\r
16 import org.simantics.db.impl.ForPossibleRelatedValueProcedure;\r
17 import org.simantics.db.impl.ResourceImpl;\r
18 import org.simantics.db.impl.TransientGraph;\r
19 import org.simantics.db.impl.graph.ReadGraphImpl;\r
20 import org.simantics.db.procedure.AsyncContextMultiProcedure;\r
21 import org.simantics.db.procedure.AsyncContextProcedure;\r
22 import org.simantics.db.procedure.AsyncMultiProcedure;\r
23 import org.simantics.db.procedure.AsyncProcedure;\r
24 import org.simantics.db.procedure.Procedure;\r
25 import org.simantics.db.procedure.SyncProcedure;\r
26 import org.simantics.db.procore.cluster.ClusterBig;\r
27 import org.simantics.db.procore.cluster.ClusterImpl;\r
28 import org.simantics.db.procore.cluster.ClusterSmall;\r
29 import org.simantics.db.procore.cluster.ResourceTableSmall;\r
30 import org.simantics.db.procore.cluster.ValueTableSmall;\r
31 import org.simantics.db.request.AsyncRead;\r
32 import org.simantics.db.service.DirectQuerySupport;\r
33 import org.simantics.utils.datastructures.Callback;\r
34 \r
35 public class DirectQuerySupportImpl implements DirectQuerySupport {\r
36 \r
37         final private SessionImplSocket session;\r
38         \r
39         DirectQuerySupportImpl(SessionImplSocket session) {\r
40                 this.session = session;\r
41         }\r
42 \r
43         @Override\r
44         final public void forEachDirectPersistentStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {\r
45                 ReadGraphImpl impl = (ReadGraphImpl)graph;\r
46                 impl.processor.forEachDirectStatement(impl, subject, procedure, true);\r
47         }\r
48 \r
49         @Override\r
50         final public void forEachDirectStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {\r
51                 ReadGraphImpl impl = (ReadGraphImpl)graph;\r
52                 impl.processor.forEachDirectStatement(impl, subject, procedure, false);\r
53         }\r
54 \r
55         @Override\r
56         public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, SyncProcedure<DirectStatements> procedure) {\r
57                 forEachDirectStatement(graph, subject, new SyncToAsyncProcedure<DirectStatements>(procedure));\r
58         }\r
59 \r
60         @Override\r
61         public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure<DirectStatements> procedure) {\r
62                 ReadGraphImpl impl = (ReadGraphImpl)graph;\r
63                 impl.processor.forEachDirectStatement(impl, subject, procedure);\r
64         }\r
65 \r
66         @Override\r
67         public void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure<RelationInfo> procedure) {\r
68                 ReadGraphImpl impl = (ReadGraphImpl)graph;\r
69                 impl.processor.forRelationInfo(impl, subject, procedure);\r
70         }\r
71 \r
72         @Override\r
73         public void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure<RelationInfo> procedure) {\r
74                 forRelationInfo(graph, subject, new SyncToAsyncProcedure<RelationInfo>(procedure));\r
75         }\r
76 \r
77         @Override\r
78         public void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure<RelationInfo> procedure) {\r
79                 forRelationInfo(graph, subject, new NoneToAsyncProcedure<RelationInfo>(procedure));\r
80         }\r
81 \r
82         @Override\r
83         public AsyncMultiProcedure<Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncMultiProcedure<Resource> user) {\r
84                 \r
85                 try {\r
86                         RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {\r
87 \r
88                                 @Override\r
89                                 public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {\r
90                                         forRelationInfo(graph, relation, procedure);\r
91                                 }\r
92 \r
93                 @Override\r
94                     public int threadHash() {\r
95                         return hashCode();\r
96                     }\r
97 \r
98                                 @Override\r
99                                 public int getFlags() {\r
100                                         return 0;\r
101                                 }\r
102 \r
103                         });\r
104                 final int predicateKey = ((ResourceImpl)relation).id;\r
105                         return new ForEachObjectProcedure(predicateKey, info, session.queryProvider2, user);\r
106                 } catch (DatabaseException e) {\r
107                         return null;\r
108                 }               \r
109         \r
110         }\r
111 \r
112         @Override\r
113         public <C> AsyncContextMultiProcedure<C, Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncContextMultiProcedure<C, Resource> user) {\r
114                 \r
115                 try {\r
116                         RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {\r
117 \r
118                                 @Override\r
119                                 public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {\r
120                                         forRelationInfo(graph, relation, procedure);\r
121                                 }\r
122 \r
123                 @Override\r
124                     public int threadHash() {\r
125                         return hashCode();\r
126                     }\r
127 \r
128                                 @Override\r
129                                 public int getFlags() {\r
130                                         return 0;\r
131                                 }\r
132 \r
133                         });\r
134                 final int predicateKey = ((ResourceImpl)relation).id;\r
135                         return new ForEachObjectContextProcedure<C>(predicateKey, info, session.queryProvider2, user);\r
136                 } catch (DatabaseException e) {\r
137                         return null;\r
138                 }               \r
139         \r
140         }\r
141         \r
142         @Override\r
143         public <T> AsyncProcedure<T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncProcedure<T> user) {\r
144                 \r
145                 try {\r
146                         RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {\r
147 \r
148                                 @Override\r
149                                 public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {\r
150                                         forRelationInfo(graph, relation, procedure);\r
151                                 }\r
152 \r
153                 @Override\r
154                     public int threadHash() {\r
155                         return hashCode();\r
156                     }\r
157 \r
158                                 @Override\r
159                                 public int getFlags() {\r
160                                         return 0;\r
161                                 }\r
162 \r
163                         });\r
164                 final int predicateKey = ((ResourceImpl)relation).id;\r
165                         return new ForPossibleRelatedValueProcedure<T>(predicateKey, info, user);\r
166                 } catch (DatabaseException e) {\r
167                         return null;\r
168                 }               \r
169         \r
170         }\r
171 \r
172         @Override\r
173         public <C, T> AsyncContextProcedure<C, T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncContextProcedure<C, T> user) {\r
174                 \r
175                 try {\r
176                         RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {\r
177 \r
178                                 @Override\r
179                                 public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {\r
180                                         forRelationInfo(graph, relation, procedure);\r
181                                 }\r
182 \r
183                 @Override\r
184                     public int threadHash() {\r
185                         return hashCode();\r
186                     }\r
187 \r
188                                 @Override\r
189                                 public int getFlags() {\r
190                                         return 0;\r
191                                 }\r
192 \r
193                         });\r
194                 final int predicateKey = ((ResourceImpl)relation).id;\r
195                         return new ForPossibleRelatedValueContextProcedure<C, T>(predicateKey, info, user);\r
196                 } catch (DatabaseException e) {\r
197                         return null;\r
198                 }               \r
199         \r
200         }\r
201         \r
202         @Override\r
203         public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, final AsyncMultiProcedure<Resource> procedure) {\r
204                 \r
205         assert(subject != null);\r
206         \r
207         final ForEachObjectProcedure proc = (ForEachObjectProcedure)procedure;\r
208 //        final RelationInfo info = proc.info;\r
209 \r
210         final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
211         final int subjectId = ((ResourceImpl)subject).id;\r
212 \r
213 //        int callerThread = impl.callerThread;\r
214 //        int suggestSchedule = (subjectId>>16) & queryProvider2.THREAD_MASK;\r
215         \r
216 //        impl.inc();\r
217         \r
218 //        if(callerThread == suggestSchedule) {\r
219                 \r
220 //              if(info.isFunctional) {\r
221 //                      querySupport.getObjects4(impl, subjectId, proc);\r
222 //              } else {\r
223                 session.querySupport.getObjects4(impl, subjectId, proc);\r
224 //              }\r
225                 \r
226 //        } else {\r
227 //              \r
228 //              impl.state.barrier.inc();\r
229 //            impl.state.barrier.dec(callerThread);\r
230 //              \r
231 //              queryProvider2.schedule(callerThread, new SessionTask(suggestSchedule) {\r
232 //      \r
233 //                      @Override\r
234 //                      public void run(int thread) {\r
235 //                              \r
236 //                      impl.state.barrier.inc(thread);\r
237 //                              impl.state.barrier.dec();\r
238 //\r
239 //                      if(info.isFunctional) {\r
240 //                              querySupport.getObjects4(impl.newAsync(thread), subjectId, proc);\r
241 //                      } else {\r
242 //                              querySupport.getObjects4(impl.newAsync(thread), subjectId, proc);\r
243 //                      }\r
244 //                              \r
245 //                      }\r
246 //                      \r
247 //                      @Override\r
248 //                      public String toString() {\r
249 //                              return "gaff8";\r
250 //                      }\r
251 //      \r
252 //              });\r
253 //              \r
254 //        }\r
255                 \r
256         }\r
257 \r
258         @Override\r
259         public <C> void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextMultiProcedure<C, Resource> procedure) {\r
260                 \r
261                 assert(subject != null);\r
262 \r
263                 final ForEachObjectContextProcedure<C> proc = (ForEachObjectContextProcedure<C>)procedure;\r
264                 final RelationInfo info = proc.info;\r
265 \r
266                 final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
267                 final int subjectId = ((ResourceImpl)subject).id;\r
268 \r
269 //              int callerThread = impl.callerThread;\r
270 //              int suggestSchedule = (subjectId>>16) & queryProvider2.THREAD_MASK;\r
271 \r
272 //              impl.inc();\r
273 \r
274                 if(info.isFunctional) {\r
275                         session.querySupport.getObjects4(impl, subjectId, context, proc);\r
276                 } else {\r
277                         session.querySupport.getObjects4(impl, subjectId, context, proc);\r
278                 }\r
279                 \r
280         }\r
281         \r
282         @Override\r
283         public <T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, final AsyncProcedure<T> procedure) {\r
284                 \r
285                 assert(subject != null);\r
286 \r
287         final ForPossibleRelatedValueProcedure<T> proc = (ForPossibleRelatedValueProcedure<T>)procedure;\r
288         final RelationInfo info = proc.info;\r
289         \r
290         final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
291         final int subjectId = ((ResourceImpl)subject).id;\r
292         \r
293 //        int callerThread = impl.callerThread;\r
294 //        int suggestSchedule = (subjectId>>16) & session.queryProvider2.THREAD_MASK;\r
295         \r
296 //        impl.inc();\r
297         \r
298 //        if(callerThread == suggestSchedule) {\r
299                 \r
300                 if(info.isFunctional) {\r
301                         getRelatedValue4(impl, subjectId, proc);\r
302                 } else {\r
303                         getRelatedValue4(impl, subjectId, proc);\r
304                 }\r
305                 \r
306 //        } else {\r
307 //              \r
308 //              impl.state.barrier.inc();\r
309 //            impl.state.barrier.dec(callerThread);\r
310 //              \r
311 //              queryProvider2.schedule(callerThread, new SessionTask(suggestSchedule) {\r
312 //      \r
313 //                      @Override\r
314 //                      public void run(int thread) {\r
315 //\r
316 //                      impl.state.barrier.inc(thread);\r
317 //                      impl.state.barrier.dec();\r
318 //                              \r
319 //                      if(info.isFunctional) {\r
320 //                              getRelatedValue4(impl.newAsync(thread), subjectId, proc);\r
321 //                      } else {\r
322 //                              getRelatedValue4(impl.newAsync(thread), subjectId, proc);\r
323 //                      }\r
324 //                              \r
325 //                      }\r
326 //                      \r
327 //                      @Override\r
328 //                      public String toString() {\r
329 //                              return "gaff11";\r
330 //                      }\r
331 //      \r
332 //              });\r
333 //              \r
334 //        }\r
335                 \r
336         }\r
337 \r
338         @Override\r
339         public <C, T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextProcedure<C, T> procedure) {\r
340                 \r
341                 assert(subject != null);\r
342 \r
343         final ForPossibleRelatedValueContextProcedure<C, T> proc = (ForPossibleRelatedValueContextProcedure<C, T>)procedure;\r
344         final RelationInfo info = proc.info;\r
345         \r
346         final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
347         final int subjectId = ((ResourceImpl)subject).id;\r
348         \r
349 //        int callerThread = impl.callerThread;\r
350 //        int suggestSchedule = (subjectId>>16) & session.queryProvider2.THREAD_MASK;\r
351         \r
352 //        impl.inc();\r
353                 \r
354         if(info.isFunctional) {\r
355                 getRelatedValue4(impl, subjectId, context, proc);\r
356         } else {\r
357                 getRelatedValue4(impl, subjectId, context, proc);\r
358         }\r
359                 \r
360         }\r
361         \r
362         @Override\r
363         public <T> void forPossibleType(final AsyncReadGraph graph, Resource subject, final AsyncProcedure<Resource> procedure) {\r
364                 \r
365         assert(subject != null);\r
366 \r
367         final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
368         final int subjectId = ((ResourceImpl)subject).id;\r
369 \r
370         try {\r
371                 \r
372                 final ClusterI cluster = session.clusterTable.getClusterByResourceKey(subjectId);\r
373                 if(!cluster.isLoaded()) {\r
374 \r
375 //                      impl.state.inc(0);\r
376                         \r
377                         session.queryProvider2.requestCluster(impl, cluster.getClusterId(), new Runnable() {\r
378                 \r
379                                         @Override\r
380                                         public void run() {\r
381 \r
382                                         try {\r
383 \r
384                                                         int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);\r
385                                                 procedure.execute(graph, new ResourceImpl(session.resourceSupport, result));\r
386 \r
387 //                                              impl.state.dec(0);                                              \r
388                                                 \r
389                                         } catch (DatabaseException e) {\r
390                                                 e.printStackTrace();\r
391                                         }\r
392                 \r
393                                         }\r
394                 \r
395                                 });\r
396                                 \r
397                 } else {\r
398 \r
399                         int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);\r
400                         procedure.execute(graph, new ResourceImpl(session.resourceSupport, result));\r
401                         \r
402                 }\r
403                 \r
404         } catch (DatabaseException e) {\r
405                 e.printStackTrace();\r
406         }\r
407         \r
408         \r
409                 \r
410         }\r
411 \r
412         @Override\r
413         public <C> void forPossibleDirectType(final AsyncReadGraph graph, Resource subject, final C context, final AsyncContextProcedure<C, Resource> procedure) {\r
414                 \r
415         assert(subject != null);\r
416 \r
417         final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
418         final int subjectId = ((ResourceImpl)subject).id;\r
419         \r
420         try {\r
421                 \r
422                 final ClusterI cluster = session.clusterTable.getClusterByResourceKey(subjectId);\r
423                 if(!cluster.isLoaded()) {\r
424 \r
425 //                      impl.state.inc(0);\r
426                         \r
427                         session.queryProvider2.requestCluster(impl, cluster.getClusterId(), new Runnable() {\r
428                 \r
429                                         @Override\r
430                                         public void run() {\r
431 \r
432                                         try {\r
433 \r
434                                                 ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subjectId, session.clusterTranslator);\r
435                                                 if(ClusterI.CompleteTypeEnum.InstanceOf == type) {\r
436                                                         int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);\r
437                                                         procedure.execute(graph, context, new ResourceImpl(session.resourceSupport, result));\r
438                                                 } else {\r
439                                                 procedure.execute(graph, context, null);\r
440                                                 }\r
441 \r
442 //                                              impl.state.dec(0);\r
443                                                 \r
444                                         } catch (DatabaseException e) {\r
445                                                 e.printStackTrace();\r
446                                         }\r
447                 \r
448                                         }\r
449                 \r
450                                 });\r
451                                 \r
452                 } else {\r
453 \r
454                         ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subjectId, session.clusterTranslator);\r
455                         if(ClusterI.CompleteTypeEnum.InstanceOf == type) {\r
456                                 int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);\r
457                                 procedure.execute(graph, context, new ResourceImpl(session.resourceSupport, result));\r
458                         } else {\r
459                         procedure.execute(graph, context, null);\r
460                         }\r
461                         \r
462                 }\r
463                 \r
464         } catch (DatabaseException e) {\r
465                 \r
466                 procedure.execute(graph, context, null);\r
467                 \r
468         } catch (Throwable t) {\r
469 \r
470                 t.printStackTrace();\r
471                 procedure.execute(graph, context, null);\r
472                 \r
473         }\r
474                 \r
475         }\r
476         \r
477         \r
478         private <C, T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
479                 \r
480                 int result = 0;\r
481                 \r
482                 final int predicate = procedure.predicateKey;\r
483 \r
484                 if(subject < 0) {\r
485 \r
486                         if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {\r
487                             SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>()  {\r
488 \r
489                                         @Override\r
490                                         public void run(ReadGraphImpl graph) {\r
491                                                 getRelatedValue4(graph, subject, context, procedure);\r
492                                         }\r
493                                         \r
494                                 });\r
495                                 return;\r
496                         }\r
497                         \r
498                         for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
499                 for (int id : g.getObjects(subject, predicate)) {\r
500                         if(result != 0) {\r
501                                 procedure.exception(graph, new DatabaseException("Multiple objects"));\r
502 //                              graph.dec();\r
503                                 return;\r
504                         } else {\r
505                                 result = id;\r
506                         }\r
507                 }\r
508                         }\r
509                         \r
510                         if(result == 0) {\r
511                                 \r
512                         procedure.exception(graph, new DatabaseException("No objects for " + subject ));\r
513 //                      graph.dec();\r
514                         return;\r
515                         \r
516                         } else {\r
517                                 \r
518                                 getValue4(graph, null, result, context, procedure);\r
519                                 return;\r
520                                 \r
521                         }\r
522                         \r
523                 } \r
524                 \r
525         final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);\r
526         if(!cluster.isLoaded()) {\r
527                 cluster.load(session.clusterTranslator, new Runnable() {\r
528 \r
529                                 @Override\r
530                                 public void run() {\r
531                                         getRelatedValue4(graph, subject, context, procedure);\r
532                                 }\r
533                         \r
534                 });\r
535                 return;\r
536         }\r
537         \r
538         if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {\r
539                         \r
540                         if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {\r
541                             SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>()  {\r
542 \r
543                                         @Override\r
544                                         public void run(ReadGraphImpl graph) {\r
545                                                 getRelatedValue4(graph, subject, context, procedure);\r
546                                         }\r
547                                         \r
548                                 });\r
549                                 return;\r
550                         }\r
551                 \r
552                         for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
553                 for (int id : g.getObjects(subject, predicate)) {\r
554                         if(result != 0) {\r
555                                 procedure.exception(graph, new DatabaseException("Multiple objects"));\r
556 //                              graph.dec();\r
557                                 return;\r
558                         } else {\r
559                                 result = id;\r
560                         }\r
561                 }\r
562                         }\r
563                         \r
564                         getRelatedDirectValue4(graph, cluster, subject, result, context, procedure);\r
565                         \r
566                 } else {\r
567                         \r
568                         getRelatedDirectValue4(graph, cluster, subject, 0, context, procedure);\r
569                         \r
570                 }\r
571                 \r
572         }\r
573         \r
574         private <T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {\r
575                 \r
576                 Object result = null;\r
577         \r
578                 if(subject < 0) {\r
579 \r
580                         if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {\r
581                             SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>()  {\r
582 \r
583                                         @Override\r
584                                         public void run(ReadGraphImpl graph) {\r
585                                                 getValue4(graph, containerCluster, subject, procedure);\r
586                                         }\r
587                                         \r
588                                 });\r
589                                 return;\r
590                         }\r
591                         \r
592                         for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
593                                 Object value = g.getValue(subject);\r
594                                 if(value != null) {\r
595                                         if(result != null) {\r
596                                                 procedure.exception(graph, new DatabaseException("Multiple values"));\r
597 //                                              graph.dec();\r
598                                                 return;\r
599                                         } else {\r
600                                                 result = value;\r
601                                         }\r
602                                 }\r
603                         }\r
604 \r
605                         procedure.execute(graph, (T)"name");\r
606 //                      graph.dec();\r
607                         return;\r
608 \r
609                 }\r
610                 \r
611                 ClusterImpl cluster = containerCluster;\r
612                 if(!containerCluster.contains(subject)) {\r
613                         cluster = session.clusterTable.getClusterByResourceKey(subject);\r
614                         if(!cluster.isLoaded()) {\r
615                                 cluster.load(session.clusterTranslator, new Runnable() {\r
616 \r
617                                         @Override\r
618                                         public void run() {\r
619                                                 getValue4(graph, containerCluster, subject, procedure);\r
620                                         }\r
621 \r
622                                 });\r
623                                 return;\r
624                         }\r
625                 }\r
626                 \r
627         if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {\r
628 \r
629                         if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {\r
630                             SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>()  {\r
631 \r
632                                         @Override\r
633                                         public void run(ReadGraphImpl graph) {\r
634                                                 getValue4(graph, containerCluster, subject, procedure);\r
635                                         }\r
636                                         \r
637                                 });\r
638                                 return;\r
639                         }\r
640                 \r
641                         for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
642                                 Object value = g.getValue(subject);\r
643                                 if(value != null) {\r
644                                         if(result != null) {\r
645                                                 procedure.exception(graph, new DatabaseException("Multiple values"));\r
646 //                                              graph.dec();\r
647                                                 return;\r
648                                         } else {\r
649                                                 result = value;\r
650                                         }\r
651                                 }\r
652                         }\r
653                         \r
654                         if(result != null) {\r
655                                 \r
656                                 procedure.execute(graph, (T)result);\r
657 //                              graph.state.barrier.dec();\r
658                                 \r
659                         } else {\r
660                                 \r
661                                 if(ClusterTypeEnum.SMALL == cluster.getType())\r
662                                         getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);\r
663                                 else \r
664                                         getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);\r
665                         }\r
666 \r
667                 } else {\r
668 \r
669                         if(ClusterTypeEnum.SMALL == cluster.getType())\r
670                                 getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);\r
671                         else \r
672                                 getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);\r
673 \r
674                 }\r
675         \r
676         }\r
677         \r
678         private <C, T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
679                 \r
680                 Object result = null;\r
681         \r
682                 if(subject < 0) {\r
683 \r
684                         if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {\r
685                             SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>()  {\r
686 \r
687                                         @Override\r
688                                         public void run(ReadGraphImpl graph) {\r
689                                                 getValue4(graph, containerCluster, subject, context, procedure);\r
690                                         }\r
691                                         \r
692                                 });\r
693                                 return;\r
694                         }\r
695                         \r
696                         for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
697                                 Object value = g.getValue(subject);\r
698                                 if(value != null) {\r
699                                         if(result != null) {\r
700                                                 procedure.exception(graph, new DatabaseException("Multiple values"));\r
701 //                                              graph.dec();\r
702                                                 return;\r
703                                         } else {\r
704                                                 result = value;\r
705                                         }\r
706                                 }\r
707                         }\r
708 \r
709                         procedure.execute(graph, context, (T)"name");\r
710 //                      graph.dec();\r
711                         return;\r
712 \r
713                 }\r
714                 \r
715                 ClusterImpl cluster = containerCluster;\r
716                 if(!containerCluster.contains(subject)) {\r
717                         cluster = session.clusterTable.getClusterByResourceKey(subject);\r
718                         if(!cluster.isLoaded()) {\r
719                                 cluster.load(session.clusterTranslator, new Runnable() {\r
720 \r
721                                         @Override\r
722                                         public void run() {\r
723                                                 getValue4(graph, containerCluster, subject, context, procedure);\r
724                                         }\r
725 \r
726                                 });\r
727                                 return;\r
728                         }\r
729                 }\r
730                 \r
731         if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {\r
732 \r
733                         if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {\r
734                             SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>()  {\r
735 \r
736                                         @Override\r
737                                         public void run(ReadGraphImpl graph) {\r
738                                                 getValue4(graph, containerCluster, subject, context, procedure);\r
739                                         }\r
740                                         \r
741                                 });\r
742                                 return;\r
743                         }\r
744                 \r
745                         for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
746                                 Object value = g.getValue(subject);\r
747                                 if(value != null) {\r
748                                         if(result != null) {\r
749                                                 procedure.exception(graph, new DatabaseException("Multiple values"));\r
750 //                                              graph.dec();\r
751                                                 return;\r
752                                         } else {\r
753                                                 result = value;\r
754                                         }\r
755                                 }\r
756                         }\r
757                         \r
758                         if(result != null) {\r
759                                 \r
760                                 procedure.execute(graph, context, (T)result);\r
761 //                              graph.state.barrier.dec();\r
762                                 \r
763                         } else {\r
764                                 \r
765                                 if(ClusterTypeEnum.SMALL == cluster.getType())\r
766                                         getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);\r
767                                 else \r
768                                         getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);\r
769                         }\r
770 \r
771                 } else {\r
772 \r
773                         if(ClusterTypeEnum.SMALL == cluster.getType())\r
774                                 getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);\r
775                         else \r
776                                 getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);\r
777 \r
778                 }\r
779         \r
780         }\r
781 \r
782         private <T> void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure<T> procedure) {\r
783 \r
784                 try {\r
785 \r
786                         int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);\r
787                         if(so == 0) {\r
788                                 if(result == 0) {\r
789                                         procedure.exception(graph, new DatabaseException("No objects " + subject + " " + procedure.predicateKey));\r
790 //                                      graph.dec();\r
791                                 } else {\r
792                                         getValue4(graph, cluster, result, procedure);\r
793                                 }\r
794                         } else {\r
795                                 if(result == 0) {\r
796                                         getValue4(graph, cluster, so, procedure);\r
797                                 } else {\r
798                                         procedure.exception(graph, new DatabaseException("Multiple objects"));\r
799 //                                      graph.dec();\r
800                                 }\r
801                         }\r
802 \r
803                 } catch (DatabaseException e) {\r
804                         e.printStackTrace();\r
805                 }\r
806                 \r
807         }\r
808 \r
809         private <C, T> void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
810 \r
811                 try {\r
812 \r
813                         int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);\r
814                         if(so == 0) {\r
815                                 if(result == 0) {\r
816                                         procedure.exception(graph, new DatabaseException("No objects " + subject + " " + procedure.predicateKey));\r
817 //                                      graph.dec();\r
818                                 } else {\r
819                                         getValue4(graph, cluster, result, context, procedure);\r
820                                 }\r
821                         } else {\r
822                                 if(result == 0) {\r
823                                         getValue4(graph, cluster, so, context, procedure);\r
824                                 } else {\r
825                                         procedure.exception(graph, new DatabaseException("Multiple objects"));\r
826 //                                      graph.dec();\r
827                                 }\r
828                         }\r
829 \r
830                 } catch (DatabaseException e) {\r
831                         e.printStackTrace();\r
832                 }\r
833                 \r
834         }\r
835         \r
836         public <T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {\r
837                 \r
838                 int result = 0;\r
839                 \r
840                 final int predicate = procedure.predicateKey;\r
841 \r
842                 if(subject < 0) {\r
843 \r
844                         if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {\r
845                             SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>()  {\r
846 \r
847                                         @Override\r
848                                         public void run(ReadGraphImpl graph) {\r
849                                                 getRelatedValue4(graph, subject, procedure);\r
850                                         }\r
851                                         \r
852                                 });\r
853                                 return;\r
854                         }\r
855                         \r
856                         for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
857                 for (int id : g.getObjects(subject, predicate)) {\r
858                         if(result != 0) {\r
859                                 procedure.exception(graph, new DatabaseException("Multiple objects"));\r
860 //                              graph.dec();\r
861                                 return;\r
862                         } else {\r
863                                 result = id;\r
864                         }\r
865                 }\r
866                         }\r
867                         \r
868                         if(result == 0) {\r
869                                 \r
870                         procedure.exception(graph, new DatabaseException("No objects for " + subject ));\r
871 //                      graph.dec();\r
872                         return;\r
873                         \r
874                         } else {\r
875                                 \r
876                                 getValue4(graph, null, result, procedure);\r
877                                 return;\r
878                                 \r
879                         }\r
880                         \r
881                 } \r
882                 \r
883         final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);\r
884         if(!cluster.isLoaded()) {\r
885                 cluster.load(session.clusterTranslator, new Runnable() {\r
886 \r
887                                 @Override\r
888                                 public void run() {\r
889                                         getRelatedValue4(graph, subject, procedure);\r
890                                 }\r
891                         \r
892                 });\r
893                 return;\r
894         }\r
895         \r
896         if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {\r
897                         \r
898                         if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {\r
899                             SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>()  {\r
900 \r
901                                         @Override\r
902                                         public void run(ReadGraphImpl graph) {\r
903                                                 getRelatedValue4(graph, subject, procedure);\r
904                                         }\r
905                                         \r
906                                 });\r
907                                 return;\r
908                         }\r
909                 \r
910                         for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
911                 for (int id : g.getObjects(subject, predicate)) {\r
912                         if(result != 0) {\r
913                                 procedure.exception(graph, new DatabaseException("Multiple objects"));\r
914 //                              graph.dec();\r
915                                 return;\r
916                         } else {\r
917                                 result = id;\r
918                         }\r
919                 }\r
920                         }\r
921                         \r
922                         getRelatedDirectValue4(graph, cluster, subject, result, procedure);\r
923                         \r
924                 } else {\r
925                         \r
926                         getRelatedDirectValue4(graph, cluster, subject, 0, procedure);\r
927                         \r
928                 }\r
929                 \r
930         }\r
931         \r
932         private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
933                 \r
934                 try {\r
935                         byte[] bytes = cluster.getValue(subject, session.clusterTranslator);\r
936                         T value = (T)utf(bytes);\r
937                         procedure.execute(graph, context, value);\r
938                 } catch (DatabaseException e) {\r
939                         procedure.execute(graph, context, null);\r
940                 }\r
941 \r
942 //              graph.dec();\r
943                 \r
944         }\r
945 \r
946         private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {\r
947                 \r
948                 try {\r
949                         byte[] bytes = cluster.getValue(subject, session.clusterTranslator);\r
950                         T value = (T)utf(bytes);\r
951                         procedure.execute(graph, value);\r
952                 } catch (DatabaseException e) {\r
953                         procedure.execute(graph, null);\r
954                 }\r
955 \r
956 //              graph.dec();\r
957                 \r
958         }\r
959 \r
960         private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
961                 \r
962                 try {\r
963                         byte[] bytes = cluster.getValue(subject, session.clusterTranslator);\r
964                         if(bytes == null) {\r
965                                 procedure.execute(graph, context, null);\r
966                         } else {\r
967                                 T value = (T)utf(bytes);\r
968                                 procedure.execute(graph, context, value);\r
969                         }\r
970                 } catch (DatabaseException e) {\r
971                         procedure.execute(graph, context, null);\r
972                 }\r
973 \r
974 //              graph.dec();\r
975                 \r
976         }\r
977         \r
978         private final char[] chars = new char[1024];\r
979         \r
980         private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {\r
981 \r
982                 ResourceTableSmall rt = cluster.resourceTable;\r
983                 ValueTableSmall vt = cluster.valueTable;\r
984 \r
985                 byte[] bs = vt.table;\r
986                 long[] ls = rt.table;\r
987 \r
988                 int index = ((subject&0xFFFF) << 1) - 1 + rt.offset;\r
989 \r
990                 int valueIndex = (int)(ls[index] >>> 24) & 0x3FFFFF + vt.offset;\r
991 \r
992                 int size = (int)bs[valueIndex++]-1;\r
993                 valueIndex++;\r
994                 for(int i=0;i<size;i++) {\r
995                         chars[i] = (char)bs[valueIndex++];\r
996                 }\r
997 \r
998                 T value = (T)new String(chars, 0, size);\r
999 \r
1000                 procedure.execute(graph, value);\r
1001 //              graph.dec();\r
1002                 \r
1003         }\r
1004 \r
1005         final private String utf(byte[] bytes) {\r
1006                 \r
1007                 if(bytes == null) return null;\r
1008                 \r
1009                 int index = 0;\r
1010                 int length = bytes[index++]&0xff; \r
1011                 if(length >= 0x80) {\r
1012                         if(length >= 0xc0) {\r
1013                                 if(length >= 0xe0) {\r
1014                                         if(length >= 0xf0) {\r
1015                                                 length &= 0x0f;\r
1016                                                 length += ((bytes[index++]&0xff)<<3);\r
1017                                                 length += ((bytes[index++]&0xff)<<11);\r
1018                                                 length += ((bytes[index++]&0xff)<<19);\r
1019                                                 length += 0x10204080;\r
1020                                         }\r
1021                                         else {\r
1022                                                 length &= 0x1f;\r
1023                                                 length += ((bytes[index++]&0xff)<<4);\r
1024                                                 length += ((bytes[index++]&0xff)<<12);\r
1025                                                 length += ((bytes[index++]&0xff)<<20);\r
1026                                                 length += 0x204080;\r
1027                                         }\r
1028                                 }\r
1029                                 else {\r
1030                                         length &= 0x3f;\r
1031                                         length += ((bytes[index++]&0xff)<<5);\r
1032                                         length += ((bytes[index++]&0xff)<<13);\r
1033                                         length += 0x4080;\r
1034                                 }\r
1035                         }\r
1036                         else {\r
1037                                 length &= 0x7f;\r
1038                                 length += ((bytes[index++]&0xff)<<6);\r
1039                                 length += 0x80;\r
1040                         }\r
1041                 }\r
1042                 \r
1043                 int i = 0;\r
1044                 int target = length+index;\r
1045                 while(index < target) {\r
1046                         int c = bytes[index++]&0xff;\r
1047                         if(c <= 0x7F) {\r
1048                                 chars[i++] = (char)(c&0x7F);\r
1049                         } else if (c > 0x07FF) {\r
1050                                 int c2 = bytes[index++]&0xff;\r
1051                                 int c3 = bytes[index++]&0xff;\r
1052                                 chars[i++] = (char)(((c&0xf)<<12) + ((c2&0x3f)<<6) + (c3&0x3f)); \r
1053                         } else {\r
1054                                 int c2 = bytes[index++]&0xff;\r
1055                                 chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f)); \r
1056                         }\r
1057                         \r
1058                         \r
1059 //                      if (!((c >= 0x0001) && (c <= 0x007F))) {\r
1060 //                      } else {\r
1061 //                      }\r
1062 //                      \r
1063 //                              if ((c >= 0x0001) && (c <= 0x007F)) {\r
1064 //                                      bytearr[byteIndex++] = (byte)( c );\r
1065 //                              } else if (c > 0x07FF) {\r
1066 //                                      bytearr[byteIndex++] = (byte)(0xE0 | ((c >> 12) & 0x0F));\r
1067 //                                      bytearr[byteIndex++] = (byte)(0x80 | ((c >>  6) & 0x3F));\r
1068 //                                      bytearr[byteIndex++] = (byte)(0x80 | ((c >>  0) & 0x3F));\r
1069 //                              } else {\r
1070 //                                      bytearr[byteIndex++] = (byte)(0xC0 | ((c >>  6) & 0x1F));\r
1071 //                                      bytearr[byteIndex++] = (byte)(0x80 | ((c >>  0) & 0x3F));\r
1072 //                              }\r
1073 //                      }\r
1074                         \r
1075                         \r
1076                 }\r
1077                 return new String(chars, 0, i);\r
1078         }\r
1079         \r
1080 }\r