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.cc
Line
Count
Source (jump to first uncovered line)
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/dbformat.h"
24
25
#ifndef __STDC_FORMAT_MACROS
26
#define __STDC_FORMAT_MACROS
27
#endif
28
29
#include <inttypes.h>
30
#include <stdio.h>
31
32
#include "yb/util/logging.h"
33
#include "yb/util/result.h"
34
35
#include "yb/rocksdb/port/port.h"
36
#include "yb/rocksdb/util/coding.h"
37
#include "yb/rocksdb/util/logging.h"
38
#include "yb/rocksdb/util/perf_context_imp.h"
39
40
namespace rocksdb {
41
42
245M
uint64_t PackSequenceAndType(uint64_t seq, ValueType t) {
43
245M
  assert(seq <= kMaxSequenceNumber);
44
245M
  assert(IsValueType(t));
45
245M
  return (seq << 8) | t;
46
245M
}
47
48
14.0M
SequenceAndType UnPackSequenceAndTypeFromEnd(const void* end) {
49
14.0M
  uint64_t packed;
50
14.0M
  memcpy(&packed, static_cast<const char*>(end) - kLastInternalComponentSize, sizeof(packed));
51
14.0M
  auto result = SequenceAndType {
52
14.0M
    .sequence = packed >> 8,
53
14.0M
    .type = static_cast<ValueType>(packed & 0xff),
54
14.0M
  };
55
56
14.0M
  assert(result.sequence <= kMaxSequenceNumber);
57
14.0M
  assert(IsValueType(result.type));
58
59
14.0M
  return result;
60
14.0M
}
61
62
1.37M
void AppendInternalKey(std::string* result, const ParsedInternalKey& key) {
63
1.37M
  result->append(key.user_key.cdata(), key.user_key.size());
64
1.37M
  PutFixed64(result, PackSequenceAndType(key.sequence, key.type));
65
1.37M
}
66
67
1.63k
std::string ParsedInternalKey::DebugString(bool hex) const {
68
1.63k
  char buf[50];
69
1.63k
  snprintf(buf, sizeof(buf), "' @ %" PRIu64 ": %d", sequence,
70
1.63k
           static_cast<int>(type));
71
1.63k
  std::string result = "'";
72
1.63k
  result += user_key.ToString(hex);
73
1.63k
  result += buf;
74
1.63k
  return result;
75
1.63k
}
76
77
1.63k
std::string InternalKey::DebugString(const std::string& rep, bool hex) {
78
1.63k
  std::string result;
79
1.63k
  ParsedInternalKey parsed;
80
1.63k
  if (ParseInternalKey(rep, &parsed)) {
81
1.63k
    result = parsed.DebugString(hex);
82
0
  } else {
83
0
    result = "(bad)";
84
0
    result.append(EscapeString(rep));
85
0
  }
86
1.63k
  return result;
87
1.63k
}
88
89
yb::Result<FileBoundaryValues<InternalKey>> MakeFileBoundaryValues(
90
    BoundaryValuesExtractor* extractor,
91
    const Slice& key,
92
71.0M
    const Slice& value) {
93
71.0M
  ParsedInternalKey parsed = { Slice(), 0, kTypeDeletion };
94
71.0M
  ParseInternalKey(key, &parsed);
95
96
71.0M
  FileBoundaryValues<InternalKey> result;
97
71.0M
  result.key = InternalKey::DecodeFrom(key);
98
71.0M
  result.seqno = parsed.sequence;
99
100
71.0M
  if (extractor) {
101
27.9M
    auto status = extractor->Extract(parsed.user_key, value, &result.user_values);
102
27.9M
    if (!status.ok()) {
103
0
      return status;
104
0
    }
105
71.0M
  }
106
71.0M
  return result;
107
71.0M
}
108
109
17.7k
const char* InternalKeyComparator::Name() const {
110
17.7k
  return name_.c_str();
111
17.7k
}
112
113
10.7G
int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const {
114
  // Order by:
115
  //    increasing user key (according to user-supplied comparator)
116
  //    decreasing sequence number
117
  //    decreasing type (though sequence# should be enough to disambiguate)
118
10.7G
  int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));
119
10.7G
  PERF_COUNTER_ADD(user_key_comparison_count, 1);
120
10.7G
  if (r == 0) {
121
319M
    const uint64_t anum = DecodeFixed64(akey.end() - 8);
122
319M
    const uint64_t bnum = DecodeFixed64(bkey.end() - 8);
123
319M
    if (anum > bnum) {
124
165M
      r = -1;
125
154M
    } else if (anum < bnum) {
126
149M
      r = +1;
127
149M
    }
128
319M
  }
129
10.7G
  return r;
130
10.7G
}
131
132
int InternalKeyComparator::Compare(const ParsedInternalKey& a,
133
978k
                                   const ParsedInternalKey& b) const {
134
  // Order by:
135
  //    increasing user key (according to user-supplied comparator)
136
  //    decreasing sequence number
137
  //    decreasing type (though sequence# should be enough to disambiguate)
138
978k
  int r = user_comparator_->Compare(a.user_key, b.user_key);
139
978k
  PERF_COUNTER_ADD(user_key_comparison_count, 1);
140
978k
  if (r == 0) {
141
97.5k
    if (a.sequence > b.sequence) {
142
32
      r = -1;
143
97.5k
    } else if (a.sequence < b.sequence) {
144
88.4k
      r = +1;
145
9.06k
    } else if (a.type > b.type) {
146
0
      r = -1;
147
9.06k
    } else if (a.type < b.type) {
148
240
      r = +1;
149
240
    }
150
97.5k
  }
151
978k
  return r;
152
978k
}
153
154
void InternalKeyComparator::FindShortestSeparator(
155
      std::string* start,
156
2.45M
      const Slice& limit) const {
157
  // Attempt to shorten the user portion of the key
158
2.45M
  Slice user_start = ExtractUserKey(*start);
159
2.45M
  Slice user_limit = ExtractUserKey(limit);
160
2.45M
  std::string tmp = user_start.ToBuffer();
161
2.45M
  user_comparator_->FindShortestSeparator(&tmp, user_limit);
162
2.45M
  if (tmp.size() < user_start.size() &&
163
1.26M
      user_comparator_->Compare(user_start, tmp) < 0) {
164
    // User key has become shorter physically, but larger logically.
165
    // Tack on the earliest possible number to the shortened user key.
166
1.26M
    PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber, kValueTypeForSeek));
167
1.26M
    assert(this->Compare(*start, tmp) < 0);
168
1.26M
    assert(this->Compare(tmp, limit) < 0);
169
1.26M
    start->swap(tmp);
170
1.26M
  }
171
2.45M
}
172
173
58.1k
void InternalKeyComparator::FindShortSuccessor(std::string* key) const {
174
58.1k
  Slice user_key = ExtractUserKey(*key);
175
58.1k
  std::string tmp = user_key.ToBuffer();
176
58.1k
  user_comparator_->FindShortSuccessor(&tmp);
177
58.1k
  if (tmp.size() < user_key.size() &&
178
54.1k
      user_comparator_->Compare(user_key, tmp) < 0) {
179
    // User key has become shorter physically, but larger logically.
180
    // Tack on the earliest possible number to the shortened user key.
181
54.1k
    PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber, kValueTypeForSeek));
182
54.1k
    assert(this->Compare(*key, tmp) < 0);
183
54.1k
    key->swap(tmp);
184
54.1k
  }
185
58.1k
}
186
187
21.3M
LookupKey::LookupKey(const Slice& _user_key, SequenceNumber s) {
188
21.3M
  size_t usize = _user_key.size();
189
21.3M
  size_t needed = usize + 13;  // A conservative estimate
190
21.3M
  char* dst;
191
21.3M
  if (needed <= sizeof(space_)) {
192
21.3M
    dst = space_;
193
3.70k
  } else {
194
3.70k
    dst = new char[needed];
195
3.70k
  }
196
21.3M
  start_ = dst;
197
  // NOTE: We don't support users keys of more than 2GB :)
198
21.3M
  dst = EncodeVarint32(dst, static_cast<uint32_t>(usize + 8));
199
21.3M
  kstart_ = dst;
200
21.3M
  memcpy(dst, _user_key.data(), usize);
201
21.3M
  dst += usize;
202
21.3M
  EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek));
203
21.3M
  dst += 8;
204
21.3M
  end_ = dst;
205
21.3M
}
206
207
}  // namespace rocksdb