From ad109c561ec47c6d15c32c34ac6b1aabc93f95db Mon Sep 17 00:00:00 2001 From: Grigory Pomadchin Date: Sat, 2 May 2020 11:48:02 -0400 Subject: [PATCH 1/6] Expose Get and Delete metadata functions --- .gitignore | 4 + src/main/java/io/tiledb/java/api/Array.java | 116 ++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/.gitignore b/.gitignore index 6ee8130c..f14a070a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ build/* */.gradle/* */build/* */performance_test/* +.classpath +.project +.settings +bin/ diff --git a/src/main/java/io/tiledb/java/api/Array.java b/src/main/java/io/tiledb/java/api/Array.java index 40e5fda5..c863dbf0 100644 --- a/src/main/java/io/tiledb/java/api/Array.java +++ b/src/main/java/io/tiledb/java/api/Array.java @@ -615,6 +615,122 @@ public HashMap> maxBufferElements(NativeArray subarray) return ret; } + /** + * Get a metadata key-value item from an open array. The array must be opened in READ mode, + * otherwise the function will error out. + * + * @param key a key to retrieve from the metadata key-value + * @param nativeType The Datatype + * @return NativeArray which contains the metadata + * @throws TileDBError A TileDB exception + */ + public NativeArray getMetadata(String key, Datatype nativeType) throws TileDBError { + checkIsOpen(); + + SWIGTYPE_p_p_void resultArrpp = tiledb.new_voidpArray(0); + SWIGTYPE_p_unsigned_int value_num = tiledb.new_uintp(); + SWIGTYPE_p_tiledb_datatype_t value_type = + tiledb.copy_tiledb_datatype_tp(nativeType.toSwigEnum()); + + ctx.handleError( + tiledb.tiledb_array_get_metadata( + ctx.getCtxp(), arrayp, key, value_type, value_num, resultArrpp)); + + long value = tiledb.uintp_value(value_num); + NativeArray result = new NativeArray(ctx, nativeType, resultArrpp, (int) value); + + tiledb.delete_uintp(value_num); + tiledb.delete_tiledb_datatype_tp(value_type); + + return result; + } + + /** + * Deletes a metadata key-value item from an open array. The array must be opened in WRITE mode, + * otherwise the function will error out. + * + * @param key a key to delete from the metadata key-value + * @throws TileDBError A TileDB exception + */ + public void deleteMetadata(String key) throws TileDBError { + checkIsOpen(); + + ctx.handleError(tiledb.tiledb_array_delete_metadata(ctx.getCtxp(), arrayp, key)); + } + + /** + * Gets the number of metadata items in an open array. The array must be opened in READ mode, + * otherwise the function will error out. + * + * @return the number of metadata items + * @throws TileDBError A TileDB exception + */ + public BigInteger getMetadataNum() throws TileDBError { + checkIsOpen(); + + SWIGTYPE_p_unsigned_long_long value_num = tiledb.new_ullp(); + + ctx.handleError(tiledb.tiledb_array_get_metadata_num(ctx.getCtxp(), arrayp, value_num)); + + BigInteger value = tiledb.ullp_value(value_num); + + tiledb.delete_ullp(value_num); + + return value; + } + + /** + * Gets a metadata item from an open array using an index. The array must be opened in READ mode, + * otherwise the function will error out. + * + * @param index index to retrieve metadata from + * @return a pair, key and the metadata NativeArray + * @throws TileDBError A TileDB exception + */ + public Pair getMetadataFromIndex(BigInteger index) throws TileDBError { + checkIsOpen(); + + SWIGTYPE_p_p_char key = tiledb.new_charpp(); + SWIGTYPE_p_unsigned_int key_len = tiledb.new_uintp(); + SWIGTYPE_p_tiledb_datatype_t value_type = tiledb.new_tiledb_datatype_tp(); + SWIGTYPE_p_unsigned_int value_num = tiledb.new_uintp(); + SWIGTYPE_p_p_void value = tiledb.new_voidpArray(0); + + ctx.handleError( + tiledb.tiledb_array_get_metadata_from_index( + ctx.getCtxp(), arrayp, index, key, key_len, value_type, value_num, value)); + + String keyString = tiledb.charpp_value(key); + long valueLength = tiledb.uintp_value(value_num); + Datatype nativeType = Datatype.fromSwigEnum(tiledb.tiledb_datatype_tp_value(value_type)); + + NativeArray result = new NativeArray(ctx, nativeType, value, (int) valueLength); + + tiledb.delete_uintp(value_num); + tiledb.delete_uintp(key_len); + tiledb.delete_charpp(key); + tiledb.delete_tiledb_datatype_tp(value_type); + + return new Pair(keyString, result); + } + + public Boolean hasMetadataKey(String key) throws TileDBError { + checkIsOpen(); + + SWIGTYPE_p_tiledb_datatype_t value_type = tiledb.new_tiledb_datatype_tp(); + SWIGTYPE_p_int has_key = tiledb.new_intp(); + + ctx.handleError( + tiledb.tiledb_array_has_metadata_key(ctx.getCtxp(), arrayp, key, value_type, has_key)); + + Boolean result = tiledb.intp_value(has_key) > 0; + + tiledb.delete_intp(has_key); + tiledb.delete_tiledb_datatype_tp(value_type); + + return result; + } + /** @return The TileDB Context object associated with the Array instance. */ public Context getCtx() { return ctx; From 1f863c745dae6d20c774e9134a06aac7c6739b3d Mon Sep 17 00:00:00 2001 From: Grigory Pomadchin Date: Sat, 2 May 2020 13:14:16 -0400 Subject: [PATCH 2/6] Add putMetadata method --- src/main/java/io/tiledb/java/api/Array.java | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/main/java/io/tiledb/java/api/Array.java b/src/main/java/io/tiledb/java/api/Array.java index c863dbf0..fc875f84 100644 --- a/src/main/java/io/tiledb/java/api/Array.java +++ b/src/main/java/io/tiledb/java/api/Array.java @@ -714,6 +714,13 @@ public Pair getMetadataFromIndex(BigInteger index) throws TileDBError { return new Pair(keyString, result); } + /** + * Checks if the key is present in the Array metadata + * + * @param key a key to retrieve from the metadata key-value + * @return true if the key is present in the metadata, false if it is not + * @throws TileDBError A TileDB exception + */ public Boolean hasMetadataKey(String key) throws TileDBError { checkIsOpen(); @@ -731,6 +738,27 @@ public Boolean hasMetadataKey(String key) throws TileDBError { return result; } + /** + * Puts a metadata key-value item to an open array. The array must be opened in WRITE mode, + * otherwise the function will error out. + * + * @param key a key to assign to the input value + * @param value the metadata to put into the Array metadata + * @throws TileDBError A TileDB exception + */ + public void putMetadata(String key, NativeArray value) throws TileDBError { + checkIsOpen(); + + ctx.handleError( + tiledb.tiledb_array_put_metadata( + ctx.getCtxp(), + arrayp, + key, + value.getNativeType().toSwigEnum(), + value.getSize(), + value.toVoidPointer())); + } + /** @return The TileDB Context object associated with the Array instance. */ public Context getCtx() { return ctx; From ddb7ed8ac67a2819c38eeee062b30ae26e5f085a Mon Sep 17 00:00:00 2001 From: Grigory Pomadchin Date: Sat, 2 May 2020 14:32:56 -0400 Subject: [PATCH 3/6] Cover Array Metadata functions with Tests --- src/main/java/io/tiledb/java/api/Array.java | 3 +- .../java/io/tiledb/java/api/ArrayTest.java | 92 +++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/tiledb/java/api/Array.java b/src/main/java/io/tiledb/java/api/Array.java index fc875f84..ac584396 100644 --- a/src/main/java/io/tiledb/java/api/Array.java +++ b/src/main/java/io/tiledb/java/api/Array.java @@ -715,7 +715,8 @@ public Pair getMetadataFromIndex(BigInteger index) throws TileDBError { } /** - * Checks if the key is present in the Array metadata + * Checks if the key is present in the Array metadata. The array must be opened in READ mode, + * otherwise the function will error out. * * @param key a key to retrieve from the metadata key-value * @return true if the key is present in the metadata, false if it is not diff --git a/src/test/java/io/tiledb/java/api/ArrayTest.java b/src/test/java/io/tiledb/java/api/ArrayTest.java index ec5119d6..e2906a5e 100644 --- a/src/test/java/io/tiledb/java/api/ArrayTest.java +++ b/src/test/java/io/tiledb/java/api/ArrayTest.java @@ -247,4 +247,96 @@ public void testArraygetNonEmptyDomainFromName() throws Exception { } catch (TileDBError error) { } } + + @Test + public void testArrayMetadata() throws Exception { + Array.create(arrayURI, schemaCreate()); + + long[] array_a = new long[] {1, 2, 3, 6}; + insertArbitraryValues(new NativeArray(ctx, array_a, Long.class)); + + Array arrayw = new Array(ctx, arrayURI, TILEDB_WRITE); + Array array = new Array(ctx, arrayURI, TILEDB_READ); + + NativeArray metadataInt = + new NativeArray( + ctx, + new int[] { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15 + }, + Integer.class); + + NativeArray metadataFloat = + new NativeArray( + ctx, + new float[] { + 0.1f, 0.2f, 1.1f, 1.2f, 2.1f, 2.2f, 3.1f, 3.2f, + 4.1f, 4.2f, 5.1f, 5.2f, 6.1f, 6.2f, 7.1f, 7.2f, + 8.1f, 8.2f, 9.1f, 9.2f, 10.1f, 10.2f, 11.1f, 11.2f, + 12.1f, 12.2f, 13.1f, 13.2f, 14.1f, 14.2f, 15.1f, 15.2f + }, + Float.class); + + String intKey = "md-int"; + String floatKey = "md-float"; + Assert.assertEquals(false, array.hasMetadataKey(intKey)); + Assert.assertEquals(false, array.hasMetadataKey(floatKey)); + Assert.assertEquals(0, array.getMetadataNum().intValue()); + array.close(); + + arrayw.putMetadata(intKey, metadataInt); + arrayw.putMetadata(floatKey, metadataFloat); + // commit changes + arrayw.close(); + + // open a new session + Array arrayn = new Array(ctx, arrayURI, TILEDB_READ); + + Assert.assertEquals(true, arrayn.hasMetadataKey(intKey)); + Assert.assertEquals(true, arrayn.hasMetadataKey(floatKey)); + Assert.assertEquals(2, arrayn.getMetadataNum().intValue()); + + NativeArray metadataIntActual = arrayn.getMetadata(intKey, Datatype.TILEDB_INT32); + NativeArray metadataFloatActual = arrayn.getMetadata(floatKey, Datatype.TILEDB_FLOAT32); + + Assert.assertNotNull(metadataIntActual); + Assert.assertNotNull(metadataFloatActual); + + Assert.assertArrayEquals( + (int[]) metadataInt.toJavaArray(), (int[]) metadataIntActual.toJavaArray()); + Assert.assertArrayEquals( + (float[]) metadataFloat.toJavaArray(), (float[]) metadataFloatActual.toJavaArray(), 1e-10f); + + // fromIndex tests + String[] keys = new String[] {floatKey, intKey}; + for (int i = 0; i < arrayn.getMetadataNum().intValue(); i++) { + Pair p = arrayn.getMetadataFromIndex(BigInteger.valueOf(i)); + Assert.assertEquals(p.getFirst(), keys[i]); + if (i == 0) { + Assert.assertArrayEquals( + (float[]) metadataFloat.toJavaArray(), (float[]) p.getSecond().toJavaArray(), 1e-10f); + } else { + Assert.assertArrayEquals( + (int[]) metadataInt.toJavaArray(), (int[]) p.getSecond().toJavaArray()); + } + } + + arrayn.close(); + + // open a new write session + Array arrayd = new Array(ctx, arrayURI, TILEDB_WRITE); + + arrayd.deleteMetadata(intKey); + arrayd.deleteMetadata(floatKey); + arrayd.close(); + + // open a new session to check the deletion + Array arraydn = new Array(ctx, arrayURI, TILEDB_READ); + Assert.assertEquals(false, arraydn.hasMetadataKey(intKey)); + Assert.assertEquals(false, arraydn.hasMetadataKey(floatKey)); + Assert.assertEquals(0, arraydn.getMetadataNum().intValue()); + + arraydn.close(); + } } From f5148cdf051dfe81e13e9db544db00cb9780ad07 Mon Sep 17 00:00:00 2001 From: Grigory Pomadchin Date: Sat, 2 May 2020 17:40:36 -0400 Subject: [PATCH 4/6] Make getMetadataFromIndex signature more strict and improve tests --- src/main/java/io/tiledb/java/api/Array.java | 6 ++--- .../java/io/tiledb/java/api/ArrayTest.java | 26 ++++++++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/main/java/io/tiledb/java/api/Array.java b/src/main/java/io/tiledb/java/api/Array.java index ac584396..027a3973 100644 --- a/src/main/java/io/tiledb/java/api/Array.java +++ b/src/main/java/io/tiledb/java/api/Array.java @@ -684,10 +684,10 @@ public BigInteger getMetadataNum() throws TileDBError { * otherwise the function will error out. * * @param index index to retrieve metadata from - * @return a pair, key and the metadata NativeArray + * @return a pair, key and the metadata * @throws TileDBError A TileDB exception */ - public Pair getMetadataFromIndex(BigInteger index) throws TileDBError { + public Pair getMetadataFromIndex(BigInteger index) throws TileDBError { checkIsOpen(); SWIGTYPE_p_p_char key = tiledb.new_charpp(); @@ -711,7 +711,7 @@ public Pair getMetadataFromIndex(BigInteger index) throws TileDBError { tiledb.delete_charpp(key); tiledb.delete_tiledb_datatype_tp(value_type); - return new Pair(keyString, result); + return new Pair(keyString, result); } /** diff --git a/src/test/java/io/tiledb/java/api/ArrayTest.java b/src/test/java/io/tiledb/java/api/ArrayTest.java index e2906a5e..a98407f3 100644 --- a/src/test/java/io/tiledb/java/api/ArrayTest.java +++ b/src/test/java/io/tiledb/java/api/ArrayTest.java @@ -34,6 +34,16 @@ public void tearDown() throws Exception { ctx.close(); } + private Object[] getArray(Object val) { + if (val instanceof Object[]) return (Object[]) val; + int arrlength = java.lang.reflect.Array.getLength(val); + Object[] outputArray = new Object[arrlength]; + for (int i = 0; i < arrlength; i++) { + outputArray[i] = java.lang.reflect.Array.get(val, i); + } + return outputArray; + } + public ArraySchema schemaCreate() throws Exception { Dimension d1 = new Dimension(ctx, "d1", Long.class, new Pair(1l, 4l), 2l); @@ -287,7 +297,7 @@ public void testArrayMetadata() throws Exception { arrayw.putMetadata(intKey, metadataInt); arrayw.putMetadata(floatKey, metadataFloat); - // commit changes + // submit changes arrayw.close(); // open a new session @@ -309,17 +319,13 @@ public void testArrayMetadata() throws Exception { (float[]) metadataFloat.toJavaArray(), (float[]) metadataFloatActual.toJavaArray(), 1e-10f); // fromIndex tests - String[] keys = new String[] {floatKey, intKey}; + String[] expectedKeys = new String[] {floatKey, intKey}; + Object[] expectedArrays = new Object[] {metadataFloat.toJavaArray(), metadataInt.toJavaArray()}; + for (int i = 0; i < arrayn.getMetadataNum().intValue(); i++) { Pair p = arrayn.getMetadataFromIndex(BigInteger.valueOf(i)); - Assert.assertEquals(p.getFirst(), keys[i]); - if (i == 0) { - Assert.assertArrayEquals( - (float[]) metadataFloat.toJavaArray(), (float[]) p.getSecond().toJavaArray(), 1e-10f); - } else { - Assert.assertArrayEquals( - (int[]) metadataInt.toJavaArray(), (int[]) p.getSecond().toJavaArray()); - } + Assert.assertEquals(expectedKeys[i], p.getFirst()); + Assert.assertArrayEquals(getArray(expectedArrays[i]), getArray(p.getSecond().toJavaArray())); } arrayn.close(); From caa69fed8f5cdbd5bb1955a5f67513e659931719 Mon Sep 17 00:00:00 2001 From: Grigory Pomadchin Date: Sat, 2 May 2020 18:38:19 -0400 Subject: [PATCH 5/6] Add more metadata types to test --- .../java/io/tiledb/java/api/ArrayTest.java | 74 ++++++++++++++++--- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/src/test/java/io/tiledb/java/api/ArrayTest.java b/src/test/java/io/tiledb/java/api/ArrayTest.java index a98407f3..39fdaf80 100644 --- a/src/test/java/io/tiledb/java/api/ArrayTest.java +++ b/src/test/java/io/tiledb/java/api/ArrayTest.java @@ -268,6 +268,10 @@ public void testArrayMetadata() throws Exception { Array arrayw = new Array(ctx, arrayURI, TILEDB_WRITE); Array array = new Array(ctx, arrayURI, TILEDB_READ); + NativeArray metadataByte = new NativeArray(ctx, new byte[] {-7, -6, -5, 0, 100}, Byte.class); + + NativeArray metadataShort = new NativeArray(ctx, new short[] {18, 19, 20, 21}, Short.class); + NativeArray metadataInt = new NativeArray( ctx, @@ -288,39 +292,85 @@ public void testArrayMetadata() throws Exception { }, Float.class); + NativeArray metadataDouble = + new NativeArray( + ctx, + new double[] { + 1.1d, 1.2d, 2.1d, 2.2d, 3.1d, 3.2d, 4.1d, 4.2d, + 5.1d, 5.2d, 6.1d, 6.2d, 7.1d, 7.2d, 8.1d, 8.2d, + 9.1d, 9.2d, 10.1d, 10.2d, 11.1d, 11.2d, 12.1d, 12.2d, + 13.1d, 14.2d, 14.1d, 14.2d, 15.1d, 15.2d, 16.1d, 16.2d + }, + Double.class); + + String byteKey = "md-byte"; + String shortKey = "md-short"; String intKey = "md-int"; String floatKey = "md-float"; - Assert.assertEquals(false, array.hasMetadataKey(intKey)); - Assert.assertEquals(false, array.hasMetadataKey(floatKey)); + String doubleKey = "md-double"; + + Assert.assertFalse(array.hasMetadataKey(byteKey)); + Assert.assertFalse(array.hasMetadataKey(shortKey)); + Assert.assertFalse(array.hasMetadataKey(intKey)); + Assert.assertFalse(array.hasMetadataKey(floatKey)); + Assert.assertFalse(array.hasMetadataKey(doubleKey)); Assert.assertEquals(0, array.getMetadataNum().intValue()); array.close(); + arrayw.putMetadata(byteKey, metadataByte); + arrayw.putMetadata(shortKey, metadataShort); arrayw.putMetadata(intKey, metadataInt); arrayw.putMetadata(floatKey, metadataFloat); + arrayw.putMetadata(doubleKey, metadataDouble); // submit changes arrayw.close(); // open a new session Array arrayn = new Array(ctx, arrayURI, TILEDB_READ); - Assert.assertEquals(true, arrayn.hasMetadataKey(intKey)); - Assert.assertEquals(true, arrayn.hasMetadataKey(floatKey)); - Assert.assertEquals(2, arrayn.getMetadataNum().intValue()); + Assert.assertTrue(arrayn.hasMetadataKey(byteKey)); + Assert.assertTrue(arrayn.hasMetadataKey(shortKey)); + Assert.assertTrue(arrayn.hasMetadataKey(intKey)); + Assert.assertTrue(arrayn.hasMetadataKey(floatKey)); + Assert.assertTrue(arrayn.hasMetadataKey(doubleKey)); + Assert.assertEquals(5, arrayn.getMetadataNum().intValue()); + NativeArray metadataByteActual = arrayn.getMetadata(byteKey, Datatype.TILEDB_INT8); + NativeArray metadataShortActual = arrayn.getMetadata(shortKey, Datatype.TILEDB_INT16); NativeArray metadataIntActual = arrayn.getMetadata(intKey, Datatype.TILEDB_INT32); NativeArray metadataFloatActual = arrayn.getMetadata(floatKey, Datatype.TILEDB_FLOAT32); + NativeArray metadataDoubleActual = arrayn.getMetadata(doubleKey, Datatype.TILEDB_FLOAT64); + Assert.assertNotNull(metadataByteActual); + Assert.assertNotNull(metadataShortActual); Assert.assertNotNull(metadataIntActual); Assert.assertNotNull(metadataFloatActual); + Assert.assertNotNull(metadataDoubleActual); + Assert.assertArrayEquals( + (byte[]) metadataByte.toJavaArray(), (byte[]) metadataByteActual.toJavaArray()); + Assert.assertArrayEquals( + (short[]) metadataShort.toJavaArray(), (short[]) metadataShortActual.toJavaArray()); Assert.assertArrayEquals( (int[]) metadataInt.toJavaArray(), (int[]) metadataIntActual.toJavaArray()); Assert.assertArrayEquals( (float[]) metadataFloat.toJavaArray(), (float[]) metadataFloatActual.toJavaArray(), 1e-10f); + Assert.assertArrayEquals( + (double[]) metadataDouble.toJavaArray(), + (double[]) metadataDoubleActual.toJavaArray(), + 1e-10d); // fromIndex tests - String[] expectedKeys = new String[] {floatKey, intKey}; - Object[] expectedArrays = new Object[] {metadataFloat.toJavaArray(), metadataInt.toJavaArray()}; + // metadata keys sorted in a lexicographic ordering + String[] expectedKeys = new String[] {byteKey, doubleKey, floatKey, intKey, shortKey}; + Object[] expectedArrays = + new Object[] { + metadataByte.toJavaArray(), + metadataDouble.toJavaArray(), + metadataFloat.toJavaArray(), + metadataInt.toJavaArray(), + metadataShort.toJavaArray() + }; for (int i = 0; i < arrayn.getMetadataNum().intValue(); i++) { Pair p = arrayn.getMetadataFromIndex(BigInteger.valueOf(i)); @@ -333,14 +383,20 @@ public void testArrayMetadata() throws Exception { // open a new write session Array arrayd = new Array(ctx, arrayURI, TILEDB_WRITE); + arrayd.deleteMetadata(byteKey); + arrayd.deleteMetadata(shortKey); arrayd.deleteMetadata(intKey); arrayd.deleteMetadata(floatKey); + arrayd.deleteMetadata(doubleKey); arrayd.close(); // open a new session to check the deletion Array arraydn = new Array(ctx, arrayURI, TILEDB_READ); - Assert.assertEquals(false, arraydn.hasMetadataKey(intKey)); - Assert.assertEquals(false, arraydn.hasMetadataKey(floatKey)); + Assert.assertFalse(arraydn.hasMetadataKey(byteKey)); + Assert.assertFalse(arraydn.hasMetadataKey(shortKey)); + Assert.assertFalse(arraydn.hasMetadataKey(intKey)); + Assert.assertFalse(arraydn.hasMetadataKey(floatKey)); + Assert.assertFalse(arraydn.hasMetadataKey(doubleKey)); Assert.assertEquals(0, arraydn.getMetadataNum().intValue()); arraydn.close(); From c02c823ea03fbc82658b2b2381dfd68fdc7d6eda Mon Sep 17 00:00:00 2001 From: Grigory Pomadchin Date: Sat, 2 May 2020 21:08:44 -0400 Subject: [PATCH 6/6] Reduce copy pasting in tests, add a new getMetadata overload --- src/main/java/io/tiledb/java/api/Array.java | 32 +++++- .../java/io/tiledb/java/api/ArrayTest.java | 104 ++++++++++-------- 2 files changed, 89 insertions(+), 47 deletions(-) diff --git a/src/main/java/io/tiledb/java/api/Array.java b/src/main/java/io/tiledb/java/api/Array.java index 027a3973..083e09b9 100644 --- a/src/main/java/io/tiledb/java/api/Array.java +++ b/src/main/java/io/tiledb/java/api/Array.java @@ -615,6 +615,18 @@ public HashMap> maxBufferElements(NativeArray subarray) return ret; } + /** + * Get a metadata key-value item from an open array. The array must be opened in READ mode, + * otherwise the function will error out. + * + * @param key a key to retrieve from the metadata key-value + * @return NativeArray which contains the metadata + * @throws TileDBError A TileDB exception + */ + public NativeArray getMetadata(String key) throws TileDBError { + return getMetadata(key, null); + } + /** * Get a metadata key-value item from an open array. The array must be opened in READ mode, * otherwise the function will error out. @@ -630,14 +642,18 @@ public NativeArray getMetadata(String key, Datatype nativeType) throws TileDBErr SWIGTYPE_p_p_void resultArrpp = tiledb.new_voidpArray(0); SWIGTYPE_p_unsigned_int value_num = tiledb.new_uintp(); SWIGTYPE_p_tiledb_datatype_t value_type = - tiledb.copy_tiledb_datatype_tp(nativeType.toSwigEnum()); + (nativeType == null) + ? tiledb.new_tiledb_datatype_tp() + : tiledb.copy_tiledb_datatype_tp(nativeType.toSwigEnum()); ctx.handleError( tiledb.tiledb_array_get_metadata( ctx.getCtxp(), arrayp, key, value_type, value_num, resultArrpp)); + Datatype derivedNativeType = Datatype.fromSwigEnum(tiledb.tiledb_datatype_tp_value(value_type)); + long value = tiledb.uintp_value(value_num); - NativeArray result = new NativeArray(ctx, nativeType, resultArrpp, (int) value); + NativeArray result = new NativeArray(ctx, derivedNativeType, resultArrpp, (int) value); tiledb.delete_uintp(value_num); tiledb.delete_tiledb_datatype_tp(value_type); @@ -679,6 +695,18 @@ public BigInteger getMetadataNum() throws TileDBError { return value; } + /** + * Gets a metadata item from an open array using an index. The array must be opened in READ mode, + * otherwise the function will error out. + * + * @param index index to retrieve metadata from + * @return a pair, key and the metadata + * @throws TileDBError A TileDB exception + */ + public Pair getMetadataFromIndex(long index) throws TileDBError { + return getMetadataFromIndex(BigInteger.valueOf(index)); + } + /** * Gets a metadata item from an open array using an index. The array must be opened in READ mode, * otherwise the function will error out. diff --git a/src/test/java/io/tiledb/java/api/ArrayTest.java b/src/test/java/io/tiledb/java/api/ArrayTest.java index 39fdaf80..e2cc6cb0 100644 --- a/src/test/java/io/tiledb/java/api/ArrayTest.java +++ b/src/test/java/io/tiledb/java/api/ArrayTest.java @@ -1,5 +1,6 @@ package io.tiledb.java.api; +import static io.tiledb.java.api.Datatype.*; import static io.tiledb.java.api.Layout.TILEDB_ROW_MAJOR; import static io.tiledb.java.api.QueryType.TILEDB_READ; import static io.tiledb.java.api.QueryType.TILEDB_WRITE; @@ -309,37 +310,50 @@ public void testArrayMetadata() throws Exception { String floatKey = "md-float"; String doubleKey = "md-double"; - Assert.assertFalse(array.hasMetadataKey(byteKey)); - Assert.assertFalse(array.hasMetadataKey(shortKey)); - Assert.assertFalse(array.hasMetadataKey(intKey)); - Assert.assertFalse(array.hasMetadataKey(floatKey)); - Assert.assertFalse(array.hasMetadataKey(doubleKey)); + // metadata keys sorted in a lexicographic ordering + String[] keys = new String[] {byteKey, doubleKey, floatKey, intKey, shortKey}; + Datatype[] types = + new Datatype[] {TILEDB_INT8, TILEDB_FLOAT64, TILEDB_FLOAT32, TILEDB_INT32, TILEDB_INT16}; + int keysNum = keys.length; + NativeArray[] nativeArrays = + new NativeArray[] {metadataByte, metadataDouble, metadataFloat, metadataInt, metadataShort}; + Object[] expectedArrays = + new Object[] { + metadataByte.toJavaArray(), + metadataDouble.toJavaArray(), + metadataFloat.toJavaArray(), + metadataInt.toJavaArray(), + metadataShort.toJavaArray() + }; + + for (int i = 0; i < keysNum; i++) { + Assert.assertFalse(array.hasMetadataKey(keys[i])); + } + Assert.assertEquals(0, array.getMetadataNum().intValue()); array.close(); - arrayw.putMetadata(byteKey, metadataByte); - arrayw.putMetadata(shortKey, metadataShort); - arrayw.putMetadata(intKey, metadataInt); - arrayw.putMetadata(floatKey, metadataFloat); - arrayw.putMetadata(doubleKey, metadataDouble); + for (int i = 0; i < keysNum; i++) { + arrayw.putMetadata(keys[i], nativeArrays[i]); + } // submit changes arrayw.close(); // open a new session Array arrayn = new Array(ctx, arrayURI, TILEDB_READ); - Assert.assertTrue(arrayn.hasMetadataKey(byteKey)); - Assert.assertTrue(arrayn.hasMetadataKey(shortKey)); - Assert.assertTrue(arrayn.hasMetadataKey(intKey)); - Assert.assertTrue(arrayn.hasMetadataKey(floatKey)); - Assert.assertTrue(arrayn.hasMetadataKey(doubleKey)); - Assert.assertEquals(5, arrayn.getMetadataNum().intValue()); + for (int i = 0; i < keysNum; i++) { + Assert.assertTrue(arrayn.hasMetadataKey(keys[i])); + } + + Assert.assertEquals(keysNum, arrayn.getMetadataNum().intValue()); - NativeArray metadataByteActual = arrayn.getMetadata(byteKey, Datatype.TILEDB_INT8); - NativeArray metadataShortActual = arrayn.getMetadata(shortKey, Datatype.TILEDB_INT16); - NativeArray metadataIntActual = arrayn.getMetadata(intKey, Datatype.TILEDB_INT32); - NativeArray metadataFloatActual = arrayn.getMetadata(floatKey, Datatype.TILEDB_FLOAT32); - NativeArray metadataDoubleActual = arrayn.getMetadata(doubleKey, Datatype.TILEDB_FLOAT64); + // manual extraction of metadata + NativeArray metadataByteActual = arrayn.getMetadata(byteKey, TILEDB_INT8); + NativeArray metadataShortActual = arrayn.getMetadata(shortKey, TILEDB_INT16); + NativeArray metadataIntActual = arrayn.getMetadata(intKey, TILEDB_INT32); + NativeArray metadataFloatActual = arrayn.getMetadata(floatKey, TILEDB_FLOAT32); + NativeArray metadataDoubleActual = arrayn.getMetadata(doubleKey, TILEDB_FLOAT64); Assert.assertNotNull(metadataByteActual); Assert.assertNotNull(metadataShortActual); @@ -360,22 +374,23 @@ public void testArrayMetadata() throws Exception { (double[]) metadataDoubleActual.toJavaArray(), 1e-10d); - // fromIndex tests - // metadata keys sorted in a lexicographic ordering - String[] expectedKeys = new String[] {byteKey, doubleKey, floatKey, intKey, shortKey}; - Object[] expectedArrays = - new Object[] { - metadataByte.toJavaArray(), - metadataDouble.toJavaArray(), - metadataFloat.toJavaArray(), - metadataInt.toJavaArray(), - metadataShort.toJavaArray() - }; + // exctracion of metadata without specifying the Datatype + for (int i = 0; i < keysNum; i++) { + NativeArray a = arrayn.getMetadata(keys[i]); + Assert.assertNotNull(a); + Assert.assertEquals(types[i], a.getNativeType()); + Assert.assertEquals(nativeArrays[i].getNativeType(), a.getNativeType()); + Assert.assertArrayEquals(getArray(expectedArrays[i]), getArray(a.toJavaArray())); + } + // fromIndex tests for (int i = 0; i < arrayn.getMetadataNum().intValue(); i++) { - Pair p = arrayn.getMetadataFromIndex(BigInteger.valueOf(i)); - Assert.assertEquals(expectedKeys[i], p.getFirst()); - Assert.assertArrayEquals(getArray(expectedArrays[i]), getArray(p.getSecond().toJavaArray())); + Pair p = arrayn.getMetadataFromIndex(i); + NativeArray a = p.getSecond(); + Assert.assertEquals(keys[i], p.getFirst()); + Assert.assertEquals(types[i], a.getNativeType()); + Assert.assertEquals(nativeArrays[i].getNativeType(), a.getNativeType()); + Assert.assertArrayEquals(getArray(expectedArrays[i]), getArray(a.toJavaArray())); } arrayn.close(); @@ -383,20 +398,19 @@ public void testArrayMetadata() throws Exception { // open a new write session Array arrayd = new Array(ctx, arrayURI, TILEDB_WRITE); - arrayd.deleteMetadata(byteKey); - arrayd.deleteMetadata(shortKey); - arrayd.deleteMetadata(intKey); - arrayd.deleteMetadata(floatKey); - arrayd.deleteMetadata(doubleKey); + for (int i = 0; i < keysNum; i++) { + arrayd.deleteMetadata(keys[i]); + } + arrayd.close(); // open a new session to check the deletion Array arraydn = new Array(ctx, arrayURI, TILEDB_READ); - Assert.assertFalse(arraydn.hasMetadataKey(byteKey)); - Assert.assertFalse(arraydn.hasMetadataKey(shortKey)); - Assert.assertFalse(arraydn.hasMetadataKey(intKey)); - Assert.assertFalse(arraydn.hasMetadataKey(floatKey)); - Assert.assertFalse(arraydn.hasMetadataKey(doubleKey)); + + for (int i = 0; i < keysNum; i++) { + Assert.assertFalse(arraydn.hasMetadataKey(keys[i])); + } + Assert.assertEquals(0, arraydn.getMetadataNum().intValue()); arraydn.close();