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