]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae FG |
5 | |
6 | package org.rocksdb.util; | |
7 | ||
f67539c2 | 8 | import org.rocksdb.AbstractComparator; |
7c673cae FG |
9 | import org.rocksdb.BuiltinComparator; |
10 | import org.rocksdb.ComparatorOptions; | |
11 | import org.rocksdb.Slice; | |
12 | ||
f67539c2 TL |
13 | import java.nio.ByteBuffer; |
14 | ||
7c673cae FG |
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 | */ | |
f67539c2 | 25 | public final class ReverseBytewiseComparator extends AbstractComparator { |
7c673cae FG |
26 | |
27 | public ReverseBytewiseComparator(final ComparatorOptions copt) { | |
28 | super(copt); | |
29 | } | |
30 | ||
31 | @Override | |
32 | public String name() { | |
33 | return "rocksdb.java.ReverseBytewiseComparator"; | |
34 | } | |
35 | ||
36 | @Override | |
f67539c2 TL |
37 | public int compare(final ByteBuffer a, final ByteBuffer b) { |
38 | return -BytewiseComparator._compare(a, b); | |
39 | } | |
40 | ||
41 | @Override | |
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 | } | |
7c673cae FG |
87 | } |
88 | } |