]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/java/src/test/java/org/rocksdb/RocksDBTest.java
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / java / src / test / java / org / rocksdb / RocksDBTest.java
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 RocksMemoryResource rocksMemoryResource =
22 new RocksMemoryResource();
23
24 @Rule
25 public TemporaryFolder dbFolder = new TemporaryFolder();
26
27 public static final Random rand = PlatformRandomHelper.
28 getPlatformSpecificRandomFactory();
29
30 @Test
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
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
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
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
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
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
187 public void put() throws RocksDBException {
188 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
189 final WriteOptions opt = new WriteOptions()) {
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
198 // put
199 Segment key3 = sliceSegment("key3");
200 Segment key4 = sliceSegment("key4");
201 Segment value0 = sliceSegment("value 0");
202 Segment value1 = sliceSegment("value 1");
203 db.put(key3.data, key3.offset, key3.len, value0.data, value0.offset, value0.len);
204 db.put(opt, key4.data, key4.offset, key4.len, value1.data, value1.offset, value1.len);
205
206 // compare
207 Assert.assertTrue(value0.isSamePayload(db.get(key3.data, key3.offset, key3.len)));
208 Assert.assertTrue(value1.isSamePayload(db.get(key4.data, key4.offset, key4.len)));
209 }
210 }
211
212 private static Segment sliceSegment(String key) {
213 ByteBuffer rawKey = ByteBuffer.allocate(key.length() + 4);
214 rawKey.put((byte)0);
215 rawKey.put((byte)0);
216 rawKey.put(key.getBytes());
217
218 return new Segment(rawKey.array(), 2, key.length());
219 }
220
221 private static class Segment {
222 final byte[] data;
223 final int offset;
224 final int len;
225
226 public boolean isSamePayload(byte[] value) {
227 if (value == null) {
228 return false;
229 }
230 if (value.length != len) {
231 return false;
232 }
233
234 for (int i = 0; i < value.length; i++) {
235 if (data[i + offset] != value[i]) {
236 return false;
237 }
238 }
239
240 return true;
241 }
242
243 public Segment(byte[] value, int offset, int len) {
244 this.data = value;
245 this.offset = offset;
246 this.len = len;
247 }
248 }
249
250 @Test
251 public void write() throws RocksDBException {
252 try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
253 final Options options = new Options()
254 .setMergeOperator(stringAppendOperator)
255 .setCreateIfMissing(true);
256 final RocksDB db = RocksDB.open(options,
257 dbFolder.getRoot().getAbsolutePath());
258 final WriteOptions opts = new WriteOptions()) {
259
260 try (final WriteBatch wb1 = new WriteBatch()) {
261 wb1.put("key1".getBytes(), "aa".getBytes());
262 wb1.merge("key1".getBytes(), "bb".getBytes());
263
264 try (final WriteBatch wb2 = new WriteBatch()) {
265 wb2.put("key2".getBytes(), "xx".getBytes());
266 wb2.merge("key2".getBytes(), "yy".getBytes());
267 db.write(opts, wb1);
268 db.write(opts, wb2);
269 }
270 }
271
272 assertThat(db.get("key1".getBytes())).isEqualTo(
273 "aa,bb".getBytes());
274 assertThat(db.get("key2".getBytes())).isEqualTo(
275 "xx,yy".getBytes());
276 }
277 }
278
279 @Test
280 public void getWithOutValue() throws RocksDBException {
281 try (final RocksDB db =
282 RocksDB.open(dbFolder.getRoot().getAbsolutePath())) {
283 db.put("key1".getBytes(), "value".getBytes());
284 db.put("key2".getBytes(), "12345678".getBytes());
285 byte[] outValue = new byte[5];
286 // not found value
287 int getResult = db.get("keyNotFound".getBytes(), outValue);
288 assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND);
289 // found value which fits in outValue
290 getResult = db.get("key1".getBytes(), outValue);
291 assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
292 assertThat(outValue).isEqualTo("value".getBytes());
293 // found value which fits partially
294 getResult = db.get("key2".getBytes(), outValue);
295 assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
296 assertThat(outValue).isEqualTo("12345".getBytes());
297 }
298 }
299
300 @Test
301 public void getWithOutValueReadOptions() throws RocksDBException {
302 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
303 final ReadOptions rOpt = new ReadOptions()) {
304 db.put("key1".getBytes(), "value".getBytes());
305 db.put("key2".getBytes(), "12345678".getBytes());
306 byte[] outValue = new byte[5];
307 // not found value
308 int getResult = db.get(rOpt, "keyNotFound".getBytes(),
309 outValue);
310 assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND);
311 // found value which fits in outValue
312 getResult = db.get(rOpt, "key1".getBytes(), outValue);
313 assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
314 assertThat(outValue).isEqualTo("value".getBytes());
315 // found value which fits partially
316 getResult = db.get(rOpt, "key2".getBytes(), outValue);
317 assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
318 assertThat(outValue).isEqualTo("12345".getBytes());
319 }
320 }
321
322 @Rule
323 public ExpectedException thrown = ExpectedException.none();
324
325 @Test
326 public void getOutOfArrayMaxSizeValue() throws RocksDBException {
327 final int numberOfValueSplits = 10;
328 final int splitSize = Integer.MAX_VALUE / numberOfValueSplits;
329
330 Runtime runtime = Runtime.getRuntime();
331 long neededMemory = ((long)(splitSize)) * (((long)numberOfValueSplits) + 3);
332 boolean isEnoughMemory = runtime.maxMemory() - runtime.totalMemory() > neededMemory;
333 Assume.assumeTrue(isEnoughMemory);
334
335 final byte[] valueSplit = new byte[splitSize];
336 final byte[] key = "key".getBytes();
337
338 thrown.expect(RocksDBException.class);
339 thrown.expectMessage("Requested array size exceeds VM limit");
340
341 // merge (numberOfValueSplits + 1) valueSplit's to get value size exceeding Integer.MAX_VALUE
342 try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
343 final Options opt = new Options()
344 .setCreateIfMissing(true)
345 .setMergeOperator(stringAppendOperator);
346 final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
347 db.put(key, valueSplit);
348 for (int i = 0; i < numberOfValueSplits; i++) {
349 db.merge(key, valueSplit);
350 }
351 db.get(key);
352 }
353 }
354
355 @Test
356 public void multiGet() throws RocksDBException, InterruptedException {
357 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
358 final ReadOptions rOpt = new ReadOptions()) {
359 db.put("key1".getBytes(), "value".getBytes());
360 db.put("key2".getBytes(), "12345678".getBytes());
361 List<byte[]> lookupKeys = new ArrayList<>();
362 lookupKeys.add("key1".getBytes());
363 lookupKeys.add("key2".getBytes());
364 Map<byte[], byte[]> results = db.multiGet(lookupKeys);
365 assertThat(results).isNotNull();
366 assertThat(results.values()).isNotNull();
367 assertThat(results.values()).
368 contains("value".getBytes(), "12345678".getBytes());
369 // test same method with ReadOptions
370 results = db.multiGet(rOpt, lookupKeys);
371 assertThat(results).isNotNull();
372 assertThat(results.values()).isNotNull();
373 assertThat(results.values()).
374 contains("value".getBytes(), "12345678".getBytes());
375
376 // remove existing key
377 lookupKeys.remove("key2".getBytes());
378 // add non existing key
379 lookupKeys.add("key3".getBytes());
380 results = db.multiGet(lookupKeys);
381 assertThat(results).isNotNull();
382 assertThat(results.values()).isNotNull();
383 assertThat(results.values()).
384 contains("value".getBytes());
385 // test same call with readOptions
386 results = db.multiGet(rOpt, lookupKeys);
387 assertThat(results).isNotNull();
388 assertThat(results.values()).isNotNull();
389 assertThat(results.values()).
390 contains("value".getBytes());
391 }
392 }
393
394 @Test
395 public void multiGetAsList() throws RocksDBException, InterruptedException {
396 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
397 final ReadOptions rOpt = new ReadOptions()) {
398 db.put("key1".getBytes(), "value".getBytes());
399 db.put("key2".getBytes(), "12345678".getBytes());
400 List<byte[]> lookupKeys = new ArrayList<>();
401 lookupKeys.add("key1".getBytes());
402 lookupKeys.add("key2".getBytes());
403 List<byte[]> results = db.multiGetAsList(lookupKeys);
404 assertThat(results).isNotNull();
405 assertThat(results).hasSize(lookupKeys.size());
406 assertThat(results).
407 containsExactly("value".getBytes(), "12345678".getBytes());
408 // test same method with ReadOptions
409 results = db.multiGetAsList(rOpt, lookupKeys);
410 assertThat(results).isNotNull();
411 assertThat(results).
412 contains("value".getBytes(), "12345678".getBytes());
413
414 // remove existing key
415 lookupKeys.remove(1);
416 // add non existing key
417 lookupKeys.add("key3".getBytes());
418 results = db.multiGetAsList(lookupKeys);
419 assertThat(results).isNotNull();
420 assertThat(results).
421 containsExactly("value".getBytes(), null);
422 // test same call with readOptions
423 results = db.multiGetAsList(rOpt, lookupKeys);
424 assertThat(results).isNotNull();
425 assertThat(results).contains("value".getBytes());
426 }
427 }
428
429 @Test
430 public void merge() throws RocksDBException {
431 try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
432 final Options opt = new Options()
433 .setCreateIfMissing(true)
434 .setMergeOperator(stringAppendOperator);
435 final WriteOptions wOpt = new WriteOptions();
436 final RocksDB db = RocksDB.open(opt,
437 dbFolder.getRoot().getAbsolutePath())
438 ) {
439 db.put("key1".getBytes(), "value".getBytes());
440 assertThat(db.get("key1".getBytes())).isEqualTo(
441 "value".getBytes());
442 // merge key1 with another value portion
443 db.merge("key1".getBytes(), "value2".getBytes());
444 assertThat(db.get("key1".getBytes())).isEqualTo(
445 "value,value2".getBytes());
446 // merge key1 with another value portion
447 db.merge(wOpt, "key1".getBytes(), "value3".getBytes());
448 assertThat(db.get("key1".getBytes())).isEqualTo(
449 "value,value2,value3".getBytes());
450 // merge on non existent key shall insert the value
451 db.merge(wOpt, "key2".getBytes(), "xxxx".getBytes());
452 assertThat(db.get("key2".getBytes())).isEqualTo(
453 "xxxx".getBytes());
454
455 Segment key3 = sliceSegment("key3");
456 Segment key4 = sliceSegment("key4");
457 Segment value0 = sliceSegment("value 0");
458 Segment value1 = sliceSegment("value 1");
459
460 db.merge(key3.data, key3.offset, key3.len, value0.data, value0.offset, value0.len);
461 db.merge(wOpt, key4.data, key4.offset, key4.len, value1.data, value1.offset, value1.len);
462
463 // compare
464 Assert.assertTrue(value0.isSamePayload(db.get(key3.data, key3.offset, key3.len)));
465 Assert.assertTrue(value1.isSamePayload(db.get(key4.data, key4.offset, key4.len)));
466 }
467 }
468
469 @Test
470 public void delete() throws RocksDBException {
471 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
472 final WriteOptions wOpt = new WriteOptions()) {
473 db.put("key1".getBytes(), "value".getBytes());
474 db.put("key2".getBytes(), "12345678".getBytes());
475 assertThat(db.get("key1".getBytes())).isEqualTo(
476 "value".getBytes());
477 assertThat(db.get("key2".getBytes())).isEqualTo(
478 "12345678".getBytes());
479 db.delete("key1".getBytes());
480 db.delete(wOpt, "key2".getBytes());
481 assertThat(db.get("key1".getBytes())).isNull();
482 assertThat(db.get("key2".getBytes())).isNull();
483
484
485 Segment key3 = sliceSegment("key3");
486 Segment key4 = sliceSegment("key4");
487 db.put("key3".getBytes(), "key3 value".getBytes());
488 db.put("key4".getBytes(), "key4 value".getBytes());
489
490 db.delete(key3.data, key3.offset, key3.len);
491 db.delete(wOpt, key4.data, key4.offset, key4.len);
492
493 assertThat(db.get("key3".getBytes())).isNull();
494 assertThat(db.get("key4".getBytes())).isNull();
495 }
496 }
497
498 @Test
499 public void singleDelete() throws RocksDBException {
500 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
501 final WriteOptions wOpt = new WriteOptions()) {
502 db.put("key1".getBytes(), "value".getBytes());
503 db.put("key2".getBytes(), "12345678".getBytes());
504 assertThat(db.get("key1".getBytes())).isEqualTo(
505 "value".getBytes());
506 assertThat(db.get("key2".getBytes())).isEqualTo(
507 "12345678".getBytes());
508 db.singleDelete("key1".getBytes());
509 db.singleDelete(wOpt, "key2".getBytes());
510 assertThat(db.get("key1".getBytes())).isNull();
511 assertThat(db.get("key2".getBytes())).isNull();
512 }
513 }
514
515 @Test
516 public void singleDelete_nonExisting() throws RocksDBException {
517 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
518 final WriteOptions wOpt = new WriteOptions()) {
519 db.singleDelete("key1".getBytes());
520 db.singleDelete(wOpt, "key2".getBytes());
521 assertThat(db.get("key1".getBytes())).isNull();
522 assertThat(db.get("key2".getBytes())).isNull();
523 }
524 }
525
526 @Test
527 public void deleteRange() throws RocksDBException {
528 try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath())) {
529 db.put("key1".getBytes(), "value".getBytes());
530 db.put("key2".getBytes(), "12345678".getBytes());
531 db.put("key3".getBytes(), "abcdefg".getBytes());
532 db.put("key4".getBytes(), "xyz".getBytes());
533 assertThat(db.get("key1".getBytes())).isEqualTo("value".getBytes());
534 assertThat(db.get("key2".getBytes())).isEqualTo("12345678".getBytes());
535 assertThat(db.get("key3".getBytes())).isEqualTo("abcdefg".getBytes());
536 assertThat(db.get("key4".getBytes())).isEqualTo("xyz".getBytes());
537 db.deleteRange("key2".getBytes(), "key4".getBytes());
538 assertThat(db.get("key1".getBytes())).isEqualTo("value".getBytes());
539 assertThat(db.get("key2".getBytes())).isNull();
540 assertThat(db.get("key3".getBytes())).isNull();
541 assertThat(db.get("key4".getBytes())).isEqualTo("xyz".getBytes());
542 }
543 }
544
545 @Test
546 public void getIntProperty() throws RocksDBException {
547 try (
548 final Options options = new Options()
549 .setCreateIfMissing(true)
550 .setMaxWriteBufferNumber(10)
551 .setMinWriteBufferNumberToMerge(10);
552 final RocksDB db = RocksDB.open(options,
553 dbFolder.getRoot().getAbsolutePath());
554 final WriteOptions wOpt = new WriteOptions().setDisableWAL(true)
555 ) {
556 db.put(wOpt, "key1".getBytes(), "value1".getBytes());
557 db.put(wOpt, "key2".getBytes(), "value2".getBytes());
558 db.put(wOpt, "key3".getBytes(), "value3".getBytes());
559 db.put(wOpt, "key4".getBytes(), "value4".getBytes());
560 assertThat(db.getLongProperty("rocksdb.num-entries-active-mem-table"))
561 .isGreaterThan(0);
562 assertThat(db.getLongProperty("rocksdb.cur-size-active-mem-table"))
563 .isGreaterThan(0);
564 }
565 }
566
567 @Test
568 public void fullCompactRange() throws RocksDBException {
569 try (final Options opt = new Options().
570 setCreateIfMissing(true).
571 setDisableAutoCompactions(true).
572 setCompactionStyle(CompactionStyle.LEVEL).
573 setNumLevels(4).
574 setWriteBufferSize(100 << 10).
575 setLevelZeroFileNumCompactionTrigger(3).
576 setTargetFileSizeBase(200 << 10).
577 setTargetFileSizeMultiplier(1).
578 setMaxBytesForLevelBase(500 << 10).
579 setMaxBytesForLevelMultiplier(1).
580 setDisableAutoCompactions(false);
581 final RocksDB db = RocksDB.open(opt,
582 dbFolder.getRoot().getAbsolutePath())) {
583 // fill database with key/value pairs
584 byte[] b = new byte[10000];
585 for (int i = 0; i < 200; i++) {
586 rand.nextBytes(b);
587 db.put((String.valueOf(i)).getBytes(), b);
588 }
589 db.compactRange();
590 }
591 }
592
593 @Test
594 public void fullCompactRangeColumnFamily()
595 throws RocksDBException {
596 try (
597 final DBOptions opt = new DBOptions().
598 setCreateIfMissing(true).
599 setCreateMissingColumnFamilies(true);
600 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
601 setDisableAutoCompactions(true).
602 setCompactionStyle(CompactionStyle.LEVEL).
603 setNumLevels(4).
604 setWriteBufferSize(100 << 10).
605 setLevelZeroFileNumCompactionTrigger(3).
606 setTargetFileSizeBase(200 << 10).
607 setTargetFileSizeMultiplier(1).
608 setMaxBytesForLevelBase(500 << 10).
609 setMaxBytesForLevelMultiplier(1).
610 setDisableAutoCompactions(false)
611 ) {
612 final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
613 Arrays.asList(
614 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
615 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts));
616
617 // open database
618 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
619 try (final RocksDB db = RocksDB.open(opt,
620 dbFolder.getRoot().getAbsolutePath(),
621 columnFamilyDescriptors,
622 columnFamilyHandles)) {
623 try {
624 // fill database with key/value pairs
625 byte[] b = new byte[10000];
626 for (int i = 0; i < 200; i++) {
627 rand.nextBytes(b);
628 db.put(columnFamilyHandles.get(1),
629 String.valueOf(i).getBytes(), b);
630 }
631 db.compactRange(columnFamilyHandles.get(1));
632 } finally {
633 for (final ColumnFamilyHandle handle : columnFamilyHandles) {
634 handle.close();
635 }
636 }
637 }
638 }
639 }
640
641 @Test
642 public void compactRangeWithKeys()
643 throws RocksDBException {
644 try (final Options opt = new Options().
645 setCreateIfMissing(true).
646 setDisableAutoCompactions(true).
647 setCompactionStyle(CompactionStyle.LEVEL).
648 setNumLevels(4).
649 setWriteBufferSize(100 << 10).
650 setLevelZeroFileNumCompactionTrigger(3).
651 setTargetFileSizeBase(200 << 10).
652 setTargetFileSizeMultiplier(1).
653 setMaxBytesForLevelBase(500 << 10).
654 setMaxBytesForLevelMultiplier(1).
655 setDisableAutoCompactions(false);
656 final RocksDB db = RocksDB.open(opt,
657 dbFolder.getRoot().getAbsolutePath())) {
658 // fill database with key/value pairs
659 byte[] b = new byte[10000];
660 for (int i = 0; i < 200; i++) {
661 rand.nextBytes(b);
662 db.put((String.valueOf(i)).getBytes(), b);
663 }
664 db.compactRange("0".getBytes(), "201".getBytes());
665 }
666 }
667
668 @Test
669 public void compactRangeWithKeysReduce()
670 throws RocksDBException {
671 try (
672 final Options opt = new Options().
673 setCreateIfMissing(true).
674 setDisableAutoCompactions(true).
675 setCompactionStyle(CompactionStyle.LEVEL).
676 setNumLevels(4).
677 setWriteBufferSize(100 << 10).
678 setLevelZeroFileNumCompactionTrigger(3).
679 setTargetFileSizeBase(200 << 10).
680 setTargetFileSizeMultiplier(1).
681 setMaxBytesForLevelBase(500 << 10).
682 setMaxBytesForLevelMultiplier(1).
683 setDisableAutoCompactions(false);
684 final RocksDB db = RocksDB.open(opt,
685 dbFolder.getRoot().getAbsolutePath())) {
686 // fill database with key/value pairs
687 byte[] b = new byte[10000];
688 for (int i = 0; i < 200; i++) {
689 rand.nextBytes(b);
690 db.put((String.valueOf(i)).getBytes(), b);
691 }
692 db.flush(new FlushOptions().setWaitForFlush(true));
693 db.compactRange("0".getBytes(), "201".getBytes(),
694 true, -1, 0);
695 }
696 }
697
698 @Test
699 public void compactRangeWithKeysColumnFamily()
700 throws RocksDBException {
701 try (final DBOptions opt = new DBOptions().
702 setCreateIfMissing(true).
703 setCreateMissingColumnFamilies(true);
704 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
705 setDisableAutoCompactions(true).
706 setCompactionStyle(CompactionStyle.LEVEL).
707 setNumLevels(4).
708 setWriteBufferSize(100 << 10).
709 setLevelZeroFileNumCompactionTrigger(3).
710 setTargetFileSizeBase(200 << 10).
711 setTargetFileSizeMultiplier(1).
712 setMaxBytesForLevelBase(500 << 10).
713 setMaxBytesForLevelMultiplier(1).
714 setDisableAutoCompactions(false)
715 ) {
716 final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
717 Arrays.asList(
718 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
719 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
720 );
721
722 // open database
723 final List<ColumnFamilyHandle> columnFamilyHandles =
724 new ArrayList<>();
725 try (final RocksDB db = RocksDB.open(opt,
726 dbFolder.getRoot().getAbsolutePath(),
727 columnFamilyDescriptors,
728 columnFamilyHandles)) {
729 try {
730 // fill database with key/value pairs
731 byte[] b = new byte[10000];
732 for (int i = 0; i < 200; i++) {
733 rand.nextBytes(b);
734 db.put(columnFamilyHandles.get(1),
735 String.valueOf(i).getBytes(), b);
736 }
737 db.compactRange(columnFamilyHandles.get(1),
738 "0".getBytes(), "201".getBytes());
739 } finally {
740 for (final ColumnFamilyHandle handle : columnFamilyHandles) {
741 handle.close();
742 }
743 }
744 }
745 }
746 }
747
748 @Test
749 public void compactRangeWithKeysReduceColumnFamily()
750 throws RocksDBException {
751 try (final DBOptions opt = new DBOptions().
752 setCreateIfMissing(true).
753 setCreateMissingColumnFamilies(true);
754 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
755 setDisableAutoCompactions(true).
756 setCompactionStyle(CompactionStyle.LEVEL).
757 setNumLevels(4).
758 setWriteBufferSize(100 << 10).
759 setLevelZeroFileNumCompactionTrigger(3).
760 setTargetFileSizeBase(200 << 10).
761 setTargetFileSizeMultiplier(1).
762 setMaxBytesForLevelBase(500 << 10).
763 setMaxBytesForLevelMultiplier(1).
764 setDisableAutoCompactions(false)
765 ) {
766 final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
767 Arrays.asList(
768 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
769 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
770 );
771
772 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
773 // open database
774 try (final RocksDB db = RocksDB.open(opt,
775 dbFolder.getRoot().getAbsolutePath(),
776 columnFamilyDescriptors,
777 columnFamilyHandles)) {
778 try {
779 // fill database with key/value pairs
780 byte[] b = new byte[10000];
781 for (int i = 0; i < 200; i++) {
782 rand.nextBytes(b);
783 db.put(columnFamilyHandles.get(1),
784 String.valueOf(i).getBytes(), b);
785 }
786 db.compactRange(columnFamilyHandles.get(1), "0".getBytes(),
787 "201".getBytes(), true, -1, 0);
788 } finally {
789 for (final ColumnFamilyHandle handle : columnFamilyHandles) {
790 handle.close();
791 }
792 }
793 }
794 }
795 }
796
797 @Test
798 public void compactRangeToLevel()
799 throws RocksDBException, InterruptedException {
800 final int NUM_KEYS_PER_L0_FILE = 100;
801 final int KEY_SIZE = 20;
802 final int VALUE_SIZE = 300;
803 final int L0_FILE_SIZE =
804 NUM_KEYS_PER_L0_FILE * (KEY_SIZE + VALUE_SIZE);
805 final int NUM_L0_FILES = 10;
806 final int TEST_SCALE = 5;
807 final int KEY_INTERVAL = 100;
808 try (final Options opt = new Options().
809 setCreateIfMissing(true).
810 setCompactionStyle(CompactionStyle.LEVEL).
811 setNumLevels(5).
812 // a slightly bigger write buffer than L0 file
813 // so that we can ensure manual flush always
814 // go before background flush happens.
815 setWriteBufferSize(L0_FILE_SIZE * 2).
816 // Disable auto L0 -> L1 compaction
817 setLevelZeroFileNumCompactionTrigger(20).
818 setTargetFileSizeBase(L0_FILE_SIZE * 100).
819 setTargetFileSizeMultiplier(1).
820 // To disable auto compaction
821 setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100).
822 setMaxBytesForLevelMultiplier(2).
823 setDisableAutoCompactions(true);
824 final RocksDB db = RocksDB.open(opt,
825 dbFolder.getRoot().getAbsolutePath())
826 ) {
827 // fill database with key/value pairs
828 byte[] value = new byte[VALUE_SIZE];
829 int int_key = 0;
830 for (int round = 0; round < 5; ++round) {
831 int initial_key = int_key;
832 for (int f = 1; f <= NUM_L0_FILES; ++f) {
833 for (int i = 0; i < NUM_KEYS_PER_L0_FILE; ++i) {
834 int_key += KEY_INTERVAL;
835 rand.nextBytes(value);
836
837 db.put(String.format("%020d", int_key).getBytes(),
838 value);
839 }
840 db.flush(new FlushOptions().setWaitForFlush(true));
841 // Make sure we do create one more L0 files.
842 assertThat(
843 db.getProperty("rocksdb.num-files-at-level0")).
844 isEqualTo("" + f);
845 }
846
847 // Compact all L0 files we just created
848 db.compactRange(
849 String.format("%020d", initial_key).getBytes(),
850 String.format("%020d", int_key - 1).getBytes());
851 // Making sure there isn't any L0 files.
852 assertThat(
853 db.getProperty("rocksdb.num-files-at-level0")).
854 isEqualTo("0");
855 // Making sure there are some L1 files.
856 // Here we only use != 0 instead of a specific number
857 // as we don't want the test make any assumption on
858 // how compaction works.
859 assertThat(
860 db.getProperty("rocksdb.num-files-at-level1")).
861 isNotEqualTo("0");
862 // Because we only compacted those keys we issued
863 // in this round, there shouldn't be any L1 -> L2
864 // compaction. So we expect zero L2 files here.
865 assertThat(
866 db.getProperty("rocksdb.num-files-at-level2")).
867 isEqualTo("0");
868 }
869 }
870 }
871
872 @Test
873 public void compactRangeToLevelColumnFamily()
874 throws RocksDBException {
875 final int NUM_KEYS_PER_L0_FILE = 100;
876 final int KEY_SIZE = 20;
877 final int VALUE_SIZE = 300;
878 final int L0_FILE_SIZE =
879 NUM_KEYS_PER_L0_FILE * (KEY_SIZE + VALUE_SIZE);
880 final int NUM_L0_FILES = 10;
881 final int TEST_SCALE = 5;
882 final int KEY_INTERVAL = 100;
883
884 try (final DBOptions opt = new DBOptions().
885 setCreateIfMissing(true).
886 setCreateMissingColumnFamilies(true);
887 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
888 setCompactionStyle(CompactionStyle.LEVEL).
889 setNumLevels(5).
890 // a slightly bigger write buffer than L0 file
891 // so that we can ensure manual flush always
892 // go before background flush happens.
893 setWriteBufferSize(L0_FILE_SIZE * 2).
894 // Disable auto L0 -> L1 compaction
895 setLevelZeroFileNumCompactionTrigger(20).
896 setTargetFileSizeBase(L0_FILE_SIZE * 100).
897 setTargetFileSizeMultiplier(1).
898 // To disable auto compaction
899 setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100).
900 setMaxBytesForLevelMultiplier(2).
901 setDisableAutoCompactions(true)
902 ) {
903 final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
904 Arrays.asList(
905 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
906 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
907 );
908
909 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
910 // open database
911 try (final RocksDB db = RocksDB.open(opt,
912 dbFolder.getRoot().getAbsolutePath(),
913 columnFamilyDescriptors,
914 columnFamilyHandles)) {
915 try {
916 // fill database with key/value pairs
917 byte[] value = new byte[VALUE_SIZE];
918 int int_key = 0;
919 for (int round = 0; round < 5; ++round) {
920 int initial_key = int_key;
921 for (int f = 1; f <= NUM_L0_FILES; ++f) {
922 for (int i = 0; i < NUM_KEYS_PER_L0_FILE; ++i) {
923 int_key += KEY_INTERVAL;
924 rand.nextBytes(value);
925
926 db.put(columnFamilyHandles.get(1),
927 String.format("%020d", int_key).getBytes(),
928 value);
929 }
930 db.flush(new FlushOptions().setWaitForFlush(true),
931 columnFamilyHandles.get(1));
932 // Make sure we do create one more L0 files.
933 assertThat(
934 db.getProperty(columnFamilyHandles.get(1),
935 "rocksdb.num-files-at-level0")).
936 isEqualTo("" + f);
937 }
938
939 // Compact all L0 files we just created
940 db.compactRange(
941 columnFamilyHandles.get(1),
942 String.format("%020d", initial_key).getBytes(),
943 String.format("%020d", int_key - 1).getBytes());
944 // Making sure there isn't any L0 files.
945 assertThat(
946 db.getProperty(columnFamilyHandles.get(1),
947 "rocksdb.num-files-at-level0")).
948 isEqualTo("0");
949 // Making sure there are some L1 files.
950 // Here we only use != 0 instead of a specific number
951 // as we don't want the test make any assumption on
952 // how compaction works.
953 assertThat(
954 db.getProperty(columnFamilyHandles.get(1),
955 "rocksdb.num-files-at-level1")).
956 isNotEqualTo("0");
957 // Because we only compacted those keys we issued
958 // in this round, there shouldn't be any L1 -> L2
959 // compaction. So we expect zero L2 files here.
960 assertThat(
961 db.getProperty(columnFamilyHandles.get(1),
962 "rocksdb.num-files-at-level2")).
963 isEqualTo("0");
964 }
965 } finally {
966 for (final ColumnFamilyHandle handle : columnFamilyHandles) {
967 handle.close();
968 }
969 }
970 }
971 }
972 }
973
974 @Test
975 public void pauseContinueBackgroundWork() throws RocksDBException {
976 try (final Options options = new Options().setCreateIfMissing(true);
977 final RocksDB db = RocksDB.open(options,
978 dbFolder.getRoot().getAbsolutePath())
979 ) {
980 db.pauseBackgroundWork();
981 db.continueBackgroundWork();
982 db.pauseBackgroundWork();
983 db.continueBackgroundWork();
984 }
985 }
986
987 @Test
988 public void enableDisableFileDeletions() throws RocksDBException {
989 try (final Options options = new Options().setCreateIfMissing(true);
990 final RocksDB db = RocksDB.open(options,
991 dbFolder.getRoot().getAbsolutePath())
992 ) {
993 db.disableFileDeletions();
994 db.enableFileDeletions(false);
995 db.disableFileDeletions();
996 db.enableFileDeletions(true);
997 }
998 }
999
1000 @Test
1001 public void setOptions() throws RocksDBException {
1002 try (final DBOptions options = new DBOptions()
1003 .setCreateIfMissing(true)
1004 .setCreateMissingColumnFamilies(true);
1005 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions()
1006 .setWriteBufferSize(4096)) {
1007
1008 final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
1009 Arrays.asList(
1010 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
1011 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts));
1012
1013 // open database
1014 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
1015 try (final RocksDB db = RocksDB.open(options,
1016 dbFolder.getRoot().getAbsolutePath(), columnFamilyDescriptors, columnFamilyHandles)) {
1017 try {
1018 final MutableColumnFamilyOptions mutableOptions =
1019 MutableColumnFamilyOptions.builder()
1020 .setWriteBufferSize(2048)
1021 .build();
1022
1023 db.setOptions(columnFamilyHandles.get(1), mutableOptions);
1024
1025 } finally {
1026 for (final ColumnFamilyHandle handle : columnFamilyHandles) {
1027 handle.close();
1028 }
1029 }
1030 }
1031 }
1032 }
1033
1034 @Test
1035 public void destroyDB() throws RocksDBException {
1036 try (final Options options = new Options().setCreateIfMissing(true)) {
1037 String dbPath = dbFolder.getRoot().getAbsolutePath();
1038 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1039 db.put("key1".getBytes(), "value".getBytes());
1040 }
1041 assertThat(dbFolder.getRoot().exists()).isTrue();
1042 RocksDB.destroyDB(dbPath, options);
1043 assertThat(dbFolder.getRoot().exists()).isFalse();
1044 }
1045 }
1046
1047 @Test(expected = RocksDBException.class)
1048 public void destroyDBFailIfOpen() throws RocksDBException {
1049 try (final Options options = new Options().setCreateIfMissing(true)) {
1050 String dbPath = dbFolder.getRoot().getAbsolutePath();
1051 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1052 // Fails as the db is open and locked.
1053 RocksDB.destroyDB(dbPath, options);
1054 }
1055 }
1056 }
1057
1058 @Ignore("This test crashes. Re-enable after fixing.")
1059 @Test
1060 public void getApproximateSizes() throws RocksDBException {
1061 final byte key1[] = "key1".getBytes(UTF_8);
1062 final byte key2[] = "key2".getBytes(UTF_8);
1063 final byte key3[] = "key3".getBytes(UTF_8);
1064 try (final Options options = new Options().setCreateIfMissing(true)) {
1065 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1066 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1067 db.put(key1, key1);
1068 db.put(key2, key2);
1069 db.put(key3, key3);
1070
1071 final long[] sizes = db.getApproximateSizes(
1072 Arrays.asList(
1073 new Range(new Slice(key1), new Slice(key2)),
1074 new Range(new Slice(key2), new Slice(key3))
1075 ),
1076 SizeApproximationFlag.INCLUDE_FILES,
1077 SizeApproximationFlag.INCLUDE_MEMTABLES);
1078
1079 assertThat(sizes.length).isEqualTo(2);
1080 assertThat(sizes[0]).isEqualTo(0);
1081 assertThat(sizes[1]).isGreaterThanOrEqualTo(1);
1082 }
1083 }
1084 }
1085
1086 @Test
1087 public void getApproximateMemTableStats() throws RocksDBException {
1088 final byte key1[] = "key1".getBytes(UTF_8);
1089 final byte key2[] = "key2".getBytes(UTF_8);
1090 final byte key3[] = "key3".getBytes(UTF_8);
1091 try (final Options options = new Options().setCreateIfMissing(true)) {
1092 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1093 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1094 db.put(key1, key1);
1095 db.put(key2, key2);
1096 db.put(key3, key3);
1097
1098 final RocksDB.CountAndSize stats =
1099 db.getApproximateMemTableStats(
1100 new Range(new Slice(key1), new Slice(key3)));
1101
1102 assertThat(stats).isNotNull();
1103 assertThat(stats.count).isGreaterThan(1);
1104 assertThat(stats.size).isGreaterThan(1);
1105 }
1106 }
1107 }
1108
1109 @Ignore("TODO(AR) re-enable when ready!")
1110 @Test
1111 public void compactFiles() throws RocksDBException {
1112 final int kTestKeySize = 16;
1113 final int kTestValueSize = 984;
1114 final int kEntrySize = kTestKeySize + kTestValueSize;
1115 final int kEntriesPerBuffer = 100;
1116 final int writeBufferSize = kEntrySize * kEntriesPerBuffer;
1117 final byte[] cfName = "pikachu".getBytes(UTF_8);
1118
1119 try (final Options options = new Options()
1120 .setCreateIfMissing(true)
1121 .setWriteBufferSize(writeBufferSize)
1122 .setCompactionStyle(CompactionStyle.LEVEL)
1123 .setTargetFileSizeBase(writeBufferSize)
1124 .setMaxBytesForLevelBase(writeBufferSize * 2)
1125 .setLevel0StopWritesTrigger(2)
1126 .setMaxBytesForLevelMultiplier(2)
1127 .setCompressionType(CompressionType.NO_COMPRESSION)
1128 .setMaxSubcompactions(4)) {
1129 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1130 try (final RocksDB db = RocksDB.open(options, dbPath);
1131 final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions(options)) {
1132 db.createColumnFamily(new ColumnFamilyDescriptor(cfName,
1133 cfOptions)).close();
1134 }
1135
1136 try (final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions(options)) {
1137 final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
1138 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOptions),
1139 new ColumnFamilyDescriptor(cfName, cfOptions)
1140 );
1141 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
1142 try (final DBOptions dbOptions = new DBOptions(options);
1143 final RocksDB db = RocksDB.open(dbOptions, dbPath, cfDescriptors,
1144 cfHandles);
1145 ) {
1146 try (final FlushOptions flushOptions = new FlushOptions()
1147 .setWaitForFlush(true)
1148 .setAllowWriteStall(true);
1149 final CompactionOptions compactionOptions = new CompactionOptions()) {
1150 final Random rnd = new Random(301);
1151 for (int key = 64 * kEntriesPerBuffer; key >= 0; --key) {
1152 final byte[] value = new byte[kTestValueSize];
1153 rnd.nextBytes(value);
1154 db.put(cfHandles.get(1), Integer.toString(key).getBytes(UTF_8),
1155 value);
1156 }
1157 db.flush(flushOptions, cfHandles);
1158
1159 final RocksDB.LiveFiles liveFiles = db.getLiveFiles();
1160 final List<String> compactedFiles =
1161 db.compactFiles(compactionOptions, cfHandles.get(1),
1162 liveFiles.files, 1, -1, null);
1163 assertThat(compactedFiles).isNotEmpty();
1164 } finally {
1165 for (final ColumnFamilyHandle cfHandle : cfHandles) {
1166 cfHandle.close();
1167 }
1168 }
1169 }
1170 }
1171 }
1172 }
1173
1174 @Test
1175 public void enableAutoCompaction() throws RocksDBException {
1176 try (final DBOptions options = new DBOptions()
1177 .setCreateIfMissing(true)) {
1178 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
1179 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
1180 );
1181 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
1182 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1183 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
1184 try {
1185 db.enableAutoCompaction(cfHandles);
1186 } finally {
1187 for (final ColumnFamilyHandle cfHandle : cfHandles) {
1188 cfHandle.close();
1189 }
1190 }
1191 }
1192 }
1193 }
1194
1195 @Test
1196 public void numberLevels() throws RocksDBException {
1197 try (final Options options = new Options().setCreateIfMissing(true)) {
1198 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1199 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1200 assertThat(db.numberLevels()).isEqualTo(7);
1201 }
1202 }
1203 }
1204
1205 @Test
1206 public void maxMemCompactionLevel() throws RocksDBException {
1207 try (final Options options = new Options().setCreateIfMissing(true)) {
1208 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1209 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1210 assertThat(db.maxMemCompactionLevel()).isEqualTo(0);
1211 }
1212 }
1213 }
1214
1215 @Test
1216 public void level0StopWriteTrigger() throws RocksDBException {
1217 try (final Options options = new Options().setCreateIfMissing(true)) {
1218 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1219 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1220 assertThat(db.level0StopWriteTrigger()).isEqualTo(36);
1221 }
1222 }
1223 }
1224
1225 @Test
1226 public void getName() throws RocksDBException {
1227 try (final Options options = new Options().setCreateIfMissing(true)) {
1228 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1229 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1230 assertThat(db.getName()).isEqualTo(dbPath);
1231 }
1232 }
1233 }
1234
1235 @Test
1236 public void getEnv() throws RocksDBException {
1237 try (final Options options = new Options().setCreateIfMissing(true)) {
1238 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1239 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1240 assertThat(db.getEnv()).isEqualTo(Env.getDefault());
1241 }
1242 }
1243 }
1244
1245 @Test
1246 public void flush() throws RocksDBException {
1247 try (final Options options = new Options().setCreateIfMissing(true)) {
1248 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1249 try (final RocksDB db = RocksDB.open(options, dbPath);
1250 final FlushOptions flushOptions = new FlushOptions()) {
1251 db.flush(flushOptions);
1252 }
1253 }
1254 }
1255
1256 @Test
1257 public void flushWal() throws RocksDBException {
1258 try (final Options options = new Options().setCreateIfMissing(true)) {
1259 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1260 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1261 db.flushWal(true);
1262 }
1263 }
1264 }
1265
1266 @Test
1267 public void syncWal() throws RocksDBException {
1268 try (final Options options = new Options().setCreateIfMissing(true)) {
1269 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1270 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1271 db.syncWal();
1272 }
1273 }
1274 }
1275
1276 @Test
1277 public void setPreserveDeletesSequenceNumber() throws RocksDBException {
1278 try (final Options options = new Options().setCreateIfMissing(true)) {
1279 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1280 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1281 assertThat(db.setPreserveDeletesSequenceNumber(db.getLatestSequenceNumber()))
1282 .isFalse();
1283 }
1284 }
1285 }
1286
1287 @Test
1288 public void getLiveFiles() throws RocksDBException {
1289 try (final Options options = new Options().setCreateIfMissing(true)) {
1290 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1291 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1292 final RocksDB.LiveFiles livefiles = db.getLiveFiles(true);
1293 assertThat(livefiles).isNotNull();
1294 assertThat(livefiles.manifestFileSize).isEqualTo(13);
1295 assertThat(livefiles.files.size()).isEqualTo(3);
1296 assertThat(livefiles.files.get(0)).isEqualTo("/CURRENT");
1297 assertThat(livefiles.files.get(1)).isEqualTo("/MANIFEST-000001");
1298 assertThat(livefiles.files.get(2)).isEqualTo("/OPTIONS-000005");
1299 }
1300 }
1301 }
1302
1303 @Test
1304 public void getSortedWalFiles() throws RocksDBException {
1305 try (final Options options = new Options().setCreateIfMissing(true)) {
1306 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1307 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1308 db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
1309 final List<LogFile> logFiles = db.getSortedWalFiles();
1310 assertThat(logFiles).isNotNull();
1311 assertThat(logFiles.size()).isEqualTo(1);
1312 assertThat(logFiles.get(0).type())
1313 .isEqualTo(WalFileType.kAliveLogFile);
1314 }
1315 }
1316 }
1317
1318 @Test
1319 public void deleteFile() throws RocksDBException {
1320 try (final Options options = new Options().setCreateIfMissing(true)) {
1321 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1322 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1323 db.deleteFile("unknown");
1324 }
1325 }
1326 }
1327
1328 @Test
1329 public void getLiveFilesMetaData() throws RocksDBException {
1330 try (final Options options = new Options().setCreateIfMissing(true)) {
1331 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1332 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1333 db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
1334 final List<LiveFileMetaData> liveFilesMetaData
1335 = db.getLiveFilesMetaData();
1336 assertThat(liveFilesMetaData).isEmpty();
1337 }
1338 }
1339 }
1340
1341 @Test
1342 public void getColumnFamilyMetaData() throws RocksDBException {
1343 try (final DBOptions options = new DBOptions()
1344 .setCreateIfMissing(true)) {
1345 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
1346 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
1347 );
1348 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
1349 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1350 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
1351 db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
1352 try {
1353 final ColumnFamilyMetaData cfMetadata =
1354 db.getColumnFamilyMetaData(cfHandles.get(0));
1355 assertThat(cfMetadata).isNotNull();
1356 assertThat(cfMetadata.name()).isEqualTo(RocksDB.DEFAULT_COLUMN_FAMILY);
1357 assertThat(cfMetadata.levels().size()).isEqualTo(7);
1358 } finally {
1359 for (final ColumnFamilyHandle cfHandle : cfHandles) {
1360 cfHandle.close();
1361 }
1362 }
1363 }
1364 }
1365 }
1366
1367 @Test
1368 public void verifyChecksum() throws RocksDBException {
1369 try (final Options options = new Options().setCreateIfMissing(true)) {
1370 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1371 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1372 db.verifyChecksum();
1373 }
1374 }
1375 }
1376
1377 @Test
1378 public void getPropertiesOfAllTables() throws RocksDBException {
1379 try (final DBOptions options = new DBOptions()
1380 .setCreateIfMissing(true)) {
1381 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
1382 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
1383 );
1384 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
1385 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1386 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
1387 db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
1388 try {
1389 final Map<String, TableProperties> properties =
1390 db.getPropertiesOfAllTables(cfHandles.get(0));
1391 assertThat(properties).isNotNull();
1392 } finally {
1393 for (final ColumnFamilyHandle cfHandle : cfHandles) {
1394 cfHandle.close();
1395 }
1396 }
1397 }
1398 }
1399 }
1400
1401 @Test
1402 public void getPropertiesOfTablesInRange() throws RocksDBException {
1403 try (final DBOptions options = new DBOptions()
1404 .setCreateIfMissing(true)) {
1405 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
1406 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
1407 );
1408 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
1409 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1410 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
1411 db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
1412 db.put(cfHandles.get(0), "key2".getBytes(UTF_8), "value2".getBytes(UTF_8));
1413 db.put(cfHandles.get(0), "key3".getBytes(UTF_8), "value3".getBytes(UTF_8));
1414 try {
1415 final Range range = new Range(
1416 new Slice("key1".getBytes(UTF_8)),
1417 new Slice("key3".getBytes(UTF_8)));
1418 final Map<String, TableProperties> properties =
1419 db.getPropertiesOfTablesInRange(
1420 cfHandles.get(0), Arrays.asList(range));
1421 assertThat(properties).isNotNull();
1422 } finally {
1423 for (final ColumnFamilyHandle cfHandle : cfHandles) {
1424 cfHandle.close();
1425 }
1426 }
1427 }
1428 }
1429 }
1430
1431 @Test
1432 public void suggestCompactRange() throws RocksDBException {
1433 try (final DBOptions options = new DBOptions()
1434 .setCreateIfMissing(true)) {
1435 final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
1436 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
1437 );
1438 final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
1439 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1440 try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
1441 db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
1442 db.put(cfHandles.get(0), "key2".getBytes(UTF_8), "value2".getBytes(UTF_8));
1443 db.put(cfHandles.get(0), "key3".getBytes(UTF_8), "value3".getBytes(UTF_8));
1444 try {
1445 final Range range = db.suggestCompactRange(cfHandles.get(0));
1446 assertThat(range).isNotNull();
1447 } finally {
1448 for (final ColumnFamilyHandle cfHandle : cfHandles) {
1449 cfHandle.close();
1450 }
1451 }
1452 }
1453 }
1454 }
1455
1456 @Test
1457 public void promoteL0() throws RocksDBException {
1458 try (final Options options = new Options().setCreateIfMissing(true)) {
1459 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1460 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1461 db.promoteL0(2);
1462 }
1463 }
1464 }
1465
1466 @Test
1467 public void startTrace() throws RocksDBException {
1468 try (final Options options = new Options().setCreateIfMissing(true)) {
1469 final String dbPath = dbFolder.getRoot().getAbsolutePath();
1470 try (final RocksDB db = RocksDB.open(options, dbPath)) {
1471 final TraceOptions traceOptions = new TraceOptions();
1472
1473 try (final InMemoryTraceWriter traceWriter = new InMemoryTraceWriter()) {
1474 db.startTrace(traceOptions, traceWriter);
1475
1476 db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
1477
1478 db.endTrace();
1479
1480 final List<byte[]> writes = traceWriter.getWrites();
1481 assertThat(writes.size()).isGreaterThan(0);
1482 }
1483 }
1484 }
1485 }
1486
1487 @Test
1488 public void setDBOptions() throws RocksDBException {
1489 try (final DBOptions options = new DBOptions()
1490 .setCreateIfMissing(true)
1491 .setCreateMissingColumnFamilies(true);
1492 final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions()
1493 .setWriteBufferSize(4096)) {
1494
1495 final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
1496 Arrays.asList(
1497 new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
1498 new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts));
1499
1500 // open database
1501 final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
1502 try (final RocksDB db = RocksDB.open(options,
1503 dbFolder.getRoot().getAbsolutePath(), columnFamilyDescriptors, columnFamilyHandles)) {
1504 try {
1505 final MutableDBOptions mutableOptions =
1506 MutableDBOptions.builder()
1507 .setBytesPerSync(1024 * 1027 * 7)
1508 .setAvoidFlushDuringShutdown(false)
1509 .build();
1510
1511 db.setDBOptions(mutableOptions);
1512 } finally {
1513 for (final ColumnFamilyHandle handle : columnFamilyHandles) {
1514 handle.close();
1515 }
1516 }
1517 }
1518 }
1519 }
1520
1521 private static class InMemoryTraceWriter extends AbstractTraceWriter {
1522 private final List<byte[]> writes = new ArrayList<>();
1523 private volatile boolean closed = false;
1524
1525 @Override
1526 public void write(final Slice slice) {
1527 if (closed) {
1528 return;
1529 }
1530 final byte[] data = slice.data();
1531 final byte[] dataCopy = new byte[data.length];
1532 System.arraycopy(data, 0, dataCopy, 0, data.length);
1533 writes.add(dataCopy);
1534 }
1535
1536 @Override
1537 public void closeWriter() {
1538 closed = true;
1539 }
1540
1541 @Override
1542 public long getFileSize() {
1543 long size = 0;
1544 for (int i = 0; i < writes.size(); i++) {
1545 size += writes.get(i).length;
1546 }
1547 return size;
1548 }
1549
1550 public List<byte[]> getWrites() {
1551 return writes;
1552 }
1553 }
1554 }