From f8e02c7825f089504fc2f96faee42740624a8e4e Mon Sep 17 00:00:00 2001 From: Adam Retter Date: Thu, 4 Feb 2016 16:55:57 +0000 Subject: [PATCH] Deprecate org.rocksdb.AbstractNativeReference#dispose() and implement java.lang.AutoCloseable --- .../AbstractImmutableNativeReference.java | 2 +- .../org/rocksdb/AbstractNativeReference.java | 23 ++- .../main/java/org/rocksdb/BackupEngine.java | 16 +- java/src/main/java/org/rocksdb/RocksDB.java | 167 ++++++++++-------- .../java/org/rocksdb/RocksMutableObject.java | 2 +- 5 files changed, 122 insertions(+), 88 deletions(-) diff --git a/java/src/main/java/org/rocksdb/AbstractImmutableNativeReference.java b/java/src/main/java/org/rocksdb/AbstractImmutableNativeReference.java index 752c78d41..b0af31ac3 100644 --- a/java/src/main/java/org/rocksdb/AbstractImmutableNativeReference.java +++ b/java/src/main/java/org/rocksdb/AbstractImmutableNativeReference.java @@ -51,7 +51,7 @@ public abstract class AbstractImmutableNativeReference } @Override - public final void dispose() { + public void close() { if (owningHandle_.compareAndSet(true, false)) { disposeInternal(); } diff --git a/java/src/main/java/org/rocksdb/AbstractNativeReference.java b/java/src/main/java/org/rocksdb/AbstractNativeReference.java index 6b71af44e..c5aae4890 100644 --- a/java/src/main/java/org/rocksdb/AbstractNativeReference.java +++ b/java/src/main/java/org/rocksdb/AbstractNativeReference.java @@ -22,7 +22,7 @@ package org.rocksdb; * suggested that you manually dispose of objects when you are finished with * them.

*/ -public abstract class AbstractNativeReference { +public abstract class AbstractNativeReference implements AutoCloseable { /** * Returns true if we are responsible for freeing the underlying C++ object @@ -42,15 +42,34 @@ public abstract class AbstractNativeReference { * disposed, calling any of its functions will lead to undefined * behavior.

*/ - public abstract void dispose(); + @Override + public abstract void close(); + + /** + * @deprecated Instead use {@link AbstractNativeReference#close()} + */ + @Deprecated + public final void dispose() { + close(); + } /** * Simply calls {@link AbstractNativeReference#dispose()} to free * any underlying C++ object reference which has not yet been manually * released. + * + * @deprecated You should not rely on GC of Rocks objects, and instead should + * either call {@link AbstractNativeReference#close()} manually or make + * use of some sort of ARM (Automatic Resource Management) such as + * Java 7's try-with-resources + * statement */ @Override + @Deprecated protected void finalize() throws Throwable { + if(isOwningHandle()) { + //TODO(AR) log a warning message... developer should have called close() + } dispose(); super.finalize(); } diff --git a/java/src/main/java/org/rocksdb/BackupEngine.java b/java/src/main/java/org/rocksdb/BackupEngine.java index 606c5d951..22f1d359e 100644 --- a/java/src/main/java/org/rocksdb/BackupEngine.java +++ b/java/src/main/java/org/rocksdb/BackupEngine.java @@ -175,8 +175,10 @@ public class BackupEngine extends RocksObject implements AutoCloseable { /** * Restore the database from the latest backup * - * @param dbDir The directory to restore the backup to, i.e. where your database is - * @param walDir The location of the log files for your database, often the same as dbDir + * @param dbDir The directory to restore the backup to, i.e. where your + * database is + * @param walDir The location of the log files for your database, often the + * same as dbDir * @param restoreOptions Options for controlling the restore * * @throws RocksDBException thrown if the database could not be restored @@ -189,16 +191,6 @@ public class BackupEngine extends RocksObject implements AutoCloseable { restoreOptions.nativeHandle_); } - /** - * Close the Backup Engine - * - * @throws RocksDBException thrown if the backup engine could not be closed - */ - @Override - public void close() throws RocksDBException { - dispose(); - } - private native static long open(final long env, final long backupableDbOptions) throws RocksDBException; diff --git a/java/src/main/java/org/rocksdb/RocksDB.java b/java/src/main/java/org/rocksdb/RocksDB.java index 143649347..ba5e18b47 100644 --- a/java/src/main/java/org/rocksdb/RocksDB.java +++ b/java/src/main/java/org/rocksdb/RocksDB.java @@ -48,7 +48,8 @@ public class RocksDB extends RocksObject { } catch (IOException e) { - throw new RuntimeException("Unable to load the RocksDB shared library" + e); + throw new RuntimeException("Unable to load the RocksDB shared library" + + e); } } @@ -78,7 +79,8 @@ public class RocksDB extends RocksObject { UnsatisfiedLinkError err = null; for (String path : paths) { try { - System.load(path + "/" + Environment.getJniLibraryFileName("rocksdbjni")); + System.load(path + "/" + + Environment.getJniLibraryFileName("rocksdbjni")); success = true; break; } catch (UnsatisfiedLinkError e) { @@ -116,8 +118,8 @@ public class RocksDB extends RocksObject { * the path to the database using the specified options and db path and a list * of column family names. *

- * If opened in read write mode every existing column family name must be passed - * within the list to this method.

+ * If opened in read write mode every existing column family name must be + * passed within the list to this method.

*

* If opened in read-only mode only a subset of existing column families must * be passed to this method.

@@ -189,8 +191,8 @@ public class RocksDB extends RocksObject { * the path to the database using the specified options and db path and a list * of column family names. *

- * If opened in read write mode every existing column family name must be passed - * within the list to this method.

+ * If opened in read write mode every existing column family name must be + * passed within the list to this method.

*

* If opened in read-only mode only a subset of existing column families must * be passed to this method.

@@ -204,7 +206,8 @@ public class RocksDB extends RocksObject { * with new Options instance as underlying native statistics instance does not * use any locks to prevent concurrent updates.

*

- * ColumnFamily handles are disposed when the RocksDB instance is disposed.

+ * ColumnFamily handles are disposed when the RocksDB instance is disposed. + *

* * @param options {@link org.rocksdb.DBOptions} instance. * @param path the path to the rocksdb. @@ -227,12 +230,14 @@ public class RocksDB extends RocksObject { final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][]; final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()]; for (int i = 0; i < columnFamilyDescriptors.size(); i++) { - final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors.get(i); + final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors + .get(i); cfNames[i] = cfDescriptor.columnFamilyName(); cfOptionHandles[i] = cfDescriptor.columnFamilyOptions().nativeHandle_; } - final long[] handles = open(options.nativeHandle_, path, cfNames, cfOptionHandles); + final long[] handles = open(options.nativeHandle_, path, cfNames, + cfOptionHandles); final RocksDB db = new RocksDB(handles[0]); db.storeOptionsInstance(options); @@ -349,12 +354,14 @@ public class RocksDB extends RocksObject { final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][]; final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()]; for (int i = 0; i < columnFamilyDescriptors.size(); i++) { - final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors.get(i); + final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors + .get(i); cfNames[i] = cfDescriptor.columnFamilyName(); cfOptionHandles[i] = cfDescriptor.columnFamilyOptions().nativeHandle_; } - final long[] handles = openROnly(options.nativeHandle_, path, cfNames, cfOptionHandles); + final long[] handles = openROnly(options.nativeHandle_, path, cfNames, + cfOptionHandles); final RocksDB db = new RocksDB(handles[0]); db.storeOptionsInstance(options); @@ -377,21 +384,14 @@ public class RocksDB extends RocksObject { */ public static List listColumnFamilies(final Options options, final String path) throws RocksDBException { - return Arrays.asList(RocksDB.listColumnFamilies(options.nativeHandle_, path)); + return Arrays.asList(RocksDB.listColumnFamilies(options.nativeHandle_, + path)); } private void storeOptionsInstance(DBOptionsInterface options) { options_ = options; } - /** - * Close the RocksDB instance. - * This function is equivalent to dispose(). - */ - public void close() { - dispose(); - } - /** * Set the database entry for "key" to "value". * @@ -401,7 +401,8 @@ public class RocksDB extends RocksObject { * @throws RocksDBException thrown if error happens in underlying * native library. */ - public void put(final byte[] key, final byte[] value) throws RocksDBException { + public void put(final byte[] key, final byte[] value) + throws RocksDBException { put(nativeHandle_, key, key.length, value, value.length); } @@ -460,8 +461,8 @@ public class RocksDB extends RocksObject { public void put(final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpts, final byte[] key, final byte[] value) throws RocksDBException { - put(nativeHandle_, writeOpts.nativeHandle_, key, key.length, value, value.length, - columnFamilyHandle.nativeHandle_); + put(nativeHandle_, writeOpts.nativeHandle_, key, key.length, value, + value.length, columnFamilyHandle.nativeHandle_); } /** @@ -495,8 +496,8 @@ public class RocksDB extends RocksObject { */ public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle, final byte[] key, final StringBuffer value){ - return keyMayExist(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_, - value); + return keyMayExist(nativeHandle_, key, key.length, + columnFamilyHandle.nativeHandle_, value); } /** @@ -578,7 +579,8 @@ public class RocksDB extends RocksObject { * @throws RocksDBException thrown if error happens in underlying * native library. */ - public void merge(final byte[] key, final byte[] value) throws RocksDBException { + public void merge(final byte[] key, final byte[] value) + throws RocksDBException { merge(nativeHandle_, key, key.length, value, value.length); } @@ -753,9 +755,10 @@ public class RocksDB extends RocksObject { * @throws RocksDBException thrown if error happens in underlying * native library. */ - public byte[] get(final ColumnFamilyHandle columnFamilyHandle, final byte[] key) - throws RocksDBException { - return get(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_); + public byte[] get(final ColumnFamilyHandle columnFamilyHandle, + final byte[] key) throws RocksDBException { + return get(nativeHandle_, key, key.length, + columnFamilyHandle.nativeHandle_); } /** @@ -811,7 +814,8 @@ public class RocksDB extends RocksObject { throws RocksDBException { assert(keys.size() != 0); - final byte[][] values = multiGet(nativeHandle_, keys.toArray(new byte[keys.size()][])); + final byte[][] values = multiGet(nativeHandle_, + keys.toArray(new byte[keys.size()][])); Map keyValueMap = new HashMap<>(); for(int i = 0; i < values.length; i++) { @@ -843,8 +847,10 @@ public class RocksDB extends RocksObject { * @throws IllegalArgumentException thrown if the size of passed keys is not * equal to the amount of passed column family handles. */ - public Map multiGet(final List columnFamilyHandleList, - final List keys) throws RocksDBException, IllegalArgumentException { + public Map multiGet( + final List columnFamilyHandleList, + final List keys) throws RocksDBException, + IllegalArgumentException { assert(keys.size() != 0); // Check if key size equals cfList size. If not a exception must be // thrown. If not a Segmentation fault happens. @@ -856,8 +862,8 @@ public class RocksDB extends RocksObject { for (int i = 0; i < columnFamilyHandleList.size(); i++) { cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_; } - final byte[][] values = multiGet(nativeHandle_, keys.toArray(new byte[keys.size()][]), - cfHandles); + final byte[][] values = multiGet(nativeHandle_, + keys.toArray(new byte[keys.size()][]), cfHandles); Map keyValueMap = new HashMap<>(); for(int i = 0; i < values.length; i++) { @@ -884,7 +890,8 @@ public class RocksDB extends RocksObject { final List keys) throws RocksDBException { assert(keys.size() != 0); - final byte[][] values = multiGet(nativeHandle_, opt.nativeHandle_, keys.toArray(new byte[keys.size()][])); + final byte[][] values = multiGet(nativeHandle_, opt.nativeHandle_, + keys.toArray(new byte[keys.size()][])); Map keyValueMap = new HashMap<>(); for(int i = 0; i < values.length; i++) { @@ -931,7 +938,8 @@ public class RocksDB extends RocksObject { for (int i = 0; i < columnFamilyHandleList.size(); i++) { cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_; } - final byte[][] values = multiGet(nativeHandle_, opt.nativeHandle_, keys.toArray(new byte[keys.size()][]), cfHandles); + final byte[][] values = multiGet(nativeHandle_, opt.nativeHandle_, + keys.toArray(new byte[keys.size()][]), cfHandles); Map keyValueMap = new HashMap<>(); for(int i = 0; i < values.length; i++) { @@ -970,8 +978,8 @@ public class RocksDB extends RocksObject { * @throws RocksDBException thrown if error happens in underlying * native library. */ - public void remove(final ColumnFamilyHandle columnFamilyHandle, final byte[] key) - throws RocksDBException { + public void remove(final ColumnFamilyHandle columnFamilyHandle, + final byte[] key) throws RocksDBException { remove(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_); } @@ -1021,8 +1029,9 @@ public class RocksDB extends RocksObject { * *

Valid property names include: *

    - *
  • "rocksdb.num-files-at-level<N>" - return the number of files at level <N>, - * where <N> is an ASCII representation of a level number (e.g. "0").
  • + *
  • "rocksdb.num-files-at-level<N>" - return the number of files at + * level <N>, where <N> is an ASCII representation of a level + * number (e.g. "0").
  • *
  • "rocksdb.stats" - returns a multi-line string that describes statistics * about the internal operation of the DB.
  • *
  • "rocksdb.sstables" - returns a multi-line string that describes all @@ -1039,8 +1048,8 @@ public class RocksDB extends RocksObject { */ public String getProperty(final ColumnFamilyHandle columnFamilyHandle, final String property) throws RocksDBException { - return getProperty0(nativeHandle_, columnFamilyHandle.nativeHandle_, property, - property.length()); + return getProperty0(nativeHandle_, columnFamilyHandle.nativeHandle_, + property, property.length()); } /** @@ -1051,8 +1060,9 @@ public class RocksDB extends RocksObject { * *

    Valid property names include: *

      - *
    • "rocksdb.num-files-at-level<N>" - return the number of files at level <N>, - * where <N> is an ASCII representation of a level number (e.g. "0").
    • + *
    • "rocksdb.num-files-at-level<N>" - return the number of files at + * level <N>, where <N> is an ASCII representation of a level + * number (e.g. "0").
    • *
    • "rocksdb.stats" - returns a multi-line string that describes statistics * about the internal operation of the DB.
    • *
    • "rocksdb.sstables" - returns a multi-line string that describes all @@ -1070,8 +1080,8 @@ public class RocksDB extends RocksObject { } /** - *

      Similar to GetProperty(), but only works for a subset of properties whose - * return value is a numerical value. Return the value as long.

      + *

      Similar to GetProperty(), but only works for a subset of properties + * whose return value is a numerical value. Return the value as long.

      * *

      Note: As the returned property is of type * {@code uint64_t} on C++ side the returning value can be negative @@ -1096,8 +1106,8 @@ public class RocksDB extends RocksObject { } /** - *

      Similar to GetProperty(), but only works for a subset of properties whose - * return value is a numerical value. Return the value as long.

      + *

      Similar to GetProperty(), but only works for a subset of properties + * whose return value is a numerical value. Return the value as long.

      * *

      Note: As the returned property is of type * {@code uint64_t} on C++ side the returning value can be negative @@ -1121,8 +1131,8 @@ public class RocksDB extends RocksObject { */ public long getLongProperty(final ColumnFamilyHandle columnFamilyHandle, final String property) throws RocksDBException { - return getLongProperty(nativeHandle_, columnFamilyHandle.nativeHandle_, property, - property.length()); + return getLongProperty(nativeHandle_, columnFamilyHandle.nativeHandle_, + property, property.length()); } /** @@ -1204,7 +1214,8 @@ public class RocksDB extends RocksObject { * instance * @return instance of iterator object. */ - public RocksIterator newIterator(final ColumnFamilyHandle columnFamilyHandle) { + public RocksIterator newIterator( + final ColumnFamilyHandle columnFamilyHandle) { return new RocksIterator(this, iteratorCF(nativeHandle_, columnFamilyHandle.nativeHandle_)); } @@ -1244,7 +1255,8 @@ public class RocksDB extends RocksObject { * native library. */ public List newIterators( - final List columnFamilyHandleList) throws RocksDBException { + final List columnFamilyHandleList) + throws RocksDBException { return newIterators(columnFamilyHandleList, new ReadOptions()); } @@ -1274,7 +1286,8 @@ public class RocksDB extends RocksObject { final long[] iteratorRefs = iterators(nativeHandle_, columnFamilyHandles, readOptions.nativeHandle_); - final List iterators = new ArrayList<>(columnFamilyHandleList.size()); + final List iterators = new ArrayList<>( + columnFamilyHandleList.size()); for (int i=0; i