diff --git a/java/org/rocksdb/RocksDB.java b/java/org/rocksdb/RocksDB.java index 2a90c7370..f536765f8 100644 --- a/java/org/rocksdb/RocksDB.java +++ b/java/org/rocksdb/RocksDB.java @@ -419,6 +419,22 @@ public class RocksDB extends RocksObject { columnFamilyHandle.nativeHandle_); } + /** + * If the key definitely does not exist in the database, then this method + * returns false, else true. + * + * This check is potentially lighter-weight than invoking DB::Get(). One way + * to make this lighter weight is to avoid doing any IOs. + * + * @param key byte array of a key to search for + * @param value StringBuffer instance which is a out parameter if a value is + * found in block-cache. + * @return boolean value indicating if key does not exist or might exist. + */ + public boolean keyMayExist(byte[] key, StringBuffer value){ + return keyMayExist(key, key.length, value); + } + /** * If the key definitely does not exist in the database, then this method * returns false, else true. @@ -438,6 +454,26 @@ public class RocksDB extends RocksObject { value); } + /** + * If the key definitely does not exist in the database, then this method + * returns false, else true. + * + * This check is potentially lighter-weight than invoking DB::Get(). One way + * to make this lighter weight is to avoid doing any IOs. + * + * @param readOptions {@link ReadOptions} instance + * @param columnFamilyHandle {@link ColumnFamilyHandle} instance + * @param key byte array of a key to search for + * @param value StringBuffer instance which is a out parameter if a value is + * found in block-cache. + * @return boolean value indicating if key does not exist or might exist. + */ + public boolean keyMayExist(ReadOptions readOptions, + byte[] key, StringBuffer value){ + return keyMayExist(readOptions.nativeHandle_, + key, key.length, value); + } + /** * If the key definitely does not exist in the database, then this method * returns false, else true. @@ -1086,8 +1122,12 @@ public class RocksDB extends RocksObject { byte[] value, int valueLen, long cfHandle) throws RocksDBException; protected native void write( long writeOptHandle, long batchHandle) throws RocksDBException; + protected native boolean keyMayExist(byte[] key, int keyLen, + StringBuffer stringBuffer); protected native boolean keyMayExist(byte[] key, int keyLen, long cfHandle, StringBuffer stringBuffer); + protected native boolean keyMayExist(long optionsHandle, byte[] key, int keyLen, + StringBuffer stringBuffer); protected native boolean keyMayExist(long optionsHandle, byte[] key, int keyLen, long cfHandle, StringBuffer stringBuffer); protected native void merge( diff --git a/java/org/rocksdb/test/KeyMayExistTest.java b/java/org/rocksdb/test/KeyMayExistTest.java index a4ecb53da..c83a70e52 100644 --- a/java/org/rocksdb/test/KeyMayExistTest.java +++ b/java/org/rocksdb/test/KeyMayExistTest.java @@ -4,10 +4,7 @@ // of patent rights can be found in the PATENTS file in the same directory. package org.rocksdb.test; -import org.rocksdb.ColumnFamilyHandle; -import org.rocksdb.Options; -import org.rocksdb.RocksDB; -import org.rocksdb.RocksDBException; +import org.rocksdb.*; import java.util.ArrayList; import java.util.List; @@ -34,13 +31,39 @@ public class KeyMayExistTest { assert(columnFamilyHandleList.size()==2); db.put("key".getBytes(), "value".getBytes()); + // Test without column family StringBuffer retValue = new StringBuffer(); + if (db.keyMayExist("key".getBytes(), retValue)) { + assert(retValue.toString().equals("value")); + } else { + assert(false); + } + // Test without column family but with readOptions + retValue = new StringBuffer(); + if (db.keyMayExist(new ReadOptions(), "key".getBytes(), + retValue)) { + assert(retValue.toString().equals("value")); + } else { + assert(false); + } + // Test with column family + retValue = new StringBuffer(); if (db.keyMayExist(columnFamilyHandleList.get(0), "key".getBytes(), retValue)) { assert(retValue.toString().equals("value")); } else { assert(false); } + // Test with column family and readOptions + retValue = new StringBuffer(); + if (db.keyMayExist(new ReadOptions(), + columnFamilyHandleList.get(0), "key".getBytes(), + retValue)) { + assert(retValue.toString().equals("value")); + } else { + assert(false); + } + // KeyMayExist in CF1 must return false assert(db.keyMayExist(columnFamilyHandleList.get(1), "key".getBytes(), retValue) == false); System.out.println("Passed KeyMayExistTest"); diff --git a/java/rocksjni/rocksjni.cc b/java/rocksjni/rocksjni.cc index 50cd8a359..d1a8bb7be 100644 --- a/java/rocksjni/rocksjni.cc +++ b/java/rocksjni/rocksjni.cc @@ -390,8 +390,15 @@ jboolean key_may_exist_helper(JNIEnv* env, rocksdb::DB* db, jboolean isCopy; jbyte* key = env->GetByteArrayElements(jkey, &isCopy); rocksdb::Slice key_slice(reinterpret_cast(key), jkey_len); - bool keyMaxExist = db->KeyMayExist(read_opt, cf_handle, key_slice, - &value, &value_found); + bool keyMayExist; + if (cf_handle != nullptr) { + keyMayExist = db->KeyMayExist(read_opt, cf_handle, key_slice, + &value, &value_found); + } else { + keyMayExist = db->KeyMayExist(read_opt, key_slice, + &value, &value_found); + } + if (value_found && !value.empty()) { jclass clazz = env->GetObjectClass(jvalue); jmethodID mid = env->GetMethodID(clazz, "append", @@ -400,7 +407,20 @@ jboolean key_may_exist_helper(JNIEnv* env, rocksdb::DB* db, env->CallObjectMethod(jvalue, mid, new_value_str); } env->ReleaseByteArrayElements(jkey, key, JNI_ABORT); - return static_cast(keyMaxExist); + return static_cast(keyMayExist); +} + +/* + * Class: org_rocksdb_RocksDB + * Method: keyMayExist + * Signature: ([BILjava/lang/StringBuffer;)Z + */ +jboolean Java_org_rocksdb_RocksDB_keyMayExist___3BILjava_lang_StringBuffer_2( + JNIEnv* env, jobject jdb, jbyteArray jkey, jint jkey_len, + jobject jvalue) { + rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb); + return key_may_exist_helper(env, db, rocksdb::ReadOptions(), + nullptr, jkey, jkey_len, jvalue); } /* @@ -424,6 +444,21 @@ jboolean Java_org_rocksdb_RocksDB_keyMayExist___3BIJLjava_lang_StringBuffer_2( return true; } +/* + * Class: org_rocksdb_RocksDB + * Method: keyMayExist + * Signature: (J[BILjava/lang/StringBuffer;)Z + */ +jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BILjava_lang_StringBuffer_2( + JNIEnv* env, jobject jdb, jlong jread_options_handle, + jbyteArray jkey, jint jkey_len, jobject jvalue) { + rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb); + auto& read_options = *reinterpret_cast( + jread_options_handle); + return key_may_exist_helper(env, db, read_options, + nullptr, jkey, jkey_len, jvalue); +} + /* * Class: org_rocksdb_RocksDB * Method: keyMayExist