org.rocksdb.ColumnFamilyHandle Maven / Gradle / Ivy
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
package org.rocksdb;
import java.util.Arrays;
import java.util.Objects;
/**
* ColumnFamilyHandle class to hold handles to underlying rocksdb
* ColumnFamily Pointers.
*/
public class ColumnFamilyHandle extends RocksObject {
/**
* Constructs column family Java object, which operates on underlying native object.
*
* @param rocksDB db instance associated with this column family
* @param nativeHandle native handle to underlying native ColumnFamily object
*/
ColumnFamilyHandle(final RocksDB rocksDB,
final long nativeHandle) {
super(nativeHandle);
// rocksDB must point to a valid RocksDB instance;
assert(rocksDB != null);
// ColumnFamilyHandle must hold a reference to the related RocksDB instance
// to guarantee that while a GC cycle starts ColumnFamilyHandle instances
// are freed prior to RocksDB instances.
this.rocksDB_ = rocksDB;
}
/**
* Constructor called only from JNI.
*
* NOTE: we are producing an additional Java Object here to represent the underlying native C++
* ColumnFamilyHandle object. The underlying object is not owned by ourselves. The Java API user
* likely already had a ColumnFamilyHandle Java object which owns the underlying C++ object, as
* they will have been presented it when they opened the database or added a Column Family.
*
*
* TODO(AR) - Potentially a better design would be to cache the active Java Column Family Objects
* in RocksDB, and return the same Java Object instead of instantiating a new one here. This could
* also help us to improve the Java API semantics for Java users. See for example
* https://github.com/facebook/rocksdb/issues/2687.
*
* @param nativeHandle native handle to the column family.
*/
ColumnFamilyHandle(final long nativeHandle) {
super(nativeHandle);
rocksDB_ = null;
disOwnNativeHandle();
}
/**
* Gets the name of the Column Family.
*
* @return The name of the Column Family.
*
* @throws RocksDBException if an error occurs whilst retrieving the name.
*/
public byte[] getName() throws RocksDBException {
assert(isOwningHandle() || isDefaultColumnFamily());
return getName(nativeHandle_);
}
/**
* Gets the ID of the Column Family.
*
* @return the ID of the Column Family.
*/
public int getID() {
assert(isOwningHandle() || isDefaultColumnFamily());
return getID(nativeHandle_);
}
/**
* Gets the up-to-date descriptor of the column family
* associated with this handle. Since it fills "*desc" with the up-to-date
* information, this call might internally lock and release DB mutex to
* access the up-to-date CF options. In addition, all the pointer-typed
* options cannot be referenced any longer than the original options exist.
*
* Note that this function is not supported in RocksDBLite.
*
* @return the up-to-date descriptor.
*
* @throws RocksDBException if an error occurs whilst retrieving the
* descriptor.
*/
public ColumnFamilyDescriptor getDescriptor() throws RocksDBException {
assert(isOwningHandle() || isDefaultColumnFamily());
return getDescriptor(nativeHandle_);
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final ColumnFamilyHandle that = (ColumnFamilyHandle) o;
try {
return rocksDB_.nativeHandle_ == that.rocksDB_.nativeHandle_ &&
getID() == that.getID() &&
Arrays.equals(getName(), that.getName());
} catch (RocksDBException e) {
throw new RuntimeException("Cannot compare column family handles", e);
}
}
@Override
public int hashCode() {
try {
int result = Objects.hash(getID(), rocksDB_.nativeHandle_);
result = 31 * result + Arrays.hashCode(getName());
return result;
} catch (RocksDBException e) {
throw new RuntimeException("Cannot calculate hash code of column family handle", e);
}
}
protected boolean isDefaultColumnFamily() {
return nativeHandle_ == rocksDB_.getDefaultColumnFamily().nativeHandle_;
}
/**
* Deletes underlying C++ iterator pointer.
*
* Note: the underlying handle can only be safely deleted if the RocksDB
* instance related to a certain ColumnFamilyHandle is still valid and
* initialized. Therefore {@code disposeInternal()} checks if the RocksDB is
* initialized before freeing the native handle.
*/
@Override
protected void disposeInternal() {
if(rocksDB_.isOwningHandle()) {
disposeInternal(nativeHandle_);
}
}
private native byte[] getName(final long handle) throws RocksDBException;
private native int getID(final long handle);
private native ColumnFamilyDescriptor getDescriptor(final long handle) throws RocksDBException;
@Override protected final native void disposeInternal(final long handle);
private final RocksDB rocksDB_;
}