import org.simantics.db.request.AsyncRead;
import org.simantics.db.service.DirectQuerySupport;
+/**
+ * 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 {
final private SessionImplSocket session;
}
+ @SuppressWarnings("unchecked")
private <T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
Object result = null;
}
+ @SuppressWarnings("unchecked")
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;
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);
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);
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) {
}
private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure<T> 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;
- char[] chars = new char[size];
- valueIndex++;
- for(int i=0;i<size;i++) {
- chars[i] = (char)bs[valueIndex++];
- }
+ 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);
- T value = (T)new String(chars);
+ @SuppressWarnings("unchecked")
+ T t = (T) utf(bs, valueIndex);
- procedure.execute(graph, value);
-// graph.dec();
-
+ procedure.execute(graph, t);
+ } catch (DatabaseException e) {
+ procedure.exception(graph, e);
+ }
}
- final private String utf(byte[] bytes) throws AssumptionException {
+ final private String utf(byte[] bytes, int offset) 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 index = offset;
int length = bytes[index++]&0xff;
if(length >= 0x80) {
if(length >= 0xc0) {