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).
8 import org
.junit
.rules
.ExpectedException
;
9 import org
.junit
.rules
.TemporaryFolder
;
11 import java
.nio
.ByteBuffer
;
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
;
18 public class RocksDBTest
{
21 public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE
=
22 new RocksNativeLibraryResource();
25 public TemporaryFolder dbFolder
= new TemporaryFolder();
27 public static final Random rand
= PlatformRandomHelper
.
28 getPlatformSpecificRandomFactory();
31 public void open() throws RocksDBException
{
32 try (final RocksDB db
=
33 RocksDB
.open(dbFolder
.getRoot().getAbsolutePath())) {
34 assertThat(db
).isNotNull();
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();
48 public void openWhenOpen() throws RocksDBException
{
49 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
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 ");
63 public void createColumnFamily() throws RocksDBException
{
64 final byte[] col1Name
= "col1".getBytes(UTF_8
);
66 try (final RocksDB db
= RocksDB
.open(dbFolder
.getRoot().getAbsolutePath());
67 final ColumnFamilyOptions cfOpts
= new ColumnFamilyOptions()
69 try (final ColumnFamilyHandle col1
=
70 db
.createColumnFamily(new ColumnFamilyDescriptor(col1Name
, cfOpts
))) {
71 assertThat(col1
).isNotNull();
72 assertThat(col1
.getName()).isEqualTo(col1Name
);
76 final List
<ColumnFamilyHandle
> cfHandles
= new ArrayList
<>();
77 try (final RocksDB db
= RocksDB
.open(dbFolder
.getRoot().getAbsolutePath(),
79 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
80 new ColumnFamilyDescriptor(col1Name
)),
83 assertThat(cfHandles
.size()).isEqualTo(2);
84 assertThat(cfHandles
.get(1)).isNotNull();
85 assertThat(cfHandles
.get(1).getName()).isEqualTo(col1Name
);
87 for (final ColumnFamilyHandle cfHandle
:
97 public void createColumnFamilies() throws RocksDBException
{
98 final byte[] col1Name
= "col1".getBytes(UTF_8
);
99 final byte[] col2Name
= "col2".getBytes(UTF_8
);
101 List
<ColumnFamilyHandle
> cfHandles
;
102 try (final RocksDB db
= RocksDB
.open(dbFolder
.getRoot().getAbsolutePath());
103 final ColumnFamilyOptions cfOpts
= new ColumnFamilyOptions()
106 db
.createColumnFamilies(cfOpts
, Arrays
.asList(col1Name
, col2Name
));
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
);
113 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
119 cfHandles
= new ArrayList
<>();
120 try (final RocksDB db
= RocksDB
.open(dbFolder
.getRoot().getAbsolutePath(),
122 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
123 new ColumnFamilyDescriptor(col1Name
),
124 new ColumnFamilyDescriptor(col2Name
)),
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
);
133 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
141 public void createColumnFamiliesfromDescriptors() throws RocksDBException
{
142 final byte[] col1Name
= "col1".getBytes(UTF_8
);
143 final byte[] col2Name
= "col2".getBytes(UTF_8
);
145 List
<ColumnFamilyHandle
> cfHandles
;
146 try (final RocksDB db
= RocksDB
.open(dbFolder
.getRoot().getAbsolutePath());
147 final ColumnFamilyOptions cfOpts
= new ColumnFamilyOptions()
150 db
.createColumnFamilies(Arrays
.asList(
151 new ColumnFamilyDescriptor(col1Name
, cfOpts
),
152 new ColumnFamilyDescriptor(col2Name
, cfOpts
)));
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
);
159 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
165 cfHandles
= new ArrayList
<>();
166 try (final RocksDB db
= RocksDB
.open(dbFolder
.getRoot().getAbsolutePath(),
168 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
169 new ColumnFamilyDescriptor(col1Name
),
170 new ColumnFamilyDescriptor(col2Name
)),
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
);
179 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
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(
194 assertThat(db
.get("key2".getBytes())).isEqualTo(
195 "12345678".getBytes());
197 ByteBuffer key
= ByteBuffer
.allocateDirect(12);
198 ByteBuffer value
= ByteBuffer
.allocateDirect(12);
200 key
.put("key3".getBytes());
201 key
.position(4).limit(8);
203 value
.put("val3".getBytes());
204 value
.position(4).limit(8);
206 db
.put(opt
, key
, value
);
208 assertThat(key
.position()).isEqualTo(8);
209 assertThat(key
.limit()).isEqualTo(8);
211 assertThat(value
.position()).isEqualTo(8);
212 assertThat(value
.limit()).isEqualTo(8);
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);
223 byte[] tmp
= new byte[4];
225 assertThat(tmp
).isEqualTo("val3".getBytes());
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];
237 assertThat(tmp2
).isEqualTo("val".getBytes());
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
);
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
)));
253 private static Segment
sliceSegment(String key
) {
254 ByteBuffer rawKey
= ByteBuffer
.allocate(key
.length() + 4);
257 rawKey
.put(key
.getBytes());
259 return new Segment(rawKey
.array(), 2, key
.length());
262 private static class Segment
{
267 public boolean isSamePayload(byte[] value
) {
271 if (value
.length
!= len
) {
275 for (int i
= 0; i
< value
.length
; i
++) {
276 if (data
[i
+ offset
] != value
[i
]) {
284 public Segment(byte[] value
, int offset
, int len
) {
286 this.offset
= offset
;
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()) {
301 try (final WriteBatch wb1
= new WriteBatch()) {
302 wb1
.put("key1".getBytes(), "aa".getBytes());
303 wb1
.merge("key1".getBytes(), "bb".getBytes());
305 try (final WriteBatch wb2
= new WriteBatch()) {
306 wb2
.put("key2".getBytes(), "xx".getBytes());
307 wb2
.merge("key2".getBytes(), "yy".getBytes());
313 assertThat(db
.get("key1".getBytes())).isEqualTo(
315 assertThat(db
.get("key2".getBytes())).isEqualTo(
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];
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());
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];
349 int getResult
= db
.get(rOpt
, "keyNotFound".getBytes(),
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());
364 public ExpectedException thrown
= ExpectedException
.none();
367 public void getOutOfArrayMaxSizeValue() throws RocksDBException
{
368 final int numberOfValueSplits
= 10;
369 final int splitSize
= Integer
.MAX_VALUE
/ numberOfValueSplits
;
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
);
376 final byte[] valueSplit
= new byte[splitSize
];
377 final byte[] key
= "key".getBytes();
379 thrown
.expect(RocksDBException
.class);
380 thrown
.expectMessage("Requested array size exceeds VM limit");
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
);
396 @SuppressWarnings("deprecated")
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());
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());
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());
449 containsExactly("value".getBytes(), "12345678".getBytes());
450 // test same method with ReadOptions
451 results
= db
.multiGetAsList(rOpt
, lookupKeys
);
452 assertThat(results
).isNotNull();
454 contains("value".getBytes(), "12345678".getBytes());
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();
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());
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())
481 db
.put("key1".getBytes(), "value".getBytes());
482 assertThat(db
.get("key1".getBytes())).isEqualTo(
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(
497 Segment key3
= sliceSegment("key3");
498 Segment key4
= sliceSegment("key4");
499 Segment value0
= sliceSegment("value 0");
500 Segment value1
= sliceSegment("value 1");
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
);
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
)));
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(
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);
531 assertThat(db
.get("key1".getBytes())).isNull();
532 assertThat(db
.get("key2".getBytes())).isNull();
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());
539 db
.delete(key3
.data
, key3
.offset
, key3
.len
);
540 db
.delete(wOpt
, key4
.data
, key4
.offset
, key4
.len
);
542 assertThat(db
.get("key3".getBytes())).isNull();
543 assertThat(db
.get("key4".getBytes())).isNull();
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(
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();
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();
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());
595 public void getIntProperty() throws RocksDBException
{
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)
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"))
611 assertThat(db
.getLongProperty("rocksdb.cur-size-active-mem-table"))
617 public void fullCompactRange() throws RocksDBException
{
618 try (final Options opt
= new Options().
619 setCreateIfMissing(true).
620 setDisableAutoCompactions(true).
621 setCompactionStyle(CompactionStyle
.LEVEL
).
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
++) {
636 db
.put((String
.valueOf(i
)).getBytes(), b
);
643 public void fullCompactRangeColumnFamily()
644 throws RocksDBException
{
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
).
653 setWriteBufferSize(100 << 10).
654 setLevelZeroFileNumCompactionTrigger(3).
655 setTargetFileSizeBase(200 << 10).
656 setTargetFileSizeMultiplier(1).
657 setMaxBytesForLevelBase(500 << 10).
658 setMaxBytesForLevelMultiplier(1).
659 setDisableAutoCompactions(false)
661 final List
<ColumnFamilyDescriptor
> columnFamilyDescriptors
=
663 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
664 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts
));
667 final List
<ColumnFamilyHandle
> columnFamilyHandles
= new ArrayList
<>();
668 try (final RocksDB db
= RocksDB
.open(opt
,
669 dbFolder
.getRoot().getAbsolutePath(),
670 columnFamilyDescriptors
,
671 columnFamilyHandles
)) {
673 // fill database with key/value pairs
674 byte[] b
= new byte[10000];
675 for (int i
= 0; i
< 200; i
++) {
677 db
.put(columnFamilyHandles
.get(1),
678 String
.valueOf(i
).getBytes(), b
);
680 db
.compactRange(columnFamilyHandles
.get(1));
682 for (final ColumnFamilyHandle handle
: columnFamilyHandles
) {
691 public void compactRangeWithKeys()
692 throws RocksDBException
{
693 try (final Options opt
= new Options().
694 setCreateIfMissing(true).
695 setDisableAutoCompactions(true).
696 setCompactionStyle(CompactionStyle
.LEVEL
).
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
++) {
711 db
.put((String
.valueOf(i
)).getBytes(), b
);
713 db
.compactRange("0".getBytes(), "201".getBytes());
718 public void compactRangeWithKeysReduce()
719 throws RocksDBException
{
721 final Options opt
= new Options().
722 setCreateIfMissing(true).
723 setDisableAutoCompactions(true).
724 setCompactionStyle(CompactionStyle
.LEVEL
).
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
++) {
739 db
.put((String
.valueOf(i
)).getBytes(), b
);
741 db
.flush(new FlushOptions().setWaitForFlush(true));
742 try (final CompactRangeOptions compactRangeOpts
= new CompactRangeOptions()
743 .setChangeLevel(true)
745 .setTargetPathId(0)) {
746 db
.compactRange(null, "0".getBytes(), "201".getBytes(),
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
).
762 setWriteBufferSize(100 << 10).
763 setLevelZeroFileNumCompactionTrigger(3).
764 setTargetFileSizeBase(200 << 10).
765 setTargetFileSizeMultiplier(1).
766 setMaxBytesForLevelBase(500 << 10).
767 setMaxBytesForLevelMultiplier(1).
768 setDisableAutoCompactions(false)
770 final List
<ColumnFamilyDescriptor
> columnFamilyDescriptors
=
772 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
773 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts
)
777 final List
<ColumnFamilyHandle
> columnFamilyHandles
=
779 try (final RocksDB db
= RocksDB
.open(opt
,
780 dbFolder
.getRoot().getAbsolutePath(),
781 columnFamilyDescriptors
,
782 columnFamilyHandles
)) {
784 // fill database with key/value pairs
785 byte[] b
= new byte[10000];
786 for (int i
= 0; i
< 200; i
++) {
788 db
.put(columnFamilyHandles
.get(1),
789 String
.valueOf(i
).getBytes(), b
);
791 db
.compactRange(columnFamilyHandles
.get(1),
792 "0".getBytes(), "201".getBytes());
794 for (final ColumnFamilyHandle handle
: columnFamilyHandles
) {
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
).
812 setWriteBufferSize(100 << 10).
813 setLevelZeroFileNumCompactionTrigger(3).
814 setTargetFileSizeBase(200 << 10).
815 setTargetFileSizeMultiplier(1).
816 setMaxBytesForLevelBase(500 << 10).
817 setMaxBytesForLevelMultiplier(1).
818 setDisableAutoCompactions(false)
820 final List
<ColumnFamilyDescriptor
> columnFamilyDescriptors
=
822 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
823 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts
)
826 final List
<ColumnFamilyHandle
> columnFamilyHandles
= new ArrayList
<>();
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)
835 .setTargetPathId(0)) {
836 // fill database with key/value pairs
837 byte[] b
= new byte[10000];
838 for (int i
= 0; i
< 200; i
++) {
840 db
.put(columnFamilyHandles
.get(1),
841 String
.valueOf(i
).getBytes(), b
);
843 db
.compactRange(columnFamilyHandles
.get(1), "0".getBytes(),
844 "201".getBytes(), compactRangeOpts
);
846 for (final ColumnFamilyHandle handle
: columnFamilyHandles
) {
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
).
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())
884 // fill database with key/value pairs
885 byte[] value
= new byte[VALUE_SIZE
];
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
);
894 db
.put(String
.format("%020d", int_key
).getBytes(),
897 db
.flush(new FlushOptions().setWaitForFlush(true));
898 // Make sure we do create one more L0 files.
900 db
.getProperty("rocksdb.num-files-at-level0")).
904 // Compact all L0 files we just created
906 String
.format("%020d", initial_key
).getBytes(),
907 String
.format("%020d", int_key
- 1).getBytes());
908 // Making sure there isn't any L0 files.
910 db
.getProperty("rocksdb.num-files-at-level0")).
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.
917 db
.getProperty("rocksdb.num-files-at-level1")).
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.
923 db
.getProperty("rocksdb.num-files-at-level2")).
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;
936 final int KEY_INTERVAL
= 10000;
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
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
);
953 // fill database with key/value pairs
954 byte[] value
= new byte[VALUE_SIZE
];
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
);
962 db
.put(String
.format("%020d", int_key
).getBytes(), value
);
965 db
.flush(new FlushOptions().setWaitForFlush(true));
967 // Make sure we do create one more L0 files.
968 assertThat(db
.getProperty("rocksdb.num-files-at-level0")).isEqualTo("0");
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);
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()),
980 files
= Integer
.parseInt(db
.getProperty("rocksdb.num-files-at-level1"));
981 assertThat(files
).isBetween(3, 7);
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;
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
).
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)
1016 final List
<ColumnFamilyDescriptor
> columnFamilyDescriptors
=
1018 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
1019 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts
)
1022 final List
<ColumnFamilyHandle
> columnFamilyHandles
= new ArrayList
<>();
1024 try (final RocksDB db
= RocksDB
.open(opt
,
1025 dbFolder
.getRoot().getAbsolutePath(),
1026 columnFamilyDescriptors
,
1027 columnFamilyHandles
)) {
1029 // fill database with key/value pairs
1030 byte[] value
= new byte[VALUE_SIZE
];
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
);
1039 db
.put(columnFamilyHandles
.get(1),
1040 String
.format("%020d", int_key
).getBytes(),
1043 db
.flush(new FlushOptions().setWaitForFlush(true),
1044 columnFamilyHandles
.get(1));
1045 // Make sure we do create one more L0 files.
1047 db
.getProperty(columnFamilyHandles
.get(1),
1048 "rocksdb.num-files-at-level0")).
1052 // Compact all L0 files we just created
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.
1059 db
.getProperty(columnFamilyHandles
.get(1),
1060 "rocksdb.num-files-at-level0")).
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.
1067 db
.getProperty(columnFamilyHandles
.get(1),
1068 "rocksdb.num-files-at-level1")).
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.
1074 db
.getProperty(columnFamilyHandles
.get(1),
1075 "rocksdb.num-files-at-level2")).
1079 for (final ColumnFamilyHandle handle
: columnFamilyHandles
) {
1088 public void pauseContinueBackgroundWork() throws RocksDBException
{
1089 try (final Options options
= new Options().setCreateIfMissing(true);
1090 final RocksDB db
= RocksDB
.open(options
,
1091 dbFolder
.getRoot().getAbsolutePath())
1093 db
.pauseBackgroundWork();
1094 db
.continueBackgroundWork();
1095 db
.pauseBackgroundWork();
1096 db
.continueBackgroundWork();
1101 public void enableDisableFileDeletions() throws RocksDBException
{
1102 try (final Options options
= new Options().setCreateIfMissing(true);
1103 final RocksDB db
= RocksDB
.open(options
,
1104 dbFolder
.getRoot().getAbsolutePath())
1106 db
.disableFileDeletions();
1107 db
.enableFileDeletions(false);
1108 db
.disableFileDeletions();
1109 db
.enableFileDeletions(true);
1114 public void setOptions() throws RocksDBException
{
1115 try (final DBOptions options
= new DBOptions()
1116 .setCreateIfMissing(true)
1117 .setCreateMissingColumnFamilies(true);
1118 final ColumnFamilyOptions new_cf_opts
= new ColumnFamilyOptions()
1119 .setWriteBufferSize(4096)) {
1121 final List
<ColumnFamilyDescriptor
> columnFamilyDescriptors
=
1123 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
1124 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts
));
1127 final List
<ColumnFamilyHandle
> columnFamilyHandles
= new ArrayList
<>();
1128 try (final RocksDB db
= RocksDB
.open(options
,
1129 dbFolder
.getRoot().getAbsolutePath(), columnFamilyDescriptors
, columnFamilyHandles
)) {
1131 final MutableColumnFamilyOptions mutableOptions
=
1132 MutableColumnFamilyOptions
.builder()
1133 .setWriteBufferSize(2048)
1136 db
.setOptions(columnFamilyHandles
.get(1), mutableOptions
);
1139 for (final ColumnFamilyHandle handle
: columnFamilyHandles
) {
1148 public void destroyDB() throws RocksDBException
{
1149 try (final Options options
= new Options().setCreateIfMissing(true)) {
1150 String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1151 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1152 db
.put("key1".getBytes(), "value".getBytes());
1154 assertThat(dbFolder
.getRoot().exists() && dbFolder
.getRoot().listFiles().length
!= 0)
1156 RocksDB
.destroyDB(dbPath
, options
);
1157 assertThat(dbFolder
.getRoot().exists() && dbFolder
.getRoot().listFiles().length
!= 0)
1162 @Test(expected
= RocksDBException
.class)
1163 public void destroyDBFailIfOpen() throws RocksDBException
{
1164 try (final Options options
= new Options().setCreateIfMissing(true)) {
1165 String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1166 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1167 // Fails as the db is open and locked.
1168 RocksDB
.destroyDB(dbPath
, options
);
1173 @Ignore("This test crashes. Re-enable after fixing.")
1175 public void getApproximateSizes() throws RocksDBException
{
1176 final byte key1
[] = "key1".getBytes(UTF_8
);
1177 final byte key2
[] = "key2".getBytes(UTF_8
);
1178 final byte key3
[] = "key3".getBytes(UTF_8
);
1179 try (final Options options
= new Options().setCreateIfMissing(true)) {
1180 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1181 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1186 final long[] sizes
= db
.getApproximateSizes(
1188 new Range(new Slice(key1
), new Slice(key2
)),
1189 new Range(new Slice(key2
), new Slice(key3
))
1191 SizeApproximationFlag
.INCLUDE_FILES
,
1192 SizeApproximationFlag
.INCLUDE_MEMTABLES
);
1194 assertThat(sizes
.length
).isEqualTo(2);
1195 assertThat(sizes
[0]).isEqualTo(0);
1196 assertThat(sizes
[1]).isGreaterThanOrEqualTo(1);
1202 public void getApproximateMemTableStats() throws RocksDBException
{
1203 final byte key1
[] = "key1".getBytes(UTF_8
);
1204 final byte key2
[] = "key2".getBytes(UTF_8
);
1205 final byte key3
[] = "key3".getBytes(UTF_8
);
1206 try (final Options options
= new Options().setCreateIfMissing(true)) {
1207 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1208 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1213 final RocksDB
.CountAndSize stats
=
1214 db
.getApproximateMemTableStats(
1215 new Range(new Slice(key1
), new Slice(key3
)));
1217 assertThat(stats
).isNotNull();
1218 assertThat(stats
.count
).isGreaterThan(1);
1219 assertThat(stats
.size
).isGreaterThan(1);
1224 @Ignore("TODO(AR) re-enable when ready!")
1226 public void compactFiles() throws RocksDBException
{
1227 final int kTestKeySize
= 16;
1228 final int kTestValueSize
= 984;
1229 final int kEntrySize
= kTestKeySize
+ kTestValueSize
;
1230 final int kEntriesPerBuffer
= 100;
1231 final int writeBufferSize
= kEntrySize
* kEntriesPerBuffer
;
1232 final byte[] cfName
= "pikachu".getBytes(UTF_8
);
1234 try (final Options options
= new Options()
1235 .setCreateIfMissing(true)
1236 .setWriteBufferSize(writeBufferSize
)
1237 .setCompactionStyle(CompactionStyle
.LEVEL
)
1238 .setTargetFileSizeBase(writeBufferSize
)
1239 .setMaxBytesForLevelBase(writeBufferSize
* 2)
1240 .setLevel0StopWritesTrigger(2)
1241 .setMaxBytesForLevelMultiplier(2)
1242 .setCompressionType(CompressionType
.NO_COMPRESSION
)
1243 .setMaxSubcompactions(4)) {
1244 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1245 try (final RocksDB db
= RocksDB
.open(options
, dbPath
);
1246 final ColumnFamilyOptions cfOptions
= new ColumnFamilyOptions(options
)) {
1247 db
.createColumnFamily(new ColumnFamilyDescriptor(cfName
,
1248 cfOptions
)).close();
1251 try (final ColumnFamilyOptions cfOptions
= new ColumnFamilyOptions(options
)) {
1252 final List
<ColumnFamilyDescriptor
> cfDescriptors
= Arrays
.asList(
1253 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
, cfOptions
),
1254 new ColumnFamilyDescriptor(cfName
, cfOptions
)
1256 final List
<ColumnFamilyHandle
> cfHandles
= new ArrayList
<>();
1257 try (final DBOptions dbOptions
= new DBOptions(options
);
1258 final RocksDB db
= RocksDB
.open(dbOptions
, dbPath
, cfDescriptors
,
1261 try (final FlushOptions flushOptions
= new FlushOptions()
1262 .setWaitForFlush(true)
1263 .setAllowWriteStall(true);
1264 final CompactionOptions compactionOptions
= new CompactionOptions()) {
1265 final Random rnd
= new Random(301);
1266 for (int key
= 64 * kEntriesPerBuffer
; key
>= 0; --key
) {
1267 final byte[] value
= new byte[kTestValueSize
];
1268 rnd
.nextBytes(value
);
1269 db
.put(cfHandles
.get(1), Integer
.toString(key
).getBytes(UTF_8
),
1272 db
.flush(flushOptions
, cfHandles
);
1274 final RocksDB
.LiveFiles liveFiles
= db
.getLiveFiles();
1275 final List
<String
> compactedFiles
=
1276 db
.compactFiles(compactionOptions
, cfHandles
.get(1),
1277 liveFiles
.files
, 1, -1, null);
1278 assertThat(compactedFiles
).isNotEmpty();
1280 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
1290 public void enableAutoCompaction() throws RocksDBException
{
1291 try (final DBOptions options
= new DBOptions()
1292 .setCreateIfMissing(true)) {
1293 final List
<ColumnFamilyDescriptor
> cfDescs
= Arrays
.asList(
1294 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
)
1296 final List
<ColumnFamilyHandle
> cfHandles
= new ArrayList
<>();
1297 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1298 try (final RocksDB db
= RocksDB
.open(options
, dbPath
, cfDescs
, cfHandles
)) {
1300 db
.enableAutoCompaction(cfHandles
);
1302 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
1311 public void numberLevels() throws RocksDBException
{
1312 try (final Options options
= new Options().setCreateIfMissing(true)) {
1313 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1314 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1315 assertThat(db
.numberLevels()).isEqualTo(7);
1321 public void maxMemCompactionLevel() throws RocksDBException
{
1322 try (final Options options
= new Options().setCreateIfMissing(true)) {
1323 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1324 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1325 assertThat(db
.maxMemCompactionLevel()).isEqualTo(0);
1331 public void level0StopWriteTrigger() throws RocksDBException
{
1332 try (final Options options
= new Options().setCreateIfMissing(true)) {
1333 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1334 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1335 assertThat(db
.level0StopWriteTrigger()).isEqualTo(36);
1341 public void getName() throws RocksDBException
{
1342 try (final Options options
= new Options().setCreateIfMissing(true)) {
1343 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1344 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1345 assertThat(db
.getName()).isEqualTo(dbPath
);
1351 public void getEnv() throws RocksDBException
{
1352 try (final Options options
= new Options().setCreateIfMissing(true)) {
1353 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1354 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1355 assertThat(db
.getEnv()).isEqualTo(Env
.getDefault());
1361 public void flush() throws RocksDBException
{
1362 try (final Options options
= new Options().setCreateIfMissing(true)) {
1363 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1364 try (final RocksDB db
= RocksDB
.open(options
, dbPath
);
1365 final FlushOptions flushOptions
= new FlushOptions()) {
1366 db
.flush(flushOptions
);
1372 public void flushWal() throws RocksDBException
{
1373 try (final Options options
= new Options().setCreateIfMissing(true)) {
1374 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1375 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1382 public void syncWal() throws RocksDBException
{
1383 try (final Options options
= new Options().setCreateIfMissing(true)) {
1384 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1385 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1392 public void setPreserveDeletesSequenceNumber() throws RocksDBException
{
1393 try (final Options options
= new Options().setCreateIfMissing(true)) {
1394 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1395 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1396 assertThat(db
.setPreserveDeletesSequenceNumber(db
.getLatestSequenceNumber()))
1403 public void getLiveFiles() throws RocksDBException
{
1404 try (final Options options
= new Options().setCreateIfMissing(true)) {
1405 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1406 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1407 final RocksDB
.LiveFiles livefiles
= db
.getLiveFiles(true);
1408 assertThat(livefiles
).isNotNull();
1409 assertThat(livefiles
.manifestFileSize
).isEqualTo(13);
1410 assertThat(livefiles
.files
.size()).isEqualTo(3);
1411 assertThat(livefiles
.files
.get(0)).isEqualTo("/CURRENT");
1412 assertThat(livefiles
.files
.get(1)).isEqualTo("/MANIFEST-000001");
1413 assertThat(livefiles
.files
.get(2)).isEqualTo("/OPTIONS-000005");
1419 public void getSortedWalFiles() throws RocksDBException
{
1420 try (final Options options
= new Options().setCreateIfMissing(true)) {
1421 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1422 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1423 db
.put("key1".getBytes(UTF_8
), "value1".getBytes(UTF_8
));
1424 final List
<LogFile
> logFiles
= db
.getSortedWalFiles();
1425 assertThat(logFiles
).isNotNull();
1426 assertThat(logFiles
.size()).isEqualTo(1);
1427 assertThat(logFiles
.get(0).type())
1428 .isEqualTo(WalFileType
.kAliveLogFile
);
1434 public void deleteFile() throws RocksDBException
{
1435 try (final Options options
= new Options().setCreateIfMissing(true)) {
1436 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1437 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1438 db
.deleteFile("unknown");
1444 public void getLiveFilesMetaData() throws RocksDBException
{
1445 try (final Options options
= new Options().setCreateIfMissing(true)) {
1446 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1447 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1448 db
.put("key1".getBytes(UTF_8
), "value1".getBytes(UTF_8
));
1449 final List
<LiveFileMetaData
> liveFilesMetaData
1450 = db
.getLiveFilesMetaData();
1451 assertThat(liveFilesMetaData
).isEmpty();
1457 public void getColumnFamilyMetaData() throws RocksDBException
{
1458 try (final DBOptions options
= new DBOptions()
1459 .setCreateIfMissing(true)) {
1460 final List
<ColumnFamilyDescriptor
> cfDescs
= Arrays
.asList(
1461 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
)
1463 final List
<ColumnFamilyHandle
> cfHandles
= new ArrayList
<>();
1464 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1465 try (final RocksDB db
= RocksDB
.open(options
, dbPath
, cfDescs
, cfHandles
)) {
1466 db
.put(cfHandles
.get(0), "key1".getBytes(UTF_8
), "value1".getBytes(UTF_8
));
1468 final ColumnFamilyMetaData cfMetadata
=
1469 db
.getColumnFamilyMetaData(cfHandles
.get(0));
1470 assertThat(cfMetadata
).isNotNull();
1471 assertThat(cfMetadata
.name()).isEqualTo(RocksDB
.DEFAULT_COLUMN_FAMILY
);
1472 assertThat(cfMetadata
.levels().size()).isEqualTo(7);
1474 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
1483 public void verifyChecksum() throws RocksDBException
{
1484 try (final Options options
= new Options().setCreateIfMissing(true)) {
1485 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1486 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1487 db
.verifyChecksum();
1493 public void getPropertiesOfAllTables() throws RocksDBException
{
1494 try (final DBOptions options
= new DBOptions()
1495 .setCreateIfMissing(true)) {
1496 final List
<ColumnFamilyDescriptor
> cfDescs
= Arrays
.asList(
1497 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
)
1499 final List
<ColumnFamilyHandle
> cfHandles
= new ArrayList
<>();
1500 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1501 try (final RocksDB db
= RocksDB
.open(options
, dbPath
, cfDescs
, cfHandles
)) {
1502 db
.put(cfHandles
.get(0), "key1".getBytes(UTF_8
), "value1".getBytes(UTF_8
));
1504 final Map
<String
, TableProperties
> properties
=
1505 db
.getPropertiesOfAllTables(cfHandles
.get(0));
1506 assertThat(properties
).isNotNull();
1508 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
1517 public void getPropertiesOfTablesInRange() throws RocksDBException
{
1518 try (final DBOptions options
= new DBOptions()
1519 .setCreateIfMissing(true)) {
1520 final List
<ColumnFamilyDescriptor
> cfDescs
= Arrays
.asList(
1521 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
)
1523 final List
<ColumnFamilyHandle
> cfHandles
= new ArrayList
<>();
1524 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1525 try (final RocksDB db
= RocksDB
.open(options
, dbPath
, cfDescs
, cfHandles
)) {
1526 db
.put(cfHandles
.get(0), "key1".getBytes(UTF_8
), "value1".getBytes(UTF_8
));
1527 db
.put(cfHandles
.get(0), "key2".getBytes(UTF_8
), "value2".getBytes(UTF_8
));
1528 db
.put(cfHandles
.get(0), "key3".getBytes(UTF_8
), "value3".getBytes(UTF_8
));
1530 final Range range
= new Range(
1531 new Slice("key1".getBytes(UTF_8
)),
1532 new Slice("key3".getBytes(UTF_8
)));
1533 final Map
<String
, TableProperties
> properties
=
1534 db
.getPropertiesOfTablesInRange(
1535 cfHandles
.get(0), Arrays
.asList(range
));
1536 assertThat(properties
).isNotNull();
1538 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
1547 public void suggestCompactRange() throws RocksDBException
{
1548 try (final DBOptions options
= new DBOptions()
1549 .setCreateIfMissing(true)) {
1550 final List
<ColumnFamilyDescriptor
> cfDescs
= Arrays
.asList(
1551 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
)
1553 final List
<ColumnFamilyHandle
> cfHandles
= new ArrayList
<>();
1554 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1555 try (final RocksDB db
= RocksDB
.open(options
, dbPath
, cfDescs
, cfHandles
)) {
1556 db
.put(cfHandles
.get(0), "key1".getBytes(UTF_8
), "value1".getBytes(UTF_8
));
1557 db
.put(cfHandles
.get(0), "key2".getBytes(UTF_8
), "value2".getBytes(UTF_8
));
1558 db
.put(cfHandles
.get(0), "key3".getBytes(UTF_8
), "value3".getBytes(UTF_8
));
1560 final Range range
= db
.suggestCompactRange(cfHandles
.get(0));
1561 assertThat(range
).isNotNull();
1563 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
1572 public void promoteL0() throws RocksDBException
{
1573 try (final Options options
= new Options().setCreateIfMissing(true)) {
1574 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1575 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1582 public void startTrace() throws RocksDBException
{
1583 try (final Options options
= new Options().setCreateIfMissing(true)) {
1584 final String dbPath
= dbFolder
.getRoot().getAbsolutePath();
1585 try (final RocksDB db
= RocksDB
.open(options
, dbPath
)) {
1586 final TraceOptions traceOptions
= new TraceOptions();
1588 try (final InMemoryTraceWriter traceWriter
= new InMemoryTraceWriter()) {
1589 db
.startTrace(traceOptions
, traceWriter
);
1591 db
.put("key1".getBytes(UTF_8
), "value1".getBytes(UTF_8
));
1595 final List
<byte[]> writes
= traceWriter
.getWrites();
1596 assertThat(writes
.size()).isGreaterThan(0);
1603 public void setDBOptions() throws RocksDBException
{
1604 try (final DBOptions options
= new DBOptions()
1605 .setCreateIfMissing(true)
1606 .setCreateMissingColumnFamilies(true);
1607 final ColumnFamilyOptions new_cf_opts
= new ColumnFamilyOptions()
1608 .setWriteBufferSize(4096)) {
1610 final List
<ColumnFamilyDescriptor
> columnFamilyDescriptors
=
1612 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
1613 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts
));
1616 final List
<ColumnFamilyHandle
> columnFamilyHandles
= new ArrayList
<>();
1617 try (final RocksDB db
= RocksDB
.open(options
,
1618 dbFolder
.getRoot().getAbsolutePath(), columnFamilyDescriptors
, columnFamilyHandles
)) {
1620 final MutableDBOptions mutableOptions
=
1621 MutableDBOptions
.builder()
1622 .setBytesPerSync(1024 * 1027 * 7)
1623 .setAvoidFlushDuringShutdown(false)
1626 db
.setDBOptions(mutableOptions
);
1628 for (final ColumnFamilyHandle handle
: columnFamilyHandles
) {
1636 private static class InMemoryTraceWriter
extends AbstractTraceWriter
{
1637 private final List
<byte[]> writes
= new ArrayList
<>();
1638 private volatile boolean closed
= false;
1641 public void write(final Slice slice
) {
1645 final byte[] data
= slice
.data();
1646 final byte[] dataCopy
= new byte[data
.length
];
1647 System
.arraycopy(data
, 0, dataCopy
, 0, data
.length
);
1648 writes
.add(dataCopy
);
1652 public void closeWriter() {
1657 public long getFileSize() {
1659 for (int i
= 0; i
< writes
.size(); i
++) {
1660 size
+= writes
.get(i
).length
;
1665 public List
<byte[]> getWrites() {