1 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 package org.rocksdb;
3 
4 import org.junit.ClassRule;
5 import org.junit.Rule;
6 import org.junit.Test;
7 import org.junit.rules.TemporaryFolder;
8 
9 import static org.assertj.core.api.Assertions.assertThat;
10 
11 public class TransactionLogIteratorTest {
12   @ClassRule
13   public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE =
14       new RocksNativeLibraryResource();
15 
16   @Rule
17   public TemporaryFolder dbFolder = new TemporaryFolder();
18 
19   @Test
transactionLogIterator()20   public void transactionLogIterator() throws RocksDBException {
21     try (final Options options = new Options()
22         .setCreateIfMissing(true);
23          final RocksDB db = RocksDB.open(options,
24              dbFolder.getRoot().getAbsolutePath());
25          final TransactionLogIterator transactionLogIterator =
26              db.getUpdatesSince(0)) {
27       //no-op
28     }
29   }
30 
31   @Test
getBatch()32   public void getBatch() throws RocksDBException {
33     final int numberOfPuts = 5;
34     try (final Options options = new Options()
35         .setCreateIfMissing(true)
36         .setWalTtlSeconds(1000)
37         .setWalSizeLimitMB(10);
38          final RocksDB db = RocksDB.open(options,
39              dbFolder.getRoot().getAbsolutePath())) {
40 
41       for (int i = 0; i < numberOfPuts; i++) {
42         db.put(String.valueOf(i).getBytes(),
43             String.valueOf(i).getBytes());
44       }
45       db.flush(new FlushOptions().setWaitForFlush(true));
46 
47       // the latest sequence number is 5 because 5 puts
48       // were written beforehand
49       assertThat(db.getLatestSequenceNumber()).
50           isEqualTo(numberOfPuts);
51 
52       // insert 5 writes into a cf
53       try (final ColumnFamilyHandle cfHandle = db.createColumnFamily(
54           new ColumnFamilyDescriptor("new_cf".getBytes()))) {
55         for (int i = 0; i < numberOfPuts; i++) {
56           db.put(cfHandle, String.valueOf(i).getBytes(),
57               String.valueOf(i).getBytes());
58         }
59         // the latest sequence number is 10 because
60         // (5 + 5) puts were written beforehand
61         assertThat(db.getLatestSequenceNumber()).
62             isEqualTo(numberOfPuts + numberOfPuts);
63 
64         // Get updates since the beginning
65         try (final TransactionLogIterator transactionLogIterator =
66                  db.getUpdatesSince(0)) {
67           assertThat(transactionLogIterator.isValid()).isTrue();
68           transactionLogIterator.status();
69 
70           // The first sequence number is 1
71           final TransactionLogIterator.BatchResult batchResult =
72               transactionLogIterator.getBatch();
73           assertThat(batchResult.sequenceNumber()).isEqualTo(1);
74         }
75       }
76     }
77   }
78 
79   @Test
transactionLogIteratorStallAtLastRecord()80   public void transactionLogIteratorStallAtLastRecord()
81       throws RocksDBException {
82     try (final Options options = new Options()
83         .setCreateIfMissing(true)
84         .setWalTtlSeconds(1000)
85         .setWalSizeLimitMB(10);
86          final RocksDB db = RocksDB.open(options,
87              dbFolder.getRoot().getAbsolutePath())) {
88 
89       db.put("key1".getBytes(), "value1".getBytes());
90       // Get updates since the beginning
91       try (final TransactionLogIterator transactionLogIterator =
92                db.getUpdatesSince(0)) {
93         transactionLogIterator.status();
94         assertThat(transactionLogIterator.isValid()).isTrue();
95         transactionLogIterator.next();
96         assertThat(transactionLogIterator.isValid()).isFalse();
97         transactionLogIterator.status();
98         db.put("key2".getBytes(), "value2".getBytes());
99         transactionLogIterator.next();
100         transactionLogIterator.status();
101         assertThat(transactionLogIterator.isValid()).isTrue();
102       }
103     }
104   }
105 
106   @Test
transactionLogIteratorCheckAfterRestart()107   public void transactionLogIteratorCheckAfterRestart()
108       throws RocksDBException {
109     final int numberOfKeys = 2;
110     try (final Options options = new Options()
111         .setCreateIfMissing(true)
112         .setWalTtlSeconds(1000)
113         .setWalSizeLimitMB(10)) {
114 
115       try (final RocksDB db = RocksDB.open(options,
116           dbFolder.getRoot().getAbsolutePath())) {
117         db.put("key1".getBytes(), "value1".getBytes());
118         db.put("key2".getBytes(), "value2".getBytes());
119         db.flush(new FlushOptions().setWaitForFlush(true));
120 
121       }
122 
123       // reopen
124       try (final RocksDB db = RocksDB.open(options,
125           dbFolder.getRoot().getAbsolutePath())) {
126         assertThat(db.getLatestSequenceNumber()).isEqualTo(numberOfKeys);
127 
128         try (final TransactionLogIterator transactionLogIterator =
129                  db.getUpdatesSince(0)) {
130           for (int i = 0; i < numberOfKeys; i++) {
131             transactionLogIterator.status();
132             assertThat(transactionLogIterator.isValid()).isTrue();
133             transactionLogIterator.next();
134           }
135         }
136       }
137     }
138   }
139 }
140