/Users/deen/code/yugabyte-db/src/yb/rocksdb/db/db_inplace_update_test.cc
Line | Count | Source |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under the BSD-style license found in the |
3 | | // LICENSE file in the root directory of this source tree. An additional grant |
4 | | // of patent rights can be found in the PATENTS file in the same directory. |
5 | | // |
6 | | // The following only applies to changes made to this file as part of YugaByte development. |
7 | | // |
8 | | // Portions Copyright (c) YugaByte, Inc. |
9 | | // |
10 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
11 | | // in compliance with the License. You may obtain a copy of the License at |
12 | | // |
13 | | // http://www.apache.org/licenses/LICENSE-2.0 |
14 | | // |
15 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
16 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
17 | | // or implied. See the License for the specific language governing permissions and limitations |
18 | | // under the License. |
19 | | // |
20 | | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
21 | | // Use of this source code is governed by a BSD-style license that can be |
22 | | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
23 | | #include "yb/rocksdb/db/db_test_util.h" |
24 | | #include "yb/rocksdb/port/stack_trace.h" |
25 | | |
26 | | namespace rocksdb { |
27 | | |
28 | | class DBTestInPlaceUpdate : public DBTestBase { |
29 | | public: |
30 | 6 | DBTestInPlaceUpdate() : DBTestBase("/db_inplace_update_test") {} |
31 | | }; |
32 | | |
33 | 1 | TEST_F(DBTestInPlaceUpdate, InPlaceUpdate) { |
34 | 5 | do { |
35 | 5 | Options options; |
36 | 5 | options.create_if_missing = true; |
37 | 5 | options.inplace_update_support = true; |
38 | 5 | options.env = env_; |
39 | 5 | options.write_buffer_size = 100000; |
40 | 5 | options = CurrentOptions(options); |
41 | 5 | CreateAndReopenWithCF({"pikachu"}, options); |
42 | | |
43 | | // Update key with values of smaller size |
44 | 5 | int numValues = 10; |
45 | 55 | for (int i = numValues; i > 0; i--) { |
46 | 50 | std::string value = DummyString(i, 'a'); |
47 | 50 | ASSERT_OK(Put(1, "key", value)); |
48 | 50 | ASSERT_EQ(value, Get(1, "key")); |
49 | 50 | } |
50 | | |
51 | | // Only 1 instance for that key. |
52 | 5 | validateNumberOfEntries(1, 1); |
53 | 5 | } while (ChangeCompactOptions()); |
54 | 1 | } |
55 | | |
56 | 1 | TEST_F(DBTestInPlaceUpdate, InPlaceUpdateLargeNewValue) { |
57 | 5 | do { |
58 | 5 | Options options; |
59 | 5 | options.create_if_missing = true; |
60 | 5 | options.inplace_update_support = true; |
61 | 5 | options.env = env_; |
62 | 5 | options.write_buffer_size = 100000; |
63 | 5 | options = CurrentOptions(options); |
64 | 5 | CreateAndReopenWithCF({"pikachu"}, options); |
65 | | |
66 | | // Update key with values of larger size |
67 | 5 | int numValues = 10; |
68 | 55 | for (int i = 0; i < numValues; i++) { |
69 | 50 | std::string value = DummyString(i, 'a'); |
70 | 50 | ASSERT_OK(Put(1, "key", value)); |
71 | 50 | ASSERT_EQ(value, Get(1, "key")); |
72 | 50 | } |
73 | | |
74 | | // All 10 updates exist in the internal iterator |
75 | 5 | validateNumberOfEntries(numValues, 1); |
76 | 5 | } while (ChangeCompactOptions()); |
77 | 1 | } |
78 | | |
79 | 1 | TEST_F(DBTestInPlaceUpdate, InPlaceUpdateCallbackSmallerSize) { |
80 | 5 | do { |
81 | 5 | Options options; |
82 | 5 | options.create_if_missing = true; |
83 | 5 | options.inplace_update_support = true; |
84 | | |
85 | 5 | options.env = env_; |
86 | 5 | options.write_buffer_size = 100000; |
87 | 5 | options.inplace_callback = |
88 | 5 | rocksdb::DBTestInPlaceUpdate::updateInPlaceSmallerSize; |
89 | 5 | options = CurrentOptions(options); |
90 | 5 | CreateAndReopenWithCF({"pikachu"}, options); |
91 | | |
92 | | // Update key with values of smaller size |
93 | 5 | int numValues = 10; |
94 | 5 | ASSERT_OK(Put(1, "key", DummyString(numValues, 'a'))); |
95 | 5 | ASSERT_EQ(DummyString(numValues, 'c'), Get(1, "key")); |
96 | | |
97 | 55 | for (int i = numValues; i > 0; i--) { |
98 | 50 | ASSERT_OK(Put(1, "key", DummyString(i, 'a'))); |
99 | 50 | ASSERT_EQ(DummyString(i - 1, 'b'), Get(1, "key")); |
100 | 50 | } |
101 | | |
102 | | // Only 1 instance for that key. |
103 | 5 | validateNumberOfEntries(1, 1); |
104 | 5 | } while (ChangeCompactOptions()); |
105 | 1 | } |
106 | | |
107 | 1 | TEST_F(DBTestInPlaceUpdate, InPlaceUpdateCallbackSmallerVarintSize) { |
108 | 5 | do { |
109 | 5 | Options options; |
110 | 5 | options.create_if_missing = true; |
111 | 5 | options.inplace_update_support = true; |
112 | | |
113 | 5 | options.env = env_; |
114 | 5 | options.write_buffer_size = 100000; |
115 | 5 | options.inplace_callback = |
116 | 5 | rocksdb::DBTestInPlaceUpdate::updateInPlaceSmallerVarintSize; |
117 | 5 | options = CurrentOptions(options); |
118 | 5 | CreateAndReopenWithCF({"pikachu"}, options); |
119 | | |
120 | | // Update key with values of smaller varint size |
121 | 5 | int numValues = 265; |
122 | 5 | ASSERT_OK(Put(1, "key", DummyString(numValues, 'a'))); |
123 | 5 | ASSERT_EQ(DummyString(numValues, 'c'), Get(1, "key")); |
124 | | |
125 | 1.33k | for (int i = numValues; i > 0; i--) { |
126 | 1.32k | ASSERT_OK(Put(1, "key", DummyString(i, 'a'))); |
127 | 1.32k | ASSERT_EQ(DummyString(1, 'b'), Get(1, "key")); |
128 | 1.32k | } |
129 | | |
130 | | // Only 1 instance for that key. |
131 | 5 | validateNumberOfEntries(1, 1); |
132 | 5 | } while (ChangeCompactOptions()); |
133 | 1 | } |
134 | | |
135 | 1 | TEST_F(DBTestInPlaceUpdate, InPlaceUpdateCallbackLargeNewValue) { |
136 | 5 | do { |
137 | 5 | Options options; |
138 | 5 | options.create_if_missing = true; |
139 | 5 | options.inplace_update_support = true; |
140 | | |
141 | 5 | options.env = env_; |
142 | 5 | options.write_buffer_size = 100000; |
143 | 5 | options.inplace_callback = |
144 | 5 | rocksdb::DBTestInPlaceUpdate::updateInPlaceLargerSize; |
145 | 5 | options = CurrentOptions(options); |
146 | 5 | CreateAndReopenWithCF({"pikachu"}, options); |
147 | | |
148 | | // Update key with values of larger size |
149 | 5 | int numValues = 10; |
150 | 55 | for (int i = 0; i < numValues; i++) { |
151 | 50 | ASSERT_OK(Put(1, "key", DummyString(i, 'a'))); |
152 | 50 | ASSERT_EQ(DummyString(i, 'c'), Get(1, "key")); |
153 | 50 | } |
154 | | |
155 | | // No inplace updates. All updates are puts with new seq number |
156 | | // All 10 updates exist in the internal iterator |
157 | 5 | validateNumberOfEntries(numValues, 1); |
158 | 5 | } while (ChangeCompactOptions()); |
159 | 1 | } |
160 | | |
161 | 1 | TEST_F(DBTestInPlaceUpdate, InPlaceUpdateCallbackNoAction) { |
162 | 5 | do { |
163 | 5 | Options options; |
164 | 5 | options.create_if_missing = true; |
165 | 5 | options.inplace_update_support = true; |
166 | | |
167 | 5 | options.env = env_; |
168 | 5 | options.write_buffer_size = 100000; |
169 | 5 | options.inplace_callback = |
170 | 5 | rocksdb::DBTestInPlaceUpdate::updateInPlaceNoAction; |
171 | 5 | options = CurrentOptions(options); |
172 | 5 | CreateAndReopenWithCF({"pikachu"}, options); |
173 | | |
174 | | // Callback function requests no actions from db |
175 | 5 | ASSERT_OK(Put(1, "key", DummyString(1, 'a'))); |
176 | 5 | ASSERT_EQ(Get(1, "key"), "NOT_FOUND"); |
177 | 5 | } while (ChangeCompactOptions()); |
178 | 1 | } |
179 | | } // namespace rocksdb |
180 | | |
181 | 13.2k | int main(int argc, char** argv) { |
182 | 13.2k | rocksdb::port::InstallStackTraceHandler(); |
183 | 13.2k | ::testing::InitGoogleTest(&argc, argv); |
184 | 13.2k | return RUN_ALL_TESTS(); |
185 | 13.2k | } |