Skip to content

Commit 9b3c6a8

Browse files
committed
Datatype Specific ByteBuffer getters
1 parent e159f22 commit 9b3c6a8

File tree

4 files changed

+354
-35
lines changed

4 files changed

+354
-35
lines changed

src/main/java/io/tiledb/java/api/Datatype.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public Class javaClass() throws TileDBError {
124124
case TILEDB_FLOAT64:
125125
return Double.class;
126126
case TILEDB_CHAR:
127-
return Short.class;
127+
return Byte.class;
128128
case TILEDB_INT8:
129129
return Byte.class;
130130
case TILEDB_UINT8:

src/main/java/io/tiledb/java/api/Query.java

Lines changed: 203 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@
2828

2929
import io.tiledb.libtiledb.*;
3030
import java.math.BigInteger;
31-
import java.nio.ByteBuffer;
32-
import java.nio.ByteOrder;
31+
import java.nio.*;
32+
import java.nio.charset.Charset;
33+
import java.nio.charset.StandardCharsets;
3334
import java.util.*;
3435

3536
/**
@@ -541,19 +542,7 @@ public synchronized Query setBuffer(String attr, long bufferElements) throws Til
541542
throw new TileDBError("Number of buffer elements must be >= 1");
542543
}
543544

544-
Datatype dt;
545-
546-
try (ArraySchema schema = array.getSchema()) {
547-
try (Domain domain = schema.getDomain()) {
548-
if (domain.hasDimension(attr)) {
549-
dt = domain.getDimension(attr).getType();
550-
} else {
551-
try (Attribute attribute = schema.getAttribute(attr)) {
552-
dt = attribute.getType();
553-
}
554-
}
555-
}
556-
}
545+
Datatype dt = Util.getFieldDatatype(array, attr);
557546

558547
int size = Util.castLongToInt(bufferElements * dt.getNativeSize());
559548

@@ -1057,33 +1046,33 @@ public Query resetBufferSizes() {
10571046
/**
10581047
* Return a Java primitive array object as a copy of the attribute buffer
10591048
*
1060-
* @param attr attribute name
1049+
* @param bufferName attribute name
10611050
* @return A Java array
10621051
* @exception TileDBError A TileDB exception
10631052
*/
1064-
public Object getBuffer(String attr) throws TileDBError {
1065-
if (buffers_.containsKey(attr)) {
1066-
NativeArray buffer = buffers_.get(attr).getSecond();
1053+
public Object getBuffer(String bufferName) throws TileDBError {
1054+
if (buffers_.containsKey(bufferName)) {
1055+
NativeArray buffer = buffers_.get(bufferName).getSecond();
10671056
Integer nelements =
10681057
(buffer_sizes_
1069-
.get(attr)
1058+
.get(bufferName)
10701059
.getSecond()
10711060
.getitem(0)
10721061
.divide(BigInteger.valueOf(buffer.getNativeTypeSize())))
10731062
.intValue();
10741063
return buffer.toJavaArray(nelements);
1075-
} else if (buffers_.containsKey(attr)) {
1076-
NativeArray buffer = buffers_.get(attr).getSecond();
1064+
} else if (buffers_.containsKey(bufferName)) {
1065+
NativeArray buffer = buffers_.get(bufferName).getSecond();
10771066
Integer nelements =
10781067
(buffer_sizes_
1079-
.get(attr)
1068+
.get(bufferName)
10801069
.getSecond()
10811070
.getitem(0)
10821071
.divide(BigInteger.valueOf(buffer.getNativeTypeSize())))
10831072
.intValue();
10841073
return buffer.toJavaArray(nelements);
10851074
} else {
1086-
throw new TileDBError("Query attribute buffer does not exist: " + attr);
1075+
throw new TileDBError("Query attribute buffer does not exist: " + bufferName);
10871076
}
10881077
}
10891078

@@ -1102,25 +1091,209 @@ public Pair<ByteBuffer, ByteBuffer> getByteBuffer(String attr) throws TileDBErro
11021091
/**
11031092
* Return an array containing offsets for a variable attribute buffer
11041093
*
1105-
* @param attr attribute name
1094+
* @param bufferName attribute name
11061095
* @return A Java long[] array
11071096
* @throws TileDBError A TileDB exception
11081097
*/
1109-
public long[] getVarBuffer(String attr) throws TileDBError {
1110-
if (!buffers_.containsKey(attr)) {
1111-
throw new TileDBError("Query variable attribute buffer does not exist: " + attr);
1098+
public long[] getVarBuffer(String bufferName) throws TileDBError {
1099+
if (!buffers_.containsKey(bufferName)) {
1100+
throw new TileDBError("Query variable attribute buffer does not exist: " + bufferName);
11121101
}
1113-
NativeArray buffer = buffers_.get(attr).getFirst();
1102+
NativeArray buffer = buffers_.get(bufferName).getFirst();
11141103
Integer nelements =
11151104
(buffer_sizes_
1116-
.get(attr)
1105+
.get(bufferName)
11171106
.getFirst()
11181107
.getitem(0)
11191108
.divide(BigInteger.valueOf(buffer.getNativeTypeSize())))
11201109
.intValue();
11211110
return (long[]) buffer.toJavaArray(nelements);
11221111
}
11231112

1113+
/**
1114+
* Retrieves an IntBuffer of an attribute attr of type Integer
1115+
*
1116+
* @param bufferName The attribute name
1117+
* @return The IntBuffer
1118+
* @throws TileDBError A TileDB exception
1119+
*/
1120+
public Pair<LongBuffer, IntBuffer> getIntBuffer(String bufferName) throws TileDBError {
1121+
Datatype dt = Util.getFieldDatatype(array, bufferName);
1122+
1123+
if (dt.javaClass() != Integer.class)
1124+
throw new TileDBError(
1125+
"IntBuffer requested, but attribute " + bufferName + " has type " + dt.name());
1126+
1127+
Pair<ByteBuffer, ByteBuffer> buffer = this.byteBuffers_.get(bufferName);
1128+
if (byteBuffers_.containsKey(bufferName)) {
1129+
LongBuffer offsets = null;
1130+
if (buffer.getFirst() != null) offsets = buffer.getFirst().asLongBuffer();
1131+
return new Pair(offsets, buffer.getSecond().asIntBuffer());
1132+
} else throw new TileDBError("ByteBuffer does not exist for attribute: " + bufferName);
1133+
}
1134+
1135+
/**
1136+
* Retrieves a LongBuffer of an attribute bufferName of type Long
1137+
*
1138+
* @param bufferName The attribute name
1139+
* @return The IntBuffer
1140+
* @throws TileDBError A TileDB exception
1141+
*/
1142+
public Pair<LongBuffer, LongBuffer> getLongBuffer(String bufferName) throws TileDBError {
1143+
Datatype dt = Util.getFieldDatatype(array, bufferName);
1144+
1145+
if (dt.javaClass() != Long.class)
1146+
throw new TileDBError(
1147+
"LongBuffer requested, but attribute " + bufferName + " has type " + dt.name());
1148+
1149+
Pair<ByteBuffer, ByteBuffer> buffer = this.byteBuffers_.get(bufferName);
1150+
if (byteBuffers_.containsKey(bufferName))
1151+
return new Pair(buffer.getFirst().asLongBuffer(), buffer.getSecond().asLongBuffer());
1152+
else throw new TileDBError("ByteBuffer does not exist for attribute: " + bufferName);
1153+
}
1154+
1155+
/**
1156+
* Retrieves the CharBuffer of an attribute bufferName of type Char
1157+
*
1158+
* @param bufferName The attribute name
1159+
* @return The CharBuffer
1160+
* @throws TileDBError A TileDB exception
1161+
*/
1162+
public Pair<LongBuffer, ShortBuffer> getShortBuffer(String bufferName) throws TileDBError {
1163+
Datatype dt = Util.getFieldDatatype(array, bufferName);
1164+
1165+
if (dt.javaClass() != Short.class)
1166+
throw new TileDBError(
1167+
"ShortBuffer requested, but attribute " + bufferName + " has type " + dt.name());
1168+
1169+
Pair<ByteBuffer, ByteBuffer> buffer = this.byteBuffers_.get(bufferName);
1170+
if (byteBuffers_.containsKey(bufferName)) {
1171+
LongBuffer offsets = null;
1172+
if (buffer.getFirst() != null) offsets = buffer.getFirst().asLongBuffer();
1173+
return new Pair(offsets, buffer.getSecond().asShortBuffer());
1174+
} else throw new TileDBError("ByteBuffer does not exist for attribute: " + bufferName);
1175+
}
1176+
1177+
/**
1178+
* Retrieves the CharBuffer of an attribute bufferName of type Char
1179+
*
1180+
* @param bufferName The attribute name
1181+
* @return The CharBuffer
1182+
* @throws TileDBError A TileDB exception
1183+
*/
1184+
public Pair<LongBuffer, CharBuffer> getCharBuffer(String bufferName) throws TileDBError {
1185+
Datatype dt = Util.getFieldDatatype(array, bufferName);
1186+
1187+
if (dt.javaClass() != Byte.class)
1188+
throw new TileDBError(
1189+
"CharBuffer requested, but attribute " + bufferName + " has type " + dt.name());
1190+
1191+
Pair<ByteBuffer, ByteBuffer> buffer = this.byteBuffers_.get(bufferName);
1192+
if (byteBuffers_.containsKey(bufferName)) {
1193+
LongBuffer offsets = null;
1194+
if (buffer.getFirst() != null) offsets = buffer.getFirst().asLongBuffer();
1195+
1196+
// Set the US_ASCII charset and decode, so each character is treated as a single byte instead
1197+
// of two.
1198+
Charset charset = StandardCharsets.US_ASCII;
1199+
CharBuffer charBuffer = charset.decode(buffer.getSecond());
1200+
return new Pair(offsets, charBuffer);
1201+
} else throw new TileDBError("ByteBuffer does not exist for attribute: " + bufferName);
1202+
}
1203+
1204+
/**
1205+
* Retrieves the an FloatBuffer of an attribute bufferName of type Float
1206+
*
1207+
* @param bufferName The attribute name
1208+
* @return The FloatBuffer
1209+
* @throws TileDBError A TileDB exception
1210+
*/
1211+
public Pair<LongBuffer, FloatBuffer> getFloatBuffer(String bufferName) throws TileDBError {
1212+
Datatype dt = Util.getFieldDatatype(array, bufferName);
1213+
1214+
if (dt.javaClass() != Float.class)
1215+
throw new TileDBError(
1216+
"FloatBuffer requested, but attribute " + bufferName + " has type " + dt.name());
1217+
1218+
Pair<ByteBuffer, ByteBuffer> buffer = this.byteBuffers_.get(bufferName);
1219+
if (byteBuffers_.containsKey(bufferName)) {
1220+
LongBuffer offsets = null;
1221+
if (buffer.getFirst() != null) offsets = buffer.getFirst().asLongBuffer();
1222+
return new Pair(offsets, buffer.getSecond().asFloatBuffer());
1223+
} else throw new TileDBError("ByteBuffer does not exist for attribute: " + bufferName);
1224+
}
1225+
1226+
/**
1227+
* Retrieves the an DoubleBuffer of an attribute bufferName of type Double
1228+
*
1229+
* @param bufferName The attribute name
1230+
* @return The DoubleBuffer
1231+
* @throws TileDBError A TileDB exception
1232+
*/
1233+
public Pair<LongBuffer, DoubleBuffer> getDoubleBuffer(String bufferName) throws TileDBError {
1234+
Datatype dt = Util.getFieldDatatype(array, bufferName);
1235+
1236+
if (dt.javaClass() != Double.class)
1237+
throw new TileDBError(
1238+
"DoubleBuffer requested, but attribute " + bufferName + " has type " + dt.name());
1239+
1240+
Pair<ByteBuffer, ByteBuffer> buffer = this.byteBuffers_.get(bufferName);
1241+
if (byteBuffers_.containsKey(bufferName)) {
1242+
LongBuffer offsets = null;
1243+
if (buffer.getFirst() != null) offsets = buffer.getFirst().asLongBuffer();
1244+
return new Pair(offsets, buffer.getSecond().asDoubleBuffer());
1245+
} else throw new TileDBError("ByteBuffer does not exist for attribute: " + bufferName);
1246+
}
1247+
1248+
/**
1249+
* Drains a ByteBuffer and returns its contents as a byte[] array
1250+
*
1251+
* @param bufferName The attribute name
1252+
* @return The byte[] array
1253+
* @throws TileDBError A TileDB exception
1254+
*/
1255+
public byte[] getByteArray(String bufferName) throws TileDBError {
1256+
ByteBuffer buffer = this.byteBuffers_.get(bufferName).getSecond();
1257+
if (byteBuffers_.containsKey(bufferName)) {
1258+
1259+
byte[] bytes = new byte[buffer.limit()];
1260+
int idx = 0;
1261+
while (buffer.hasRemaining()) bytes[idx++] = buffer.get();
1262+
1263+
// Reset buffer position after draining, so it can be reused.
1264+
buffer.flip();
1265+
1266+
return bytes;
1267+
}
1268+
1269+
throw new TileDBError("ByteBuffer does not exist for attribute: " + bufferName);
1270+
}
1271+
1272+
/**
1273+
* Drains a variable-sized buffer and returns its offsets as a byte[] Array
1274+
*
1275+
* @param bufferName The attribute name
1276+
* @return The byte[] array
1277+
* @throws TileDBError A TileDB exception
1278+
*/
1279+
public long[] getOffsetArray(String bufferName) throws TileDBError {
1280+
Pair<ByteBuffer, ByteBuffer> buffer = this.byteBuffers_.get(bufferName);
1281+
if (byteBuffers_.containsKey(bufferName)) {
1282+
LongBuffer offsets = null;
1283+
if (buffer.getFirst() != null) {
1284+
offsets = buffer.getFirst().asLongBuffer();
1285+
1286+
long[] offsetArr = new long[offsets.limit()];
1287+
int idx = 0;
1288+
while (offsets.hasRemaining()) offsetArr[idx++] = offsets.get();
1289+
1290+
return offsetArr;
1291+
}
1292+
}
1293+
1294+
throw new TileDBError("ByteBuffer does not exist for attribute: " + bufferName);
1295+
}
1296+
11241297
/**
11251298
* Returns the result size estimate for each attribute/dimension
11261299
*

src/main/java/io/tiledb/java/api/Util.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,29 @@ public static int castLongToInt(long num) throws TileDBError {
3636

3737
return (int) num;
3838
}
39+
40+
/**
41+
* Returns the Datatype of the input field
42+
*
43+
* @param array The TileDB array
44+
* @param fieldName The field name
45+
* @return The Datatype
46+
* @throws TileDBError A TileDBError
47+
*/
48+
public static Datatype getFieldDatatype(Array array, String fieldName) throws TileDBError {
49+
Datatype dt;
50+
try (ArraySchema schema = array.getSchema()) {
51+
try (Domain domain = schema.getDomain()) {
52+
if (domain.hasDimension(fieldName)) {
53+
dt = domain.getDimension(fieldName).getType();
54+
} else {
55+
try (Attribute attribute = schema.getAttribute(fieldName)) {
56+
dt = attribute.getType();
57+
}
58+
}
59+
}
60+
}
61+
62+
return dt;
63+
}
3964
}

0 commit comments

Comments
 (0)