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).
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9 #include "db/db_test_util.h"
10 #include "port/stack_trace.h"
12 namespace ROCKSDB_NAMESPACE
{
14 class DBTestInPlaceUpdate
: public DBTestBase
{
17 : DBTestBase("/db_inplace_update_test", /*env_do_fsync=*/true) {}
20 TEST_F(DBTestInPlaceUpdate
, InPlaceUpdate
) {
22 Options options
= CurrentOptions();
23 options
.create_if_missing
= true;
24 options
.inplace_update_support
= true;
26 options
.write_buffer_size
= 100000;
27 options
.allow_concurrent_memtable_write
= false;
29 CreateAndReopenWithCF({"pikachu"}, options
);
31 // Update key with values of smaller size
33 for (int i
= numValues
; i
> 0; i
--) {
34 std::string value
= DummyString(i
, 'a');
35 ASSERT_OK(Put(1, "key", value
));
36 ASSERT_EQ(value
, Get(1, "key"));
39 // Only 1 instance for that key.
40 validateNumberOfEntries(1, 1);
41 } while (ChangeCompactOptions());
44 TEST_F(DBTestInPlaceUpdate
, InPlaceUpdateLargeNewValue
) {
46 Options options
= CurrentOptions();
47 options
.create_if_missing
= true;
48 options
.inplace_update_support
= true;
50 options
.write_buffer_size
= 100000;
51 options
.allow_concurrent_memtable_write
= false;
53 CreateAndReopenWithCF({"pikachu"}, options
);
55 // Update key with values of larger size
57 for (int i
= 0; i
< numValues
; i
++) {
58 std::string value
= DummyString(i
, 'a');
59 ASSERT_OK(Put(1, "key", value
));
60 ASSERT_EQ(value
, Get(1, "key"));
63 // All 10 updates exist in the internal iterator
64 validateNumberOfEntries(numValues
, 1);
65 } while (ChangeCompactOptions());
68 TEST_F(DBTestInPlaceUpdate
, InPlaceUpdateCallbackSmallerSize
) {
70 Options options
= CurrentOptions();
71 options
.create_if_missing
= true;
72 options
.inplace_update_support
= true;
75 options
.write_buffer_size
= 100000;
76 options
.inplace_callback
=
77 ROCKSDB_NAMESPACE::DBTestInPlaceUpdate::updateInPlaceSmallerSize
;
78 options
.allow_concurrent_memtable_write
= false;
80 CreateAndReopenWithCF({"pikachu"}, options
);
82 // Update key with values of smaller size
84 ASSERT_OK(Put(1, "key", DummyString(numValues
, 'a')));
85 ASSERT_EQ(DummyString(numValues
, 'c'), Get(1, "key"));
87 for (int i
= numValues
; i
> 0; i
--) {
88 ASSERT_OK(Put(1, "key", DummyString(i
, 'a')));
89 ASSERT_EQ(DummyString(i
- 1, 'b'), Get(1, "key"));
92 // Only 1 instance for that key.
93 validateNumberOfEntries(1, 1);
94 } while (ChangeCompactOptions());
97 TEST_F(DBTestInPlaceUpdate
, InPlaceUpdateCallbackSmallerVarintSize
) {
99 Options options
= CurrentOptions();
100 options
.create_if_missing
= true;
101 options
.inplace_update_support
= true;
104 options
.write_buffer_size
= 100000;
105 options
.inplace_callback
=
106 ROCKSDB_NAMESPACE::DBTestInPlaceUpdate::updateInPlaceSmallerVarintSize
;
107 options
.allow_concurrent_memtable_write
= false;
109 CreateAndReopenWithCF({"pikachu"}, options
);
111 // Update key with values of smaller varint size
113 ASSERT_OK(Put(1, "key", DummyString(numValues
, 'a')));
114 ASSERT_EQ(DummyString(numValues
, 'c'), Get(1, "key"));
116 for (int i
= numValues
; i
> 0; i
--) {
117 ASSERT_OK(Put(1, "key", DummyString(i
, 'a')));
118 ASSERT_EQ(DummyString(1, 'b'), Get(1, "key"));
121 // Only 1 instance for that key.
122 validateNumberOfEntries(1, 1);
123 } while (ChangeCompactOptions());
126 TEST_F(DBTestInPlaceUpdate
, InPlaceUpdateCallbackLargeNewValue
) {
128 Options options
= CurrentOptions();
129 options
.create_if_missing
= true;
130 options
.inplace_update_support
= true;
133 options
.write_buffer_size
= 100000;
134 options
.inplace_callback
=
135 ROCKSDB_NAMESPACE::DBTestInPlaceUpdate::updateInPlaceLargerSize
;
136 options
.allow_concurrent_memtable_write
= false;
138 CreateAndReopenWithCF({"pikachu"}, options
);
140 // Update key with values of larger size
142 for (int i
= 0; i
< numValues
; i
++) {
143 ASSERT_OK(Put(1, "key", DummyString(i
, 'a')));
144 ASSERT_EQ(DummyString(i
, 'c'), Get(1, "key"));
147 // No inplace updates. All updates are puts with new seq number
148 // All 10 updates exist in the internal iterator
149 validateNumberOfEntries(numValues
, 1);
150 } while (ChangeCompactOptions());
153 TEST_F(DBTestInPlaceUpdate
, InPlaceUpdateCallbackNoAction
) {
155 Options options
= CurrentOptions();
156 options
.create_if_missing
= true;
157 options
.inplace_update_support
= true;
160 options
.write_buffer_size
= 100000;
161 options
.inplace_callback
=
162 ROCKSDB_NAMESPACE::DBTestInPlaceUpdate::updateInPlaceNoAction
;
163 options
.allow_concurrent_memtable_write
= false;
165 CreateAndReopenWithCF({"pikachu"}, options
);
167 // Callback function requests no actions from db
168 ASSERT_OK(Put(1, "key", DummyString(1, 'a')));
169 ASSERT_EQ(Get(1, "key"), "NOT_FOUND");
170 } while (ChangeCompactOptions());
172 } // namespace ROCKSDB_NAMESPACE
174 int main(int argc
, char** argv
) {
175 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
176 ::testing::InitGoogleTest(&argc
, argv
);
177 return RUN_ALL_TESTS();