1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.filter;
19
20 import java.util.Arrays;
21
22 import org.apache.hadoop.hbase.KeyValue;
23 import org.apache.hadoop.hbase.KeyValueUtil;
24 import org.apache.hadoop.hbase.testclassification.SmallTests;
25 import org.apache.hadoop.hbase.util.Bytes;
26 import org.junit.Assert;
27 import org.junit.Test;
28 import org.junit.experimental.categories.Category;
29 import org.junit.internal.ArrayComparisonFailure;
30
31 @Category(SmallTests.class)
32 public class TestFuzzyRowFilter {
33
34 @Test
35 public void testIdempotentMaskShift() {
36 byte[] test = new byte[] {
37 -1,
38 FuzzyRowFilter.V1_PROCESSED_WILDCARD_MASK,
39 FuzzyRowFilter.V2_PROCESSED_WILDCARD_MASK
40 };
41
42 byte[] original = Arrays.copyOf(test, test.length);
43 byte[] expected = new byte[] { -1, 0, 0};
44
45 Assert.assertArrayEquals(test, original);
46 assertArrayNotEquals(expected, test);
47
48
49 FuzzyRowFilter.idempotentMaskShift(test);
50 Assert.assertArrayEquals(expected, test);
51 assertArrayNotEquals(original, test);
52
53
54 FuzzyRowFilter.idempotentMaskShift(test);
55 Assert.assertArrayEquals(expected, test);
56 assertArrayNotEquals(original, test);
57 }
58
59 private void assertArrayNotEquals(byte[] expected, byte[] testcase) {
60 try {
61 Assert.assertArrayEquals(expected, testcase);
62 Assert.fail("expected arrays to fail equality test");
63 } catch (ArrayComparisonFailure e) {
64
65 }
66 }
67
68 @Test
69 public void testSatisfiesNoUnsafeForward() {
70
71 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
72 FuzzyRowFilter.satisfiesNoUnsafe(false,
73 new byte[]{1, (byte) -128, 1, 0, 1},
74 0, 5,
75 new byte[]{1, 0, 1},
76 new byte[]{0, 1, 0}));
77
78 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
79 FuzzyRowFilter.satisfiesNoUnsafe(false,
80 new byte[]{1, (byte) -128, 2, 0, 1},
81 0, 5,
82 new byte[]{1, 0, 1},
83 new byte[]{0, 1, 0}));
84
85
86 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
87 FuzzyRowFilter.satisfiesNoUnsafe(false,
88 new byte[]{1, 2, 1, 3, 3},
89 0, 5,
90 new byte[]{1, 2, 0, 3},
91 new byte[]{0, 0, 1, 0}));
92
93 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
94 FuzzyRowFilter.satisfiesNoUnsafe(false,
95 new byte[]{1, 1, 1, 3, 0},
96 0, 5,
97 new byte[]{1, 2, 0, 3},
98 new byte[]{0, 0, 1, 0}));
99
100 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
101 FuzzyRowFilter.satisfiesNoUnsafe(false,
102 new byte[]{1, 1, 1, 3, 0},
103 0, 5,
104 new byte[]{1, (byte) 245, 0, 3},
105 new byte[]{0, 0, 1, 0}));
106
107 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
108 FuzzyRowFilter.satisfiesNoUnsafe(false,
109 new byte[]{1, 2, 1, 0, 1},
110 0, 5,
111 new byte[]{0, 1, 2},
112 new byte[]{1, 0, 0}));
113 }
114
115 @Test
116 public void testSatisfiesForward() {
117
118 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
119 FuzzyRowFilter.satisfies(false,
120 new byte[]{1, (byte) -128, 1, 0, 1},
121 new byte[]{1, 0, 1},
122 new byte[]{-1, 0, -1}));
123
124 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
125 FuzzyRowFilter.satisfies(false,
126 new byte[]{1, (byte) -128, 2, 0, 1},
127 new byte[]{1, 0, 1},
128 new byte[]{-1, 0, -1}));
129
130
131 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
132 FuzzyRowFilter.satisfies(false,
133 new byte[]{1, 2, 1, 3, 3},
134 new byte[]{1, 2, 0, 3},
135 new byte[]{-1, -1, 0, -1}));
136
137 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
138 FuzzyRowFilter.satisfies(false,
139 new byte[]{1, 1, 1, 3, 0},
140 new byte[]{1, 2, 0, 3},
141 new byte[]{-1, -1, 0, -1}));
142
143 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
144 FuzzyRowFilter.satisfies(false,
145 new byte[]{1, 1, 1, 3, 0},
146 new byte[]{1, (byte) 245, 0, 3},
147 new byte[]{-1, -1, 0, -1}));
148
149 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
150 FuzzyRowFilter.satisfies(false,
151 new byte[]{1, 2, 1, 0, 1},
152 new byte[]{0, 1, 2},
153 new byte[]{0, -1, -1}));
154 }
155
156 @Test
157 public void testSatisfiesReverse() {
158 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
159 FuzzyRowFilter.satisfies(true,
160 new byte[]{1, (byte) -128, 1, 0, 1},
161 new byte[]{1, 0, 1},
162 new byte[]{-1, 0, -1}));
163
164 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
165 FuzzyRowFilter.satisfies(true,
166 new byte[]{1, (byte) -128, 2, 0, 1},
167 new byte[]{1, 0, 1},
168 new byte[]{-1, 0, -1}));
169
170 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
171 FuzzyRowFilter.satisfies(true,
172 new byte[]{2, 3, 1, 1, 1},
173 new byte[]{1, 0, 1},
174 new byte[]{-1, 0, -1}));
175
176 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
177 FuzzyRowFilter.satisfies(true,
178 new byte[]{1, 2, 1, 3, 3},
179 new byte[]{1, 2, 0, 3},
180 new byte[]{-1, -1, 0, -1}));
181
182 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
183 FuzzyRowFilter.satisfies(true,
184 new byte[]{1, (byte) 245, 1, 3, 0},
185 new byte[]{1, 1, 0, 3},
186 new byte[]{-1, -1, 0, -1}));
187
188 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
189 FuzzyRowFilter.satisfies(true,
190 new byte[]{1, 3, 1, 3, 0},
191 new byte[]{1, 2, 0, 3},
192 new byte[]{-1, -1, 0, -1}));
193
194 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
195 FuzzyRowFilter.satisfies(true,
196 new byte[]{2, 1, 1, 1, 0},
197 new byte[]{1, 2, 0, 3},
198 new byte[]{-1, -1, 0, -1}));
199
200 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
201 FuzzyRowFilter.satisfies(true,
202 new byte[]{1, 2, 1, 0, 1},
203 new byte[]{0, 1, 2},
204 new byte[]{0, -1, -1}));
205 }
206
207 @Test
208 public void testSatisfiesNoUnsafeReverse() {
209 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
210 FuzzyRowFilter.satisfiesNoUnsafe(true,
211 new byte[]{1, (byte) -128, 1, 0, 1},
212 0, 5,
213 new byte[]{1, 0, 1},
214 new byte[]{0, 1, 0}));
215
216 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
217 FuzzyRowFilter.satisfiesNoUnsafe(true,
218 new byte[]{1, (byte) -128, 2, 0, 1},
219 0, 5,
220 new byte[]{1, 0, 1},
221 new byte[]{0, 1, 0}));
222
223 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
224 FuzzyRowFilter.satisfiesNoUnsafe(true,
225 new byte[]{2, 3, 1, 1, 1},
226 0, 5,
227 new byte[]{1, 0, 1},
228 new byte[]{0, 1, 0}));
229
230 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
231 FuzzyRowFilter.satisfiesNoUnsafe(true,
232 new byte[]{1, 2, 1, 3, 3},
233 0, 5,
234 new byte[]{1, 2, 0, 3},
235 new byte[]{0, 0, 1, 0}));
236
237 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
238 FuzzyRowFilter.satisfiesNoUnsafe(true,
239 new byte[]{1, (byte) 245, 1, 3, 0},
240 0, 5,
241 new byte[]{1, 1, 0, 3},
242 new byte[]{0, 0, 1, 0}));
243
244 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
245 FuzzyRowFilter.satisfiesNoUnsafe(true,
246 new byte[]{1, 3, 1, 3, 0},
247 0, 5,
248 new byte[]{1, 2, 0, 3},
249 new byte[]{0, 0, 1, 0}));
250
251 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
252 FuzzyRowFilter.satisfiesNoUnsafe(true,
253 new byte[]{2, 1, 1, 1, 0},
254 0, 5,
255 new byte[]{1, 2, 0, 3},
256 new byte[]{0, 0, 1, 0}));
257
258 Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
259 FuzzyRowFilter.satisfiesNoUnsafe(true,
260 new byte[]{1, 2, 1, 0, 1},
261 0, 5,
262 new byte[]{0, 1, 2},
263 new byte[]{1, 0, 0}));
264 }
265 @Test
266 public void testGetNextForFuzzyRuleForward() {
267 assertNext(false,
268 new byte[]{0, 1, 2},
269 new byte[]{0, -1, -1},
270 new byte[]{1, 2, 1, 0, 1},
271 new byte[]{2, 1, 2});
272
273 assertNext(false,
274 new byte[]{0, 1, 2},
275 new byte[]{0, -1, -1},
276 new byte[]{1, 1, 2, 0, 1},
277 new byte[]{1, 1, 2, 0, 2});
278
279 assertNext(false,
280 new byte[]{0, 1, 0, 2, 0},
281 new byte[]{0, -1, 0, -1, 0},
282 new byte[]{1, 0, 2, 0, 1},
283 new byte[]{1, 1, 0, 2});
284
285 assertNext(false,
286 new byte[]{1, 0, 1},
287 new byte[]{-1, 0, -1},
288 new byte[]{1, (byte) 128, 2, 0, 1},
289 new byte[]{1, (byte) 129, 1});
290
291 assertNext(false,
292 new byte[]{0, 1, 0, 1},
293 new byte[]{0, -1, 0, -1},
294 new byte[]{5, 1, 0, 1},
295 new byte[]{5, 1, 1, 1});
296
297 assertNext(false,
298 new byte[]{0, 1, 0, 1},
299 new byte[]{0, -1, 0, -1},
300 new byte[]{5, 1, 0, 1, 1},
301 new byte[]{5, 1, 0, 1, 2});
302
303 assertNext(false,
304 new byte[]{0, 1, 0, 0},
305 new byte[]{0, -1, 0, 0},
306 new byte[]{5, 1, (byte) 255, 1},
307 new byte[]{5, 1, (byte) 255, 2});
308
309 assertNext(false,
310 new byte[]{0, 1, 0, 1},
311 new byte[]{0, -1, 0, -1},
312 new byte[]{5, 1, (byte) 255, 1},
313 new byte[]{6, 1, 0, 1});
314
315 assertNext(false,
316 new byte[]{0, 1, 0, 1},
317 new byte[]{0, -1, 0, -1},
318 new byte[]{5, 1, (byte) 255, 0},
319 new byte[]{5, 1, (byte) 255, 1});
320
321 assertNext(false,
322 new byte[]{5, 1, 1, 0},
323 new byte[]{-1, -1, 0, 0},
324 new byte[]{5, 1, (byte) 255, 1},
325 new byte[]{5, 1, (byte) 255, 2});
326
327 assertNext(false,
328 new byte[]{1, 1, 1, 1},
329 new byte[]{-1, -1, 0, 0},
330 new byte[]{1, 1, 2, 2},
331 new byte[]{1, 1, 2, 3});
332
333 assertNext(false,
334 new byte[]{1, 1, 1, 1},
335 new byte[]{-1, -1, 0, 0},
336 new byte[]{1, 1, 3, 2},
337 new byte[]{1, 1, 3, 3});
338
339 assertNext(false,
340 new byte[]{1, 1, 1, 1},
341 new byte[]{0, 0, 0, 0},
342 new byte[]{1, 1, 2, 3},
343 new byte[]{1, 1, 2, 4});
344
345 assertNext(false,
346 new byte[]{1, 1, 1, 1},
347 new byte[]{0, 0, 0, 0},
348 new byte[]{1, 1, 3, 2},
349 new byte[]{1, 1, 3, 3});
350
351 assertNext(false,
352 new byte[]{1, 1, 0, 0},
353 new byte[]{-1, -1, 0, 0},
354 new byte[]{0, 1, 3, 2},
355 new byte[]{1, 1});
356
357
358 Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
359 new byte[]{2, 3, 1, 1, 1},
360 new byte[]{1, 0, 1},
361 new byte[]{-1, 0, -1}));
362 Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
363 new byte[]{1, (byte) 245, 1, 3, 0},
364 new byte[]{1, 1, 0, 3},
365 new byte[]{-1, -1, 0, -1}));
366 Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
367 new byte[]{1, 3, 1, 3, 0},
368 new byte[]{1, 2, 0, 3},
369 new byte[]{-1, -1, 0, -1}));
370 Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
371 new byte[]{2, 1, 1, 1, 0},
372 new byte[]{1, 2, 0, 3},
373 new byte[]{-1, -1, 0, -1}));
374 }
375
376 @Test
377 public void testGetNextForFuzzyRuleReverse() {
378 assertNext(true,
379 new byte[]{0, 1, 2},
380 new byte[]{0, -1, -1},
381 new byte[]{1, 2, 1, 0, 1},
382
383 new byte[]{1, 1, 2, (byte) 0xFF, (byte) 0xFF});
384
385 assertNext(true,
386 new byte[]{0, 1, 0, 2, 0},
387 new byte[]{0, -1, 0, -1, 0},
388 new byte[]{1, 2, 1, 3, 1},
389
390 new byte[]{1, 1, 0, 2, 0});
391
392 assertNext(true,
393 new byte[]{1, 0, 1},
394 new byte[]{-1, 0, -1},
395 new byte[]{1, (byte) 128, 2, 0, 1},
396
397 new byte[]{1, (byte) 128, 1, (byte) 0xFF, (byte) 0xFF});
398
399 assertNext(true,
400 new byte[]{0, 1, 0, 1},
401 new byte[]{0, -1, 0, -1},
402 new byte[]{5, 1, 0, 2, 1},
403
404 new byte[]{5, 1, 0, 1, (byte) 0xFF});
405
406 assertNext(true,
407 new byte[]{0, 1, 0, 0},
408 new byte[]{0, -1, 0, 0},
409 new byte[]{5, 1, (byte) 255, 1},
410 new byte[]{5, 1, (byte) 255, 0});
411
412 assertNext(true,
413 new byte[]{0, 1, 0, 1},
414 new byte[]{0, -1, 0, -1},
415 new byte[]{5, 1, 0, 1},
416 new byte[]{4, 1, (byte) 255, 1});
417
418 assertNext(true,
419 new byte[]{0, 1, 0, 1},
420 new byte[]{0, -1, 0, -1},
421 new byte[]{5, 1, (byte) 255, 0},
422 new byte[]{5, 1, (byte) 254, 1});
423
424 assertNext(true,
425 new byte[]{1, 1, 0, 0},
426 new byte[]{-1, -1, 0, 0},
427 new byte[]{2, 1, 3, 2},
428
429 new byte[]{1, 1, 0, 0});
430
431 assertNext(true,
432 new byte[]{1, 0, 1},
433 new byte[]{-1, 0, -1},
434 new byte[]{2, 3, 1, 1, 1},
435
436 new byte[]{1, 0, 1, (byte) 0xFF, (byte) 0xFF});
437
438 assertNext(true,
439 new byte[]{1, 1, 0, 3},
440 new byte[]{-1, -1, 0, -1},
441 new byte[]{1, (byte) 245, 1, 3, 0},
442
443 new byte[]{1, 1, 0, 3, (byte) 0xFF});
444
445 assertNext(true,
446 new byte[]{1, 2, 0, 3},
447 new byte[]{-1, -1, 0, -1},
448 new byte[]{1, 3, 1, 3, 0},
449
450 new byte[]{1, 2, 0, 3, (byte) 0xFF});
451
452 assertNext(true,
453 new byte[]{1, 2, 0, 3},
454 new byte[]{-1, -1, 0, -1},
455 new byte[]{2, 1, 1, 1, 0},
456
457 new byte[]{1, 2, 0, 3, (byte) 0xFF});
458
459 assertNext(true,
460
461 new byte[]{1, 0, 1},
462 new byte[]{-1, 0, -1},
463 new byte[]{1, (byte) 128, 2},
464 new byte[]{1, (byte) 128, 1});
465
466 assertNext(true,
467
468 new byte[]{0, 1, 0, 1},
469 new byte[]{0, -1, 0, -1},
470 new byte[]{5, 1, 0, 2},
471 new byte[]{5, 1, 0, 1});
472
473 assertNext(true,
474
475 new byte[]{5, 1, 1, 0},
476 new byte[]{-1, -1, 0, 0},
477 new byte[]{5, 1, (byte) 0xFF, 1},
478 new byte[]{5, 1, (byte) 0xFF, 0});
479
480 assertNext(true,
481
482 new byte[]{1, 1, 1, 1},
483 new byte[]{-1, -1, 0, 0},
484 new byte[]{1, 1, 2, 2},
485 new byte[]{1, 1, 2, 1});
486
487 assertNext(true,
488
489 new byte[]{1, 1, 1, 1},
490 new byte[]{0, 0, 0, 0},
491 new byte[]{1, 1, 2, 3},
492 new byte[]{1, 1, 2, 2});
493
494 Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(true,
495 new byte[]{1, 1, 1, 3, 0},
496 new byte[]{1, 2, 0, 3},
497 new byte[]{-1, -1, 0, -1}));
498 }
499
500 private static void assertNext(boolean reverse, byte[] fuzzyRow, byte[] mask, byte[] current,
501 byte[] expected) {
502 KeyValue kv = KeyValueUtil.createFirstOnRow(current);
503 byte[] nextForFuzzyRule = FuzzyRowFilter.getNextForFuzzyRule(reverse, kv.getRowArray(),
504 kv.getRowOffset(), kv.getRowLength(), fuzzyRow, mask);
505 Assert.assertEquals(Bytes.toStringBinary(expected), Bytes.toStringBinary(nextForFuzzyRule));
506 }
507 }