1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import java.io.Serializable;
22 import java.util.Comparator;
23
24 import org.apache.hadoop.hbase.classification.InterfaceAudience;
25 import org.apache.hadoop.hbase.classification.InterfaceStability;
26 import org.apache.hadoop.hbase.KeyValue.Type;
27 import org.apache.hadoop.hbase.util.Bytes;
28
29 import com.google.common.primitives.Longs;
30
31
32
33
34
35
36
37
38 @edu.umd.cs.findbugs.annotations.SuppressWarnings(
39 value="UNKNOWN",
40 justification="Findbugs doesn't like the way we are negating the result of a compare in below")
41 @InterfaceAudience.Private
42 @InterfaceStability.Evolving
43 public class CellComparator implements Comparator<Cell>, Serializable{
44 private static final long serialVersionUID = -8760041766259623329L;
45
46 @Override
47 public int compare(Cell a, Cell b) {
48 return compareStatic(a, b);
49 }
50
51 public static int compareStatic(Cell a, Cell b) {
52 return compareStatic(a, b, false);
53 }
54
55 public static int compareStatic(Cell a, Cell b, boolean onlyKey) {
56
57 int c = Bytes.compareTo(
58 a.getRowArray(), a.getRowOffset(), a.getRowLength(),
59 b.getRowArray(), b.getRowOffset(), b.getRowLength());
60 if (c != 0) return c;
61
62
63
64
65
66
67 if (a.getFamilyLength() == 0 && a.getTypeByte() == Type.Minimum.getCode()) {
68
69 return 1;
70 }
71 if (b.getFamilyLength() == 0 && b.getTypeByte() == Type.Minimum.getCode()) {
72 return -1;
73 }
74
75
76 c = Bytes.compareTo(
77 a.getFamilyArray(), a.getFamilyOffset(), a.getFamilyLength(),
78 b.getFamilyArray(), b.getFamilyOffset(), b.getFamilyLength());
79 if (c != 0) return c;
80
81
82 c = Bytes.compareTo(
83 a.getQualifierArray(), a.getQualifierOffset(), a.getQualifierLength(),
84 b.getQualifierArray(), b.getQualifierOffset(), b.getQualifierLength());
85 if (c != 0) return c;
86
87
88 c = Longs.compare(b.getTimestamp(), a.getTimestamp());
89 if (c != 0) return c;
90
91
92 c = (0xff & b.getTypeByte()) - (0xff & a.getTypeByte());
93 if (c != 0) return c;
94
95 if (onlyKey) return c;
96
97
98 return Longs.compare(b.getMvccVersion(), a.getMvccVersion());
99 }
100
101
102
103
104 public static boolean equals(Cell a, Cell b){
105 return equalsRow(a, b)
106 && equalsFamily(a, b)
107 && equalsQualifier(a, b)
108 && equalsTimestamp(a, b)
109 && equalsType(a, b);
110 }
111
112 public static boolean equalsRow(Cell a, Cell b){
113 return Bytes.equals(
114 a.getRowArray(), a.getRowOffset(), a.getRowLength(),
115 b.getRowArray(), b.getRowOffset(), b.getRowLength());
116 }
117
118 public static boolean equalsFamily(Cell a, Cell b){
119 return Bytes.equals(
120 a.getFamilyArray(), a.getFamilyOffset(), a.getFamilyLength(),
121 b.getFamilyArray(), b.getFamilyOffset(), b.getFamilyLength());
122 }
123
124 public static boolean equalsQualifier(Cell a, Cell b){
125 return Bytes.equals(
126 a.getQualifierArray(), a.getQualifierOffset(), a.getQualifierLength(),
127 b.getQualifierArray(), b.getQualifierOffset(), b.getQualifierLength());
128 }
129
130 public static boolean equalsTimestamp(Cell a, Cell b){
131 return a.getTimestamp() == b.getTimestamp();
132 }
133
134 public static boolean equalsType(Cell a, Cell b){
135 return a.getTypeByte() == b.getTypeByte();
136 }
137
138
139
140
141
142
143
144 public static int hashCode(Cell cell){
145 if (cell == null) {
146 return 0;
147 }
148 int hash = calculateHashForKeyValue(cell);
149 hash = 31 * hash + (int)cell.getMvccVersion();
150 return hash;
151 }
152
153
154
155
156
157
158
159
160 public static int hashCodeIgnoreMvcc(Cell cell) {
161 if (cell == null) {
162 return 0;
163 }
164 int hash = calculateHashForKeyValue(cell);
165 return hash;
166 }
167
168 private static int calculateHashForKeyValue(Cell cell) {
169
170 int rowHash = Bytes.hashCode(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
171 int familyHash =
172 Bytes.hashCode(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
173 int qualifierHash = Bytes.hashCode(cell.getQualifierArray(), cell.getQualifierOffset(),
174 cell.getQualifierLength());
175
176
177 int hash = 31 * rowHash + familyHash;
178 hash = 31 * hash + qualifierHash;
179 hash = 31 * hash + (int)cell.getTimestamp();
180 hash = 31 * hash + cell.getTypeByte();
181 return hash;
182 }
183
184
185
186
187 public static boolean areKeyLengthsEqual(Cell a, Cell b) {
188 return a.getRowLength() == b.getRowLength()
189 && a.getFamilyLength() == b.getFamilyLength()
190 && a.getQualifierLength() == b.getQualifierLength();
191 }
192
193 public static boolean areRowLengthsEqual(Cell a, Cell b) {
194 return a.getRowLength() == b.getRowLength();
195 }
196
197
198
199
200
201
202
203 private static int compareStaticIgnoreMvccVersion(Cell a, Cell b) {
204
205 int c = Bytes.compareTo(
206 a.getRowArray(), a.getRowOffset(), a.getRowLength(),
207 b.getRowArray(), b.getRowOffset(), b.getRowLength());
208 if (c != 0) return c;
209
210
211 c = Bytes.compareTo(
212 a.getFamilyArray(), a.getFamilyOffset(), a.getFamilyLength(),
213 b.getFamilyArray(), b.getFamilyOffset(), b.getFamilyLength());
214 if (c != 0) return c;
215
216
217 c = Bytes.compareTo(
218 a.getQualifierArray(), a.getQualifierOffset(), a.getQualifierLength(),
219 b.getQualifierArray(), b.getQualifierOffset(), b.getQualifierLength());
220 if (c != 0) return c;
221
222
223 c = Longs.compare(b.getTimestamp(), a.getTimestamp());
224 if (c != 0) return c;
225
226
227 c = (0xff & b.getTypeByte()) - (0xff & a.getTypeByte());
228 return c;
229 }
230
231
232
233
234 public static boolean equalsIgnoreMvccVersion(Cell a, Cell b){
235 return 0 == compareStaticIgnoreMvccVersion(a, b);
236 }
237
238 }