]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db/dbformat_test.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / rocksdb / db / dbformat_test.cc
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
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).
7c673cae
FG
5//
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
10#include "db/dbformat.h"
f67539c2 11#include "test_util/testharness.h"
7c673cae 12
f67539c2 13namespace ROCKSDB_NAMESPACE {
7c673cae
FG
14
15static std::string IKey(const std::string& user_key,
16 uint64_t seq,
17 ValueType vt) {
18 std::string encoded;
19 AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt));
20 return encoded;
21}
22
23static std::string Shorten(const std::string& s, const std::string& l) {
24 std::string result = s;
25 InternalKeyComparator(BytewiseComparator()).FindShortestSeparator(&result, l);
26 return result;
27}
28
29static std::string ShortSuccessor(const std::string& s) {
30 std::string result = s;
31 InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result);
32 return result;
33}
34
35static void TestKey(const std::string& key,
36 uint64_t seq,
37 ValueType vt) {
38 std::string encoded = IKey(key, seq, vt);
39
40 Slice in(encoded);
41 ParsedInternalKey decoded("", 0, kTypeValue);
42
20effc67 43 ASSERT_OK(ParseInternalKey(in, &decoded, true /* log_err_key */));
7c673cae
FG
44 ASSERT_EQ(key, decoded.user_key.ToString());
45 ASSERT_EQ(seq, decoded.sequence);
46 ASSERT_EQ(vt, decoded.type);
47
20effc67 48 ASSERT_NOK(ParseInternalKey(Slice("bar"), &decoded, true /* log_err_key */));
7c673cae
FG
49}
50
51class FormatTest : public testing::Test {};
52
53TEST_F(FormatTest, InternalKey_EncodeDecode) {
54 const char* keys[] = { "", "k", "hello", "longggggggggggggggggggggg" };
55 const uint64_t seq[] = {
56 1, 2, 3,
57 (1ull << 8) - 1, 1ull << 8, (1ull << 8) + 1,
58 (1ull << 16) - 1, 1ull << 16, (1ull << 16) + 1,
59 (1ull << 32) - 1, 1ull << 32, (1ull << 32) + 1
60 };
61 for (unsigned int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) {
62 for (unsigned int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) {
63 TestKey(keys[k], seq[s], kTypeValue);
64 TestKey("hello", 1, kTypeDeletion);
65 }
66 }
67}
68
69TEST_F(FormatTest, InternalKeyShortSeparator) {
70 // When user keys are same
71 ASSERT_EQ(IKey("foo", 100, kTypeValue),
72 Shorten(IKey("foo", 100, kTypeValue),
73 IKey("foo", 99, kTypeValue)));
74 ASSERT_EQ(IKey("foo", 100, kTypeValue),
75 Shorten(IKey("foo", 100, kTypeValue),
76 IKey("foo", 101, kTypeValue)));
77 ASSERT_EQ(IKey("foo", 100, kTypeValue),
78 Shorten(IKey("foo", 100, kTypeValue),
79 IKey("foo", 100, kTypeValue)));
80 ASSERT_EQ(IKey("foo", 100, kTypeValue),
81 Shorten(IKey("foo", 100, kTypeValue),
82 IKey("foo", 100, kTypeDeletion)));
83
84 // When user keys are misordered
85 ASSERT_EQ(IKey("foo", 100, kTypeValue),
86 Shorten(IKey("foo", 100, kTypeValue),
87 IKey("bar", 99, kTypeValue)));
88
89 // When user keys are different, but correctly ordered
90 ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
91 Shorten(IKey("foo", 100, kTypeValue),
92 IKey("hello", 200, kTypeValue)));
93
94 ASSERT_EQ(IKey("ABC2", kMaxSequenceNumber, kValueTypeForSeek),
95 Shorten(IKey("ABC1AAAAA", 100, kTypeValue),
96 IKey("ABC2ABB", 200, kTypeValue)));
97
98 ASSERT_EQ(IKey("AAA2", kMaxSequenceNumber, kValueTypeForSeek),
99 Shorten(IKey("AAA1AAA", 100, kTypeValue),
100 IKey("AAA2AA", 200, kTypeValue)));
101
102 ASSERT_EQ(
103 IKey("AAA2", kMaxSequenceNumber, kValueTypeForSeek),
104 Shorten(IKey("AAA1AAA", 100, kTypeValue), IKey("AAA4", 200, kTypeValue)));
105
106 ASSERT_EQ(
107 IKey("AAA1B", kMaxSequenceNumber, kValueTypeForSeek),
108 Shorten(IKey("AAA1AAA", 100, kTypeValue), IKey("AAA2", 200, kTypeValue)));
109
110 ASSERT_EQ(IKey("AAA2", kMaxSequenceNumber, kValueTypeForSeek),
111 Shorten(IKey("AAA1AAA", 100, kTypeValue),
112 IKey("AAA2A", 200, kTypeValue)));
113
114 ASSERT_EQ(
115 IKey("AAA1", 100, kTypeValue),
116 Shorten(IKey("AAA1", 100, kTypeValue), IKey("AAA2", 200, kTypeValue)));
117
118 // When start user key is prefix of limit user key
119 ASSERT_EQ(IKey("foo", 100, kTypeValue),
120 Shorten(IKey("foo", 100, kTypeValue),
121 IKey("foobar", 200, kTypeValue)));
122
123 // When limit user key is prefix of start user key
124 ASSERT_EQ(IKey("foobar", 100, kTypeValue),
125 Shorten(IKey("foobar", 100, kTypeValue),
126 IKey("foo", 200, kTypeValue)));
127}
128
129TEST_F(FormatTest, InternalKeyShortestSuccessor) {
130 ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
131 ShortSuccessor(IKey("foo", 100, kTypeValue)));
132 ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue),
133 ShortSuccessor(IKey("\xff\xff", 100, kTypeValue)));
134}
135
136TEST_F(FormatTest, IterKeyOperation) {
137 IterKey k;
138 const char p[] = "abcdefghijklmnopqrstuvwxyz";
139 const char q[] = "0123456789";
140
141 ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
142 std::string(""));
143
144 k.TrimAppend(0, p, 3);
145 ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
146 std::string("abc"));
147
148 k.TrimAppend(1, p, 3);
149 ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
150 std::string("aabc"));
151
152 k.TrimAppend(0, p, 26);
153 ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
154 std::string("abcdefghijklmnopqrstuvwxyz"));
155
156 k.TrimAppend(26, q, 10);
157 ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
158 std::string("abcdefghijklmnopqrstuvwxyz0123456789"));
159
160 k.TrimAppend(36, q, 1);
161 ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
162 std::string("abcdefghijklmnopqrstuvwxyz01234567890"));
163
164 k.TrimAppend(26, q, 1);
165 ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
166 std::string("abcdefghijklmnopqrstuvwxyz0"));
167
168 // Size going up, memory allocation is triggered
169 k.TrimAppend(27, p, 26);
170 ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
171 std::string("abcdefghijklmnopqrstuvwxyz0"
172 "abcdefghijklmnopqrstuvwxyz"));
173}
174
175TEST_F(FormatTest, UpdateInternalKey) {
176 std::string user_key("abcdefghijklmnopqrstuvwxyz");
177 uint64_t new_seq = 0x123456;
178 ValueType new_val_type = kTypeDeletion;
179
180 std::string ikey;
181 AppendInternalKey(&ikey, ParsedInternalKey(user_key, 100U, kTypeValue));
182 size_t ikey_size = ikey.size();
183 UpdateInternalKey(&ikey, new_seq, new_val_type);
184 ASSERT_EQ(ikey_size, ikey.size());
185
186 Slice in(ikey);
187 ParsedInternalKey decoded;
20effc67 188 ASSERT_OK(ParseInternalKey(in, &decoded, true /* log_err_key */));
7c673cae
FG
189 ASSERT_EQ(user_key, decoded.user_key.ToString());
190 ASSERT_EQ(new_seq, decoded.sequence);
191 ASSERT_EQ(new_val_type, decoded.type);
192}
193
11fdf7f2
TL
194TEST_F(FormatTest, RangeTombstoneSerializeEndKey) {
195 RangeTombstone t("a", "b", 2);
196 InternalKey k("b", 3, kTypeValue);
197 const InternalKeyComparator cmp(BytewiseComparator());
198 ASSERT_LT(cmp.Compare(t.SerializeEndKey(), k), 0);
199}
200
f67539c2 201} // namespace ROCKSDB_NAMESPACE
7c673cae
FG
202
203int main(int argc, char** argv) {
204 ::testing::InitGoogleTest(&argc, argv);
205 return RUN_ALL_TESTS();
206}