YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/db/dbformat_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
24
#include <string>
25
26
#include <gtest/gtest.h>
27
28
#include "yb/rocksdb/db/dbformat.h"
29
#include "yb/rocksdb/util/testutil.h"
30
31
namespace rocksdb {
32
33
static std::string IKey(const std::string& user_key,
34
                        uint64_t seq,
35
151
                        ValueType vt) {
36
151
  std::string encoded;
37
151
  AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt));
38
151
  return encoded;
39
151
}
40
41
17
static std::string Shorten(const std::string& s, const std::string& l) {
42
17
  std::string result = s;
43
17
  InternalKeyComparator(BytewiseComparator()).FindShortestSeparator(&result, l);
44
17
  return result;
45
17
}
46
47
12
auto ShortenUserKeys(const char* s, const char* l) {
48
12
  return Shorten(IKey(s, 100, kTypeValue), IKey(l, 200, kTypeValue));
49
12
}
50
51
#define TEST_SHORTEN_USER_KEYS(expected, start, limit) \
52
8
  ASSERT_EQ(IKey((expected), kMaxSequenceNumber, kValueTypeForSeek), ShortenUserKeys(start, limit))
53
54
2
static std::string ShortSuccessor(const std::string& s) {
55
2
  std::string result = s;
56
2
  InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result);
57
2
  return result;
58
2
}
59
60
static void TestKey(const std::string& key,
61
                    uint64_t seq,
62
96
                    ValueType vt) {
63
96
  std::string encoded = IKey(key, seq, vt);
64
65
96
  Slice in(encoded);
66
96
  ParsedInternalKey decoded("", 0, kTypeValue);
67
68
96
  ASSERT_TRUE(ParseInternalKey(in, &decoded));
69
96
  ASSERT_EQ(key, decoded.user_key.ToString());
70
96
  ASSERT_EQ(seq, decoded.sequence);
71
96
  ASSERT_EQ(vt, decoded.type);
72
73
96
  ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded));
74
96
}
75
76
class FormatTest : public RocksDBTest {};
77
78
1
TEST_F(FormatTest, InternalKey_EncodeDecode) {
79
1
  const char* keys[] = { "", "k", "hello", "longggggggggggggggggggggg" };
80
1
  const uint64_t seq[] = {
81
1
    1, 2, 3,
82
1
    (1ull << 8) - 1, 1ull << 8, (1ull << 8) + 1,
83
1
    (1ull << 16) - 1, 1ull << 16, (1ull << 16) + 1,
84
1
    (1ull << 32) - 1, 1ull << 32, (1ull << 32) + 1
85
1
  };
86
5
  for (unsigned int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) {
87
52
    for (unsigned int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) {
88
48
      TestKey(keys[k], seq[s], kTypeValue);
89
48
      TestKey("hello", 1, kTypeDeletion);
90
48
    }
91
4
  }
92
1
}
93
94
1
TEST_F(FormatTest, InternalKeyShortSeparator) {
95
  // When user keys are same
96
1
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
97
1
            Shorten(IKey("foo", 100, kTypeValue),
98
1
                    IKey("foo", 99, kTypeValue)));
99
1
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
100
1
            Shorten(IKey("foo", 100, kTypeValue),
101
1
                    IKey("foo", 101, kTypeValue)));
102
1
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
103
1
            Shorten(IKey("foo", 100, kTypeValue),
104
1
                    IKey("foo", 100, kTypeValue)));
105
1
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
106
1
            Shorten(IKey("foo", 100, kTypeValue),
107
1
                    IKey("foo", 100, kTypeDeletion)));
108
109
  // When user keys are misordered
110
1
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
111
1
            Shorten(IKey("foo", 100, kTypeValue),
112
1
                    IKey("bar", 99, kTypeValue)));
113
1
  ASSERT_EQ(IKey("ABC\xffZ123", 100, kTypeValue), ShortenUserKeys("ABC\xffZ123", "ABC\x01"));
114
115
  // When user keys are different, but correctly ordered
116
1
  TEST_SHORTEN_USER_KEYS("g", "foo", "hello");
117
1
  TEST_SHORTEN_USER_KEYS("ABC2", "ABC1AAAAA", "ABC2ABB");
118
1
  TEST_SHORTEN_USER_KEYS("ABC1B", "ABC1AAA", "ABC2");
119
1
  TEST_SHORTEN_USER_KEYS("ABC1\xffH", "ABC1\xffG123", "ABC2");
120
1
  TEST_SHORTEN_USER_KEYS("AAA2", "AAA1AAA", "AAA2AA");
121
1
  TEST_SHORTEN_USER_KEYS("AAA2", "AAA1AAA", "AAA4");
122
1
  TEST_SHORTEN_USER_KEYS("AAA1B", "AAA1AAA", "AAA2");
123
1
  TEST_SHORTEN_USER_KEYS("AAA2", "AAA1AAA", "AAA2A");
124
1
  ASSERT_EQ(IKey("AAA1", 100, kTypeValue), ShortenUserKeys("AAA1", "AAA2"));
125
126
  // When start user key is prefix of limit user key
127
1
  ASSERT_EQ(IKey("foo", 100, kTypeValue), ShortenUserKeys("foo", "foobar"));
128
129
  // When limit user key is prefix of start user key
130
1
  ASSERT_EQ(IKey("foobar", 100, kTypeValue), ShortenUserKeys("foobar", "foo"));
131
1
}
132
133
1
TEST_F(FormatTest, InternalKeyShortestSuccessor) {
134
1
  ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
135
1
            ShortSuccessor(IKey("foo", 100, kTypeValue)));
136
1
  ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue),
137
1
            ShortSuccessor(IKey("\xff\xff", 100, kTypeValue)));
138
1
}
139
140
1
TEST_F(FormatTest, IterKeyOperation) {
141
1
  IterKey k;
142
1
  const char p[] = "abcdefghijklmnopqrstuvwxyz";
143
1
  const char q[] = "0123456789";
144
145
1
  ASSERT_EQ(k.GetKey(), "");
146
147
1
  k.TrimAppend(0, p, 3);
148
1
  ASSERT_EQ(k.GetKey(), "abc");
149
150
1
  k.TrimAppend(1, p, 3);
151
1
  ASSERT_EQ(k.GetKey(), "aabc");
152
153
1
  k.TrimAppend(0, p, 26);
154
1
  ASSERT_EQ(k.GetKey(), "abcdefghijklmnopqrstuvwxyz");
155
156
1
  k.TrimAppend(26, q, 10);
157
1
  ASSERT_EQ(k.GetKey(), "abcdefghijklmnopqrstuvwxyz0123456789");
158
159
1
  k.TrimAppend(36, q, 1);
160
1
  ASSERT_EQ(k.GetKey(), "abcdefghijklmnopqrstuvwxyz01234567890");
161
162
1
  k.TrimAppend(26, q, 1);
163
1
  ASSERT_EQ(k.GetKey(), "abcdefghijklmnopqrstuvwxyz0");
164
165
  // Size going up, memory allocation is triggered
166
1
  k.TrimAppend(27, p, 26);
167
1
  ASSERT_EQ(k.GetKey(), "abcdefghijklmnopqrstuvwxyz0abcdefghijklmnopqrstuvwxyz");
168
1
}
169
170
1
TEST_F(FormatTest, UpdateInternalKey) {
171
1
  std::string user_key("abcdefghijklmnopqrstuvwxyz");
172
1
  uint64_t new_seq = 0x123456;
173
1
  ValueType new_val_type = kTypeDeletion;
174
175
1
  std::string ikey;
176
1
  AppendInternalKey(&ikey, ParsedInternalKey(user_key, 100U, kTypeValue));
177
1
  size_t ikey_size = ikey.size();
178
1
  UpdateInternalKey(&ikey, new_seq, new_val_type);
179
1
  ASSERT_EQ(ikey_size, ikey.size());
180
181
1
  Slice in(ikey);
182
1
  ParsedInternalKey decoded;
183
1
  ASSERT_TRUE(ParseInternalKey(in, &decoded));
184
1
  ASSERT_EQ(user_key, decoded.user_key);
185
1
  ASSERT_EQ(new_seq, decoded.sequence);
186
1
  ASSERT_EQ(new_val_type, decoded.type);
187
1
}
188
189
}  // namespace rocksdb
190
191
13.2k
int main(int argc, char** argv) {
192
13.2k
  ::testing::InitGoogleTest(&argc, argv);
193
13.2k
  return RUN_ALL_TESTS();
194
13.2k
}