1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
8 import org
.junit
.ClassRule
;
10 import org
.junit
.Test
;
11 import org
.junit
.rules
.TemporaryFolder
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Arrays
;
15 import java
.util
.List
;
18 import static org
.assertj
.core
.api
.Assertions
.assertThat
;
19 import static org
.rocksdb
.util
.TestUtil
.*;
21 public class WalFilterTest
{
24 public static final RocksMemoryResource rocksMemoryResource
=
25 new RocksMemoryResource();
28 public TemporaryFolder dbFolder
= new TemporaryFolder();
31 public void walFilter() throws RocksDBException
{
32 // Create 3 batches with two keys each
33 final byte[][][] batchKeys
= {
49 final List
<ColumnFamilyDescriptor
> cfDescriptors
= Arrays
.asList(
50 new ColumnFamilyDescriptor(RocksDB
.DEFAULT_COLUMN_FAMILY
),
51 new ColumnFamilyDescriptor(u("pikachu"))
53 final List
<ColumnFamilyHandle
> cfHandles
= new ArrayList
<>();
55 // Test with all WAL processing options
56 for (final WalProcessingOption option
: WalProcessingOption
.values()) {
57 try (final Options options
= optionsForLogIterTest();
58 final DBOptions dbOptions
= new DBOptions(options
)
59 .setCreateMissingColumnFamilies(true);
60 final RocksDB db
= RocksDB
.open(dbOptions
,
61 dbFolder
.getRoot().getAbsolutePath(),
62 cfDescriptors
, cfHandles
)) {
63 try (final WriteOptions writeOptions
= new WriteOptions()) {
64 // Write given keys in given batches
65 for (int i
= 0; i
< batchKeys
.length
; i
++) {
66 final WriteBatch batch
= new WriteBatch();
67 for (int j
= 0; j
< batchKeys
[i
].length
; j
++) {
68 batch
.put(cfHandles
.get(0), batchKeys
[i
][j
], dummyString(1024));
70 db
.write(writeOptions
, batch
);
73 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
80 // Create a test filter that would apply wal_processing_option at the first
82 final int applyOptionForRecordIndex
= 1;
83 try (final TestableWalFilter walFilter
=
84 new TestableWalFilter(option
, applyOptionForRecordIndex
)) {
86 try (final Options options
= optionsForLogIterTest();
87 final DBOptions dbOptions
= new DBOptions(options
)
88 .setWalFilter(walFilter
)) {
90 try (final RocksDB db
= RocksDB
.open(dbOptions
,
91 dbFolder
.getRoot().getAbsolutePath(),
92 cfDescriptors
, cfHandles
)) {
95 assertThat(walFilter
.logNumbers
).isNotEmpty();
96 assertThat(walFilter
.logFileNames
).isNotEmpty();
98 for (final ColumnFamilyHandle cfHandle
: cfHandles
) {
103 } catch (final RocksDBException e
) {
104 if (option
!= WalProcessingOption
.CORRUPTED_RECORD
) {
105 // exception is expected when CORRUPTED_RECORD!
115 private static class TestableWalFilter
extends AbstractWalFilter
{
116 private final WalProcessingOption walProcessingOption
;
117 private final int applyOptionForRecordIndex
;
118 Map
<Integer
, Long
> cfLognumber
;
119 Map
<String
, Integer
> cfNameId
;
120 final List
<Long
> logNumbers
= new ArrayList
<>();
121 final List
<String
> logFileNames
= new ArrayList
<>();
122 private int currentRecordIndex
= 0;
124 public TestableWalFilter(final WalProcessingOption walProcessingOption
,
125 final int applyOptionForRecordIndex
) {
127 this.walProcessingOption
= walProcessingOption
;
128 this.applyOptionForRecordIndex
= applyOptionForRecordIndex
;
132 public void columnFamilyLogNumberMap(final Map
<Integer
, Long
> cfLognumber
,
133 final Map
<String
, Integer
> cfNameId
) {
134 this.cfLognumber
= cfLognumber
;
135 this.cfNameId
= cfNameId
;
139 public LogRecordFoundResult
logRecordFound(
140 final long logNumber
, final String logFileName
, final WriteBatch batch
,
141 final WriteBatch newBatch
) {
143 logNumbers
.add(logNumber
);
144 logFileNames
.add(logFileName
);
146 final WalProcessingOption optionToReturn
;
147 if (currentRecordIndex
== applyOptionForRecordIndex
) {
148 optionToReturn
= walProcessingOption
;
151 optionToReturn
= WalProcessingOption
.CONTINUE_PROCESSING
;
154 currentRecordIndex
++;
156 return new LogRecordFoundResult(optionToReturn
, false);
160 public String
name() {
161 return "testable-wal-filter";