2011-03-18 22:37:00 +00:00
|
|
|
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
|
|
|
|
2019-05-04 17:40:21 -07:00
|
|
|
#include "leveldb/comparator.h"
|
|
|
|
|
2011-07-19 23:36:47 +00:00
|
|
|
#include <algorithm>
|
2018-09-10 15:38:12 -07:00
|
|
|
#include <cstdint>
|
|
|
|
#include <string>
|
2019-05-04 17:40:21 -07:00
|
|
|
#include <type_traits>
|
2018-09-10 15:38:12 -07:00
|
|
|
|
2011-03-30 18:35:40 +00:00
|
|
|
#include "leveldb/slice.h"
|
2011-03-18 22:37:00 +00:00
|
|
|
#include "util/logging.h"
|
2018-09-10 15:38:12 -07:00
|
|
|
#include "util/no_destructor.h"
|
2011-03-18 22:37:00 +00:00
|
|
|
|
|
|
|
namespace leveldb {
|
|
|
|
|
2019-05-04 17:40:21 -07:00
|
|
|
Comparator::~Comparator() = default;
|
2011-03-18 22:37:00 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
class BytewiseComparatorImpl : public Comparator {
|
|
|
|
public:
|
2019-05-04 17:40:21 -07:00
|
|
|
BytewiseComparatorImpl() = default;
|
2011-03-18 22:37:00 +00:00
|
|
|
|
2019-05-04 17:40:21 -07:00
|
|
|
const char* Name() const override { return "leveldb.BytewiseComparator"; }
|
2011-03-18 22:37:00 +00:00
|
|
|
|
2019-05-04 17:40:21 -07:00
|
|
|
int Compare(const Slice& a, const Slice& b) const override {
|
2011-03-18 22:37:00 +00:00
|
|
|
return a.compare(b);
|
|
|
|
}
|
|
|
|
|
2019-05-04 17:40:21 -07:00
|
|
|
void FindShortestSeparator(std::string* start,
|
|
|
|
const Slice& limit) const override {
|
2011-03-18 22:37:00 +00:00
|
|
|
// Find length of common prefix
|
|
|
|
size_t min_length = std::min(start->size(), limit.size());
|
|
|
|
size_t diff_index = 0;
|
|
|
|
while ((diff_index < min_length) &&
|
|
|
|
((*start)[diff_index] == limit[diff_index])) {
|
|
|
|
diff_index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (diff_index >= min_length) {
|
|
|
|
// Do not shorten if one string is a prefix of the other
|
|
|
|
} else {
|
|
|
|
uint8_t diff_byte = static_cast<uint8_t>((*start)[diff_index]);
|
|
|
|
if (diff_byte < static_cast<uint8_t>(0xff) &&
|
|
|
|
diff_byte + 1 < static_cast<uint8_t>(limit[diff_index])) {
|
|
|
|
(*start)[diff_index]++;
|
|
|
|
start->resize(diff_index + 1);
|
|
|
|
assert(Compare(*start, limit) < 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 17:40:21 -07:00
|
|
|
void FindShortSuccessor(std::string* key) const override {
|
2011-03-18 22:37:00 +00:00
|
|
|
// Find first character that can be incremented
|
|
|
|
size_t n = key->size();
|
2011-04-20 22:48:11 +00:00
|
|
|
for (size_t i = 0; i < n; i++) {
|
2011-03-18 22:37:00 +00:00
|
|
|
const uint8_t byte = (*key)[i];
|
|
|
|
if (byte != static_cast<uint8_t>(0xff)) {
|
|
|
|
(*key)[i] = byte + 1;
|
2019-05-02 11:01:00 -07:00
|
|
|
key->resize(i + 1);
|
2011-03-18 22:37:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// *key is a run of 0xffs. Leave it alone.
|
|
|
|
}
|
|
|
|
};
|
2011-10-31 17:22:06 +00:00
|
|
|
} // namespace
|
2011-11-14 17:06:16 +00:00
|
|
|
|
2011-03-18 22:37:00 +00:00
|
|
|
const Comparator* BytewiseComparator() {
|
2018-09-10 15:38:12 -07:00
|
|
|
static NoDestructor<BytewiseComparatorImpl> singleton;
|
|
|
|
return singleton.get();
|
2011-03-18 22:37:00 +00:00
|
|
|
}
|
|
|
|
|
2011-10-31 17:22:06 +00:00
|
|
|
} // namespace leveldb
|