diff --git a/java/src/main/java/org/rocksdb/AbstractComparator.java b/java/src/main/java/org/rocksdb/AbstractComparator.java
index a459a9366..78ee37165 100644
--- a/java/src/main/java/org/rocksdb/AbstractComparator.java
+++ b/java/src/main/java/org/rocksdb/AbstractComparator.java
@@ -14,7 +14,8 @@ package org.rocksdb;
* @see org.rocksdb.Comparator
* @see org.rocksdb.DirectComparator
*/
-public abstract class AbstractComparator
+ * This will prevent the object from attempting to delete the underlying
+ * native object in its finalizer. This must be used when another object
+ * takes over ownership of the native object or both will attempt to delete
+ * the underlying object when garbage collected.
+ *
+ * When {@code disOwnNativeHandle()} is called, {@code dispose()} will
+ * subsequently take no action. As a result, incorrect use of this function
+ * may cause a memory leak.
+ *
+ * AbstractNativeReference has the {@link AbstractNativeReference#dispose()}
+ * method, which frees its associated C++ object.
+ * This function should be called manually, however, if required it will be
+ * called automatically during the regular Java GC process via
+ * {@link AbstractNativeReference#finalize()}.
+ * Note - Java can only see the long member variable (which is the C++ pointer
+ * value to the native object), as such it does not know the real size of the
+ * object and therefore may assign a low GC priority for it; So it is strongly
+ * suggested that you manually dispose of objects when you are finished with
+ * them.
+ * It is strong recommended that the developer calls this after they
+ * have finished using the object.
+ * Note, that once an instance of {@link AbstractNativeReference} has been
+ * disposed, calling any of its functions will lead to undefined
+ * behavior.
- * This will prevent the object from attempting to delete the underlying - * native object in its finalizer. This must be used when another object - * takes over ownership of the native object or both will attempt to delete - * the underlying object when garbage collected. - *
- * When {@code disOwnNativeHandle()} is called, {@code dispose()} will simply set - * {@code nativeHandle_} to 0 without releasing its associated C++ resource. - * As a result, incorrectly use this function may cause memory leak, and this - * function call will not affect the return value of {@code isInitialized()}. - *
- * @see #dispose() - */ - protected final void disOwnNativeHandle() { - owningHandle_.set(false); - } - - /** - * Release the c++ object manually pointed by the native handle. - *- * Note that {@code dispose()} will also be called during the GC process - * if it was not called before its {@code RocksObject} went out-of-scope. - * However, since Java may wrongly wrongly assume those objects are - * small in that they seems to only hold a long variable. As a result, - * they might have low priority in the GC process. To prevent this, - * it is suggested to call {@code dispose()} manually. - *
- *- * Note that once an instance of {@code RocksObject} has been disposed, - * calling its function will lead undefined behavior. - *
- */ - public final void dispose() { - if (owningHandle_.compareAndSet(true, false)) { - disposeInternal(); - } - } - - /** - * The helper function of {@code dispose()} which all subclasses of - * {@code RocksObject} must implement to release their associated - * C++ resource. - */ - protected abstract void disposeInternal(); - - /** - * Simply calls {@code dispose()} and release its c++ resource if it has not - * yet released. - */ - @Override - protected void finalize() throws Throwable { - dispose(); - super.finalize(); - } -} diff --git a/java/src/main/java/org/rocksdb/RocksMutableObject.java b/java/src/main/java/org/rocksdb/RocksMutableObject.java index 823711742..ff6c8502b 100644 --- a/java/src/main/java/org/rocksdb/RocksMutableObject.java +++ b/java/src/main/java/org/rocksdb/RocksMutableObject.java @@ -1,50 +1,69 @@ +// Copyright (c) 2016, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. + package org.rocksdb; -public abstract class RocksMutableObject /*extends NativeReference*/ { +/** + * RocksMutableObject is an implementation of {@link AbstractNativeReference} + * whose reference to the underlying native C++ object can change. + * + *The use of {@code RocksMutableObject} should be kept to a minimum, as it + * has synchronization overheads and introduces complexity. Instead it is + * recommended to use {@link RocksObject} where possible.
+ */ +public abstract class RocksMutableObject extends AbstractNativeReference { - private long nativeHandle_; - private boolean owningHandle_; + /** + * An mutable reference to the value of the C++ pointer pointing to some + * underlying native RocksDB C++ object. + */ + private long nativeHandle_; + private boolean owningHandle_; - protected RocksMutableObject() { + protected RocksMutableObject() { + } + + protected RocksMutableObject(final long nativeHandle) { + this.nativeHandle_ = nativeHandle; + this.owningHandle_ = true; + } + + public synchronized void setNativeHandle(final long nativeHandle, + final boolean owningNativeHandle) { + this.nativeHandle_ = nativeHandle; + this.owningHandle_ = owningNativeHandle; + } + + @Override + protected synchronized boolean isOwningHandle() { + return this.owningHandle_; + } + + /** + * Gets the value of the C++ pointer pointing to the underlying + * native C++ object + * + * @return the pointer value for the native object + */ + protected synchronized long getNativeHandle() { + assert (this.nativeHandle_ != 0); + return this.nativeHandle_; + } + + @Override + public synchronized final void dispose() { + if (isOwningHandle()) { + disposeInternal(); + this.owningHandle_ = false; + this.nativeHandle_ = 0; } + } - protected RocksMutableObject(final long nativeHandle) { - this.nativeHandle_ = nativeHandle; - this.owningHandle_ = true; - } + protected void disposeInternal() { + disposeInternal(nativeHandle_); + } - public synchronized void setNativeHandle(final long nativeHandle, final boolean owningNativeHandle) { - this.nativeHandle_ = nativeHandle; - this.owningHandle_ = owningNativeHandle; - } - - //@Override - protected synchronized boolean isOwningHandle() { - return this.owningHandle_; - } - - protected synchronized long getNativeHandle() { - assert(this.nativeHandle_ != 0); - return this.nativeHandle_; - } - - public synchronized final void dispose() { - if(isOwningHandle()) { - disposeInternal(); - this.owningHandle_ = false; - this.nativeHandle_ = 0; - } - } - - @Override - protected void finalize() throws Throwable { - dispose(); - super.finalize(); - } - - protected void disposeInternal() { - disposeInternal(nativeHandle_); - } - - protected abstract void disposeInternal(final long handle); + protected abstract void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/RocksObject.java b/java/src/main/java/org/rocksdb/RocksObject.java index d5c71aecb..2a35852c5 100644 --- a/java/src/main/java/org/rocksdb/RocksObject.java +++ b/java/src/main/java/org/rocksdb/RocksObject.java @@ -6,26 +6,21 @@ package org.rocksdb; /** - * RocksObject is the base-class of all RocksDB classes that has a pointer to - * some c++ {@code rocksdb} object. - * + * RocksObject is an implementation of {@link AbstractNativeReference} which + * has an immutable and therefore thread-safe reference to the underlying + * native C++ RocksDB object. *- * RocksObject has {@code dispose()} function, which releases its associated c++ - * resource.
+ * RocksObject is the base-class of almost all RocksDB classes that have a + * pointer to some underlying native C++ {@code rocksdb} object. *- * This function can be either called manually, or being called automatically - * during the regular Java GC process. However, since Java may wrongly assume a - * RocksObject only contains a long member variable and think it is small in size, - * Java may give {@code RocksObject} low priority in the GC process. For this, it is - * suggested to call {@code dispose()} manually. However, it is safe to let - * {@code RocksObject} go out-of-scope without manually calling {@code dispose()} - * as {@code dispose()} will be called in the finalizer during the - * regular GC process.
+ * The use of {@code RocksObject} should always be preferred over + * {@link RocksMutableObject}. */ -public abstract class RocksObject extends NativeReference { +public abstract class RocksObject extends AbstractImmutableNativeReference { /** - * A long variable holding c++ pointer pointing to some RocksDB C++ object. + * An immutable reference to the value of the C++ pointer pointing to some + * underlying native RocksDB C++ object. */ protected final long nativeHandle_; diff --git a/java/src/main/java/org/rocksdb/WriteBatch.java b/java/src/main/java/org/rocksdb/WriteBatch.java index 760e5dea7..de614b1b5 100644 --- a/java/src/main/java/org/rocksdb/WriteBatch.java +++ b/java/src/main/java/org/rocksdb/WriteBatch.java @@ -90,7 +90,7 @@ public class WriteBatch extends AbstractWriteBatch { /** * Handler callback for iterating over the contents of a batch. */ - public static abstract class Handler extends NativeReference { + public static abstract class Handler extends AbstractImmutableNativeReference { private final long nativeHandle_; public Handler() { super(true);