X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.procore%2Fsrc%2Ffi%2Fvtt%2Fsimantics%2Fprocore%2Finternal%2FDirectQuerySupportImpl.java;h=5f6c722acfdffa0d721b71b600cb8be99d51533e;hb=2f79fa2a6d636373340bffb6d09b2f849b722f88;hp=9d6b019e4a2d22de5a3954f77f125abde174a468;hpb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;p=simantics%2Fplatform.git 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 9d6b019e4..5f6c722ac 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 @@ -7,7 +7,9 @@ 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; @@ -30,10 +32,20 @@ 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.simantics.utils.datastructures.Callback; - +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); + final private SessionImplSocket session; DirectQuerySupportImpl(SessionImplSocket session) { @@ -484,14 +496,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(subject < 0) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback() { - - @Override - public void run(ReadGraphImpl graph) { - getRelatedValue4(graph, subject, context, procedure); - } - - }); + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, + g -> getRelatedValue4(g, subject, context, procedure) + ); return; } @@ -524,28 +531,16 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { 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, context, procedure); - } - - }); + 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, new Callback() { - - @Override - public void run(ReadGraphImpl graph) { - getRelatedValue4(graph, subject, context, procedure); - } - - }); + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, + g -> getRelatedValue4(g, subject, context, procedure) + ); return; } @@ -571,6 +566,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } + @SuppressWarnings("unchecked") private void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure procedure) { Object result = null; @@ -578,14 +574,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(subject < 0) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback() { - - @Override - public void run(ReadGraphImpl graph) { - getValue4(graph, containerCluster, subject, procedure); - } - - }); + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, + g -> getValue4(g, containerCluster, subject, procedure) + ); return; } @@ -627,14 +618,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback() { - - @Override - public void run(ReadGraphImpl graph) { - getValue4(graph, containerCluster, subject, procedure); - } - - }); + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, + g -> getValue4(g, containerCluster, subject, procedure) + ); return; } @@ -675,6 +661,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } + @SuppressWarnings("unchecked") private void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) { Object result = null; @@ -682,14 +669,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(subject < 0) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback() { - - @Override - public void run(ReadGraphImpl graph) { - getValue4(graph, containerCluster, subject, context, procedure); - } - - }); + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, + g -> getValue4(g, containerCluster, subject, context, procedure) + ); return; } @@ -731,14 +713,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, new Callback() { - - @Override - public void run(ReadGraphImpl graph) { - getValue4(graph, containerCluster, subject, context, procedure); - } - - }); + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, + g -> getValue4(g, containerCluster, subject, context, procedure) + ); return; } @@ -813,7 +790,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator); if(so == 0) { if(result == 0) { - procedure.exception(graph, new DatabaseException("No objects " + subject + " " + procedure.predicateKey)); + procedure.exception(graph, new NoSingleResultException("No objects " + subject + " " + procedure.predicateKey, result)); // graph.dec(); } else { getValue4(graph, cluster, result, context, procedure); @@ -822,13 +799,13 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(result == 0) { getValue4(graph, cluster, so, context, procedure); } else { - procedure.exception(graph, new DatabaseException("Multiple objects")); + procedure.exception(graph, new NoSingleResultException("Multiple objects for " + subject + " " + procedure.predicateKey, result)); // graph.dec(); } } } catch (DatabaseException e) { - e.printStackTrace(); + LOGGER.error("Could not compute related value for subject {} with predicate {}", subject, procedure.predicateKey); } } @@ -842,14 +819,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(subject < 0) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback() { - - @Override - public void run(ReadGraphImpl graph) { - getRelatedValue4(graph, subject, procedure); - } - - }); + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, + g -> getRelatedValue4(g, subject, procedure) + ); return; } @@ -896,14 +868,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) { if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) { - SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, new Callback() { - - @Override - public void run(ReadGraphImpl graph) { - getRelatedValue4(graph, subject, procedure); - } - - }); + SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, + g -> getRelatedValue4(graph, subject, procedure) + ); return; } @@ -933,7 +900,8 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { try { byte[] bytes = cluster.getValue(subject, session.clusterTranslator); - T value = (T)utf(bytes); + @SuppressWarnings("unchecked") + T value = (T)utf(bytes, 0); procedure.execute(graph, context, value); } catch (DatabaseException e) { procedure.execute(graph, context, null); @@ -947,7 +915,8 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { try { byte[] bytes = cluster.getValue(subject, session.clusterTranslator); - T value = (T)utf(bytes); + @SuppressWarnings("unchecked") + T value = (T)utf(bytes, 0); procedure.execute(graph, value); } catch (DatabaseException e) { procedure.execute(graph, null); @@ -964,7 +933,8 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { if(bytes == null) { procedure.execute(graph, context, null); } else { - T value = (T)utf(bytes); + @SuppressWarnings("unchecked") + T value = (T)utf(bytes, 0); procedure.execute(graph, context, value); } } catch (DatabaseException e) { @@ -975,38 +945,43 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } - private final char[] chars = new char[1024]; - private void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure procedure) { + try { + // 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; - - byte[] bs = vt.table; - long[] ls = rt.table; + ResourceTableSmall rt = cluster.resourceTable; + ValueTableSmall vt = cluster.valueTable; - int index = ((subject&0xFFFF) << 1) - 1 + rt.offset; + byte[] bs = vt.table; + long[] ls = rt.table; - int valueIndex = (int)(ls[index] >>> 24) & 0x3FFFFF + vt.offset; + int index = ((subject&0xFFF) << 1) - 1 + rt.offset; + int valueIndex = ((int)(ls[index] >>> 24) & 0x3FFFFF) + vt.offset; - int size = (int)bs[valueIndex++]-1; - valueIndex++; - for(int i=0;i= 0x80) { if(length >= 0xc0) { @@ -1039,42 +1014,68 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { length += 0x80; } } - - int i = 0; - int target = length+index; - while(index < target) { - int c = bytes[index++]&0xff; - if(c <= 0x7F) { - chars[i++] = (char)(c&0x7F); - } else if (c > 0x07FF) { - int c2 = bytes[index++]&0xff; - int c3 = bytes[index++]&0xff; - chars[i++] = (char)(((c&0xf)<<12) + ((c2&0x3f)<<6) + (c3&0x3f)); - } else { - int c2 = bytes[index++]&0xff; - chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f)); + + // 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); } - - -// if (!((c >= 0x0001) && (c <= 0x007F))) { -// } else { -// } -// -// if ((c >= 0x0001) && (c <= 0x007F)) { -// bytearr[byteIndex++] = (byte)( c ); -// } else if (c > 0x07FF) { -// bytearr[byteIndex++] = (byte)(0xE0 | ((c >> 12) & 0x0F)); -// bytearr[byteIndex++] = (byte)(0x80 | ((c >> 6) & 0x3F)); -// bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F)); -// } else { -// bytearr[byteIndex++] = (byte)(0xC0 | ((c >> 6) & 0x1F)); -// bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F)); -// } -// } - - } - return new String(chars, 0, i); + + // The number of chars produced may be less than utflen + return new String(chararr, 0, chararr_count); } - + }