/root/bitcoin/src/leveldb/util/comparator.cc
| Line | Count | Source | 
| 1 |  | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. | 
| 2 |  | // Use of this source code is governed by a BSD-style license that can be | 
| 3 |  | // found in the LICENSE file. See the AUTHORS file for names of contributors. | 
| 4 |  |  | 
| 5 |  | #include "leveldb/comparator.h" | 
| 6 |  |  | 
| 7 |  | #include <algorithm> | 
| 8 |  | #include <cstdint> | 
| 9 |  | #include <string> | 
| 10 |  | #include <type_traits> | 
| 11 |  |  | 
| 12 |  | #include "leveldb/slice.h" | 
| 13 |  | #include "util/logging.h" | 
| 14 |  | #include "util/no_destructor.h" | 
| 15 |  |  | 
| 16 |  | namespace leveldb { | 
| 17 |  |  | 
| 18 | 8 | Comparator::~Comparator() = default; | 
| 19 |  |  | 
| 20 |  | namespace { | 
| 21 |  | class BytewiseComparatorImpl : public Comparator { | 
| 22 |  |  public: | 
| 23 | 0 |   BytewiseComparatorImpl() = default; | 
| 24 |  |  | 
| 25 | 0 |   const char* Name() const override { return "leveldb.BytewiseComparator"; } | 
| 26 |  |  | 
| 27 | 0 |   int Compare(const Slice& a, const Slice& b) const override { | 
| 28 | 0 |     return a.compare(b); | 
| 29 | 0 |   } | 
| 30 |  |  | 
| 31 |  |   void FindShortestSeparator(std::string* start, | 
| 32 | 0 |                              const Slice& limit) const override { | 
| 33 |  |     // Find length of common prefix | 
| 34 | 0 |     size_t min_length = std::min(start->size(), limit.size()); | 
| 35 | 0 |     size_t diff_index = 0; | 
| 36 | 0 |     while ((diff_index < min_length) && | 
| 37 | 0 |            ((*start)[diff_index] == limit[diff_index])) { | 
| 38 | 0 |       diff_index++; | 
| 39 | 0 |     } | 
| 40 |  | 
 | 
| 41 | 0 |     if (diff_index >= min_length) { | 
| 42 |  |       // Do not shorten if one string is a prefix of the other | 
| 43 | 0 |     } else { | 
| 44 | 0 |       uint8_t diff_byte = static_cast<uint8_t>((*start)[diff_index]); | 
| 45 | 0 |       if (diff_byte < static_cast<uint8_t>(0xff) && | 
| 46 | 0 |           diff_byte + 1 < static_cast<uint8_t>(limit[diff_index])) { | 
| 47 | 0 |         (*start)[diff_index]++; | 
| 48 | 0 |         start->resize(diff_index + 1); | 
| 49 | 0 |         assert(Compare(*start, limit) < 0); | 
| 50 | 0 |       } | 
| 51 | 0 |     } | 
| 52 | 0 |   } | 
| 53 |  |  | 
| 54 | 0 |   void FindShortSuccessor(std::string* key) const override { | 
| 55 |  |     // Find first character that can be incremented | 
| 56 | 0 |     size_t n = key->size(); | 
| 57 | 0 |     for (size_t i = 0; i < n; i++) { | 
| 58 | 0 |       const uint8_t byte = (*key)[i]; | 
| 59 | 0 |       if (byte != static_cast<uint8_t>(0xff)) { | 
| 60 | 0 |         (*key)[i] = byte + 1; | 
| 61 | 0 |         key->resize(i + 1); | 
| 62 | 0 |         return; | 
| 63 | 0 |       } | 
| 64 | 0 |     } | 
| 65 |  |     // *key is a run of 0xffs.  Leave it alone. | 
| 66 | 0 |   } | 
| 67 |  | }; | 
| 68 |  | }  // namespace | 
| 69 |  |  | 
| 70 | 0 | const Comparator* BytewiseComparator() { | 
| 71 | 0 |   static NoDestructor<BytewiseComparatorImpl> singleton; | 
| 72 | 0 |   return singleton.get(); | 
| 73 | 0 | } | 
| 74 |  |  | 
| 75 |  | }  // namespace leveldb |