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.ClassRule; 8 import org.junit.Rule; 9 import org.junit.Test; 10 import org.junit.rules.TemporaryFolder; 11 12 import static org.assertj.core.api.Assertions.assertThat; 13 14 public class SnapshotTest { 15 16 @ClassRule 17 public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE = 18 new RocksNativeLibraryResource(); 19 20 @Rule 21 public TemporaryFolder dbFolder = new TemporaryFolder(); 22 23 @Test snapshots()24 public void snapshots() throws RocksDBException { 25 try (final Options options = new Options().setCreateIfMissing(true); 26 final RocksDB db = RocksDB.open(options, 27 dbFolder.getRoot().getAbsolutePath())) { 28 db.put("key".getBytes(), "value".getBytes()); 29 // Get new Snapshot of database 30 try (final Snapshot snapshot = db.getSnapshot()) { 31 assertThat(snapshot.getSequenceNumber()).isGreaterThan(0); 32 assertThat(snapshot.getSequenceNumber()).isEqualTo(1); 33 try (final ReadOptions readOptions = new ReadOptions()) { 34 // set snapshot in ReadOptions 35 readOptions.setSnapshot(snapshot); 36 37 // retrieve key value pair 38 assertThat(new String(db.get("key".getBytes()))). 39 isEqualTo("value"); 40 // retrieve key value pair created before 41 // the snapshot was made 42 assertThat(new String(db.get(readOptions, 43 "key".getBytes()))).isEqualTo("value"); 44 // add new key/value pair 45 db.put("newkey".getBytes(), "newvalue".getBytes()); 46 // using no snapshot the latest db entries 47 // will be taken into account 48 assertThat(new String(db.get("newkey".getBytes()))). 49 isEqualTo("newvalue"); 50 // snapshopot was created before newkey 51 assertThat(db.get(readOptions, "newkey".getBytes())). 52 isNull(); 53 // Retrieve snapshot from read options 54 try (final Snapshot sameSnapshot = readOptions.snapshot()) { 55 readOptions.setSnapshot(sameSnapshot); 56 // results must be the same with new Snapshot 57 // instance using the same native pointer 58 assertThat(new String(db.get(readOptions, 59 "key".getBytes()))).isEqualTo("value"); 60 // update key value pair to newvalue 61 db.put("key".getBytes(), "newvalue".getBytes()); 62 // read with previously created snapshot will 63 // read previous version of key value pair 64 assertThat(new String(db.get(readOptions, 65 "key".getBytes()))).isEqualTo("value"); 66 // read for newkey using the snapshot must be 67 // null 68 assertThat(db.get(readOptions, "newkey".getBytes())). 69 isNull(); 70 // setting null to snapshot in ReadOptions leads 71 // to no Snapshot being used. 72 readOptions.setSnapshot(null); 73 assertThat(new String(db.get(readOptions, 74 "newkey".getBytes()))).isEqualTo("newvalue"); 75 // release Snapshot 76 db.releaseSnapshot(snapshot); 77 } 78 } 79 } 80 } 81 } 82 83 @Test iteratorWithSnapshot()84 public void iteratorWithSnapshot() throws RocksDBException { 85 try (final Options options = new Options().setCreateIfMissing(true); 86 final RocksDB db = RocksDB.open(options, 87 dbFolder.getRoot().getAbsolutePath())) { 88 db.put("key".getBytes(), "value".getBytes()); 89 90 // Get new Snapshot of database 91 // set snapshot in ReadOptions 92 try (final Snapshot snapshot = db.getSnapshot(); 93 final ReadOptions readOptions = 94 new ReadOptions().setSnapshot(snapshot)) { 95 db.put("key2".getBytes(), "value2".getBytes()); 96 97 // iterate over current state of db 98 try (final RocksIterator iterator = db.newIterator()) { 99 iterator.seekToFirst(); 100 assertThat(iterator.isValid()).isTrue(); 101 assertThat(iterator.key()).isEqualTo("key".getBytes()); 102 iterator.next(); 103 assertThat(iterator.isValid()).isTrue(); 104 assertThat(iterator.key()).isEqualTo("key2".getBytes()); 105 iterator.next(); 106 assertThat(iterator.isValid()).isFalse(); 107 } 108 109 // iterate using a snapshot 110 try (final RocksIterator snapshotIterator = 111 db.newIterator(readOptions)) { 112 snapshotIterator.seekToFirst(); 113 assertThat(snapshotIterator.isValid()).isTrue(); 114 assertThat(snapshotIterator.key()).isEqualTo("key".getBytes()); 115 snapshotIterator.next(); 116 assertThat(snapshotIterator.isValid()).isFalse(); 117 } 118 119 // release Snapshot 120 db.releaseSnapshot(snapshot); 121 } 122 } 123 } 124 125 @Test iteratorWithSnapshotOnColumnFamily()126 public void iteratorWithSnapshotOnColumnFamily() throws RocksDBException { 127 try (final Options options = new Options() 128 .setCreateIfMissing(true); 129 final RocksDB db = RocksDB.open(options, 130 dbFolder.getRoot().getAbsolutePath())) { 131 132 db.put("key".getBytes(), "value".getBytes()); 133 134 // Get new Snapshot of database 135 // set snapshot in ReadOptions 136 try (final Snapshot snapshot = db.getSnapshot(); 137 final ReadOptions readOptions = new ReadOptions() 138 .setSnapshot(snapshot)) { 139 db.put("key2".getBytes(), "value2".getBytes()); 140 141 // iterate over current state of column family 142 try (final RocksIterator iterator = db.newIterator( 143 db.getDefaultColumnFamily())) { 144 iterator.seekToFirst(); 145 assertThat(iterator.isValid()).isTrue(); 146 assertThat(iterator.key()).isEqualTo("key".getBytes()); 147 iterator.next(); 148 assertThat(iterator.isValid()).isTrue(); 149 assertThat(iterator.key()).isEqualTo("key2".getBytes()); 150 iterator.next(); 151 assertThat(iterator.isValid()).isFalse(); 152 } 153 154 // iterate using a snapshot on default column family 155 try (final RocksIterator snapshotIterator = db.newIterator( 156 db.getDefaultColumnFamily(), readOptions)) { 157 snapshotIterator.seekToFirst(); 158 assertThat(snapshotIterator.isValid()).isTrue(); 159 assertThat(snapshotIterator.key()).isEqualTo("key".getBytes()); 160 snapshotIterator.next(); 161 assertThat(snapshotIterator.isValid()).isFalse(); 162 163 // release Snapshot 164 db.releaseSnapshot(snapshot); 165 } 166 } 167 } 168 } 169 } 170