YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/docdb/key_bytes.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#ifndef YB_DOCDB_KEY_BYTES_H_
15
#define YB_DOCDB_KEY_BYTES_H_
16
17
#include <string>
18
19
#include "yb/common/common_fwd.h"
20
21
#include "yb/util/kv_util.h"
22
#include "yb/util/slice.h"
23
24
namespace yb {
25
namespace docdb {
26
27
enum class ValueType;
28
29
// Represents part (usually a prefix) of a RocksDB key. Has convenience methods for composing keys
30
// used in our DocDB layer -> RocksDB mapping.
31
class KeyBytes {
32
 public:
33
603M
  KeyBytes() = default;
34
431k
  explicit KeyBytes(const std::string& data) : data_(data) {}
35
818M
  explicit KeyBytes(const Slice& slice) : data_(slice) {}
36
37
905M
  KeyBytes(const KeyBytes& rhs) = default;
38
88.0M
  KeyBytes& operator=(const KeyBytes& rhs) = default;
39
38.0M
  KeyBytes(KeyBytes&& rhs) = default;
40
20.6M
  KeyBytes& operator=(KeyBytes&& rhs) = default;
41
42
0
  KeyBytes(const Slice& slice, char suffix) {
43
0
    data_.reserve(slice.size() + 1);
44
0
    data_.append(slice.cdata(), slice.size());
45
0
    data_.push_back(suffix);
46
0
  }
47
48
98.2M
  KeyBytes(const Slice& slice1, const Slice& slice2) {
49
98.2M
    data_.reserve(slice1.size() + slice2.size());
50
98.2M
    data_.append(slice1.cdata(), slice1.size());
51
98.2M
    data_.append(slice2.cdata(), slice2.size());
52
98.2M
  }
53
54
1.10G
  void Reserve(size_t len) {
55
1.10G
    data_.reserve(len);
56
1.10G
  }
57
58
  std::string ToString() const;
59
60
10.7G
  bool empty() const {
61
10.7G
    return data_.empty();
62
10.7G
  }
63
64
81.9M
  std::string ToStringBuffer() const {
65
81.9M
    return data().ToStringBuffer();
66
81.9M
  }
67
68
474M
  const KeyBuffer& data() const {
69
474M
    return data_;
70
474M
  }
71
72
0
  void Append(const KeyBytes& other) {
73
0
    data_.append(other.data_);
74
0
  }
75
76
201M
  void AppendRawBytes(const char* raw_bytes, size_t n) {
77
201M
    data_.append(raw_bytes, n);
78
201M
  }
79
80
1.65G
  void AppendRawBytes(const Slice& slice) {
81
1.65G
    data_.append(slice);
82
1.65G
  }
83
84
12.9M
  void AppendRawBytes(const std::string& data) {
85
12.9M
    data_.append(data);
86
12.9M
  }
87
88
  void AppendValueType(ValueType value_type);
89
90
  void AppendValueTypeBeforeGroupEnd(ValueType value_type);
91
92
  void AppendString(const std::string& raw_string);
93
94
  void AppendDescendingString(const std::string &raw_string);
95
96
24.0k
  void AppendDecimal(const std::string& encoded_decimal_str) {
97
24.0k
    data_.append(encoded_decimal_str);
98
24.0k
  }
99
100
125
  void AppendDecimalDescending(const std::string& encoded_decimal_str) {
101
    // Flipping all the bits negates the decimal number this string represents.
102
103
    // 0 is a special case because the first two bits are always 10.
104
125
    if ((unsigned char)encoded_decimal_str[0] == 128) {
105
1
      data_.push_back(encoded_decimal_str[0]);
106
1
      return;
107
1
    }
108
109
124
    data_.reserve(data_.size() + encoded_decimal_str.size());
110
7.31k
    for (auto c : encoded_decimal_str) {
111
7.31k
      data_.push_back(~c);
112
7.31k
    }
113
124
  }
114
115
23.0k
  void AppendVarInt(const std::string& encoded_varint_str) {
116
23.0k
    data_.append(encoded_varint_str);
117
23.0k
  }
118
119
  void AppendUInt64AsVarInt(uint64_t value);
120
121
122
  void AppendVarIntDescending(const std::string& encoded_varint_str) {
122
    // Flipping all the bits negates the varint number this string represents.
123
124
    // 0 is a special case because the first two bits are always 10.
125
122
    if (static_cast<uint8_t>(encoded_varint_str[0]) == 128) {
126
1
      data_.push_back(encoded_varint_str[0]);
127
1
      return;
128
1
    }
129
130
3.30k
    
for (auto c : encoded_varint_str)121
{
131
3.30k
      data_.push_back(~c);
132
3.30k
    }
133
121
  }
134
135
3.37M
  void AppendInt64(int64_t x) {
136
3.37M
    util::AppendInt64ToKey(x, &data_);
137
3.37M
  }
138
139
  void AppendUInt64(uint64_t x);
140
141
  void AppendDescendingUInt64(uint64_t x);
142
143
60.4M
  void AppendInt32(int32_t x) {
144
60.4M
    util::AppendInt32ToKey(x, &data_);
145
60.4M
  }
146
147
  void AppendUInt32(uint32_t x);
148
149
  void AppendDescendingUInt32(uint32_t x);
150
151
  template <class EnumBitSet>
152
0
  void AppendIntentTypeSet(EnumBitSet intent_type_set) {
153
0
    data_.push_back(static_cast<char>(intent_type_set.ToUIntPtr()));
154
0
  }
155
156
1.48M
  void AppendDescendingInt64(int64_t x) {
157
    // AppendInt64ToKey flips the highest bit. We flip all the x's bits before calling
158
    // AppendInt64ToKey, but the order of the operations (FLIP_HIGHEST_BIT and FLIP_ALL_BITS)
159
    // doesn't matter because they are commutative operations.
160
    // Example for an 8-bit integer (works the same for 64-bit integers):
161
    //    normal encoding (flip first bit)
162
    //    -128 = 0x80 -> 0x00
163
    //    -1   = 0xFF -> 0x7F
164
    //    0    = 0x00 -> 0x80
165
    //    127  = 0x7F -> 0xFF
166
    //    (everything compares correctly)
167
    //
168
    //    descending encoding (flip all bits, then first, or flip first bit, then all, doesn't
169
    //    matter which)
170
    //    -128 = 0x80 -> 0x7F -> 0xFF
171
    //    -1   = 0xFF -> 0x00 -> 0x80
172
    //    0    = 0x00 -> 0xFF -> 0x7F
173
    //    127  = 0x7F -> 0x80 -> 0x00
174
1.48M
    util::AppendInt64ToKey(~x, &data_);
175
1.48M
  }
176
177
342k
  void AppendDescendingInt32(int32_t x) {
178
342k
    util::AppendInt32ToKey(~x, &data_);
179
342k
  }
180
181
4.14k
  void AppendUint8(uint8_t x) {
182
4.14k
    data_.push_back(static_cast<char>(x));
183
4.14k
  }
184
185
  void AppendUInt16(uint16_t x);
186
187
  void AppendHybridTime(const DocHybridTime& hybrid_time);
188
189
  void AppendColumnId(ColumnId column_id);
190
191
420
  void AppendDescendingFloat(float x) {
192
420
    util::AppendFloatToKey(x, &data_, /* descending */ true);
193
420
  }
194
195
1.41k
  void AppendFloat(float x) {
196
1.41k
    util::AppendFloatToKey(x, &data_);
197
1.41k
  }
198
199
521
  void AppendDescendingDouble(double x) {
200
521
    util::AppendDoubleToKey(x, &data_, /* descending */ true);
201
521
  }
202
203
681k
  void AppendDouble(double x) {
204
681k
    util::AppendDoubleToKey(x, &data_);
205
681k
  }
206
207
  void AppendGroupEnd();
208
209
  void RemoveValueTypeSuffix(ValueType value_type);
210
211
1.88G
  size_t size() const { return data_.size(); }
212
213
728k
  bool IsPrefixOf(const rocksdb::Slice& slice) const {
214
728k
    return slice.starts_with(data_.AsSlice());
215
728k
  }
216
217
2.62G
  rocksdb::Slice AsSlice() const { return data_.AsSlice(); }
218
219
2.89G
  operator Slice() const { return data_.AsSlice(); }
220
221
236M
  void Reset(const Slice& slice) {
222
236M
    data_.assign(slice.cdata(), slice.size());
223
236M
  }
224
225
0
  void ResetRawBytes(const char* raw_bytes, size_t n) {
226
0
    data_.assign(raw_bytes, n);
227
0
  }
228
229
453M
  void Clear() {
230
453M
    data_.clear();
231
453M
  }
232
233
616k
  int CompareTo(const KeyBytes& other) const {
234
616k
    return data_.AsSlice().compare(other.data_.AsSlice());
235
616k
  }
236
237
86.2M
  int CompareTo(const Slice& other) const {
238
86.2M
    return data_.AsSlice().compare(other);
239
86.2M
  }
240
241
  // This can be used to e.g. move the internal state of KeyBytes somewhere else, including a
242
  // string field in a protobuf, without copying the bytes.
243
1.52M
  KeyBuffer* mutable_data() {
244
1.52M
    return &data_;
245
1.52M
  }
246
247
  void Truncate(size_t new_size);
248
249
  void RemoveLastByte();
250
251
 private:
252
  KeyBuffer data_;
253
};
254
255
6.25M
inline bool operator<(const KeyBytes& lhs, const KeyBytes& rhs) {
256
6.25M
  return lhs.data() < rhs.data();
257
6.25M
}
258
259
166
inline bool operator>=(const KeyBytes& lhs, const KeyBytes& rhs) {
260
166
  return !(lhs < rhs);
261
166
}
262
263
3.12M
inline bool operator>(const KeyBytes& lhs, const KeyBytes& rhs) {
264
3.12M
  return rhs < lhs;
265
3.12M
}
266
267
190
inline bool operator<=(const KeyBytes& lhs, const KeyBytes& rhs) {
268
190
  return !(rhs < lhs);
269
190
}
270
271
694M
inline bool operator==(const KeyBytes& lhs, const KeyBytes& rhs) {
272
694M
  return lhs.AsSlice() == rhs.AsSlice();
273
694M
}
274
275
0
inline bool operator!=(const KeyBytes& lhs, const KeyBytes& rhs) {
276
0
  return lhs.AsSlice() != rhs.AsSlice();
277
0
}
278
279
void AppendDocHybridTime(const DocHybridTime& time, KeyBytes* key);
280
void AppendHash(uint16_t hash, KeyBytes* key);
281
282
}  // namespace docdb
283
}  // namespace yb
284
285
#endif  // YB_DOCDB_KEY_BYTES_H_