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.*; 8 import org.junit.rules.ExpectedException; 9 import org.junit.rules.TemporaryFolder; 10 11 import java.nio.ByteBuffer; 12 import java.util.*; 13 14 import static java.nio.charset.StandardCharsets.UTF_8; 15 import static org.assertj.core.api.Assertions.assertThat; 16 import static org.junit.Assert.fail; 17 18 public class RocksDBTest { 19 20 @ClassRule 21 public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE = 22 new RocksNativeLibraryResource(); 23 24 @Rule 25 public TemporaryFolder dbFolder = new TemporaryFolder(); 26 27 public static final Random rand = PlatformRandomHelper. 28 getPlatformSpecificRandomFactory(); 29 30 @Test open()31 public void open() throws RocksDBException { 32 try (final RocksDB db = 33 RocksDB.open(dbFolder.getRoot().getAbsolutePath())) { 34 assertThat(db).isNotNull(); 35 } 36 } 37 38 @Test open_opt()39 public void open_opt() throws RocksDBException { 40 try (final Options opt = new Options().setCreateIfMissing(true); 41 final RocksDB db = RocksDB.open(opt, 42 dbFolder.getRoot().getAbsolutePath())) { 43 assertThat(db).isNotNull(); 44 } 45 } 46 47 @Test openWhenOpen()48 public void openWhenOpen() throws RocksDBException { 49 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 50 51 try (final RocksDB db1 = RocksDB.open(dbPath)) { 52 try (final RocksDB db2 = RocksDB.open(dbPath)) { 53 fail("Should have thrown an exception when opening the same db twice"); 54 } catch (final RocksDBException e) { 55 assertThat(e.getStatus().getCode()).isEqualTo(Status.Code.IOError); 56 assertThat(e.getStatus().getSubCode()).isEqualTo(Status.SubCode.None); 57 assertThat(e.getStatus().getState()).contains("lock "); 58 } 59 } 60 } 61 62 @Test createColumnFamily()63 public void createColumnFamily() throws RocksDBException { 64 final byte[] col1Name = "col1".getBytes(UTF_8); 65 66 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 67 final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions() 68 ) { 69 try (final ColumnFamilyHandle col1 = 70 db.createColumnFamily(new ColumnFamilyDescriptor(col1Name, cfOpts))) { 71 assertThat(col1).isNotNull(); 72 assertThat(col1.getName()).isEqualTo(col1Name); 73 } 74 } 75 76 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); 77 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath(), 78 Arrays.asList( 79 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 80 new ColumnFamilyDescriptor(col1Name)), 81 cfHandles)) { 82 try { 83 assertThat(cfHandles.size()).isEqualTo(2); 84 assertThat(cfHandles.get(1)).isNotNull(); 85 assertThat(cfHandles.get(1).getName()).isEqualTo(col1Name); 86 } finally { 87 for (final ColumnFamilyHandle cfHandle : 88 cfHandles) { 89 cfHandle.close(); 90 } 91 } 92 } 93 } 94 95 96 @Test createColumnFamilies()97 public void createColumnFamilies() throws RocksDBException { 98 final byte[] col1Name = "col1".getBytes(UTF_8); 99 final byte[] col2Name = "col2".getBytes(UTF_8); 100 101 List<ColumnFamilyHandle> cfHandles; 102 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 103 final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions() 104 ) { 105 cfHandles = 106 db.createColumnFamilies(cfOpts, Arrays.asList(col1Name, col2Name)); 107 try { 108 assertThat(cfHandles).isNotNull(); 109 assertThat(cfHandles.size()).isEqualTo(2); 110 assertThat(cfHandles.get(0).getName()).isEqualTo(col1Name); 111 assertThat(cfHandles.get(1).getName()).isEqualTo(col2Name); 112 } finally { 113 for (final ColumnFamilyHandle cfHandle : cfHandles) { 114 cfHandle.close(); 115 } 116 } 117 } 118 119 cfHandles = new ArrayList<>(); 120 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath(), 121 Arrays.asList( 122 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 123 new ColumnFamilyDescriptor(col1Name), 124 new ColumnFamilyDescriptor(col2Name)), 125 cfHandles)) { 126 try { 127 assertThat(cfHandles.size()).isEqualTo(3); 128 assertThat(cfHandles.get(1)).isNotNull(); 129 assertThat(cfHandles.get(1).getName()).isEqualTo(col1Name); 130 assertThat(cfHandles.get(2)).isNotNull(); 131 assertThat(cfHandles.get(2).getName()).isEqualTo(col2Name); 132 } finally { 133 for (final ColumnFamilyHandle cfHandle : cfHandles) { 134 cfHandle.close(); 135 } 136 } 137 } 138 } 139 140 @Test createColumnFamiliesfromDescriptors()141 public void createColumnFamiliesfromDescriptors() throws RocksDBException { 142 final byte[] col1Name = "col1".getBytes(UTF_8); 143 final byte[] col2Name = "col2".getBytes(UTF_8); 144 145 List<ColumnFamilyHandle> cfHandles; 146 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 147 final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions() 148 ) { 149 cfHandles = 150 db.createColumnFamilies(Arrays.asList( 151 new ColumnFamilyDescriptor(col1Name, cfOpts), 152 new ColumnFamilyDescriptor(col2Name, cfOpts))); 153 try { 154 assertThat(cfHandles).isNotNull(); 155 assertThat(cfHandles.size()).isEqualTo(2); 156 assertThat(cfHandles.get(0).getName()).isEqualTo(col1Name); 157 assertThat(cfHandles.get(1).getName()).isEqualTo(col2Name); 158 } finally { 159 for (final ColumnFamilyHandle cfHandle : cfHandles) { 160 cfHandle.close(); 161 } 162 } 163 } 164 165 cfHandles = new ArrayList<>(); 166 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath(), 167 Arrays.asList( 168 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 169 new ColumnFamilyDescriptor(col1Name), 170 new ColumnFamilyDescriptor(col2Name)), 171 cfHandles)) { 172 try { 173 assertThat(cfHandles.size()).isEqualTo(3); 174 assertThat(cfHandles.get(1)).isNotNull(); 175 assertThat(cfHandles.get(1).getName()).isEqualTo(col1Name); 176 assertThat(cfHandles.get(2)).isNotNull(); 177 assertThat(cfHandles.get(2).getName()).isEqualTo(col2Name); 178 } finally { 179 for (final ColumnFamilyHandle cfHandle : cfHandles) { 180 cfHandle.close(); 181 } 182 } 183 } 184 } 185 186 @Test put()187 public void put() throws RocksDBException { 188 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 189 final WriteOptions opt = new WriteOptions(); final ReadOptions optr = new ReadOptions()) { 190 db.put("key1".getBytes(), "value".getBytes()); 191 db.put(opt, "key2".getBytes(), "12345678".getBytes()); 192 assertThat(db.get("key1".getBytes())).isEqualTo( 193 "value".getBytes()); 194 assertThat(db.get("key2".getBytes())).isEqualTo( 195 "12345678".getBytes()); 196 197 ByteBuffer key = ByteBuffer.allocateDirect(12); 198 ByteBuffer value = ByteBuffer.allocateDirect(12); 199 key.position(4); 200 key.put("key3".getBytes()); 201 key.position(4).limit(8); 202 value.position(4); 203 value.put("val3".getBytes()); 204 value.position(4).limit(8); 205 206 db.put(opt, key, value); 207 208 assertThat(key.position()).isEqualTo(8); 209 assertThat(key.limit()).isEqualTo(8); 210 211 assertThat(value.position()).isEqualTo(8); 212 assertThat(value.limit()).isEqualTo(8); 213 214 key.position(4); 215 216 ByteBuffer result = ByteBuffer.allocateDirect(12); 217 assertThat(db.get(optr, key, result)).isEqualTo(4); 218 assertThat(result.position()).isEqualTo(0); 219 assertThat(result.limit()).isEqualTo(4); 220 assertThat(key.position()).isEqualTo(8); 221 assertThat(key.limit()).isEqualTo(8); 222 223 byte[] tmp = new byte[4]; 224 result.get(tmp); 225 assertThat(tmp).isEqualTo("val3".getBytes()); 226 227 key.position(4); 228 229 result.clear().position(9); 230 assertThat(db.get(optr, key, result)).isEqualTo(4); 231 assertThat(result.position()).isEqualTo(9); 232 assertThat(result.limit()).isEqualTo(12); 233 assertThat(key.position()).isEqualTo(8); 234 assertThat(key.limit()).isEqualTo(8); 235 byte[] tmp2 = new byte[3]; 236 result.get(tmp2); 237 assertThat(tmp2).isEqualTo("val".getBytes()); 238 239 // put 240 Segment key3 = sliceSegment("key3"); 241 Segment key4 = sliceSegment("key4"); 242 Segment value0 = sliceSegment("value 0"); 243 Segment value1 = sliceSegment("value 1"); 244 db.put(key3.data, key3.offset, key3.len, value0.data, value0.offset, value0.len); 245 db.put(opt, key4.data, key4.offset, key4.len, value1.data, value1.offset, value1.len); 246 247 // compare 248 Assert.assertTrue(value0.isSamePayload(db.get(key3.data, key3.offset, key3.len))); 249 Assert.assertTrue(value1.isSamePayload(db.get(key4.data, key4.offset, key4.len))); 250 } 251 } 252 sliceSegment(String key)253 private static Segment sliceSegment(String key) { 254 ByteBuffer rawKey = ByteBuffer.allocate(key.length() + 4); 255 rawKey.put((byte)0); 256 rawKey.put((byte)0); 257 rawKey.put(key.getBytes()); 258 259 return new Segment(rawKey.array(), 2, key.length()); 260 } 261 262 private static class Segment { 263 final byte[] data; 264 final int offset; 265 final int len; 266 isSamePayload(byte[] value)267 public boolean isSamePayload(byte[] value) { 268 if (value == null) { 269 return false; 270 } 271 if (value.length != len) { 272 return false; 273 } 274 275 for (int i = 0; i < value.length; i++) { 276 if (data[i + offset] != value[i]) { 277 return false; 278 } 279 } 280 281 return true; 282 } 283 Segment(byte[] value, int offset, int len)284 public Segment(byte[] value, int offset, int len) { 285 this.data = value; 286 this.offset = offset; 287 this.len = len; 288 } 289 } 290 291 @Test write()292 public void write() throws RocksDBException { 293 try (final StringAppendOperator stringAppendOperator = new StringAppendOperator(); 294 final Options options = new Options() 295 .setMergeOperator(stringAppendOperator) 296 .setCreateIfMissing(true); 297 final RocksDB db = RocksDB.open(options, 298 dbFolder.getRoot().getAbsolutePath()); 299 final WriteOptions opts = new WriteOptions()) { 300 301 try (final WriteBatch wb1 = new WriteBatch()) { 302 wb1.put("key1".getBytes(), "aa".getBytes()); 303 wb1.merge("key1".getBytes(), "bb".getBytes()); 304 305 try (final WriteBatch wb2 = new WriteBatch()) { 306 wb2.put("key2".getBytes(), "xx".getBytes()); 307 wb2.merge("key2".getBytes(), "yy".getBytes()); 308 db.write(opts, wb1); 309 db.write(opts, wb2); 310 } 311 } 312 313 assertThat(db.get("key1".getBytes())).isEqualTo( 314 "aa,bb".getBytes()); 315 assertThat(db.get("key2".getBytes())).isEqualTo( 316 "xx,yy".getBytes()); 317 } 318 } 319 320 @Test getWithOutValue()321 public void getWithOutValue() throws RocksDBException { 322 try (final RocksDB db = 323 RocksDB.open(dbFolder.getRoot().getAbsolutePath())) { 324 db.put("key1".getBytes(), "value".getBytes()); 325 db.put("key2".getBytes(), "12345678".getBytes()); 326 byte[] outValue = new byte[5]; 327 // not found value 328 int getResult = db.get("keyNotFound".getBytes(), outValue); 329 assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND); 330 // found value which fits in outValue 331 getResult = db.get("key1".getBytes(), outValue); 332 assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND); 333 assertThat(outValue).isEqualTo("value".getBytes()); 334 // found value which fits partially 335 getResult = db.get("key2".getBytes(), outValue); 336 assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND); 337 assertThat(outValue).isEqualTo("12345".getBytes()); 338 } 339 } 340 341 @Test getWithOutValueReadOptions()342 public void getWithOutValueReadOptions() throws RocksDBException { 343 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 344 final ReadOptions rOpt = new ReadOptions()) { 345 db.put("key1".getBytes(), "value".getBytes()); 346 db.put("key2".getBytes(), "12345678".getBytes()); 347 byte[] outValue = new byte[5]; 348 // not found value 349 int getResult = db.get(rOpt, "keyNotFound".getBytes(), 350 outValue); 351 assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND); 352 // found value which fits in outValue 353 getResult = db.get(rOpt, "key1".getBytes(), outValue); 354 assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND); 355 assertThat(outValue).isEqualTo("value".getBytes()); 356 // found value which fits partially 357 getResult = db.get(rOpt, "key2".getBytes(), outValue); 358 assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND); 359 assertThat(outValue).isEqualTo("12345".getBytes()); 360 } 361 } 362 363 @Rule 364 public ExpectedException thrown = ExpectedException.none(); 365 366 @Test getOutOfArrayMaxSizeValue()367 public void getOutOfArrayMaxSizeValue() throws RocksDBException { 368 final int numberOfValueSplits = 10; 369 final int splitSize = Integer.MAX_VALUE / numberOfValueSplits; 370 371 Runtime runtime = Runtime.getRuntime(); 372 long neededMemory = ((long)(splitSize)) * (((long)numberOfValueSplits) + 3); 373 boolean isEnoughMemory = runtime.maxMemory() - runtime.totalMemory() > neededMemory; 374 Assume.assumeTrue(isEnoughMemory); 375 376 final byte[] valueSplit = new byte[splitSize]; 377 final byte[] key = "key".getBytes(); 378 379 thrown.expect(RocksDBException.class); 380 thrown.expectMessage("Requested array size exceeds VM limit"); 381 382 // merge (numberOfValueSplits + 1) valueSplit's to get value size exceeding Integer.MAX_VALUE 383 try (final StringAppendOperator stringAppendOperator = new StringAppendOperator(); 384 final Options opt = new Options() 385 .setCreateIfMissing(true) 386 .setMergeOperator(stringAppendOperator); 387 final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) { 388 db.put(key, valueSplit); 389 for (int i = 0; i < numberOfValueSplits; i++) { 390 db.merge(key, valueSplit); 391 } 392 db.get(key); 393 } 394 } 395 396 @SuppressWarnings("deprecated") 397 @Test multiGet()398 public void multiGet() throws RocksDBException { 399 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 400 final ReadOptions rOpt = new ReadOptions()) { 401 db.put("key1".getBytes(), "value".getBytes()); 402 db.put("key2".getBytes(), "12345678".getBytes()); 403 List<byte[]> lookupKeys = new ArrayList<>(); 404 lookupKeys.add("key1".getBytes()); 405 lookupKeys.add("key2".getBytes()); 406 Map<byte[], byte[]> results = db.multiGet(lookupKeys); 407 assertThat(results).isNotNull(); 408 assertThat(results.values()).isNotNull(); 409 assertThat(results.values()). 410 contains("value".getBytes(), "12345678".getBytes()); 411 // test same method with ReadOptions 412 results = db.multiGet(rOpt, lookupKeys); 413 assertThat(results).isNotNull(); 414 assertThat(results.values()).isNotNull(); 415 assertThat(results.values()). 416 contains("value".getBytes(), "12345678".getBytes()); 417 418 // remove existing key 419 lookupKeys.remove("key2".getBytes()); 420 // add non existing key 421 lookupKeys.add("key3".getBytes()); 422 results = db.multiGet(lookupKeys); 423 assertThat(results).isNotNull(); 424 assertThat(results.values()).isNotNull(); 425 assertThat(results.values()). 426 contains("value".getBytes()); 427 // test same call with readOptions 428 results = db.multiGet(rOpt, lookupKeys); 429 assertThat(results).isNotNull(); 430 assertThat(results.values()).isNotNull(); 431 assertThat(results.values()). 432 contains("value".getBytes()); 433 } 434 } 435 436 @Test multiGetAsList()437 public void multiGetAsList() throws RocksDBException { 438 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 439 final ReadOptions rOpt = new ReadOptions()) { 440 db.put("key1".getBytes(), "value".getBytes()); 441 db.put("key2".getBytes(), "12345678".getBytes()); 442 List<byte[]> lookupKeys = new ArrayList<>(); 443 lookupKeys.add("key1".getBytes()); 444 lookupKeys.add("key2".getBytes()); 445 List<byte[]> results = db.multiGetAsList(lookupKeys); 446 assertThat(results).isNotNull(); 447 assertThat(results).hasSize(lookupKeys.size()); 448 assertThat(results). 449 containsExactly("value".getBytes(), "12345678".getBytes()); 450 // test same method with ReadOptions 451 results = db.multiGetAsList(rOpt, lookupKeys); 452 assertThat(results).isNotNull(); 453 assertThat(results). 454 contains("value".getBytes(), "12345678".getBytes()); 455 456 // remove existing key 457 lookupKeys.remove(1); 458 // add non existing key 459 lookupKeys.add("key3".getBytes()); 460 results = db.multiGetAsList(lookupKeys); 461 assertThat(results).isNotNull(); 462 assertThat(results). 463 containsExactly("value".getBytes(), null); 464 // test same call with readOptions 465 results = db.multiGetAsList(rOpt, lookupKeys); 466 assertThat(results).isNotNull(); 467 assertThat(results).contains("value".getBytes()); 468 } 469 } 470 471 @Test merge()472 public void merge() throws RocksDBException { 473 try (final StringAppendOperator stringAppendOperator = new StringAppendOperator(); 474 final Options opt = new Options() 475 .setCreateIfMissing(true) 476 .setMergeOperator(stringAppendOperator); 477 final WriteOptions wOpt = new WriteOptions(); 478 final RocksDB db = RocksDB.open(opt, 479 dbFolder.getRoot().getAbsolutePath()) 480 ) { 481 db.put("key1".getBytes(), "value".getBytes()); 482 assertThat(db.get("key1".getBytes())).isEqualTo( 483 "value".getBytes()); 484 // merge key1 with another value portion 485 db.merge("key1".getBytes(), "value2".getBytes()); 486 assertThat(db.get("key1".getBytes())).isEqualTo( 487 "value,value2".getBytes()); 488 // merge key1 with another value portion 489 db.merge(wOpt, "key1".getBytes(), "value3".getBytes()); 490 assertThat(db.get("key1".getBytes())).isEqualTo( 491 "value,value2,value3".getBytes()); 492 // merge on non existent key shall insert the value 493 db.merge(wOpt, "key2".getBytes(), "xxxx".getBytes()); 494 assertThat(db.get("key2".getBytes())).isEqualTo( 495 "xxxx".getBytes()); 496 497 Segment key3 = sliceSegment("key3"); 498 Segment key4 = sliceSegment("key4"); 499 Segment value0 = sliceSegment("value 0"); 500 Segment value1 = sliceSegment("value 1"); 501 502 db.merge(key3.data, key3.offset, key3.len, value0.data, value0.offset, value0.len); 503 db.merge(wOpt, key4.data, key4.offset, key4.len, value1.data, value1.offset, value1.len); 504 505 // compare 506 Assert.assertTrue(value0.isSamePayload(db.get(key3.data, key3.offset, key3.len))); 507 Assert.assertTrue(value1.isSamePayload(db.get(key4.data, key4.offset, key4.len))); 508 } 509 } 510 511 @Test delete()512 public void delete() throws RocksDBException { 513 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 514 final WriteOptions wOpt = new WriteOptions()) { 515 db.put("key1".getBytes(), "value".getBytes()); 516 db.put("key2".getBytes(), "12345678".getBytes()); 517 db.put("key3".getBytes(), "33".getBytes()); 518 assertThat(db.get("key1".getBytes())).isEqualTo( 519 "value".getBytes()); 520 assertThat(db.get("key2".getBytes())).isEqualTo( 521 "12345678".getBytes()); 522 assertThat(db.get("key3".getBytes())).isEqualTo("33".getBytes()); 523 db.delete("key1".getBytes()); 524 db.delete(wOpt, "key2".getBytes()); 525 ByteBuffer key = ByteBuffer.allocateDirect(16); 526 key.put("key3".getBytes()).flip(); 527 db.delete(wOpt, key); 528 assertThat(key.position()).isEqualTo(4); 529 assertThat(key.limit()).isEqualTo(4); 530 531 assertThat(db.get("key1".getBytes())).isNull(); 532 assertThat(db.get("key2".getBytes())).isNull(); 533 534 Segment key3 = sliceSegment("key3"); 535 Segment key4 = sliceSegment("key4"); 536 db.put("key3".getBytes(), "key3 value".getBytes()); 537 db.put("key4".getBytes(), "key4 value".getBytes()); 538 539 db.delete(key3.data, key3.offset, key3.len); 540 db.delete(wOpt, key4.data, key4.offset, key4.len); 541 542 assertThat(db.get("key3".getBytes())).isNull(); 543 assertThat(db.get("key4".getBytes())).isNull(); 544 } 545 } 546 547 @Test singleDelete()548 public void singleDelete() throws RocksDBException { 549 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 550 final WriteOptions wOpt = new WriteOptions()) { 551 db.put("key1".getBytes(), "value".getBytes()); 552 db.put("key2".getBytes(), "12345678".getBytes()); 553 assertThat(db.get("key1".getBytes())).isEqualTo( 554 "value".getBytes()); 555 assertThat(db.get("key2".getBytes())).isEqualTo( 556 "12345678".getBytes()); 557 db.singleDelete("key1".getBytes()); 558 db.singleDelete(wOpt, "key2".getBytes()); 559 assertThat(db.get("key1".getBytes())).isNull(); 560 assertThat(db.get("key2".getBytes())).isNull(); 561 } 562 } 563 564 @Test singleDelete_nonExisting()565 public void singleDelete_nonExisting() throws RocksDBException { 566 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); 567 final WriteOptions wOpt = new WriteOptions()) { 568 db.singleDelete("key1".getBytes()); 569 db.singleDelete(wOpt, "key2".getBytes()); 570 assertThat(db.get("key1".getBytes())).isNull(); 571 assertThat(db.get("key2".getBytes())).isNull(); 572 } 573 } 574 575 @Test deleteRange()576 public void deleteRange() throws RocksDBException { 577 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath())) { 578 db.put("key1".getBytes(), "value".getBytes()); 579 db.put("key2".getBytes(), "12345678".getBytes()); 580 db.put("key3".getBytes(), "abcdefg".getBytes()); 581 db.put("key4".getBytes(), "xyz".getBytes()); 582 assertThat(db.get("key1".getBytes())).isEqualTo("value".getBytes()); 583 assertThat(db.get("key2".getBytes())).isEqualTo("12345678".getBytes()); 584 assertThat(db.get("key3".getBytes())).isEqualTo("abcdefg".getBytes()); 585 assertThat(db.get("key4".getBytes())).isEqualTo("xyz".getBytes()); 586 db.deleteRange("key2".getBytes(), "key4".getBytes()); 587 assertThat(db.get("key1".getBytes())).isEqualTo("value".getBytes()); 588 assertThat(db.get("key2".getBytes())).isNull(); 589 assertThat(db.get("key3".getBytes())).isNull(); 590 assertThat(db.get("key4".getBytes())).isEqualTo("xyz".getBytes()); 591 } 592 } 593 594 @Test getIntProperty()595 public void getIntProperty() throws RocksDBException { 596 try ( 597 final Options options = new Options() 598 .setCreateIfMissing(true) 599 .setMaxWriteBufferNumber(10) 600 .setMinWriteBufferNumberToMerge(10); 601 final RocksDB db = RocksDB.open(options, 602 dbFolder.getRoot().getAbsolutePath()); 603 final WriteOptions wOpt = new WriteOptions().setDisableWAL(true) 604 ) { 605 db.put(wOpt, "key1".getBytes(), "value1".getBytes()); 606 db.put(wOpt, "key2".getBytes(), "value2".getBytes()); 607 db.put(wOpt, "key3".getBytes(), "value3".getBytes()); 608 db.put(wOpt, "key4".getBytes(), "value4".getBytes()); 609 assertThat(db.getLongProperty("rocksdb.num-entries-active-mem-table")) 610 .isGreaterThan(0); 611 assertThat(db.getLongProperty("rocksdb.cur-size-active-mem-table")) 612 .isGreaterThan(0); 613 } 614 } 615 616 @Test fullCompactRange()617 public void fullCompactRange() throws RocksDBException { 618 try (final Options opt = new Options(). 619 setCreateIfMissing(true). 620 setDisableAutoCompactions(true). 621 setCompactionStyle(CompactionStyle.LEVEL). 622 setNumLevels(4). 623 setWriteBufferSize(100 << 10). 624 setLevelZeroFileNumCompactionTrigger(3). 625 setTargetFileSizeBase(200 << 10). 626 setTargetFileSizeMultiplier(1). 627 setMaxBytesForLevelBase(500 << 10). 628 setMaxBytesForLevelMultiplier(1). 629 setDisableAutoCompactions(false); 630 final RocksDB db = RocksDB.open(opt, 631 dbFolder.getRoot().getAbsolutePath())) { 632 // fill database with key/value pairs 633 byte[] b = new byte[10000]; 634 for (int i = 0; i < 200; i++) { 635 rand.nextBytes(b); 636 db.put((String.valueOf(i)).getBytes(), b); 637 } 638 db.compactRange(); 639 } 640 } 641 642 @Test fullCompactRangeColumnFamily()643 public void fullCompactRangeColumnFamily() 644 throws RocksDBException { 645 try ( 646 final DBOptions opt = new DBOptions(). 647 setCreateIfMissing(true). 648 setCreateMissingColumnFamilies(true); 649 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions(). 650 setDisableAutoCompactions(true). 651 setCompactionStyle(CompactionStyle.LEVEL). 652 setNumLevels(4). 653 setWriteBufferSize(100 << 10). 654 setLevelZeroFileNumCompactionTrigger(3). 655 setTargetFileSizeBase(200 << 10). 656 setTargetFileSizeMultiplier(1). 657 setMaxBytesForLevelBase(500 << 10). 658 setMaxBytesForLevelMultiplier(1). 659 setDisableAutoCompactions(false) 660 ) { 661 final List<ColumnFamilyDescriptor> columnFamilyDescriptors = 662 Arrays.asList( 663 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 664 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)); 665 666 // open database 667 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); 668 try (final RocksDB db = RocksDB.open(opt, 669 dbFolder.getRoot().getAbsolutePath(), 670 columnFamilyDescriptors, 671 columnFamilyHandles)) { 672 try { 673 // fill database with key/value pairs 674 byte[] b = new byte[10000]; 675 for (int i = 0; i < 200; i++) { 676 rand.nextBytes(b); 677 db.put(columnFamilyHandles.get(1), 678 String.valueOf(i).getBytes(), b); 679 } 680 db.compactRange(columnFamilyHandles.get(1)); 681 } finally { 682 for (final ColumnFamilyHandle handle : columnFamilyHandles) { 683 handle.close(); 684 } 685 } 686 } 687 } 688 } 689 690 @Test compactRangeWithKeys()691 public void compactRangeWithKeys() 692 throws RocksDBException { 693 try (final Options opt = new Options(). 694 setCreateIfMissing(true). 695 setDisableAutoCompactions(true). 696 setCompactionStyle(CompactionStyle.LEVEL). 697 setNumLevels(4). 698 setWriteBufferSize(100 << 10). 699 setLevelZeroFileNumCompactionTrigger(3). 700 setTargetFileSizeBase(200 << 10). 701 setTargetFileSizeMultiplier(1). 702 setMaxBytesForLevelBase(500 << 10). 703 setMaxBytesForLevelMultiplier(1). 704 setDisableAutoCompactions(false); 705 final RocksDB db = RocksDB.open(opt, 706 dbFolder.getRoot().getAbsolutePath())) { 707 // fill database with key/value pairs 708 byte[] b = new byte[10000]; 709 for (int i = 0; i < 200; i++) { 710 rand.nextBytes(b); 711 db.put((String.valueOf(i)).getBytes(), b); 712 } 713 db.compactRange("0".getBytes(), "201".getBytes()); 714 } 715 } 716 717 @Test compactRangeWithKeysReduce()718 public void compactRangeWithKeysReduce() 719 throws RocksDBException { 720 try ( 721 final Options opt = new Options(). 722 setCreateIfMissing(true). 723 setDisableAutoCompactions(true). 724 setCompactionStyle(CompactionStyle.LEVEL). 725 setNumLevels(4). 726 setWriteBufferSize(100 << 10). 727 setLevelZeroFileNumCompactionTrigger(3). 728 setTargetFileSizeBase(200 << 10). 729 setTargetFileSizeMultiplier(1). 730 setMaxBytesForLevelBase(500 << 10). 731 setMaxBytesForLevelMultiplier(1). 732 setDisableAutoCompactions(false); 733 final RocksDB db = RocksDB.open(opt, 734 dbFolder.getRoot().getAbsolutePath())) { 735 // fill database with key/value pairs 736 byte[] b = new byte[10000]; 737 for (int i = 0; i < 200; i++) { 738 rand.nextBytes(b); 739 db.put((String.valueOf(i)).getBytes(), b); 740 } 741 db.flush(new FlushOptions().setWaitForFlush(true)); 742 try (final CompactRangeOptions compactRangeOpts = new CompactRangeOptions() 743 .setChangeLevel(true) 744 .setTargetLevel(-1) 745 .setTargetPathId(0)) { 746 db.compactRange(null, "0".getBytes(), "201".getBytes(), 747 compactRangeOpts); 748 } 749 } 750 } 751 752 @Test compactRangeWithKeysColumnFamily()753 public void compactRangeWithKeysColumnFamily() 754 throws RocksDBException { 755 try (final DBOptions opt = new DBOptions(). 756 setCreateIfMissing(true). 757 setCreateMissingColumnFamilies(true); 758 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions(). 759 setDisableAutoCompactions(true). 760 setCompactionStyle(CompactionStyle.LEVEL). 761 setNumLevels(4). 762 setWriteBufferSize(100 << 10). 763 setLevelZeroFileNumCompactionTrigger(3). 764 setTargetFileSizeBase(200 << 10). 765 setTargetFileSizeMultiplier(1). 766 setMaxBytesForLevelBase(500 << 10). 767 setMaxBytesForLevelMultiplier(1). 768 setDisableAutoCompactions(false) 769 ) { 770 final List<ColumnFamilyDescriptor> columnFamilyDescriptors = 771 Arrays.asList( 772 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 773 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts) 774 ); 775 776 // open database 777 final List<ColumnFamilyHandle> columnFamilyHandles = 778 new ArrayList<>(); 779 try (final RocksDB db = RocksDB.open(opt, 780 dbFolder.getRoot().getAbsolutePath(), 781 columnFamilyDescriptors, 782 columnFamilyHandles)) { 783 try { 784 // fill database with key/value pairs 785 byte[] b = new byte[10000]; 786 for (int i = 0; i < 200; i++) { 787 rand.nextBytes(b); 788 db.put(columnFamilyHandles.get(1), 789 String.valueOf(i).getBytes(), b); 790 } 791 db.compactRange(columnFamilyHandles.get(1), 792 "0".getBytes(), "201".getBytes()); 793 } finally { 794 for (final ColumnFamilyHandle handle : columnFamilyHandles) { 795 handle.close(); 796 } 797 } 798 } 799 } 800 } 801 802 @Test compactRangeWithKeysReduceColumnFamily()803 public void compactRangeWithKeysReduceColumnFamily() 804 throws RocksDBException { 805 try (final DBOptions opt = new DBOptions(). 806 setCreateIfMissing(true). 807 setCreateMissingColumnFamilies(true); 808 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions(). 809 setDisableAutoCompactions(true). 810 setCompactionStyle(CompactionStyle.LEVEL). 811 setNumLevels(4). 812 setWriteBufferSize(100 << 10). 813 setLevelZeroFileNumCompactionTrigger(3). 814 setTargetFileSizeBase(200 << 10). 815 setTargetFileSizeMultiplier(1). 816 setMaxBytesForLevelBase(500 << 10). 817 setMaxBytesForLevelMultiplier(1). 818 setDisableAutoCompactions(false) 819 ) { 820 final List<ColumnFamilyDescriptor> columnFamilyDescriptors = 821 Arrays.asList( 822 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 823 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts) 824 ); 825 826 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); 827 // open database 828 try (final RocksDB db = RocksDB.open(opt, 829 dbFolder.getRoot().getAbsolutePath(), 830 columnFamilyDescriptors, 831 columnFamilyHandles)) { 832 try (final CompactRangeOptions compactRangeOpts = new CompactRangeOptions() 833 .setChangeLevel(true) 834 .setTargetLevel(-1) 835 .setTargetPathId(0)) { 836 // fill database with key/value pairs 837 byte[] b = new byte[10000]; 838 for (int i = 0; i < 200; i++) { 839 rand.nextBytes(b); 840 db.put(columnFamilyHandles.get(1), 841 String.valueOf(i).getBytes(), b); 842 } 843 db.compactRange(columnFamilyHandles.get(1), "0".getBytes(), 844 "201".getBytes(), compactRangeOpts); 845 } finally { 846 for (final ColumnFamilyHandle handle : columnFamilyHandles) { 847 handle.close(); 848 } 849 } 850 } 851 } 852 } 853 854 @Test compactRangeToLevel()855 public void compactRangeToLevel() 856 throws RocksDBException, InterruptedException { 857 final int NUM_KEYS_PER_L0_FILE = 100; 858 final int KEY_SIZE = 20; 859 final int VALUE_SIZE = 300; 860 final int L0_FILE_SIZE = 861 NUM_KEYS_PER_L0_FILE * (KEY_SIZE + VALUE_SIZE); 862 final int NUM_L0_FILES = 10; 863 final int TEST_SCALE = 5; 864 final int KEY_INTERVAL = 100; 865 try (final Options opt = new Options(). 866 setCreateIfMissing(true). 867 setCompactionStyle(CompactionStyle.LEVEL). 868 setNumLevels(5). 869 // a slightly bigger write buffer than L0 file 870 // so that we can ensure manual flush always 871 // go before background flush happens. 872 setWriteBufferSize(L0_FILE_SIZE * 2). 873 // Disable auto L0 -> L1 compaction 874 setLevelZeroFileNumCompactionTrigger(20). 875 setTargetFileSizeBase(L0_FILE_SIZE * 100). 876 setTargetFileSizeMultiplier(1). 877 // To disable auto compaction 878 setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100). 879 setMaxBytesForLevelMultiplier(2). 880 setDisableAutoCompactions(true); 881 final RocksDB db = RocksDB.open(opt, 882 dbFolder.getRoot().getAbsolutePath()) 883 ) { 884 // fill database with key/value pairs 885 byte[] value = new byte[VALUE_SIZE]; 886 int int_key = 0; 887 for (int round = 0; round < 5; ++round) { 888 int initial_key = int_key; 889 for (int f = 1; f <= NUM_L0_FILES; ++f) { 890 for (int i = 0; i < NUM_KEYS_PER_L0_FILE; ++i) { 891 int_key += KEY_INTERVAL; 892 rand.nextBytes(value); 893 894 db.put(String.format("%020d", int_key).getBytes(), 895 value); 896 } 897 db.flush(new FlushOptions().setWaitForFlush(true)); 898 // Make sure we do create one more L0 files. 899 assertThat( 900 db.getProperty("rocksdb.num-files-at-level0")). 901 isEqualTo("" + f); 902 } 903 904 // Compact all L0 files we just created 905 db.compactRange( 906 String.format("%020d", initial_key).getBytes(), 907 String.format("%020d", int_key - 1).getBytes()); 908 // Making sure there isn't any L0 files. 909 assertThat( 910 db.getProperty("rocksdb.num-files-at-level0")). 911 isEqualTo("0"); 912 // Making sure there are some L1 files. 913 // Here we only use != 0 instead of a specific number 914 // as we don't want the test make any assumption on 915 // how compaction works. 916 assertThat( 917 db.getProperty("rocksdb.num-files-at-level1")). 918 isNotEqualTo("0"); 919 // Because we only compacted those keys we issued 920 // in this round, there shouldn't be any L1 -> L2 921 // compaction. So we expect zero L2 files here. 922 assertThat( 923 db.getProperty("rocksdb.num-files-at-level2")). 924 isEqualTo("0"); 925 } 926 } 927 } 928 929 @Test deleteFilesInRange()930 public void deleteFilesInRange() throws RocksDBException, InterruptedException { 931 final int KEY_SIZE = 20; 932 final int VALUE_SIZE = 1000; 933 final int FILE_SIZE = 64000; 934 final int NUM_FILES = 10; 935 936 final int KEY_INTERVAL = 10000; 937 /* 938 * Intention of these options is to end up reliably with 10 files 939 * we will be deleting using deleteFilesInRange. 940 * It is writing roughly number of keys that will fit in 10 files (target size) 941 * It is writing interleaved so that files from memory on L0 will overlap 942 * Then compaction cleans everything and we should end up with 10 files 943 */ 944 try (final Options opt = new Options() 945 .setCreateIfMissing(true) 946 .setCompressionType(CompressionType.NO_COMPRESSION) 947 .setTargetFileSizeBase(FILE_SIZE) 948 .setWriteBufferSize(FILE_SIZE / 2) 949 .setDisableAutoCompactions(true); 950 final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) { 951 int records = FILE_SIZE / (KEY_SIZE + VALUE_SIZE); 952 953 // fill database with key/value pairs 954 byte[] value = new byte[VALUE_SIZE]; 955 int key_init = 0; 956 for (int o = 0; o < NUM_FILES; ++o) { 957 int int_key = key_init++; 958 for (int i = 0; i < records; ++i) { 959 int_key += KEY_INTERVAL; 960 rand.nextBytes(value); 961 962 db.put(String.format("%020d", int_key).getBytes(), value); 963 } 964 } 965 db.flush(new FlushOptions().setWaitForFlush(true)); 966 db.compactRange(); 967 // Make sure we do create one more L0 files. 968 assertThat(db.getProperty("rocksdb.num-files-at-level0")).isEqualTo("0"); 969 970 // Should be 10, but we are OK with asserting +- 2 971 int files = Integer.parseInt(db.getProperty("rocksdb.num-files-at-level1")); 972 assertThat(files).isBetween(8, 12); 973 974 // Delete lower 60% (roughly). Result should be 5, but we are OK with asserting +- 2 975 // Important is that we know something was deleted (JNI call did something) 976 // Exact assertions are done in C++ unit tests 977 db.deleteFilesInRanges(null, 978 Arrays.asList(null, String.format("%020d", records * KEY_INTERVAL * 6 / 10).getBytes()), 979 false); 980 files = Integer.parseInt(db.getProperty("rocksdb.num-files-at-level1")); 981 assertThat(files).isBetween(3, 7); 982 } 983 } 984 985 @Test compactRangeToLevelColumnFamily()986 public void compactRangeToLevelColumnFamily() 987 throws RocksDBException { 988 final int NUM_KEYS_PER_L0_FILE = 100; 989 final int KEY_SIZE = 20; 990 final int VALUE_SIZE = 300; 991 final int L0_FILE_SIZE = 992 NUM_KEYS_PER_L0_FILE * (KEY_SIZE + VALUE_SIZE); 993 final int NUM_L0_FILES = 10; 994 final int TEST_SCALE = 5; 995 final int KEY_INTERVAL = 100; 996 997 try (final DBOptions opt = new DBOptions(). 998 setCreateIfMissing(true). 999 setCreateMissingColumnFamilies(true); 1000 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions(). 1001 setCompactionStyle(CompactionStyle.LEVEL). 1002 setNumLevels(5). 1003 // a slightly bigger write buffer than L0 file 1004 // so that we can ensure manual flush always 1005 // go before background flush happens. 1006 setWriteBufferSize(L0_FILE_SIZE * 2). 1007 // Disable auto L0 -> L1 compaction 1008 setLevelZeroFileNumCompactionTrigger(20). 1009 setTargetFileSizeBase(L0_FILE_SIZE * 100). 1010 setTargetFileSizeMultiplier(1). 1011 // To disable auto compaction 1012 setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100). 1013 setMaxBytesForLevelMultiplier(2). 1014 setDisableAutoCompactions(true) 1015 ) { 1016 final List<ColumnFamilyDescriptor> columnFamilyDescriptors = 1017 Arrays.asList( 1018 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 1019 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts) 1020 ); 1021 1022 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); 1023 // open database 1024 try (final RocksDB db = RocksDB.open(opt, 1025 dbFolder.getRoot().getAbsolutePath(), 1026 columnFamilyDescriptors, 1027 columnFamilyHandles)) { 1028 try { 1029 // fill database with key/value pairs 1030 byte[] value = new byte[VALUE_SIZE]; 1031 int int_key = 0; 1032 for (int round = 0; round < 5; ++round) { 1033 int initial_key = int_key; 1034 for (int f = 1; f <= NUM_L0_FILES; ++f) { 1035 for (int i = 0; i < NUM_KEYS_PER_L0_FILE; ++i) { 1036 int_key += KEY_INTERVAL; 1037 rand.nextBytes(value); 1038 1039 db.put(columnFamilyHandles.get(1), 1040 String.format("%020d", int_key).getBytes(), 1041 value); 1042 } 1043 db.flush(new FlushOptions().setWaitForFlush(true), 1044 columnFamilyHandles.get(1)); 1045 // Make sure we do create one more L0 files. 1046 assertThat( 1047 db.getProperty(columnFamilyHandles.get(1), 1048 "rocksdb.num-files-at-level0")). 1049 isEqualTo("" + f); 1050 } 1051 1052 // Compact all L0 files we just created 1053 db.compactRange( 1054 columnFamilyHandles.get(1), 1055 String.format("%020d", initial_key).getBytes(), 1056 String.format("%020d", int_key - 1).getBytes()); 1057 // Making sure there isn't any L0 files. 1058 assertThat( 1059 db.getProperty(columnFamilyHandles.get(1), 1060 "rocksdb.num-files-at-level0")). 1061 isEqualTo("0"); 1062 // Making sure there are some L1 files. 1063 // Here we only use != 0 instead of a specific number 1064 // as we don't want the test make any assumption on 1065 // how compaction works. 1066 assertThat( 1067 db.getProperty(columnFamilyHandles.get(1), 1068 "rocksdb.num-files-at-level1")). 1069 isNotEqualTo("0"); 1070 // Because we only compacted those keys we issued 1071 // in this round, there shouldn't be any L1 -> L2 1072 // compaction. So we expect zero L2 files here. 1073 assertThat( 1074 db.getProperty(columnFamilyHandles.get(1), 1075 "rocksdb.num-files-at-level2")). 1076 isEqualTo("0"); 1077 } 1078 } finally { 1079 for (final ColumnFamilyHandle handle : columnFamilyHandles) { 1080 handle.close(); 1081 } 1082 } 1083 } 1084 } 1085 } 1086 1087 @Test continueBackgroundWorkAfterCancelAllBackgroundWork()1088 public void continueBackgroundWorkAfterCancelAllBackgroundWork() throws RocksDBException { 1089 final int KEY_SIZE = 20; 1090 final int VALUE_SIZE = 300; 1091 try (final DBOptions opt = new DBOptions(). 1092 setCreateIfMissing(true). 1093 setCreateMissingColumnFamilies(true); 1094 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions() 1095 ) { 1096 final List<ColumnFamilyDescriptor> columnFamilyDescriptors = 1097 Arrays.asList( 1098 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 1099 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts) 1100 ); 1101 1102 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); 1103 // open the database 1104 try (final RocksDB db = RocksDB.open(opt, 1105 dbFolder.getRoot().getAbsolutePath(), 1106 columnFamilyDescriptors, 1107 columnFamilyHandles)) { 1108 try { 1109 db.cancelAllBackgroundWork(true); 1110 try { 1111 db.put(new byte[KEY_SIZE], new byte[VALUE_SIZE]); 1112 db.flush(new FlushOptions().setWaitForFlush(true)); 1113 fail("Expected RocksDBException to be thrown if we attempt to trigger a flush after" + 1114 " all background work is cancelled."); 1115 } catch (RocksDBException ignored) { } 1116 } finally { 1117 for (final ColumnFamilyHandle handle : columnFamilyHandles) { 1118 handle.close(); 1119 } 1120 } 1121 } 1122 } 1123 } 1124 1125 @Test cancelAllBackgroundWorkTwice()1126 public void cancelAllBackgroundWorkTwice() throws RocksDBException { 1127 try (final Options options = new Options().setCreateIfMissing(true); 1128 final RocksDB db = RocksDB.open(options, 1129 dbFolder.getRoot().getAbsolutePath()) 1130 ) { 1131 // Cancel all background work synchronously 1132 db.cancelAllBackgroundWork(true); 1133 // Cancel all background work asynchronously 1134 db.cancelAllBackgroundWork(false); 1135 } 1136 } 1137 1138 @Test pauseContinueBackgroundWork()1139 public void pauseContinueBackgroundWork() throws RocksDBException { 1140 try (final Options options = new Options().setCreateIfMissing(true); 1141 final RocksDB db = RocksDB.open(options, 1142 dbFolder.getRoot().getAbsolutePath()) 1143 ) { 1144 db.pauseBackgroundWork(); 1145 db.continueBackgroundWork(); 1146 db.pauseBackgroundWork(); 1147 db.continueBackgroundWork(); 1148 } 1149 } 1150 1151 @Test enableDisableFileDeletions()1152 public void enableDisableFileDeletions() throws RocksDBException { 1153 try (final Options options = new Options().setCreateIfMissing(true); 1154 final RocksDB db = RocksDB.open(options, 1155 dbFolder.getRoot().getAbsolutePath()) 1156 ) { 1157 db.disableFileDeletions(); 1158 db.enableFileDeletions(false); 1159 db.disableFileDeletions(); 1160 db.enableFileDeletions(true); 1161 } 1162 } 1163 1164 @Test setOptions()1165 public void setOptions() throws RocksDBException { 1166 try (final DBOptions options = new DBOptions() 1167 .setCreateIfMissing(true) 1168 .setCreateMissingColumnFamilies(true); 1169 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions() 1170 .setWriteBufferSize(4096)) { 1171 1172 final List<ColumnFamilyDescriptor> columnFamilyDescriptors = 1173 Arrays.asList( 1174 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 1175 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)); 1176 1177 // open database 1178 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); 1179 try (final RocksDB db = RocksDB.open(options, 1180 dbFolder.getRoot().getAbsolutePath(), columnFamilyDescriptors, columnFamilyHandles)) { 1181 try { 1182 final MutableColumnFamilyOptions mutableOptions = 1183 MutableColumnFamilyOptions.builder() 1184 .setWriteBufferSize(2048) 1185 .build(); 1186 1187 db.setOptions(columnFamilyHandles.get(1), mutableOptions); 1188 1189 } finally { 1190 for (final ColumnFamilyHandle handle : columnFamilyHandles) { 1191 handle.close(); 1192 } 1193 } 1194 } 1195 } 1196 } 1197 1198 @Test destroyDB()1199 public void destroyDB() throws RocksDBException { 1200 try (final Options options = new Options().setCreateIfMissing(true)) { 1201 String dbPath = dbFolder.getRoot().getAbsolutePath(); 1202 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1203 db.put("key1".getBytes(), "value".getBytes()); 1204 } 1205 assertThat(dbFolder.getRoot().exists() && dbFolder.getRoot().listFiles().length != 0) 1206 .isTrue(); 1207 RocksDB.destroyDB(dbPath, options); 1208 assertThat(dbFolder.getRoot().exists() && dbFolder.getRoot().listFiles().length != 0) 1209 .isFalse(); 1210 } 1211 } 1212 1213 @Test(expected = RocksDBException.class) destroyDBFailIfOpen()1214 public void destroyDBFailIfOpen() throws RocksDBException { 1215 try (final Options options = new Options().setCreateIfMissing(true)) { 1216 String dbPath = dbFolder.getRoot().getAbsolutePath(); 1217 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1218 // Fails as the db is open and locked. 1219 RocksDB.destroyDB(dbPath, options); 1220 } 1221 } 1222 } 1223 1224 @Test getApproximateSizes()1225 public void getApproximateSizes() throws RocksDBException { 1226 final byte key1[] = "key1".getBytes(UTF_8); 1227 final byte key2[] = "key2".getBytes(UTF_8); 1228 final byte key3[] = "key3".getBytes(UTF_8); 1229 try (final Options options = new Options().setCreateIfMissing(true)) { 1230 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1231 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1232 db.put(key1, key1); 1233 db.put(key2, key2); 1234 db.put(key3, key3); 1235 1236 final long[] sizes = db.getApproximateSizes( 1237 Arrays.asList( 1238 new Range(new Slice(key1), new Slice(key1)), 1239 new Range(new Slice(key2), new Slice(key3)) 1240 ), 1241 SizeApproximationFlag.INCLUDE_FILES, 1242 SizeApproximationFlag.INCLUDE_MEMTABLES); 1243 1244 assertThat(sizes.length).isEqualTo(2); 1245 assertThat(sizes[0]).isEqualTo(0); 1246 assertThat(sizes[1]).isGreaterThanOrEqualTo(1); 1247 } 1248 } 1249 } 1250 1251 @Test getApproximateMemTableStats()1252 public void getApproximateMemTableStats() throws RocksDBException { 1253 final byte key1[] = "key1".getBytes(UTF_8); 1254 final byte key2[] = "key2".getBytes(UTF_8); 1255 final byte key3[] = "key3".getBytes(UTF_8); 1256 try (final Options options = new Options().setCreateIfMissing(true)) { 1257 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1258 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1259 db.put(key1, key1); 1260 db.put(key2, key2); 1261 db.put(key3, key3); 1262 1263 final RocksDB.CountAndSize stats = 1264 db.getApproximateMemTableStats( 1265 new Range(new Slice(key1), new Slice(key3))); 1266 1267 assertThat(stats).isNotNull(); 1268 assertThat(stats.count).isGreaterThan(1); 1269 assertThat(stats.size).isGreaterThan(1); 1270 } 1271 } 1272 } 1273 1274 @Test getApproximateMemTableStatsSingleKey()1275 public void getApproximateMemTableStatsSingleKey() throws RocksDBException { 1276 final byte key1[] = "key1".getBytes(UTF_8); 1277 final byte key2[] = "key2".getBytes(UTF_8); 1278 final byte key3[] = "key3".getBytes(UTF_8); 1279 try (final Options options = new Options().setCreateIfMissing(true)) { 1280 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1281 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1282 db.put(key1, key1); 1283 1284 final RocksDB.CountAndSize stats = 1285 db.getApproximateMemTableStats(new Range(new Slice(key1), new Slice(key3))); 1286 1287 assertThat(stats).isNotNull(); 1288 assertThat(stats.count).isEqualTo(1); 1289 assertThat(stats.size).isGreaterThan(1); 1290 } 1291 } 1292 } 1293 1294 @Ignore("TODO(AR) re-enable when ready!") 1295 @Test compactFiles()1296 public void compactFiles() throws RocksDBException { 1297 final int kTestKeySize = 16; 1298 final int kTestValueSize = 984; 1299 final int kEntrySize = kTestKeySize + kTestValueSize; 1300 final int kEntriesPerBuffer = 100; 1301 final int writeBufferSize = kEntrySize * kEntriesPerBuffer; 1302 final byte[] cfName = "pikachu".getBytes(UTF_8); 1303 1304 try (final Options options = new Options() 1305 .setCreateIfMissing(true) 1306 .setWriteBufferSize(writeBufferSize) 1307 .setCompactionStyle(CompactionStyle.LEVEL) 1308 .setTargetFileSizeBase(writeBufferSize) 1309 .setMaxBytesForLevelBase(writeBufferSize * 2) 1310 .setLevel0StopWritesTrigger(2) 1311 .setMaxBytesForLevelMultiplier(2) 1312 .setCompressionType(CompressionType.NO_COMPRESSION) 1313 .setMaxSubcompactions(4)) { 1314 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1315 try (final RocksDB db = RocksDB.open(options, dbPath); 1316 final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions(options)) { 1317 db.createColumnFamily(new ColumnFamilyDescriptor(cfName, 1318 cfOptions)).close(); 1319 } 1320 1321 try (final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions(options)) { 1322 final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList( 1323 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOptions), 1324 new ColumnFamilyDescriptor(cfName, cfOptions) 1325 ); 1326 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); 1327 try (final DBOptions dbOptions = new DBOptions(options); 1328 final RocksDB db = RocksDB.open(dbOptions, dbPath, cfDescriptors, 1329 cfHandles); 1330 ) { 1331 try (final FlushOptions flushOptions = new FlushOptions() 1332 .setWaitForFlush(true) 1333 .setAllowWriteStall(true); 1334 final CompactionOptions compactionOptions = new CompactionOptions()) { 1335 final Random rnd = new Random(301); 1336 for (int key = 64 * kEntriesPerBuffer; key >= 0; --key) { 1337 final byte[] value = new byte[kTestValueSize]; 1338 rnd.nextBytes(value); 1339 db.put(cfHandles.get(1), Integer.toString(key).getBytes(UTF_8), 1340 value); 1341 } 1342 db.flush(flushOptions, cfHandles); 1343 1344 final RocksDB.LiveFiles liveFiles = db.getLiveFiles(); 1345 final List<String> compactedFiles = 1346 db.compactFiles(compactionOptions, cfHandles.get(1), 1347 liveFiles.files, 1, -1, null); 1348 assertThat(compactedFiles).isNotEmpty(); 1349 } finally { 1350 for (final ColumnFamilyHandle cfHandle : cfHandles) { 1351 cfHandle.close(); 1352 } 1353 } 1354 } 1355 } 1356 } 1357 } 1358 1359 @Test enableAutoCompaction()1360 public void enableAutoCompaction() throws RocksDBException { 1361 try (final DBOptions options = new DBOptions() 1362 .setCreateIfMissing(true)) { 1363 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList( 1364 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY) 1365 ); 1366 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); 1367 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1368 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) { 1369 try { 1370 db.enableAutoCompaction(cfHandles); 1371 } finally { 1372 for (final ColumnFamilyHandle cfHandle : cfHandles) { 1373 cfHandle.close(); 1374 } 1375 } 1376 } 1377 } 1378 } 1379 1380 @Test numberLevels()1381 public void numberLevels() throws RocksDBException { 1382 try (final Options options = new Options().setCreateIfMissing(true)) { 1383 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1384 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1385 assertThat(db.numberLevels()).isEqualTo(7); 1386 } 1387 } 1388 } 1389 1390 @Test maxMemCompactionLevel()1391 public void maxMemCompactionLevel() throws RocksDBException { 1392 try (final Options options = new Options().setCreateIfMissing(true)) { 1393 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1394 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1395 assertThat(db.maxMemCompactionLevel()).isEqualTo(0); 1396 } 1397 } 1398 } 1399 1400 @Test level0StopWriteTrigger()1401 public void level0StopWriteTrigger() throws RocksDBException { 1402 try (final Options options = new Options().setCreateIfMissing(true)) { 1403 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1404 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1405 assertThat(db.level0StopWriteTrigger()).isEqualTo(36); 1406 } 1407 } 1408 } 1409 1410 @Test getName()1411 public void getName() throws RocksDBException { 1412 try (final Options options = new Options().setCreateIfMissing(true)) { 1413 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1414 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1415 assertThat(db.getName()).isEqualTo(dbPath); 1416 } 1417 } 1418 } 1419 1420 @Test getEnv()1421 public void getEnv() throws RocksDBException { 1422 try (final Options options = new Options().setCreateIfMissing(true)) { 1423 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1424 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1425 assertThat(db.getEnv()).isEqualTo(Env.getDefault()); 1426 } 1427 } 1428 } 1429 1430 @Test flush()1431 public void flush() throws RocksDBException { 1432 try (final Options options = new Options().setCreateIfMissing(true)) { 1433 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1434 try (final RocksDB db = RocksDB.open(options, dbPath); 1435 final FlushOptions flushOptions = new FlushOptions()) { 1436 db.flush(flushOptions); 1437 } 1438 } 1439 } 1440 1441 @Test flushWal()1442 public void flushWal() throws RocksDBException { 1443 try (final Options options = new Options().setCreateIfMissing(true)) { 1444 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1445 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1446 db.flushWal(true); 1447 } 1448 } 1449 } 1450 1451 @Test syncWal()1452 public void syncWal() throws RocksDBException { 1453 try (final Options options = new Options().setCreateIfMissing(true)) { 1454 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1455 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1456 db.syncWal(); 1457 } 1458 } 1459 } 1460 1461 @Test setPreserveDeletesSequenceNumber()1462 public void setPreserveDeletesSequenceNumber() throws RocksDBException { 1463 try (final Options options = new Options().setCreateIfMissing(true)) { 1464 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1465 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1466 assertThat(db.setPreserveDeletesSequenceNumber(db.getLatestSequenceNumber())) 1467 .isFalse(); 1468 } 1469 } 1470 } 1471 1472 @Test getLiveFiles()1473 public void getLiveFiles() throws RocksDBException { 1474 try (final Options options = new Options().setCreateIfMissing(true)) { 1475 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1476 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1477 final RocksDB.LiveFiles livefiles = db.getLiveFiles(true); 1478 assertThat(livefiles).isNotNull(); 1479 assertThat(livefiles.manifestFileSize).isEqualTo(57); 1480 assertThat(livefiles.files.size()).isEqualTo(3); 1481 assertThat(livefiles.files.get(0)).isEqualTo("/CURRENT"); 1482 assertThat(livefiles.files.get(1)).isEqualTo("/MANIFEST-000004"); 1483 assertThat(livefiles.files.get(2)).isEqualTo("/OPTIONS-000007"); 1484 } 1485 } 1486 } 1487 1488 @Test getSortedWalFiles()1489 public void getSortedWalFiles() throws RocksDBException { 1490 try (final Options options = new Options().setCreateIfMissing(true)) { 1491 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1492 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1493 db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8)); 1494 final List<LogFile> logFiles = db.getSortedWalFiles(); 1495 assertThat(logFiles).isNotNull(); 1496 assertThat(logFiles.size()).isEqualTo(1); 1497 assertThat(logFiles.get(0).type()) 1498 .isEqualTo(WalFileType.kAliveLogFile); 1499 } 1500 } 1501 } 1502 1503 @Test deleteFile()1504 public void deleteFile() throws RocksDBException { 1505 try (final Options options = new Options().setCreateIfMissing(true)) { 1506 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1507 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1508 db.deleteFile("unknown"); 1509 } 1510 } 1511 } 1512 1513 @Test getLiveFilesMetaData()1514 public void getLiveFilesMetaData() throws RocksDBException { 1515 try (final Options options = new Options().setCreateIfMissing(true)) { 1516 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1517 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1518 db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8)); 1519 final List<LiveFileMetaData> liveFilesMetaData 1520 = db.getLiveFilesMetaData(); 1521 assertThat(liveFilesMetaData).isEmpty(); 1522 } 1523 } 1524 } 1525 1526 @Test getColumnFamilyMetaData()1527 public void getColumnFamilyMetaData() throws RocksDBException { 1528 try (final DBOptions options = new DBOptions() 1529 .setCreateIfMissing(true)) { 1530 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList( 1531 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY) 1532 ); 1533 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); 1534 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1535 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) { 1536 db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8)); 1537 try { 1538 final ColumnFamilyMetaData cfMetadata = 1539 db.getColumnFamilyMetaData(cfHandles.get(0)); 1540 assertThat(cfMetadata).isNotNull(); 1541 assertThat(cfMetadata.name()).isEqualTo(RocksDB.DEFAULT_COLUMN_FAMILY); 1542 assertThat(cfMetadata.levels().size()).isEqualTo(7); 1543 } finally { 1544 for (final ColumnFamilyHandle cfHandle : cfHandles) { 1545 cfHandle.close(); 1546 } 1547 } 1548 } 1549 } 1550 } 1551 1552 @Test verifyChecksum()1553 public void verifyChecksum() throws RocksDBException { 1554 try (final Options options = new Options().setCreateIfMissing(true)) { 1555 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1556 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1557 db.verifyChecksum(); 1558 } 1559 } 1560 } 1561 1562 @Test getPropertiesOfAllTables()1563 public void getPropertiesOfAllTables() throws RocksDBException { 1564 try (final DBOptions options = new DBOptions() 1565 .setCreateIfMissing(true)) { 1566 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList( 1567 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY) 1568 ); 1569 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); 1570 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1571 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) { 1572 db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8)); 1573 try { 1574 final Map<String, TableProperties> properties = 1575 db.getPropertiesOfAllTables(cfHandles.get(0)); 1576 assertThat(properties).isNotNull(); 1577 } finally { 1578 for (final ColumnFamilyHandle cfHandle : cfHandles) { 1579 cfHandle.close(); 1580 } 1581 } 1582 } 1583 } 1584 } 1585 1586 @Test getPropertiesOfTablesInRange()1587 public void getPropertiesOfTablesInRange() throws RocksDBException { 1588 try (final DBOptions options = new DBOptions() 1589 .setCreateIfMissing(true)) { 1590 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList( 1591 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY) 1592 ); 1593 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); 1594 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1595 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) { 1596 db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8)); 1597 db.put(cfHandles.get(0), "key2".getBytes(UTF_8), "value2".getBytes(UTF_8)); 1598 db.put(cfHandles.get(0), "key3".getBytes(UTF_8), "value3".getBytes(UTF_8)); 1599 try { 1600 final Range range = new Range( 1601 new Slice("key1".getBytes(UTF_8)), 1602 new Slice("key3".getBytes(UTF_8))); 1603 final Map<String, TableProperties> properties = 1604 db.getPropertiesOfTablesInRange( 1605 cfHandles.get(0), Arrays.asList(range)); 1606 assertThat(properties).isNotNull(); 1607 } finally { 1608 for (final ColumnFamilyHandle cfHandle : cfHandles) { 1609 cfHandle.close(); 1610 } 1611 } 1612 } 1613 } 1614 } 1615 1616 @Test suggestCompactRange()1617 public void suggestCompactRange() throws RocksDBException { 1618 try (final DBOptions options = new DBOptions() 1619 .setCreateIfMissing(true)) { 1620 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList( 1621 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY) 1622 ); 1623 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); 1624 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1625 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) { 1626 db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8)); 1627 db.put(cfHandles.get(0), "key2".getBytes(UTF_8), "value2".getBytes(UTF_8)); 1628 db.put(cfHandles.get(0), "key3".getBytes(UTF_8), "value3".getBytes(UTF_8)); 1629 try { 1630 final Range range = db.suggestCompactRange(cfHandles.get(0)); 1631 assertThat(range).isNotNull(); 1632 } finally { 1633 for (final ColumnFamilyHandle cfHandle : cfHandles) { 1634 cfHandle.close(); 1635 } 1636 } 1637 } 1638 } 1639 } 1640 1641 @Test promoteL0()1642 public void promoteL0() throws RocksDBException { 1643 try (final Options options = new Options().setCreateIfMissing(true)) { 1644 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1645 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1646 db.promoteL0(2); 1647 } 1648 } 1649 } 1650 1651 @Test startTrace()1652 public void startTrace() throws RocksDBException { 1653 try (final Options options = new Options().setCreateIfMissing(true)) { 1654 final String dbPath = dbFolder.getRoot().getAbsolutePath(); 1655 try (final RocksDB db = RocksDB.open(options, dbPath)) { 1656 final TraceOptions traceOptions = new TraceOptions(); 1657 1658 try (final InMemoryTraceWriter traceWriter = new InMemoryTraceWriter()) { 1659 db.startTrace(traceOptions, traceWriter); 1660 1661 db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8)); 1662 1663 db.endTrace(); 1664 1665 final List<byte[]> writes = traceWriter.getWrites(); 1666 assertThat(writes.size()).isGreaterThan(0); 1667 } 1668 } 1669 } 1670 } 1671 1672 @Test setDBOptions()1673 public void setDBOptions() throws RocksDBException { 1674 try (final DBOptions options = new DBOptions() 1675 .setCreateIfMissing(true) 1676 .setCreateMissingColumnFamilies(true); 1677 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions() 1678 .setWriteBufferSize(4096)) { 1679 1680 final List<ColumnFamilyDescriptor> columnFamilyDescriptors = 1681 Arrays.asList( 1682 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), 1683 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)); 1684 1685 // open database 1686 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); 1687 try (final RocksDB db = RocksDB.open(options, 1688 dbFolder.getRoot().getAbsolutePath(), columnFamilyDescriptors, columnFamilyHandles)) { 1689 try { 1690 final MutableDBOptions mutableOptions = 1691 MutableDBOptions.builder() 1692 .setBytesPerSync(1024 * 1027 * 7) 1693 .setAvoidFlushDuringShutdown(false) 1694 .build(); 1695 1696 db.setDBOptions(mutableOptions); 1697 } finally { 1698 for (final ColumnFamilyHandle handle : columnFamilyHandles) { 1699 handle.close(); 1700 } 1701 } 1702 } 1703 } 1704 } 1705 1706 @Test rocksdbVersion()1707 public void rocksdbVersion() { 1708 final RocksDB.Version version = RocksDB.rocksdbVersion(); 1709 assertThat(version).isNotNull(); 1710 assertThat(version.getMajor()).isGreaterThan(1); 1711 } 1712 1713 private static class InMemoryTraceWriter extends AbstractTraceWriter { 1714 private final List<byte[]> writes = new ArrayList<>(); 1715 private volatile boolean closed = false; 1716 1717 @Override write(final Slice slice)1718 public void write(final Slice slice) { 1719 if (closed) { 1720 return; 1721 } 1722 final byte[] data = slice.data(); 1723 final byte[] dataCopy = new byte[data.length]; 1724 System.arraycopy(data, 0, dataCopy, 0, data.length); 1725 writes.add(dataCopy); 1726 } 1727 1728 @Override closeWriter()1729 public void closeWriter() { 1730 closed = true; 1731 } 1732 1733 @Override getFileSize()1734 public long getFileSize() { 1735 long size = 0; 1736 for (int i = 0; i < writes.size(); i++) { 1737 size += writes.get(i).length; 1738 } 1739 return size; 1740 } 1741 getWrites()1742 public List<byte[]> getWrites() { 1743 return writes; 1744 } 1745 } 1746 } 1747