1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 6 package org.rocksdb.util; 7 8 import org.rocksdb.AbstractComparator; 9 import org.rocksdb.BuiltinComparator; 10 import org.rocksdb.ComparatorOptions; 11 import org.rocksdb.Slice; 12 13 import java.nio.ByteBuffer; 14 15 /** 16 * This is a Java Native implementation of the C++ 17 * equivalent ReverseBytewiseComparatorImpl using {@link Slice} 18 * 19 * The performance of Comparators implemented in Java is always 20 * less than their C++ counterparts due to the bridging overhead, 21 * as such you likely don't want to use this apart from benchmarking 22 * and you most likely instead wanted 23 * {@link BuiltinComparator#REVERSE_BYTEWISE_COMPARATOR} 24 */ 25 public final class ReverseBytewiseComparator extends AbstractComparator { 26 ReverseBytewiseComparator(final ComparatorOptions copt)27 public ReverseBytewiseComparator(final ComparatorOptions copt) { 28 super(copt); 29 } 30 31 @Override name()32 public String name() { 33 return "rocksdb.java.ReverseBytewiseComparator"; 34 } 35 36 @Override compare(final ByteBuffer a, final ByteBuffer b)37 public int compare(final ByteBuffer a, final ByteBuffer b) { 38 return -BytewiseComparator._compare(a, b); 39 } 40 41 @Override findShortestSeparator(final ByteBuffer start, final ByteBuffer limit)42 public void findShortestSeparator(final ByteBuffer start, 43 final ByteBuffer limit) { 44 // Find length of common prefix 45 final int minLength = Math.min(start.remaining(), limit.remaining()); 46 int diffIndex = 0; 47 while (diffIndex < minLength && 48 start.get(diffIndex) == limit.get(diffIndex)) { 49 diffIndex++; 50 } 51 52 assert(diffIndex <= minLength); 53 if (diffIndex == minLength) { 54 // Do not shorten if one string is a prefix of the other 55 // 56 // We could handle cases like: 57 // V 58 // A A 2 X Y 59 // A A 2 60 // in a similar way as BytewiseComparator::FindShortestSeparator(). 61 // We keep it simple by not implementing it. We can come back to it 62 // later when needed. 63 } else { 64 final int startByte = start.get(diffIndex) & 0xff; 65 final int limitByte = limit.get(diffIndex) & 0xff; 66 if (startByte > limitByte && diffIndex < start.remaining() - 1) { 67 // Case like 68 // V 69 // A A 3 A A 70 // A A 1 B B 71 // 72 // or 73 // v 74 // A A 2 A A 75 // A A 1 B B 76 // In this case "AA2" will be good. 77 //#ifndef NDEBUG 78 // std::string old_start = *start; 79 //#endif 80 start.limit(diffIndex + 1); 81 //#ifndef NDEBUG 82 // assert(old_start >= *start); 83 //#endif 84 assert(BytewiseComparator._compare(start.duplicate(), limit.duplicate()) > 0); 85 } 86 } 87 } 88 } 89