Home | History | Annotate | Download | only in util
      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 <algorithm>
      6 #include <stdint.h>
      7 #include "leveldb/comparator.h"
      8 #include "leveldb/slice.h"
      9 #include "port/port.h"
     10 #include "util/logging.h"
     11 
     12 namespace leveldb {
     13 
     14 Comparator::~Comparator() { }
     15 
     16 namespace {
     17 class BytewiseComparatorImpl : public Comparator {
     18  public:
     19   BytewiseComparatorImpl() { }
     20 
     21   virtual const char* Name() const {
     22     return "leveldb.BytewiseComparator";
     23   }
     24 
     25   virtual int Compare(const Slice& a, const Slice& b) const {
     26     return a.compare(b);
     27   }
     28 
     29   virtual void FindShortestSeparator(
     30       std::string* start,
     31       const Slice& limit) const {
     32     // Find length of common prefix
     33     size_t min_length = std::min(start->size(), limit.size());
     34     size_t diff_index = 0;
     35     while ((diff_index < min_length) &&
     36            ((*start)[diff_index] == limit[diff_index])) {
     37       diff_index++;
     38     }
     39 
     40     if (diff_index >= min_length) {
     41       // Do not shorten if one string is a prefix of the other
     42     } else {
     43       uint8_t diff_byte = static_cast<uint8_t>((*start)[diff_index]);
     44       if (diff_byte < static_cast<uint8_t>(0xff) &&
     45           diff_byte + 1 < static_cast<uint8_t>(limit[diff_index])) {
     46         (*start)[diff_index]++;
     47         start->resize(diff_index + 1);
     48         assert(Compare(*start, limit) < 0);
     49       }
     50     }
     51   }
     52 
     53   virtual void FindShortSuccessor(std::string* key) const {
     54     // Find first character that can be incremented
     55     size_t n = key->size();
     56     for (size_t i = 0; i < n; i++) {
     57       const uint8_t byte = (*key)[i];
     58       if (byte != static_cast<uint8_t>(0xff)) {
     59         (*key)[i] = byte + 1;
     60         key->resize(i+1);
     61         return;
     62       }
     63     }
     64     // *key is a run of 0xffs.  Leave it alone.
     65   }
     66 };
     67 }  // namespace
     68 
     69 static port::OnceType once = LEVELDB_ONCE_INIT;
     70 static const Comparator* bytewise;
     71 
     72 static void InitModule() {
     73   bytewise = new BytewiseComparatorImpl;
     74 }
     75 
     76 const Comparator* BytewiseComparator() {
     77   port::InitOnce(&once, InitModule);
     78   return bytewise;
     79 }
     80 
     81 }  // namespace leveldb
     82