X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.procore%2Fsrc%2Ffi%2Fvtt%2Fsimantics%2Fprocore%2Finternal%2FDirectQuerySupportImpl.java;h=fb6a1f7638e6716e283e3d654775ff665092dc36;hp=0b640861e1d6af93255b25114c429b2f374ce54f;hb=HEAD;hpb=2bbecd30ee49d821a0abeaf6d417b5a7fdbe015f diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java index 0b640861e..fb6a1f763 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java @@ -1,12 +1,9 @@ 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; @@ -19,22 +16,26 @@ 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.SyncContextMultiProcedure; +import org.simantics.db.procedure.SyncContextProcedure; +import org.simantics.db.procedure.SyncMultiProcedure; 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; +/** + * Note that the direct value retrieval in this implementation only supports + * String-type literals - nothing else! + * + * This implementation is mainly intended for optimizing database indexing + * performance. + */ public class DirectQuerySupportImpl implements DirectQuerySupport { private static final Logger LOGGER = LoggerFactory.getLogger(DirectQuerySupportImpl.class); @@ -46,166 +47,61 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } @Override - final public void forEachDirectPersistentStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure procedure) { + final public DirectStatements getDirectPersistentStatements(ReadGraph graph, final Resource subject) { ReadGraphImpl impl = (ReadGraphImpl)graph; - impl.processor.forEachDirectStatement(impl, subject, procedure, true); + return impl.processor.getDirectStatements(impl, subject, true); } @Override - final public void forEachDirectStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure procedure) { + final public DirectStatements getDirectStatements(ReadGraph graph, final Resource subject) { ReadGraphImpl impl = (ReadGraphImpl)graph; - impl.processor.forEachDirectStatement(impl, subject, procedure, false); + return impl.processor.getDirectStatements(impl, subject, false); } @Override - public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, SyncProcedure procedure) { - forEachDirectStatement(graph, subject, new SyncToAsyncProcedure(procedure)); - } - - @Override - public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure procedure) { + public RelationInfo getRelationInfo(ReadGraph graph, Resource subject) throws DatabaseException { ReadGraphImpl impl = (ReadGraphImpl)graph; - impl.processor.forEachDirectStatement(impl, subject, procedure); + return impl.processor.getRelationInfo(impl, subject); } @Override - public void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure procedure) { - ReadGraphImpl impl = (ReadGraphImpl)graph; - impl.processor.forRelationInfo(impl, subject, procedure); - } + public SyncMultiProcedure compileForEachObject(ReadGraph graph, final Resource relation, SyncMultiProcedure user) throws DatabaseException { - @Override - public void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure procedure) { - forRelationInfo(graph, subject, new SyncToAsyncProcedure(procedure)); - } + RelationInfo info = getRelationInfo(graph, relation); + final int predicateKey = ((ResourceImpl)relation).id; + return new ForEachObjectProcedure(predicateKey, info, session.queryProvider2, user); - @Override - public void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure procedure) { - forRelationInfo(graph, subject, new NoneToAsyncProcedure(procedure)); } @Override - public AsyncMultiProcedure compileForEachObject(ReadGraph graph, final Resource relation, AsyncMultiProcedure user) { - - try { - RelationInfo info = graph.syncRequest(new AsyncRead() { + public SyncContextMultiProcedure compileForEachObject(ReadGraph graph, final Resource relation, SyncContextMultiProcedure user) throws DatabaseException { - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { - forRelationInfo(graph, relation, procedure); - } - - @Override - public int threadHash() { - return hashCode(); - } + RelationInfo info = getRelationInfo(graph, relation); + final int predicateKey = ((ResourceImpl)relation).id; + return new ForEachObjectContextProcedure(predicateKey, info, session.queryProvider2, user); - @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 AsyncContextMultiProcedure compileForEachObject(ReadGraph graph, final Resource relation, AsyncContextMultiProcedure user) { - - try { - RelationInfo info = graph.syncRequest(new AsyncRead() { - - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { - forRelationInfo(graph, relation, procedure); - } + public SyncProcedure compilePossibleRelatedValue(ReadGraph graph, final Resource relation, SyncProcedure user) throws DatabaseException { - @Override - public int threadHash() { - return hashCode(); - } + RelationInfo info = getRelationInfo(graph, relation); + final int predicateKey = ((ResourceImpl)relation).id; + return new ForPossibleRelatedValueProcedure(predicateKey, info, user); - @Override - public int getFlags() { - return 0; - } - - }); - final int predicateKey = ((ResourceImpl)relation).id; - return new ForEachObjectContextProcedure(predicateKey, info, session.queryProvider2, user); - } catch (DatabaseException e) { - return null; - } - - } - - @Override - public AsyncProcedure compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncProcedure user) { - - try { - RelationInfo info = graph.syncRequest(new AsyncRead() { - - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure 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(predicateKey, info, user); - } catch (DatabaseException e) { - return null; - } - } @Override - public AsyncContextProcedure compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncContextProcedure user) { - - try { - RelationInfo info = graph.syncRequest(new AsyncRead() { + public SyncContextProcedure compilePossibleRelatedValue(ReadGraph graph, final Resource relation, SyncContextProcedure user) throws DatabaseException { - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { - forRelationInfo(graph, relation, procedure); - } - - @Override - public int threadHash() { - return hashCode(); - } + RelationInfo info = getRelationInfo(graph, relation); + final int predicateKey = ((ResourceImpl)relation).id; + return new ForPossibleRelatedValueContextProcedure(predicateKey, info, user); - @Override - public int getFlags() { - return 0; - } - - }); - final int predicateKey = ((ResourceImpl)relation).id; - return new ForPossibleRelatedValueContextProcedure(predicateKey, info, user); - } catch (DatabaseException e) { - return null; - } - } - + @Override - public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, final AsyncMultiProcedure procedure) { + public void forEachObjectCompiled(ReadGraph graph, Resource subject, final SyncMultiProcedure procedure) { assert(subject != null); @@ -261,7 +157,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } @Override - public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextMultiProcedure procedure) { + public void forEachObjectCompiled(ReadGraph graph, Resource subject, C context, final SyncContextMultiProcedure procedure) { assert(subject != null); @@ -283,14 +179,13 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } } - + @Override - public void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, final AsyncProcedure procedure) { + public void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, final SyncProcedure procedure) { assert(subject != null); final ForPossibleRelatedValueProcedure proc = (ForPossibleRelatedValueProcedure)procedure; - final RelationInfo info = proc.info; final ReadGraphImpl impl = (ReadGraphImpl)graph; final int subjectId = ((ResourceImpl)subject).id; @@ -302,11 +197,24 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { // if(callerThread == suggestSchedule) { - if(info.isFunctional) { - getRelatedValue4(impl, subjectId, proc); - } else { - getRelatedValue4(impl, subjectId, proc); +// if(proc.info.isFunctional) { + try { + T result = getRelatedValue4(impl, subjectId, proc); + try { + proc.execute(graph, result); + } catch (DatabaseException e2) { + LOGGER.error("Unexpected exception while handling related value", e2); + } + } catch (DatabaseException e) { + try { + proc.exception(graph, e); + } catch (DatabaseException e2) { + LOGGER.error("Unexpected exception while handling related value", e2); } + } +// } else { +// getRelatedValue4(impl, subjectId, proc); +// } // } else { // @@ -341,12 +249,11 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } @Override - public void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextProcedure procedure) { + public void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, C context, final SyncContextProcedure procedure) { assert(subject != null); final ForPossibleRelatedValueContextProcedure proc = (ForPossibleRelatedValueContextProcedure)procedure; - final RelationInfo info = proc.info; final ReadGraphImpl impl = (ReadGraphImpl)graph; final int subjectId = ((ResourceImpl)subject).id; @@ -356,15 +263,21 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { // impl.inc(); - if(info.isFunctional) { - getRelatedValue4(impl, subjectId, context, proc); - } else { - getRelatedValue4(impl, subjectId, context, proc); - } +// if(proc.info.isFunctional) { +// } else { +// getRelatedValue4(impl, subjectId, context, proc); +// } + + try { + T result = getRelatedValue4(impl, subjectId, context, proc); + proc.execute(graph, context, result); + } catch (DatabaseException e) { + proc.execute(graph, context, null); + } } - @Override +/* @Override public void forPossibleType(final AsyncReadGraph graph, Resource subject, final AsyncProcedure procedure) { assert(subject != null); @@ -413,9 +326,11 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } + + */ @Override - public void forPossibleDirectType(final AsyncReadGraph graph, Resource subject, final C context, final AsyncContextProcedure procedure) { + public void forPossibleDirectType(final ReadGraph graph, Resource subject, final C context, final SyncContextProcedure procedure) { assert(subject != null); @@ -447,7 +362,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { // impl.state.dec(0); } catch (DatabaseException e) { - e.printStackTrace(); + LOGGER.error("forPossibleDirectType requestCluster callback failed", e); } } @@ -472,15 +387,14 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } catch (Throwable t) { - t.printStackTrace(); + LOGGER.error("forPossibleDirectType failed unexpectedly", t); procedure.execute(graph, context, null); } } - - private void getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) { + private T getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) throws DatabaseException { int result = 0; @@ -489,18 +403,14 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(subject < 0) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, - g -> getRelatedValue4(g, subject, context, procedure) - ); - return; + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, g -> {}); + return getRelatedValue4(graph, subject, context, procedure); } 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; + throw new DatabaseException("Multiple objects"); } else { result = id; } @@ -508,121 +418,95 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } if(result == 0) { - - procedure.exception(graph, new DatabaseException("No objects for " + subject )); -// graph.dec(); - return; - + throw new DatabaseException("No objects for " + subject ); } else { - - getValue4(graph, null, result, context, procedure); - return; - + return getValue4(graph, null, result, context, procedure); } } 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; + cluster.load(); + return getRelatedValue4(graph, subject, context, procedure); } 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; + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, g -> {}); + return getRelatedValue4(graph, subject, context, procedure); } 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; + throw new DatabaseException("Multiple objects"); } else { result = id; } } } - getRelatedDirectValue4(graph, cluster, subject, result, context, procedure); + return getRelatedDirectValue4(graph, cluster, subject, result, context, procedure); } else { - getRelatedDirectValue4(graph, cluster, subject, 0, context, procedure); + return getRelatedDirectValue4(graph, cluster, subject, 0, context, procedure); } } - private void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure procedure) { + @SuppressWarnings("unchecked") + private T getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure procedure) throws DatabaseException { 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; + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, g -> {}); + return getValue4(graph, containerCluster, subject, procedure); } 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; + throw new DatabaseException("Multiple values"); } else { result = value; } } } - - procedure.execute(graph, (T)"name"); -// graph.dec(); - return; - + + // FIXME: throw something here instead + return (T)"name"; + } 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; + cluster.load(); + return getValue4(graph, containerCluster, subject, procedure); } } 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; + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, g -> {}); + return getValue4(graph, containerCluster, subject, procedure); } 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; + throw new DatabaseException("Multiple values"); } else { result = value; } @@ -630,93 +514,74 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } if(result != null) { - - procedure.execute(graph, (T)result); -// graph.state.barrier.dec(); - + return (T)result; } else { - if(ClusterTypeEnum.SMALL == cluster.getType()) - getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure); + return getDirectValue4(graph, (ClusterSmall)cluster, subject); else - getDirectValue4(graph, (ClusterBig)cluster, subject, procedure); + return getDirectValue4(graph, (ClusterBig)cluster, subject); } } else { if(ClusterTypeEnum.SMALL == cluster.getType()) - getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure); + return getDirectValue4(graph, (ClusterSmall)cluster, subject); else - getDirectValue4(graph, (ClusterBig)cluster, subject, procedure); + return getDirectValue4(graph, (ClusterBig)cluster, subject); } } - private void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) { + @SuppressWarnings("unchecked") + private T getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) throws DatabaseException { 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; + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, g -> {}); + return getValue4(graph, containerCluster, subject, context, procedure); } 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; + throw new DatabaseException("Multiple values"); } else { result = value; } } } - procedure.execute(graph, context, (T)"name"); -// graph.dec(); - return; - + // FIXME: throw something here instead + return (T)"name"; + } 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; + cluster.load(); + return getValue4(graph, containerCluster, subject, context, procedure); } } 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; + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, g -> {}); + return getValue4(graph, containerCluster, subject, context, procedure); } 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; + throw new DatabaseException("Multiple values"); } else { result = value; } @@ -724,84 +589,64 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } if(result != null) { - - procedure.execute(graph, context, (T)result); -// graph.state.barrier.dec(); - + return (T)result; } else { - if(ClusterTypeEnum.SMALL == cluster.getType()) - getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure); + return getDirectValue4(graph, (ClusterSmall)cluster, subject); else - getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure); + return getDirectValue4(graph, (ClusterBig)cluster, subject); } } else { if(ClusterTypeEnum.SMALL == cluster.getType()) - getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure); + return getDirectValue4(graph, (ClusterSmall)cluster, subject); else - getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure); + return getDirectValue4(graph, (ClusterBig)cluster, subject); } } - private void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure procedure) { - - try { + private T getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure procedure) throws DatabaseException { - 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); - } + int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator); + if(so == 0) { + if(result == 0) { + throw new DatabaseException("No objects " + subject + " " + procedure.predicateKey); } else { - if(result == 0) { - getValue4(graph, cluster, so, procedure); - } else { - procedure.exception(graph, new DatabaseException("Multiple objects")); -// graph.dec(); - } + return getValue4(graph, cluster, result, procedure); + } + } else { + if(result == 0) { + return getValue4(graph, cluster, so, procedure); + } else { + throw new DatabaseException("Multiple objects"); } - - } catch (DatabaseException e) { - e.printStackTrace(); } - - } - private void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final C context, final ForPossibleRelatedValueContextProcedure procedure) { - - try { + } + + private T getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final C context, final ForPossibleRelatedValueContextProcedure procedure) throws DatabaseException { - 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); - } + int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator); + if(so == 0) { + if(result == 0) { + throw new NoSingleResultException("No objects " + subject + " " + procedure.predicateKey, result); } 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(); - } + return getValue4(graph, cluster, result, context, procedure); + } + } else { + if(result == 0) { + return getValue4(graph, cluster, so, context, procedure); + } else { + throw new NoSingleResultException("Multiple objects for " + subject + " " + procedure.predicateKey, result); } - - } catch (DatabaseException e) { - LOGGER.error("Could not compute related value for subject {} with predicate {}", subject, procedure.predicateKey); } } - public void getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure procedure) { + public T getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure procedure) throws DatabaseException { int result = 0; @@ -810,18 +655,14 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(subject < 0) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, - g -> getRelatedValue4(g, subject, procedure) - ); - return; + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, g -> {}); + return getRelatedValue4(graph, subject, procedure); } 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; + throw new DatabaseException("Multiple objects"); } else { result = id; } @@ -829,64 +670,47 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } if(result == 0) { - - procedure.exception(graph, new DatabaseException("No objects for " + subject )); -// graph.dec(); - return; - + throw new DatabaseException("No objects for " + subject ); } else { - - getValue4(graph, null, result, procedure); - return; - + return getValue4(graph, null, result, procedure); } } 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; + cluster.load(); + return getRelatedValue4(graph, subject, procedure); } 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; + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, g -> {}); + return getRelatedValue4(graph, subject, procedure); } 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; + throw new DatabaseException("Multiple objects"); } else { result = id; } } } - getRelatedDirectValue4(graph, cluster, subject, result, procedure); + return getRelatedDirectValue4(graph, cluster, subject, result, procedure); } else { - getRelatedDirectValue4(graph, cluster, subject, 0, procedure); + return getRelatedDirectValue4(graph, cluster, subject, 0, procedure); } } - + + /* private void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) { try { @@ -900,40 +724,21 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { // graph.dec(); } + */ - private void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final ForPossibleRelatedValueProcedure 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(); - - } + @SuppressWarnings("unchecked") + private T getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject) throws DatabaseException { - private void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure 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); - } + byte[] bytes = cluster.getValue(subject, session.clusterTranslator); + return (T) utf(bytes, 0); -// graph.dec(); - } - - private void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure procedure) { + + @SuppressWarnings("unchecked") + private T getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject) throws DatabaseException { + // Note: this code avoids creating an intermediate byte[] + // to store the encoded string bytes and reads the UTF string + // from the value table byte[] directly into String instead. ResourceTableSmall rt = cluster.resourceTable; ValueTableSmall vt = cluster.valueTable; @@ -941,31 +746,25 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { byte[] bs = vt.table; long[] ls = rt.table; - int index = ((subject&0xFFFF) << 1) - 1 + rt.offset; + int index = ((subject&0xFFF) << 1) - 1 + rt.offset; + int valueIndex = ((int)(ls[index] >>> 24) & 0x3FFFFF) + vt.offset; - int valueIndex = (int)(ls[index] >>> 24) & 0x3FFFFF + vt.offset; + int size = bs[valueIndex++]; + if (size < 0) // two byte size + size = (int)(((size & 0x7F) << 8) | (bs[valueIndex++] & 0xFF)); + if (size <= 0) + throw new DatabaseException("No value for " + subject); - int size = (int)bs[valueIndex++]-1; - char[] chars = new char[size]; - valueIndex++; - for(int i=0;i= 0x80) { if(length >= 0xc0) {