1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 package org.rocksdb; 6 7 import org.junit.ClassRule; 8 import org.junit.Rule; 9 import org.junit.Test; 10 import org.junit.rules.TemporaryFolder; 11 12 import java.util.ArrayList; 13 import java.util.Arrays; 14 import java.util.List; 15 16 import static java.nio.charset.StandardCharsets.UTF_8; 17 import static org.assertj.core.api.Assertions.assertThat; 18 19 public class KeyMayExistTest { 20 21 @ClassRule 22 public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE = 23 new RocksNativeLibraryResource(); 24 25 @Rule 26 public TemporaryFolder dbFolder = new TemporaryFolder(); 27 28 @Test keyMayExist()29 public void keyMayExist() throws RocksDBException { 30 final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList( 31 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 32 new ColumnFamilyDescriptor("new_cf".getBytes()) 33 ); 34 35 final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>(); 36 try (final DBOptions options = new DBOptions() 37 .setCreateIfMissing(true) 38 .setCreateMissingColumnFamilies(true); 39 final RocksDB db = RocksDB.open(options, 40 dbFolder.getRoot().getAbsolutePath(), 41 cfDescriptors, columnFamilyHandleList)) { 42 try { 43 assertThat(columnFamilyHandleList.size()). 44 isEqualTo(2); 45 db.put("key".getBytes(UTF_8), "value".getBytes(UTF_8)); 46 // Test without column family 47 final Holder<byte[]> holder = new Holder<>(); 48 boolean exists = db.keyMayExist("key".getBytes(UTF_8), holder); 49 assertThat(exists).isTrue(); 50 assertThat(holder.getValue()).isNotNull(); 51 assertThat(new String(holder.getValue(), UTF_8)).isEqualTo("value"); 52 53 exists = db.keyMayExist("key".getBytes(UTF_8), null); 54 assertThat(exists).isTrue(); 55 56 // Slice key 57 final StringBuilder builder = new StringBuilder("prefix"); 58 final int offset = builder.toString().length(); 59 builder.append("slice key 0"); 60 final int len = builder.toString().length() - offset; 61 builder.append("suffix"); 62 63 final byte[] sliceKey = builder.toString().getBytes(UTF_8); 64 final byte[] sliceValue = "slice value 0".getBytes(UTF_8); 65 db.put(sliceKey, offset, len, sliceValue, 0, sliceValue.length); 66 67 exists = db.keyMayExist(sliceKey, offset, len, holder); 68 assertThat(exists).isTrue(); 69 assertThat(holder.getValue()).isNotNull(); 70 assertThat(holder.getValue()).isEqualTo(sliceValue); 71 72 exists = db.keyMayExist(sliceKey, offset, len, null); 73 assertThat(exists).isTrue(); 74 75 // Test without column family but with readOptions 76 try (final ReadOptions readOptions = new ReadOptions()) { 77 exists = db.keyMayExist(readOptions, "key".getBytes(UTF_8), holder); 78 assertThat(exists).isTrue(); 79 assertThat(holder.getValue()).isNotNull(); 80 assertThat(new String(holder.getValue(), UTF_8)).isEqualTo("value"); 81 82 exists = db.keyMayExist(readOptions, "key".getBytes(UTF_8), null); 83 assertThat(exists).isTrue(); 84 85 exists = db.keyMayExist(readOptions, sliceKey, offset, len, holder); 86 assertThat(exists).isTrue(); 87 assertThat(holder.getValue()).isNotNull(); 88 assertThat(holder.getValue()).isEqualTo(sliceValue); 89 90 exists = db.keyMayExist(readOptions, sliceKey, offset, len, null); 91 assertThat(exists).isTrue(); 92 } 93 94 // Test with column family 95 exists = db.keyMayExist(columnFamilyHandleList.get(0), "key".getBytes(UTF_8), 96 holder); 97 assertThat(exists).isTrue(); 98 assertThat(holder.getValue()).isNotNull(); 99 assertThat(new String(holder.getValue(), UTF_8)).isEqualTo("value"); 100 101 exists = db.keyMayExist(columnFamilyHandleList.get(0), "key".getBytes(UTF_8), 102 null); 103 assertThat(exists).isTrue(); 104 105 // Test slice sky with column family 106 exists = db.keyMayExist(columnFamilyHandleList.get(0), sliceKey, offset, len, 107 holder); 108 assertThat(exists).isTrue(); 109 assertThat(holder.getValue()).isNotNull(); 110 assertThat(holder.getValue()).isEqualTo(sliceValue); 111 112 exists = db.keyMayExist(columnFamilyHandleList.get(0), sliceKey, offset, len, 113 null); 114 assertThat(exists).isTrue(); 115 116 // Test with column family and readOptions 117 try (final ReadOptions readOptions = new ReadOptions()) { 118 exists = db.keyMayExist(columnFamilyHandleList.get(0), readOptions, 119 "key".getBytes(UTF_8), holder); 120 assertThat(exists).isTrue(); 121 assertThat(holder.getValue()).isNotNull(); 122 assertThat(new String(holder.getValue(), UTF_8)).isEqualTo("value"); 123 124 exists = db.keyMayExist(columnFamilyHandleList.get(0), readOptions, 125 "key".getBytes(UTF_8), null); 126 assertThat(exists).isTrue(); 127 128 // Test slice key with column family and read options 129 exists = db.keyMayExist(columnFamilyHandleList.get(0), readOptions, 130 sliceKey, offset, len, holder); 131 assertThat(exists).isTrue(); 132 assertThat(holder.getValue()).isNotNull(); 133 assertThat(holder.getValue()).isEqualTo(sliceValue); 134 135 exists = db.keyMayExist(columnFamilyHandleList.get(0), readOptions, 136 sliceKey, offset, len, null); 137 assertThat(exists).isTrue(); 138 } 139 140 // KeyMayExist in CF1 must return null value 141 exists = db.keyMayExist(columnFamilyHandleList.get(1), 142 "key".getBytes(UTF_8), holder); 143 assertThat(exists).isFalse(); 144 assertThat(holder.getValue()).isNull(); 145 exists = db.keyMayExist(columnFamilyHandleList.get(1), 146 "key".getBytes(UTF_8), null); 147 assertThat(exists).isFalse(); 148 149 // slice key 150 exists = db.keyMayExist(columnFamilyHandleList.get(1), 151 sliceKey, 1, 3, holder); 152 assertThat(exists).isFalse(); 153 assertThat(holder.getValue()).isNull(); 154 exists = db.keyMayExist(columnFamilyHandleList.get(1), 155 sliceKey, 1, 3, null); 156 assertThat(exists).isFalse(); 157 } finally { 158 for (final ColumnFamilyHandle columnFamilyHandle : 159 columnFamilyHandleList) { 160 columnFamilyHandle.close(); 161 } 162 } 163 } 164 } 165 166 @Test keyMayExistNonUnicodeString()167 public void keyMayExistNonUnicodeString() throws RocksDBException { 168 try (final Options options = new Options() 169 .setCreateIfMissing(true) 170 .setCreateMissingColumnFamilies(true); 171 final RocksDB db = RocksDB.open(options, 172 dbFolder.getRoot().getAbsolutePath())) { 173 final byte key[] = "key".getBytes(UTF_8); 174 final byte value[] = { (byte)0x80 }; // invalid unicode code-point 175 db.put(key, value); 176 177 final byte buf[] = new byte[10]; 178 final int read = db.get(key, buf); 179 assertThat(read).isEqualTo(1); 180 assertThat(buf).startsWith(value); 181 182 final Holder<byte[]> holder = new Holder<>(); 183 boolean exists = db.keyMayExist("key".getBytes(UTF_8), holder); 184 assertThat(exists).isTrue(); 185 assertThat(holder.getValue()).isNotNull(); 186 assertThat(holder.getValue()).isEqualTo(value); 187 188 exists = db.keyMayExist("key".getBytes(UTF_8), null); 189 assertThat(exists).isTrue(); 190 } 191 } 192 } 193