-package fi.vtt.simantics.procore.internal;\r
-\r
-import org.simantics.db.AsyncReadGraph;\r
-import org.simantics.db.DirectStatements;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.RelationInfo;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;\r
-import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.impl.ClusterI;\r
-import org.simantics.db.impl.ClusterI.ClusterTypeEnum;\r
-import org.simantics.db.impl.ForEachObjectContextProcedure;\r
-import org.simantics.db.impl.ForEachObjectProcedure;\r
-import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;\r
-import org.simantics.db.impl.ForPossibleRelatedValueProcedure;\r
-import org.simantics.db.impl.ResourceImpl;\r
-import org.simantics.db.impl.TransientGraph;\r
-import org.simantics.db.impl.graph.ReadGraphImpl;\r
-import org.simantics.db.procedure.AsyncContextMultiProcedure;\r
-import org.simantics.db.procedure.AsyncContextProcedure;\r
-import org.simantics.db.procedure.AsyncMultiProcedure;\r
-import org.simantics.db.procedure.AsyncProcedure;\r
-import org.simantics.db.procedure.Procedure;\r
-import org.simantics.db.procedure.SyncProcedure;\r
-import org.simantics.db.procore.cluster.ClusterBig;\r
-import org.simantics.db.procore.cluster.ClusterImpl;\r
-import org.simantics.db.procore.cluster.ClusterSmall;\r
-import org.simantics.db.procore.cluster.ResourceTableSmall;\r
-import org.simantics.db.procore.cluster.ValueTableSmall;\r
-import org.simantics.db.request.AsyncRead;\r
-import org.simantics.db.service.DirectQuerySupport;\r
-import org.simantics.utils.datastructures.Callback;\r
-\r
-public class DirectQuerySupportImpl implements DirectQuerySupport {\r
-\r
- final private SessionImplSocket session;\r
- \r
- DirectQuerySupportImpl(SessionImplSocket session) {\r
- this.session = session;\r
- }\r
-\r
- @Override\r
- final public void forEachDirectPersistentStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {\r
- ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- impl.processor.forEachDirectStatement(impl, subject, procedure, true);\r
- }\r
-\r
- @Override\r
- final public void forEachDirectStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {\r
- ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- impl.processor.forEachDirectStatement(impl, subject, procedure, false);\r
- }\r
-\r
- @Override\r
- public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, SyncProcedure<DirectStatements> procedure) {\r
- forEachDirectStatement(graph, subject, new SyncToAsyncProcedure<DirectStatements>(procedure));\r
- }\r
-\r
- @Override\r
- public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure<DirectStatements> procedure) {\r
- ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- impl.processor.forEachDirectStatement(impl, subject, procedure);\r
- }\r
-\r
- @Override\r
- public void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure<RelationInfo> procedure) {\r
- ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- impl.processor.forRelationInfo(impl, subject, procedure);\r
- }\r
-\r
- @Override\r
- public void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure<RelationInfo> procedure) {\r
- forRelationInfo(graph, subject, new SyncToAsyncProcedure<RelationInfo>(procedure));\r
- }\r
-\r
- @Override\r
- public void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure<RelationInfo> procedure) {\r
- forRelationInfo(graph, subject, new NoneToAsyncProcedure<RelationInfo>(procedure));\r
- }\r
-\r
- @Override\r
- public AsyncMultiProcedure<Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncMultiProcedure<Resource> user) {\r
- \r
- try {\r
- RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {\r
-\r
- @Override\r
- public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {\r
- forRelationInfo(graph, relation, procedure);\r
- }\r
-\r
- @Override\r
- public int threadHash() {\r
- return hashCode();\r
- }\r
-\r
- @Override\r
- public int getFlags() {\r
- return 0;\r
- }\r
-\r
- });\r
- final int predicateKey = ((ResourceImpl)relation).id;\r
- return new ForEachObjectProcedure(predicateKey, info, session.queryProvider2, user);\r
- } catch (DatabaseException e) {\r
- return null;\r
- } \r
- \r
- }\r
-\r
- @Override\r
- public <C> AsyncContextMultiProcedure<C, Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncContextMultiProcedure<C, Resource> user) {\r
- \r
- try {\r
- RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {\r
-\r
- @Override\r
- public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {\r
- forRelationInfo(graph, relation, procedure);\r
- }\r
-\r
- @Override\r
- public int threadHash() {\r
- return hashCode();\r
- }\r
-\r
- @Override\r
- public int getFlags() {\r
- return 0;\r
- }\r
-\r
- });\r
- final int predicateKey = ((ResourceImpl)relation).id;\r
- return new ForEachObjectContextProcedure<C>(predicateKey, info, session.queryProvider2, user);\r
- } catch (DatabaseException e) {\r
- return null;\r
- } \r
- \r
- }\r
- \r
- @Override\r
- public <T> AsyncProcedure<T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncProcedure<T> user) {\r
- \r
- try {\r
- RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {\r
-\r
- @Override\r
- public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {\r
- forRelationInfo(graph, relation, procedure);\r
- }\r
-\r
- @Override\r
- public int threadHash() {\r
- return hashCode();\r
- }\r
-\r
- @Override\r
- public int getFlags() {\r
- return 0;\r
- }\r
-\r
- });\r
- final int predicateKey = ((ResourceImpl)relation).id;\r
- return new ForPossibleRelatedValueProcedure<T>(predicateKey, info, user);\r
- } catch (DatabaseException e) {\r
- return null;\r
- } \r
- \r
- }\r
-\r
- @Override\r
- public <C, T> AsyncContextProcedure<C, T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncContextProcedure<C, T> user) {\r
- \r
- try {\r
- RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {\r
-\r
- @Override\r
- public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {\r
- forRelationInfo(graph, relation, procedure);\r
- }\r
-\r
- @Override\r
- public int threadHash() {\r
- return hashCode();\r
- }\r
-\r
- @Override\r
- public int getFlags() {\r
- return 0;\r
- }\r
-\r
- });\r
- final int predicateKey = ((ResourceImpl)relation).id;\r
- return new ForPossibleRelatedValueContextProcedure<C, T>(predicateKey, info, user);\r
- } catch (DatabaseException e) {\r
- return null;\r
- } \r
- \r
- }\r
- \r
- @Override\r
- public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, final AsyncMultiProcedure<Resource> procedure) {\r
- \r
- assert(subject != null);\r
- \r
- final ForEachObjectProcedure proc = (ForEachObjectProcedure)procedure;\r
-// final RelationInfo info = proc.info;\r
-\r
- final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- final int subjectId = ((ResourceImpl)subject).id;\r
-\r
-// int callerThread = impl.callerThread;\r
-// int suggestSchedule = (subjectId>>16) & queryProvider2.THREAD_MASK;\r
- \r
-// impl.inc();\r
- \r
-// if(callerThread == suggestSchedule) {\r
- \r
-// if(info.isFunctional) {\r
-// querySupport.getObjects4(impl, subjectId, proc);\r
-// } else {\r
- session.querySupport.getObjects4(impl, subjectId, proc);\r
-// }\r
- \r
-// } else {\r
-// \r
-// impl.state.barrier.inc();\r
-// impl.state.barrier.dec(callerThread);\r
-// \r
-// queryProvider2.schedule(callerThread, new SessionTask(suggestSchedule) {\r
-// \r
-// @Override\r
-// public void run(int thread) {\r
-// \r
-// impl.state.barrier.inc(thread);\r
-// impl.state.barrier.dec();\r
-//\r
-// if(info.isFunctional) {\r
-// querySupport.getObjects4(impl.newAsync(thread), subjectId, proc);\r
-// } else {\r
-// querySupport.getObjects4(impl.newAsync(thread), subjectId, proc);\r
-// }\r
-// \r
-// }\r
-// \r
-// @Override\r
-// public String toString() {\r
-// return "gaff8";\r
-// }\r
-// \r
-// });\r
-// \r
-// }\r
- \r
- }\r
-\r
- @Override\r
- public <C> void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextMultiProcedure<C, Resource> procedure) {\r
- \r
- assert(subject != null);\r
-\r
- final ForEachObjectContextProcedure<C> proc = (ForEachObjectContextProcedure<C>)procedure;\r
- final RelationInfo info = proc.info;\r
-\r
- final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- final int subjectId = ((ResourceImpl)subject).id;\r
-\r
-// int callerThread = impl.callerThread;\r
-// int suggestSchedule = (subjectId>>16) & queryProvider2.THREAD_MASK;\r
-\r
-// impl.inc();\r
-\r
- if(info.isFunctional) {\r
- session.querySupport.getObjects4(impl, subjectId, context, proc);\r
- } else {\r
- session.querySupport.getObjects4(impl, subjectId, context, proc);\r
- }\r
- \r
- }\r
- \r
- @Override\r
- public <T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, final AsyncProcedure<T> procedure) {\r
- \r
- assert(subject != null);\r
-\r
- final ForPossibleRelatedValueProcedure<T> proc = (ForPossibleRelatedValueProcedure<T>)procedure;\r
- final RelationInfo info = proc.info;\r
- \r
- final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- final int subjectId = ((ResourceImpl)subject).id;\r
- \r
-// int callerThread = impl.callerThread;\r
-// int suggestSchedule = (subjectId>>16) & session.queryProvider2.THREAD_MASK;\r
- \r
-// impl.inc();\r
- \r
-// if(callerThread == suggestSchedule) {\r
- \r
- if(info.isFunctional) {\r
- getRelatedValue4(impl, subjectId, proc);\r
- } else {\r
- getRelatedValue4(impl, subjectId, proc);\r
- }\r
- \r
-// } else {\r
-// \r
-// impl.state.barrier.inc();\r
-// impl.state.barrier.dec(callerThread);\r
-// \r
-// queryProvider2.schedule(callerThread, new SessionTask(suggestSchedule) {\r
-// \r
-// @Override\r
-// public void run(int thread) {\r
-//\r
-// impl.state.barrier.inc(thread);\r
-// impl.state.barrier.dec();\r
-// \r
-// if(info.isFunctional) {\r
-// getRelatedValue4(impl.newAsync(thread), subjectId, proc);\r
-// } else {\r
-// getRelatedValue4(impl.newAsync(thread), subjectId, proc);\r
-// }\r
-// \r
-// }\r
-// \r
-// @Override\r
-// public String toString() {\r
-// return "gaff11";\r
-// }\r
-// \r
-// });\r
-// \r
-// }\r
- \r
- }\r
-\r
- @Override\r
- public <C, T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextProcedure<C, T> procedure) {\r
- \r
- assert(subject != null);\r
-\r
- final ForPossibleRelatedValueContextProcedure<C, T> proc = (ForPossibleRelatedValueContextProcedure<C, T>)procedure;\r
- final RelationInfo info = proc.info;\r
- \r
- final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- final int subjectId = ((ResourceImpl)subject).id;\r
- \r
-// int callerThread = impl.callerThread;\r
-// int suggestSchedule = (subjectId>>16) & session.queryProvider2.THREAD_MASK;\r
- \r
-// impl.inc();\r
- \r
- if(info.isFunctional) {\r
- getRelatedValue4(impl, subjectId, context, proc);\r
- } else {\r
- getRelatedValue4(impl, subjectId, context, proc);\r
- }\r
- \r
- }\r
- \r
- @Override\r
- public <T> void forPossibleType(final AsyncReadGraph graph, Resource subject, final AsyncProcedure<Resource> procedure) {\r
- \r
- assert(subject != null);\r
-\r
- final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- final int subjectId = ((ResourceImpl)subject).id;\r
-\r
- try {\r
- \r
- final ClusterI cluster = session.clusterTable.getClusterByResourceKey(subjectId);\r
- if(!cluster.isLoaded()) {\r
-\r
-// impl.state.inc(0);\r
- \r
- session.queryProvider2.requestCluster(impl, cluster.getClusterId(), new Runnable() {\r
- \r
- @Override\r
- public void run() {\r
-\r
- try {\r
-\r
- int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);\r
- procedure.execute(graph, new ResourceImpl(session.resourceSupport, result));\r
-\r
-// impl.state.dec(0); \r
- \r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- \r
- }\r
- \r
- });\r
- \r
- } else {\r
-\r
- int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);\r
- procedure.execute(graph, new ResourceImpl(session.resourceSupport, result));\r
- \r
- }\r
- \r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- \r
- \r
- \r
- }\r
-\r
- @Override\r
- public <C> void forPossibleDirectType(final AsyncReadGraph graph, Resource subject, final C context, final AsyncContextProcedure<C, Resource> procedure) {\r
- \r
- assert(subject != null);\r
-\r
- final ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- final int subjectId = ((ResourceImpl)subject).id;\r
- \r
- try {\r
- \r
- final ClusterI cluster = session.clusterTable.getClusterByResourceKey(subjectId);\r
- if(!cluster.isLoaded()) {\r
-\r
-// impl.state.inc(0);\r
- \r
- session.queryProvider2.requestCluster(impl, cluster.getClusterId(), new Runnable() {\r
- \r
- @Override\r
- public void run() {\r
-\r
- try {\r
-\r
- ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subjectId, session.clusterTranslator);\r
- if(ClusterI.CompleteTypeEnum.InstanceOf == type) {\r
- int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);\r
- procedure.execute(graph, context, new ResourceImpl(session.resourceSupport, result));\r
- } else {\r
- procedure.execute(graph, context, null);\r
- }\r
-\r
-// impl.state.dec(0);\r
- \r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- \r
- }\r
- \r
- });\r
- \r
- } else {\r
-\r
- ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subjectId, session.clusterTranslator);\r
- if(ClusterI.CompleteTypeEnum.InstanceOf == type) {\r
- int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);\r
- procedure.execute(graph, context, new ResourceImpl(session.resourceSupport, result));\r
- } else {\r
- procedure.execute(graph, context, null);\r
- }\r
- \r
- }\r
- \r
- } catch (DatabaseException e) {\r
- \r
- procedure.execute(graph, context, null);\r
- \r
- } catch (Throwable t) {\r
-\r
- t.printStackTrace();\r
- procedure.execute(graph, context, null);\r
- \r
- }\r
- \r
- }\r
- \r
- \r
- private <C, T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
- \r
- int result = 0;\r
- \r
- final int predicate = procedure.predicateKey;\r
-\r
- if(subject < 0) {\r
-\r
- if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {\r
- SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
-\r
- @Override\r
- public void run(ReadGraphImpl graph) {\r
- getRelatedValue4(graph, subject, context, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
- for (int id : g.getObjects(subject, predicate)) {\r
- if(result != 0) {\r
- procedure.exception(graph, new DatabaseException("Multiple objects"));\r
-// graph.dec();\r
- return;\r
- } else {\r
- result = id;\r
- }\r
- }\r
- }\r
- \r
- if(result == 0) {\r
- \r
- procedure.exception(graph, new DatabaseException("No objects for " + subject ));\r
-// graph.dec();\r
- return;\r
- \r
- } else {\r
- \r
- getValue4(graph, null, result, context, procedure);\r
- return;\r
- \r
- }\r
- \r
- } \r
- \r
- final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);\r
- if(!cluster.isLoaded()) {\r
- cluster.load(session.clusterTranslator, new Runnable() {\r
-\r
- @Override\r
- public void run() {\r
- getRelatedValue4(graph, subject, context, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {\r
- \r
- if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {\r
- SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
-\r
- @Override\r
- public void run(ReadGraphImpl graph) {\r
- getRelatedValue4(graph, subject, context, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
- for (int id : g.getObjects(subject, predicate)) {\r
- if(result != 0) {\r
- procedure.exception(graph, new DatabaseException("Multiple objects"));\r
-// graph.dec();\r
- return;\r
- } else {\r
- result = id;\r
- }\r
- }\r
- }\r
- \r
- getRelatedDirectValue4(graph, cluster, subject, result, context, procedure);\r
- \r
- } else {\r
- \r
- getRelatedDirectValue4(graph, cluster, subject, 0, context, procedure);\r
- \r
- }\r
- \r
- }\r
- \r
- private <T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {\r
- \r
- Object result = null;\r
- \r
- if(subject < 0) {\r
-\r
- if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {\r
- SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
-\r
- @Override\r
- public void run(ReadGraphImpl graph) {\r
- getValue4(graph, containerCluster, subject, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
- Object value = g.getValue(subject);\r
- if(value != null) {\r
- if(result != null) {\r
- procedure.exception(graph, new DatabaseException("Multiple values"));\r
-// graph.dec();\r
- return;\r
- } else {\r
- result = value;\r
- }\r
- }\r
- }\r
-\r
- procedure.execute(graph, (T)"name");\r
-// graph.dec();\r
- return;\r
-\r
- }\r
- \r
- ClusterImpl cluster = containerCluster;\r
- if(!containerCluster.contains(subject)) {\r
- cluster = session.clusterTable.getClusterByResourceKey(subject);\r
- if(!cluster.isLoaded()) {\r
- cluster.load(session.clusterTranslator, new Runnable() {\r
-\r
- @Override\r
- public void run() {\r
- getValue4(graph, containerCluster, subject, procedure);\r
- }\r
-\r
- });\r
- return;\r
- }\r
- }\r
- \r
- if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {\r
-\r
- if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {\r
- SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
-\r
- @Override\r
- public void run(ReadGraphImpl graph) {\r
- getValue4(graph, containerCluster, subject, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
- Object value = g.getValue(subject);\r
- if(value != null) {\r
- if(result != null) {\r
- procedure.exception(graph, new DatabaseException("Multiple values"));\r
-// graph.dec();\r
- return;\r
- } else {\r
- result = value;\r
- }\r
- }\r
- }\r
- \r
- if(result != null) {\r
- \r
- procedure.execute(graph, (T)result);\r
-// graph.state.barrier.dec();\r
- \r
- } else {\r
- \r
- if(ClusterTypeEnum.SMALL == cluster.getType())\r
- getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);\r
- else \r
- getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);\r
- }\r
-\r
- } else {\r
-\r
- if(ClusterTypeEnum.SMALL == cluster.getType())\r
- getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);\r
- else \r
- getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);\r
-\r
- }\r
- \r
- }\r
- \r
- private <C, T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
- \r
- Object result = null;\r
- \r
- if(subject < 0) {\r
-\r
- if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {\r
- SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
-\r
- @Override\r
- public void run(ReadGraphImpl graph) {\r
- getValue4(graph, containerCluster, subject, context, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
- Object value = g.getValue(subject);\r
- if(value != null) {\r
- if(result != null) {\r
- procedure.exception(graph, new DatabaseException("Multiple values"));\r
-// graph.dec();\r
- return;\r
- } else {\r
- result = value;\r
- }\r
- }\r
- }\r
-\r
- procedure.execute(graph, context, (T)"name");\r
-// graph.dec();\r
- return;\r
-\r
- }\r
- \r
- ClusterImpl cluster = containerCluster;\r
- if(!containerCluster.contains(subject)) {\r
- cluster = session.clusterTable.getClusterByResourceKey(subject);\r
- if(!cluster.isLoaded()) {\r
- cluster.load(session.clusterTranslator, new Runnable() {\r
-\r
- @Override\r
- public void run() {\r
- getValue4(graph, containerCluster, subject, context, procedure);\r
- }\r
-\r
- });\r
- return;\r
- }\r
- }\r
- \r
- if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {\r
-\r
- if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {\r
- SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
-\r
- @Override\r
- public void run(ReadGraphImpl graph) {\r
- getValue4(graph, containerCluster, subject, context, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
- Object value = g.getValue(subject);\r
- if(value != null) {\r
- if(result != null) {\r
- procedure.exception(graph, new DatabaseException("Multiple values"));\r
-// graph.dec();\r
- return;\r
- } else {\r
- result = value;\r
- }\r
- }\r
- }\r
- \r
- if(result != null) {\r
- \r
- procedure.execute(graph, context, (T)result);\r
-// graph.state.barrier.dec();\r
- \r
- } else {\r
- \r
- if(ClusterTypeEnum.SMALL == cluster.getType())\r
- getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);\r
- else \r
- getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);\r
- }\r
-\r
- } else {\r
-\r
- if(ClusterTypeEnum.SMALL == cluster.getType())\r
- getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);\r
- else \r
- getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);\r
-\r
- }\r
- \r
- }\r
-\r
- private <T> void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure<T> procedure) {\r
-\r
- try {\r
-\r
- int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);\r
- if(so == 0) {\r
- if(result == 0) {\r
- procedure.exception(graph, new DatabaseException("No objects " + subject + " " + procedure.predicateKey));\r
-// graph.dec();\r
- } else {\r
- getValue4(graph, cluster, result, procedure);\r
- }\r
- } else {\r
- if(result == 0) {\r
- getValue4(graph, cluster, so, procedure);\r
- } else {\r
- procedure.exception(graph, new DatabaseException("Multiple objects"));\r
-// graph.dec();\r
- }\r
- }\r
-\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- \r
- }\r
-\r
- 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
-\r
- try {\r
-\r
- int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);\r
- if(so == 0) {\r
- if(result == 0) {\r
- procedure.exception(graph, new DatabaseException("No objects " + subject + " " + procedure.predicateKey));\r
-// graph.dec();\r
- } else {\r
- getValue4(graph, cluster, result, context, procedure);\r
- }\r
- } else {\r
- if(result == 0) {\r
- getValue4(graph, cluster, so, context, procedure);\r
- } else {\r
- procedure.exception(graph, new DatabaseException("Multiple objects"));\r
-// graph.dec();\r
- }\r
- }\r
-\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- \r
- }\r
- \r
- public <T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {\r
- \r
- int result = 0;\r
- \r
- final int predicate = procedure.predicateKey;\r
-\r
- if(subject < 0) {\r
-\r
- if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {\r
- SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
-\r
- @Override\r
- public void run(ReadGraphImpl graph) {\r
- getRelatedValue4(graph, subject, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
- for (int id : g.getObjects(subject, predicate)) {\r
- if(result != 0) {\r
- procedure.exception(graph, new DatabaseException("Multiple objects"));\r
-// graph.dec();\r
- return;\r
- } else {\r
- result = id;\r
- }\r
- }\r
- }\r
- \r
- if(result == 0) {\r
- \r
- procedure.exception(graph, new DatabaseException("No objects for " + subject ));\r
-// graph.dec();\r
- return;\r
- \r
- } else {\r
- \r
- getValue4(graph, null, result, procedure);\r
- return;\r
- \r
- }\r
- \r
- } \r
- \r
- final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);\r
- if(!cluster.isLoaded()) {\r
- cluster.load(session.clusterTranslator, new Runnable() {\r
-\r
- @Override\r
- public void run() {\r
- getRelatedValue4(graph, subject, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {\r
- \r
- if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {\r
- SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
-\r
- @Override\r
- public void run(ReadGraphImpl graph) {\r
- getRelatedValue4(graph, subject, procedure);\r
- }\r
- \r
- });\r
- return;\r
- }\r
- \r
- for(TransientGraph g : session.virtualGraphServerSupport.providers) {\r
- for (int id : g.getObjects(subject, predicate)) {\r
- if(result != 0) {\r
- procedure.exception(graph, new DatabaseException("Multiple objects"));\r
-// graph.dec();\r
- return;\r
- } else {\r
- result = id;\r
- }\r
- }\r
- }\r
- \r
- getRelatedDirectValue4(graph, cluster, subject, result, procedure);\r
- \r
- } else {\r
- \r
- getRelatedDirectValue4(graph, cluster, subject, 0, procedure);\r
- \r
- }\r
- \r
- }\r
- \r
- private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
- \r
- try {\r
- byte[] bytes = cluster.getValue(subject, session.clusterTranslator);\r
- T value = (T)utf(bytes);\r
- procedure.execute(graph, context, value);\r
- } catch (DatabaseException e) {\r
- procedure.execute(graph, context, null);\r
- }\r
-\r
-// graph.dec();\r
- \r
- }\r
-\r
- private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {\r
- \r
- try {\r
- byte[] bytes = cluster.getValue(subject, session.clusterTranslator);\r
- T value = (T)utf(bytes);\r
- procedure.execute(graph, value);\r
- } catch (DatabaseException e) {\r
- procedure.execute(graph, null);\r
- }\r
-\r
-// graph.dec();\r
- \r
- }\r
-\r
- private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {\r
- \r
- try {\r
- byte[] bytes = cluster.getValue(subject, session.clusterTranslator);\r
- if(bytes == null) {\r
- procedure.execute(graph, context, null);\r
- } else {\r
- T value = (T)utf(bytes);\r
- procedure.execute(graph, context, value);\r
- }\r
- } catch (DatabaseException e) {\r
- procedure.execute(graph, context, null);\r
- }\r
-\r
-// graph.dec();\r
- \r
- }\r
- \r
- private final char[] chars = new char[1024];\r
- \r
- private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {\r
-\r
- ResourceTableSmall rt = cluster.resourceTable;\r
- ValueTableSmall vt = cluster.valueTable;\r
-\r
- byte[] bs = vt.table;\r
- long[] ls = rt.table;\r
-\r
- int index = ((subject&0xFFFF) << 1) - 1 + rt.offset;\r
-\r
- int valueIndex = (int)(ls[index] >>> 24) & 0x3FFFFF + vt.offset;\r
-\r
- int size = (int)bs[valueIndex++]-1;\r
- valueIndex++;\r
- for(int i=0;i<size;i++) {\r
- chars[i] = (char)bs[valueIndex++];\r
- }\r
-\r
- T value = (T)new String(chars, 0, size);\r
-\r
- procedure.execute(graph, value);\r
-// graph.dec();\r
- \r
- }\r
-\r
- final private String utf(byte[] bytes) {\r
- \r
- if(bytes == null) return null;\r
- \r
- int index = 0;\r
- int length = bytes[index++]&0xff; \r
- if(length >= 0x80) {\r
- if(length >= 0xc0) {\r
- if(length >= 0xe0) {\r
- if(length >= 0xf0) {\r
- length &= 0x0f;\r
- length += ((bytes[index++]&0xff)<<3);\r
- length += ((bytes[index++]&0xff)<<11);\r
- length += ((bytes[index++]&0xff)<<19);\r
- length += 0x10204080;\r
- }\r
- else {\r
- length &= 0x1f;\r
- length += ((bytes[index++]&0xff)<<4);\r
- length += ((bytes[index++]&0xff)<<12);\r
- length += ((bytes[index++]&0xff)<<20);\r
- length += 0x204080;\r
- }\r
- }\r
- else {\r
- length &= 0x3f;\r
- length += ((bytes[index++]&0xff)<<5);\r
- length += ((bytes[index++]&0xff)<<13);\r
- length += 0x4080;\r
- }\r
- }\r
- else {\r
- length &= 0x7f;\r
- length += ((bytes[index++]&0xff)<<6);\r
- length += 0x80;\r
- }\r
- }\r
- \r
- int i = 0;\r
- int target = length+index;\r
- while(index < target) {\r
- int c = bytes[index++]&0xff;\r
- if(c <= 0x7F) {\r
- chars[i++] = (char)(c&0x7F);\r
- } else if (c > 0x07FF) {\r
- int c2 = bytes[index++]&0xff;\r
- int c3 = bytes[index++]&0xff;\r
- chars[i++] = (char)(((c&0xf)<<12) + ((c2&0x3f)<<6) + (c3&0x3f)); \r
- } else {\r
- int c2 = bytes[index++]&0xff;\r
- chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f)); \r
- }\r
- \r
- \r
-// if (!((c >= 0x0001) && (c <= 0x007F))) {\r
-// } else {\r
-// }\r
-// \r
-// if ((c >= 0x0001) && (c <= 0x007F)) {\r
-// bytearr[byteIndex++] = (byte)( c );\r
-// } else if (c > 0x07FF) {\r
-// bytearr[byteIndex++] = (byte)(0xE0 | ((c >> 12) & 0x0F));\r
-// bytearr[byteIndex++] = (byte)(0x80 | ((c >> 6) & 0x3F));\r
-// bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F));\r
-// } else {\r
-// bytearr[byteIndex++] = (byte)(0xC0 | ((c >> 6) & 0x1F));\r
-// bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F));\r
-// }\r
-// }\r
- \r
- \r
- }\r
- return new String(chars, 0, i);\r
- }\r
- \r
-}\r
+package fi.vtt.simantics.procore.internal;
+
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.DirectStatements;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RelationInfo;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
+import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
+import org.simantics.db.exception.AssumptionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.NoSingleResultException;
+import org.simantics.db.impl.ClusterI;
+import org.simantics.db.impl.ClusterI.ClusterTypeEnum;
+import org.simantics.db.impl.ForEachObjectContextProcedure;
+import org.simantics.db.impl.ForEachObjectProcedure;
+import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;
+import org.simantics.db.impl.ForPossibleRelatedValueProcedure;
+import org.simantics.db.impl.ResourceImpl;
+import org.simantics.db.impl.TransientGraph;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.procedure.AsyncContextMultiProcedure;
+import org.simantics.db.procedure.AsyncContextProcedure;
+import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.procedure.Procedure;
+import org.simantics.db.procedure.SyncProcedure;
+import org.simantics.db.procore.cluster.ClusterBig;
+import org.simantics.db.procore.cluster.ClusterImpl;
+import org.simantics.db.procore.cluster.ClusterSmall;
+import org.simantics.db.procore.cluster.ResourceTableSmall;
+import org.simantics.db.procore.cluster.ValueTableSmall;
+import org.simantics.db.request.AsyncRead;
+import org.simantics.db.service.DirectQuerySupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DirectQuerySupportImpl implements DirectQuerySupport {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DirectQuerySupportImpl.class);
+
+ final private SessionImplSocket session;
+
+ DirectQuerySupportImpl(SessionImplSocket session) {
+ this.session = session;
+ }
+
+ @Override
+ final public void forEachDirectPersistentStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ impl.processor.forEachDirectStatement(impl, subject, procedure, true);
+ }
+
+ @Override
+ final public void forEachDirectStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ impl.processor.forEachDirectStatement(impl, subject, procedure, false);
+ }
+
+ @Override
+ public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, SyncProcedure<DirectStatements> procedure) {
+ forEachDirectStatement(graph, subject, new SyncToAsyncProcedure<DirectStatements>(procedure));
+ }
+
+ @Override
+ public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure<DirectStatements> procedure) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ impl.processor.forEachDirectStatement(impl, subject, procedure);
+ }
+
+ @Override
+ public void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure<RelationInfo> procedure) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ impl.processor.forRelationInfo(impl, subject, procedure);
+ }
+
+ @Override
+ public void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure<RelationInfo> procedure) {
+ forRelationInfo(graph, subject, new SyncToAsyncProcedure<RelationInfo>(procedure));
+ }
+
+ @Override
+ public void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure<RelationInfo> procedure) {
+ forRelationInfo(graph, subject, new NoneToAsyncProcedure<RelationInfo>(procedure));
+ }
+
+ @Override
+ public AsyncMultiProcedure<Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncMultiProcedure<Resource> user) {
+
+ try {
+ RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
+
+ @Override
+ public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
+ forRelationInfo(graph, relation, procedure);
+ }
+
+ @Override
+ public int threadHash() {
+ return hashCode();
+ }
+
+ @Override
+ public int getFlags() {
+ return 0;
+ }
+
+ });
+ final int predicateKey = ((ResourceImpl)relation).id;
+ return new ForEachObjectProcedure(predicateKey, info, session.queryProvider2, user);
+ } catch (DatabaseException e) {
+ return null;
+ }
+
+ }
+
+ @Override
+ public <C> AsyncContextMultiProcedure<C, Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncContextMultiProcedure<C, Resource> user) {
+
+ try {
+ RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
+
+ @Override
+ public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
+ forRelationInfo(graph, relation, procedure);
+ }
+
+ @Override
+ public int threadHash() {
+ return hashCode();
+ }
+
+ @Override
+ public int getFlags() {
+ return 0;
+ }
+
+ });
+ final int predicateKey = ((ResourceImpl)relation).id;
+ return new ForEachObjectContextProcedure<C>(predicateKey, info, session.queryProvider2, user);
+ } catch (DatabaseException e) {
+ return null;
+ }
+
+ }
+
+ @Override
+ public <T> AsyncProcedure<T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncProcedure<T> user) {
+
+ try {
+ RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
+
+ @Override
+ public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
+ forRelationInfo(graph, relation, procedure);
+ }
+
+ @Override
+ public int threadHash() {
+ return hashCode();
+ }
+
+ @Override
+ public int getFlags() {
+ return 0;
+ }
+
+ });
+ final int predicateKey = ((ResourceImpl)relation).id;
+ return new ForPossibleRelatedValueProcedure<T>(predicateKey, info, user);
+ } catch (DatabaseException e) {
+ return null;
+ }
+
+ }
+
+ @Override
+ public <C, T> AsyncContextProcedure<C, T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncContextProcedure<C, T> user) {
+
+ try {
+ RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
+
+ @Override
+ public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
+ forRelationInfo(graph, relation, procedure);
+ }
+
+ @Override
+ public int threadHash() {
+ return hashCode();
+ }
+
+ @Override
+ public int getFlags() {
+ return 0;
+ }
+
+ });
+ final int predicateKey = ((ResourceImpl)relation).id;
+ return new ForPossibleRelatedValueContextProcedure<C, T>(predicateKey, info, user);
+ } catch (DatabaseException e) {
+ return null;
+ }
+
+ }
+
+ @Override
+ public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, final AsyncMultiProcedure<Resource> procedure) {
+
+ assert(subject != null);
+
+ final ForEachObjectProcedure proc = (ForEachObjectProcedure)procedure;
+// final RelationInfo info = proc.info;
+
+ final ReadGraphImpl impl = (ReadGraphImpl)graph;
+ final int subjectId = ((ResourceImpl)subject).id;
+
+// int callerThread = impl.callerThread;
+// int suggestSchedule = (subjectId>>16) & queryProvider2.THREAD_MASK;
+
+// impl.inc();
+
+// if(callerThread == suggestSchedule) {
+
+// if(info.isFunctional) {
+// querySupport.getObjects4(impl, subjectId, proc);
+// } else {
+ session.querySupport.getObjects4(impl, subjectId, proc);
+// }
+
+// } else {
+//
+// impl.state.barrier.inc();
+// impl.state.barrier.dec(callerThread);
+//
+// queryProvider2.schedule(callerThread, new SessionTask(suggestSchedule) {
+//
+// @Override
+// public void run(int thread) {
+//
+// impl.state.barrier.inc(thread);
+// impl.state.barrier.dec();
+//
+// if(info.isFunctional) {
+// querySupport.getObjects4(impl.newAsync(thread), subjectId, proc);
+// } else {
+// querySupport.getObjects4(impl.newAsync(thread), subjectId, proc);
+// }
+//
+// }
+//
+// @Override
+// public String toString() {
+// return "gaff8";
+// }
+//
+// });
+//
+// }
+
+ }
+
+ @Override
+ public <C> void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextMultiProcedure<C, Resource> procedure) {
+
+ assert(subject != null);
+
+ final ForEachObjectContextProcedure<C> proc = (ForEachObjectContextProcedure<C>)procedure;
+ final RelationInfo info = proc.info;
+
+ final ReadGraphImpl impl = (ReadGraphImpl)graph;
+ final int subjectId = ((ResourceImpl)subject).id;
+
+// int callerThread = impl.callerThread;
+// int suggestSchedule = (subjectId>>16) & queryProvider2.THREAD_MASK;
+
+// impl.inc();
+
+ if(info.isFunctional) {
+ session.querySupport.getObjects4(impl, subjectId, context, proc);
+ } else {
+ session.querySupport.getObjects4(impl, subjectId, context, proc);
+ }
+
+ }
+
+ @Override
+ public <T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, final AsyncProcedure<T> procedure) {
+
+ assert(subject != null);
+
+ final ForPossibleRelatedValueProcedure<T> proc = (ForPossibleRelatedValueProcedure<T>)procedure;
+ final RelationInfo info = proc.info;
+
+ final ReadGraphImpl impl = (ReadGraphImpl)graph;
+ final int subjectId = ((ResourceImpl)subject).id;
+
+// int callerThread = impl.callerThread;
+// int suggestSchedule = (subjectId>>16) & session.queryProvider2.THREAD_MASK;
+
+// impl.inc();
+
+// if(callerThread == suggestSchedule) {
+
+ if(info.isFunctional) {
+ getRelatedValue4(impl, subjectId, proc);
+ } else {
+ getRelatedValue4(impl, subjectId, proc);
+ }
+
+// } else {
+//
+// impl.state.barrier.inc();
+// impl.state.barrier.dec(callerThread);
+//
+// queryProvider2.schedule(callerThread, new SessionTask(suggestSchedule) {
+//
+// @Override
+// public void run(int thread) {
+//
+// impl.state.barrier.inc(thread);
+// impl.state.barrier.dec();
+//
+// if(info.isFunctional) {
+// getRelatedValue4(impl.newAsync(thread), subjectId, proc);
+// } else {
+// getRelatedValue4(impl.newAsync(thread), subjectId, proc);
+// }
+//
+// }
+//
+// @Override
+// public String toString() {
+// return "gaff11";
+// }
+//
+// });
+//
+// }
+
+ }
+
+ @Override
+ public <C, T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextProcedure<C, T> procedure) {
+
+ assert(subject != null);
+
+ final ForPossibleRelatedValueContextProcedure<C, T> proc = (ForPossibleRelatedValueContextProcedure<C, T>)procedure;
+ final RelationInfo info = proc.info;
+
+ final ReadGraphImpl impl = (ReadGraphImpl)graph;
+ final int subjectId = ((ResourceImpl)subject).id;
+
+// int callerThread = impl.callerThread;
+// int suggestSchedule = (subjectId>>16) & session.queryProvider2.THREAD_MASK;
+
+// impl.inc();
+
+ if(info.isFunctional) {
+ getRelatedValue4(impl, subjectId, context, proc);
+ } else {
+ getRelatedValue4(impl, subjectId, context, proc);
+ }
+
+ }
+
+ @Override
+ public <T> void forPossibleType(final AsyncReadGraph graph, Resource subject, final AsyncProcedure<Resource> procedure) {
+
+ assert(subject != null);
+
+ final ReadGraphImpl impl = (ReadGraphImpl)graph;
+ final int subjectId = ((ResourceImpl)subject).id;
+
+ try {
+
+ final ClusterI cluster = session.clusterTable.getClusterByResourceKey(subjectId);
+ if(!cluster.isLoaded()) {
+
+// impl.state.inc(0);
+
+ session.queryProvider2.requestCluster(impl, cluster.getClusterId(), new Runnable() {
+
+ @Override
+ public void run() {
+
+ try {
+
+ int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);
+ procedure.execute(graph, new ResourceImpl(session.resourceSupport, result));
+
+// impl.state.dec(0);
+
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ });
+
+ } else {
+
+ int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);
+ procedure.execute(graph, new ResourceImpl(session.resourceSupport, result));
+
+ }
+
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+
+
+
+ }
+
+ @Override
+ public <C> void forPossibleDirectType(final AsyncReadGraph graph, Resource subject, final C context, final AsyncContextProcedure<C, Resource> procedure) {
+
+ assert(subject != null);
+
+ final ReadGraphImpl impl = (ReadGraphImpl)graph;
+ final int subjectId = ((ResourceImpl)subject).id;
+
+ try {
+
+ final ClusterI cluster = session.clusterTable.getClusterByResourceKey(subjectId);
+ if(!cluster.isLoaded()) {
+
+// impl.state.inc(0);
+
+ session.queryProvider2.requestCluster(impl, cluster.getClusterId(), new Runnable() {
+
+ @Override
+ public void run() {
+
+ try {
+
+ ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subjectId, session.clusterTranslator);
+ if(ClusterI.CompleteTypeEnum.InstanceOf == type) {
+ int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);
+ procedure.execute(graph, context, new ResourceImpl(session.resourceSupport, result));
+ } else {
+ procedure.execute(graph, context, null);
+ }
+
+// impl.state.dec(0);
+
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ });
+
+ } else {
+
+ ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subjectId, session.clusterTranslator);
+ if(ClusterI.CompleteTypeEnum.InstanceOf == type) {
+ int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);
+ procedure.execute(graph, context, new ResourceImpl(session.resourceSupport, result));
+ } else {
+ procedure.execute(graph, context, null);
+ }
+
+ }
+
+ } catch (DatabaseException e) {
+
+ procedure.execute(graph, context, null);
+
+ } catch (Throwable t) {
+
+ t.printStackTrace();
+ procedure.execute(graph, context, null);
+
+ }
+
+ }
+
+
+ private <C, T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
+
+ int result = 0;
+
+ final int predicate = procedure.predicateKey;
+
+ if(subject < 0) {
+
+ if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
+ SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
+ g -> getRelatedValue4(g, subject, context, procedure)
+ );
+ return;
+ }
+
+ for(TransientGraph g : session.virtualGraphServerSupport.providers) {
+ for (int id : g.getObjects(subject, predicate)) {
+ if(result != 0) {
+ procedure.exception(graph, new DatabaseException("Multiple objects"));
+// graph.dec();
+ return;
+ } else {
+ result = id;
+ }
+ }
+ }
+
+ if(result == 0) {
+
+ procedure.exception(graph, new DatabaseException("No objects for " + subject ));
+// graph.dec();
+ return;
+
+ } else {
+
+ getValue4(graph, null, result, context, procedure);
+ return;
+
+ }
+
+ }
+
+ final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);
+ if(!cluster.isLoaded()) {
+ cluster.load(session.clusterTranslator, () -> getRelatedValue4(graph, subject, context, procedure));
+ return;
+ }
+
+ if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
+
+ if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
+ SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
+ g -> getRelatedValue4(g, subject, context, procedure)
+ );
+ return;
+ }
+
+ for(TransientGraph g : session.virtualGraphServerSupport.providers) {
+ for (int id : g.getObjects(subject, predicate)) {
+ if(result != 0) {
+ procedure.exception(graph, new DatabaseException("Multiple objects"));
+// graph.dec();
+ return;
+ } else {
+ result = id;
+ }
+ }
+ }
+
+ getRelatedDirectValue4(graph, cluster, subject, result, context, procedure);
+
+ } else {
+
+ getRelatedDirectValue4(graph, cluster, subject, 0, context, procedure);
+
+ }
+
+ }
+
+ private <T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
+
+ Object result = null;
+
+ if(subject < 0) {
+
+ if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
+ SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
+ g -> getValue4(g, containerCluster, subject, procedure)
+ );
+ return;
+ }
+
+ for(TransientGraph g : session.virtualGraphServerSupport.providers) {
+ Object value = g.getValue(subject);
+ if(value != null) {
+ if(result != null) {
+ procedure.exception(graph, new DatabaseException("Multiple values"));
+// graph.dec();
+ return;
+ } else {
+ result = value;
+ }
+ }
+ }
+
+ procedure.execute(graph, (T)"name");
+// graph.dec();
+ return;
+
+ }
+
+ ClusterImpl cluster = containerCluster;
+ if(!containerCluster.contains(subject)) {
+ cluster = session.clusterTable.getClusterByResourceKey(subject);
+ if(!cluster.isLoaded()) {
+ cluster.load(session.clusterTranslator, new Runnable() {
+
+ @Override
+ public void run() {
+ getValue4(graph, containerCluster, subject, procedure);
+ }
+
+ });
+ return;
+ }
+ }
+
+ if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
+
+ if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
+ SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
+ g -> getValue4(g, containerCluster, subject, procedure)
+ );
+ return;
+ }
+
+ for(TransientGraph g : session.virtualGraphServerSupport.providers) {
+ Object value = g.getValue(subject);
+ if(value != null) {
+ if(result != null) {
+ procedure.exception(graph, new DatabaseException("Multiple values"));
+// graph.dec();
+ return;
+ } else {
+ result = value;
+ }
+ }
+ }
+
+ if(result != null) {
+
+ procedure.execute(graph, (T)result);
+// graph.state.barrier.dec();
+
+ } else {
+
+ if(ClusterTypeEnum.SMALL == cluster.getType())
+ getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);
+ else
+ getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);
+ }
+
+ } else {
+
+ if(ClusterTypeEnum.SMALL == cluster.getType())
+ getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);
+ else
+ getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);
+
+ }
+
+ }
+
+ private <C, T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
+
+ Object result = null;
+
+ if(subject < 0) {
+
+ if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
+ SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
+ g -> getValue4(g, containerCluster, subject, context, procedure)
+ );
+ return;
+ }
+
+ for(TransientGraph g : session.virtualGraphServerSupport.providers) {
+ Object value = g.getValue(subject);
+ if(value != null) {
+ if(result != null) {
+ procedure.exception(graph, new DatabaseException("Multiple values"));
+// graph.dec();
+ return;
+ } else {
+ result = value;
+ }
+ }
+ }
+
+ procedure.execute(graph, context, (T)"name");
+// graph.dec();
+ return;
+
+ }
+
+ ClusterImpl cluster = containerCluster;
+ if(!containerCluster.contains(subject)) {
+ cluster = session.clusterTable.getClusterByResourceKey(subject);
+ if(!cluster.isLoaded()) {
+ cluster.load(session.clusterTranslator, new Runnable() {
+
+ @Override
+ public void run() {
+ getValue4(graph, containerCluster, subject, context, procedure);
+ }
+
+ });
+ return;
+ }
+ }
+
+ if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
+
+ if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
+ SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
+ g -> getValue4(g, containerCluster, subject, context, procedure)
+ );
+ return;
+ }
+
+ for(TransientGraph g : session.virtualGraphServerSupport.providers) {
+ Object value = g.getValue(subject);
+ if(value != null) {
+ if(result != null) {
+ procedure.exception(graph, new DatabaseException("Multiple values"));
+// graph.dec();
+ return;
+ } else {
+ result = value;
+ }
+ }
+ }
+
+ if(result != null) {
+
+ procedure.execute(graph, context, (T)result);
+// graph.state.barrier.dec();
+
+ } else {
+
+ if(ClusterTypeEnum.SMALL == cluster.getType())
+ getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);
+ else
+ getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);
+ }
+
+ } else {
+
+ if(ClusterTypeEnum.SMALL == cluster.getType())
+ getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);
+ else
+ getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);
+
+ }
+
+ }
+
+ private <T> void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure<T> procedure) {
+
+ try {
+
+ int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);
+ if(so == 0) {
+ if(result == 0) {
+ procedure.exception(graph, new DatabaseException("No objects " + subject + " " + procedure.predicateKey));
+// graph.dec();
+ } else {
+ getValue4(graph, cluster, result, procedure);
+ }
+ } else {
+ if(result == 0) {
+ getValue4(graph, cluster, so, procedure);
+ } else {
+ procedure.exception(graph, new DatabaseException("Multiple objects"));
+// graph.dec();
+ }
+ }
+
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ 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) {
+
+ try {
+
+ int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);
+ if(so == 0) {
+ if(result == 0) {
+ procedure.exception(graph, new NoSingleResultException("No objects " + subject + " " + procedure.predicateKey, result));
+// graph.dec();
+ } else {
+ getValue4(graph, cluster, result, context, procedure);
+ }
+ } else {
+ if(result == 0) {
+ getValue4(graph, cluster, so, context, procedure);
+ } else {
+ procedure.exception(graph, new NoSingleResultException("Multiple objects for " + subject + " " + procedure.predicateKey, result));
+// graph.dec();
+ }
+ }
+
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not compute related value for subject {} with predicate {}", subject, procedure.predicateKey);
+ }
+
+ }
+
+ public <T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
+
+ int result = 0;
+
+ final int predicate = procedure.predicateKey;
+
+ if(subject < 0) {
+
+ if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
+ SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
+ g -> getRelatedValue4(g, subject, procedure)
+ );
+ return;
+ }
+
+ for(TransientGraph g : session.virtualGraphServerSupport.providers) {
+ for (int id : g.getObjects(subject, predicate)) {
+ if(result != 0) {
+ procedure.exception(graph, new DatabaseException("Multiple objects"));
+// graph.dec();
+ return;
+ } else {
+ result = id;
+ }
+ }
+ }
+
+ if(result == 0) {
+
+ procedure.exception(graph, new DatabaseException("No objects for " + subject ));
+// graph.dec();
+ return;
+
+ } else {
+
+ getValue4(graph, null, result, procedure);
+ return;
+
+ }
+
+ }
+
+ final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);
+ if(!cluster.isLoaded()) {
+ cluster.load(session.clusterTranslator, new Runnable() {
+
+ @Override
+ public void run() {
+ getRelatedValue4(graph, subject, procedure);
+ }
+
+ });
+ return;
+ }
+
+ if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
+
+ if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
+ SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
+ g -> getRelatedValue4(graph, subject, procedure)
+ );
+ return;
+ }
+
+ for(TransientGraph g : session.virtualGraphServerSupport.providers) {
+ for (int id : g.getObjects(subject, predicate)) {
+ if(result != 0) {
+ procedure.exception(graph, new DatabaseException("Multiple objects"));
+// graph.dec();
+ return;
+ } else {
+ result = id;
+ }
+ }
+ }
+
+ getRelatedDirectValue4(graph, cluster, subject, result, procedure);
+
+ } else {
+
+ getRelatedDirectValue4(graph, cluster, subject, 0, procedure);
+
+ }
+
+ }
+
+ private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
+
+ try {
+ byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
+ T value = (T)utf(bytes);
+ procedure.execute(graph, context, value);
+ } catch (DatabaseException e) {
+ procedure.execute(graph, context, null);
+ }
+
+// graph.dec();
+
+ }
+
+ private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
+
+ try {
+ byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
+ T value = (T)utf(bytes);
+ procedure.execute(graph, value);
+ } catch (DatabaseException e) {
+ procedure.execute(graph, null);
+ }
+
+// graph.dec();
+
+ }
+
+ private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
+
+ try {
+ byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
+ if(bytes == null) {
+ procedure.execute(graph, context, null);
+ } else {
+ T value = (T)utf(bytes);
+ procedure.execute(graph, context, value);
+ }
+ } catch (DatabaseException e) {
+ procedure.execute(graph, context, null);
+ }
+
+// graph.dec();
+
+ }
+
+ private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
+
+ ResourceTableSmall rt = cluster.resourceTable;
+ ValueTableSmall vt = cluster.valueTable;
+
+ byte[] bs = vt.table;
+ long[] ls = rt.table;
+
+ int index = ((subject&0xFFFF) << 1) - 1 + rt.offset;
+
+ int valueIndex = (int)(ls[index] >>> 24) & 0x3FFFFF + vt.offset;
+
+ int size = (int)bs[valueIndex++]-1;
+ char[] chars = new char[size];
+ valueIndex++;
+ for(int i=0;i<size;i++) {
+ chars[i] = (char)bs[valueIndex++];
+ }
+
+ T value = (T)new String(chars);
+
+ procedure.execute(graph, value);
+// graph.dec();
+
+ }
+
+ final private String utf(byte[] bytes) throws AssumptionException {
+
+ if(bytes == null) return null;
+
+ // Read databoard int32 using Length encoding
+ // https://dev.simantics.org/index.php/Databoard_Specification#Length
+ int index = 0;
+ int length = bytes[index++]&0xff;
+ if(length >= 0x80) {
+ if(length >= 0xc0) {
+ if(length >= 0xe0) {
+ if(length >= 0xf0) {
+ length &= 0x0f;
+ length += ((bytes[index++]&0xff)<<3);
+ length += ((bytes[index++]&0xff)<<11);
+ length += ((bytes[index++]&0xff)<<19);
+ length += 0x10204080;
+ }
+ else {
+ length &= 0x1f;
+ length += ((bytes[index++]&0xff)<<4);
+ length += ((bytes[index++]&0xff)<<12);
+ length += ((bytes[index++]&0xff)<<20);
+ length += 0x204080;
+ }
+ }
+ else {
+ length &= 0x3f;
+ length += ((bytes[index++]&0xff)<<5);
+ length += ((bytes[index++]&0xff)<<13);
+ length += 0x4080;
+ }
+ }
+ else {
+ length &= 0x7f;
+ length += ((bytes[index++]&0xff)<<6);
+ length += 0x80;
+ }
+ }
+
+ // Copied from DataInputStream
+ int utflen = length;
+ char[] chararr = new char[utflen];
+
+ int c, char2, char3;
+ int count = index;
+ int target = index + length;
+ int chararr_count=0;
+
+ while (count < target) {
+ c = (int) bytes[count] & 0xff;
+ if (c > 127) break;
+ count++;
+ chararr[chararr_count++]=(char)c;
+ }
+
+ while (count < target) {
+ c = (int) bytes[count] & 0xff;
+ switch (c >> 4) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+ /* 0xxxxxxx*/
+ count++;
+ chararr[chararr_count++]=(char)c;
+ break;
+ case 12: case 13:
+ /* 110x xxxx 10xx xxxx*/
+ count += 2;
+ if (count > target)
+ throw new AssumptionException(
+ "malformed input: partial character at end (" + (count-index) + " > " + utflen + ")");
+ char2 = (int) bytes[count-1];
+ if ((char2 & 0xC0) != 0x80)
+ throw new AssumptionException(
+ "malformed input around byte " + count);
+ chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
+ (char2 & 0x3F));
+ break;
+ case 14:
+ /* 1110 xxxx 10xx xxxx 10xx xxxx */
+ count += 3;
+ if (count > target)
+ throw new AssumptionException(
+ "malformed input: partial character at end (" + (count-index) + " > " + utflen + ")");
+ char2 = (int) bytes[count-2];
+ char3 = (int) bytes[count-1];
+ if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
+ throw new AssumptionException(
+ "malformed input around byte " + (count-1));
+ chararr[chararr_count++]=(char)(((c & 0x0F) << 12) |
+ ((char2 & 0x3F) << 6) |
+ ((char3 & 0x3F) << 0));
+ break;
+ default:
+ /* 10xx xxxx, 1111 xxxx */
+ throw new AssumptionException(
+ "malformed input around byte " + count);
+ }
+ }
+
+ // The number of chars produced may be less than utflen
+ return new String(chararr, 0, chararr_count);
+ }
+
+}