View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.filter;
19  
20  import org.apache.hadoop.hbase.KeyValue;
21  import org.apache.hadoop.hbase.testclassification.SmallTests;
22  import org.apache.hadoop.hbase.util.Bytes;
23  import org.junit.Assert;
24  import org.junit.Test;
25  import org.junit.experimental.categories.Category;
26  
27  @Category(SmallTests.class)
28  public class TestFuzzyRowFilter {
29    @Test
30    public void testSatisfiesNoUnsafeForward() {
31  
32      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
33              FuzzyRowFilter.satisfiesNoUnsafe(false,
34                                       new byte[]{1, (byte) -128, 1, 0, 1},
35                                       0, 5,
36                                       new byte[]{1, 0, 1},
37                                       new byte[]{0, 1, 0}));
38  
39      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
40              FuzzyRowFilter.satisfiesNoUnsafe(false,
41                                       new byte[]{1, (byte) -128, 2, 0, 1},
42                                       0, 5,
43                                       new byte[]{1, 0, 1},
44                                       new byte[]{0, 1, 0}));
45  
46  
47      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
48              FuzzyRowFilter.satisfiesNoUnsafe(false,
49                                       new byte[]{1, 2, 1, 3, 3},
50                                       0, 5,
51                                       new byte[]{1, 2, 0, 3},
52                                       new byte[]{0, 0, 1, 0}));
53  
54      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
55              FuzzyRowFilter.satisfiesNoUnsafe(false,
56                                       new byte[]{1, 1, 1, 3, 0}, // row to check
57                                       0, 5,
58                                       new byte[]{1, 2, 0, 3}, // fuzzy row
59                                       new byte[]{0, 0, 1, 0})); // mask
60  
61      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
62              FuzzyRowFilter.satisfiesNoUnsafe(false,
63                                       new byte[]{1, 1, 1, 3, 0},
64                                       0, 5,
65                                       new byte[]{1, (byte) 245, 0, 3},
66                                       new byte[]{0, 0, 1, 0}));
67  
68      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
69              FuzzyRowFilter.satisfiesNoUnsafe(false,
70                                       new byte[]{1, 2, 1, 0, 1},
71                                       0, 5,
72                                       new byte[]{0, 1, 2},
73                                       new byte[]{1, 0, 0}));
74    }
75  
76    @Test
77    public void testSatisfiesForward() {
78  
79      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
80              FuzzyRowFilter.satisfies(false,
81                                       new byte[]{1, (byte) -128, 1, 0, 1},
82                                       new byte[]{1, 0, 1},
83                                       new byte[]{-1, 0, -1}));
84  
85      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
86              FuzzyRowFilter.satisfies(false,
87                                       new byte[]{1, (byte) -128, 2, 0, 1},
88                                       new byte[]{1, 0, 1},
89                                       new byte[]{-1, 0, -1}));
90  
91  
92      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
93              FuzzyRowFilter.satisfies(false,
94                                       new byte[]{1, 2, 1, 3, 3},
95                                       new byte[]{1, 2, 0, 3},
96                                       new byte[]{-1, -1, 0, -1}));
97  
98      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
99              FuzzyRowFilter.satisfies(false,
100                                      new byte[]{1, 1, 1, 3, 0}, // row to check
101                                      new byte[]{1, 2, 0, 3}, // fuzzy row
102                                      new byte[]{-1, -1, 0, -1})); // mask
103 
104     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
105             FuzzyRowFilter.satisfies(false,
106                                      new byte[]{1, 1, 1, 3, 0},
107                                      new byte[]{1, (byte) 245, 0, 3},
108                                      new byte[]{-1, -1, 0, -1}));
109 
110     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
111             FuzzyRowFilter.satisfies(false,
112                                      new byte[]{1, 2, 1, 0, 1},
113                                      new byte[]{0, 1, 2},
114                                      new byte[]{0, -1, -1}));
115   }
116 
117   @Test
118   public void testSatisfiesReverse() {
119     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
120       FuzzyRowFilter.satisfies(true,
121         new byte[]{1, (byte) -128, 1, 0, 1},
122         new byte[]{1, 0, 1},
123         new byte[]{-1, 0, -1}));
124 
125     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
126       FuzzyRowFilter.satisfies(true,
127         new byte[]{1, (byte) -128, 2, 0, 1},
128         new byte[]{1, 0, 1},
129         new byte[]{-1, 0, -1}));
130 
131     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
132       FuzzyRowFilter.satisfies(true,
133         new byte[]{2, 3, 1, 1, 1},
134         new byte[]{1, 0, 1},
135         new byte[]{-1, 0, -1}));
136 
137     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
138       FuzzyRowFilter.satisfies(true,
139         new byte[]{1, 2, 1, 3, 3},
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(true,
145         new byte[]{1, (byte) 245, 1, 3, 0},
146         new byte[]{1, 1, 0, 3},
147         new byte[]{-1, -1, 0, -1}));
148 
149     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
150       FuzzyRowFilter.satisfies(true,
151         new byte[]{1, 3, 1, 3, 0},
152         new byte[]{1, 2, 0, 3},
153         new byte[]{-1, -1, 0, -1}));
154 
155     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
156       FuzzyRowFilter.satisfies(true,
157         new byte[]{2, 1, 1, 1, 0},
158         new byte[]{1, 2, 0, 3},
159         new byte[]{-1, -1, 0, -1}));
160 
161     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
162       FuzzyRowFilter.satisfies(true,
163         new byte[]{1, 2, 1, 0, 1},
164         new byte[]{0, 1, 2},
165         new byte[]{0, -1, -1}));
166   }
167 
168   @Test
169   public void testSatisfiesNoUnsafeReverse() {
170     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
171       FuzzyRowFilter.satisfiesNoUnsafe(true,
172         new byte[]{1, (byte) -128, 1, 0, 1},
173         0, 5,
174         new byte[]{1, 0, 1},
175         new byte[]{0, 1, 0}));
176 
177     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
178       FuzzyRowFilter.satisfiesNoUnsafe(true,
179         new byte[]{1, (byte) -128, 2, 0, 1},
180         0, 5,
181         new byte[]{1, 0, 1},
182         new byte[]{0, 1, 0}));
183 
184     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
185       FuzzyRowFilter.satisfiesNoUnsafe(true,
186         new byte[]{2, 3, 1, 1, 1},
187         0, 5,
188         new byte[]{1, 0, 1},
189         new byte[]{0, 1, 0}));
190 
191     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
192       FuzzyRowFilter.satisfiesNoUnsafe(true,
193         new byte[]{1, 2, 1, 3, 3},
194         0, 5,
195         new byte[]{1, 2, 0, 3},
196         new byte[]{0, 0, 1, 0}));
197 
198     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
199       FuzzyRowFilter.satisfiesNoUnsafe(true,
200         new byte[]{1, (byte) 245, 1, 3, 0},
201         0, 5,
202         new byte[]{1, 1, 0, 3},
203         new byte[]{0, 0, 1, 0}));
204 
205     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
206       FuzzyRowFilter.satisfiesNoUnsafe(true,
207         new byte[]{1, 3, 1, 3, 0},
208         0, 5,
209         new byte[]{1, 2, 0, 3},
210         new byte[]{0, 0, 1, 0}));
211 
212     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
213       FuzzyRowFilter.satisfiesNoUnsafe(true,
214         new byte[]{2, 1, 1, 1, 0},
215         0, 5,
216         new byte[]{1, 2, 0, 3},
217         new byte[]{0, 0, 1, 0}));
218 
219     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
220       FuzzyRowFilter.satisfiesNoUnsafe(true,
221         new byte[]{1, 2, 1, 0, 1},
222         0, 5,
223         new byte[]{0, 1, 2},
224         new byte[]{1, 0, 0}));
225   }  
226   @Test
227   public void testGetNextForFuzzyRuleForward() {
228     assertNext(false,
229             new byte[]{0, 1, 2}, // fuzzy row
230             new byte[]{0, -1, -1}, // mask
231             new byte[]{1, 2, 1, 0, 1}, // current
232             new byte[]{2, 1, 2}); // expected next
233 
234     assertNext(false,
235             new byte[]{0, 1, 2}, // fuzzy row
236             new byte[]{0, -1, -1}, // mask
237             new byte[]{1, 1, 2, 0, 1}, // current
238             new byte[]{1, 1, 2, 0, 2}); // expected next
239 
240     assertNext(false,
241             new byte[]{0, 1, 0, 2, 0}, // fuzzy row
242             new byte[]{0, -1, 0, -1, 0}, // mask
243             new byte[]{1, 0, 2, 0, 1}, // current
244             new byte[]{1, 1, 0, 2}); // expected next
245 
246     assertNext(false,
247             new byte[]{1, 0, 1},
248             new byte[]{-1, 0, -1},
249             new byte[]{1, (byte) 128, 2, 0, 1},
250             new byte[]{1, (byte) 129, 1});
251 
252     assertNext(false,
253             new byte[]{0, 1, 0, 1},
254             new byte[]{0, -1, 0, -1},
255             new byte[]{5, 1, 0, 1},
256             new byte[]{5, 1, 1, 1});
257 
258     assertNext(false,
259             new byte[]{0, 1, 0, 1},
260             new byte[]{0, -1, 0, -1},
261             new byte[]{5, 1, 0, 1, 1},
262             new byte[]{5, 1, 0, 1, 2});
263 
264     assertNext(false,
265             new byte[]{0, 1, 0, 0}, // fuzzy row
266             new byte[]{0, -1, 0, 0}, // mask
267             new byte[]{5, 1, (byte) 255, 1}, // current
268             new byte[]{5, 1, (byte) 255, 2}); // expected next
269 
270     assertNext(false,
271             new byte[]{0, 1, 0, 1}, // fuzzy row
272             new byte[]{0, -1, 0, -1}, // mask
273             new byte[]{5, 1, (byte) 255, 1}, // current
274             new byte[]{6, 1, 0, 1}); // expected next
275 
276     assertNext(false,
277             new byte[]{0, 1, 0, 1}, // fuzzy row
278             new byte[]{0, -1, 0, -1}, // mask
279             new byte[]{5, 1, (byte) 255, 0}, // current
280             new byte[]{5, 1, (byte) 255, 1}); // expected next
281 
282     assertNext(false,
283             new byte[]{5, 1, 1, 0},
284             new byte[]{-1, -1, 0, 0},
285             new byte[]{5, 1, (byte) 255, 1},
286             new byte[]{5, 1, (byte) 255, 2});
287 
288     assertNext(false,
289             new byte[]{1, 1, 1, 1},
290             new byte[]{-1, -1, 0, 0},
291             new byte[]{1, 1, 2, 2},
292             new byte[]{1, 1, 2, 3});
293 
294     assertNext(false,
295             new byte[]{1, 1, 1, 1},
296             new byte[]{-1, -1, 0, 0},
297             new byte[]{1, 1, 3, 2},
298             new byte[]{1, 1, 3, 3});
299 
300     assertNext(false,
301             new byte[]{1, 1, 1, 1},
302             new byte[]{0, 0, 0, 0},
303             new byte[]{1, 1, 2, 3},
304             new byte[]{1, 1, 2, 4});
305 
306     assertNext(false,
307             new byte[]{1, 1, 1, 1},
308             new byte[]{0, 0, 0, 0},
309             new byte[]{1, 1, 3, 2},
310             new byte[]{1, 1, 3, 3});
311 
312     assertNext(false,
313             new byte[]{1, 1, 0, 0},
314             new byte[]{-1, -1, 0, 0},
315             new byte[]{0, 1, 3, 2},
316             new byte[]{1, 1});
317 
318     // No next for this one
319     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
320             new byte[]{2, 3, 1, 1, 1}, // row to check
321             new byte[]{1, 0, 1}, // fuzzy row
322             new byte[]{-1, 0, -1})); // mask
323     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
324             new byte[]{1, (byte) 245, 1, 3, 0},
325             new byte[]{1, 1, 0, 3},
326             new byte[]{-1, -1, 0, -1}));
327     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
328             new byte[]{1, 3, 1, 3, 0},
329             new byte[]{1, 2, 0, 3},
330             new byte[]{-1, -1, 0, -1}));
331     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
332             new byte[]{2, 1, 1, 1, 0},
333             new byte[]{1, 2, 0, 3},
334             new byte[]{-1, -1, 0, -1}));
335   }
336 
337   @Test
338   public void testGetNextForFuzzyRuleReverse() {
339     assertNext(true,
340       new byte[]{0, 1, 2}, // fuzzy row
341       new byte[]{0, -1, -1}, // mask
342       new byte[]{1, 2, 1, 0, 1}, // current
343       // TODO: should be {1, 1, 3} ?
344       new byte[]{1, 1, 2, (byte) 0xFF, (byte) 0xFF}); // expected next
345 
346     assertNext(true,
347       new byte[]{0, 1, 0, 2, 0}, // fuzzy row
348       new byte[]{0, -1, 0, -1, 0}, // mask
349       new byte[]{1, 2, 1, 3, 1}, // current
350       // TODO: should be {1, 1, 1, 3} ?
351       new byte[]{1, 1, 0, 2, 0}); // expected next
352 
353     assertNext(true,
354       new byte[]{1, 0, 1},
355       new byte[]{-1, 0, -1},
356       new byte[]{1, (byte) 128, 2, 0, 1},
357       // TODO: should be {1, (byte) 128, 2} ?
358       new byte[]{1, (byte) 128, 1, (byte) 0xFF, (byte) 0xFF});
359 
360     assertNext(true,
361       new byte[]{0, 1, 0, 1},
362       new byte[]{0, -1, 0, -1},
363       new byte[]{5, 1, 0, 2, 1},
364       // TODO: should be {5, 1, 0, 2} ?
365       new byte[]{5, 1, 0, 1, (byte) 0xFF});
366 
367     assertNext(true,
368       new byte[]{0, 1, 0, 0}, // fuzzy row
369       new byte[]{0, -1, 0, 0}, // mask
370       new byte[]{5, 1, (byte) 255, 1}, // current
371       new byte[]{5, 1, (byte) 255, 0}); // expected next
372 
373     assertNext(true,
374       new byte[]{0, 1, 0, 1}, // fuzzy row
375       new byte[]{0, -1, 0, -1}, // mask
376       new byte[]{5, 1, 0, 1}, // current
377       new byte[]{4, 1, (byte) 255, 1}); // expected next
378 
379     assertNext(true,
380       new byte[]{0, 1, 0, 1}, // fuzzy row
381       new byte[]{0, -1, 0, -1}, // mask
382       new byte[]{5, 1, (byte) 255, 0}, // current
383       new byte[]{5, 1, (byte) 254, 1}); // expected next
384 
385     assertNext(true,
386       new byte[]{1, 1, 0, 0},
387       new byte[]{-1, -1, 0, 0},
388       new byte[]{2, 1, 3, 2},
389       // TODO: should be {1, 0} ?
390       new byte[]{1, 1, 0, 0});
391 
392     assertNext(true,
393       new byte[]{1, 0, 1}, // fuzzy row
394       new byte[]{-1, 0, -1}, // mask
395       new byte[]{2, 3, 1, 1, 1}, // row to check
396       // TODO: should be {1, (byte) 0xFF, 2} ?
397       new byte[]{1, 0, 1, (byte) 0xFF, (byte) 0xFF});
398 
399     assertNext(true,
400       new byte[]{1, 1, 0, 3},
401       new byte[]{-1, -1, 0, -1},
402       new byte[]{1, (byte) 245, 1, 3, 0},
403       // TODO: should be {1, 1, (byte) 255, 4} ?
404       new byte[]{1, 1, 0, 3, (byte) 0xFF});
405 
406     assertNext(true,
407       new byte[]{1, 2, 0, 3},
408       new byte[]{-1, -1, 0, -1},
409       new byte[]{1, 3, 1, 3, 0},
410       // TODO: should be 1, 2, (byte) 255, 4 ?
411       new byte[]{1, 2, 0, 3, (byte) 0xFF});
412 
413     assertNext(true,
414       new byte[]{1, 2, 0, 3},
415       new byte[]{-1, -1, 0, -1},
416       new byte[]{2, 1, 1, 1, 0},
417       // TODO: should be {1, 2, (byte) 255, 4} ?
418       new byte[]{1, 2, 0, 3, (byte) 0xFF});
419 
420     assertNext(true,
421       // TODO: should be null?
422       new byte[]{1, 0, 1},
423       new byte[]{-1, 0, -1},
424       new byte[]{1, (byte) 128, 2},
425       new byte[]{1, (byte) 128, 1});
426 
427     assertNext(true,
428       // TODO: should be null?
429       new byte[]{0, 1, 0, 1},
430       new byte[]{0, -1, 0, -1},
431       new byte[]{5, 1, 0, 2},
432       new byte[]{5, 1, 0, 1});
433 
434     assertNext(true,
435       // TODO: should be null?
436       new byte[]{5, 1, 1, 0},
437       new byte[]{-1, -1, 0, 0},
438       new byte[]{5, 1, (byte) 0xFF, 1},
439       new byte[]{5, 1, (byte) 0xFF, 0});
440 
441     assertNext(true,
442       // TODO: should be null?
443       new byte[]{1, 1, 1, 1},
444       new byte[]{-1, -1, 0, 0},
445       new byte[]{1, 1, 2, 2},
446       new byte[]{1, 1, 2, 1});
447 
448     assertNext(true,
449       // TODO: should be null?
450       new byte[]{1, 1, 1, 1},
451       new byte[]{0, 0, 0, 0},
452       new byte[]{1, 1, 2, 3},
453       new byte[]{1, 1, 2, 2});
454 
455     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(true,
456       new byte[]{1, 1, 1, 3, 0},
457       new byte[]{1, 2, 0, 3},
458       new byte[]{-1, -1, 0, -1}));
459   }
460 
461   private static void assertNext(boolean reverse, byte[] fuzzyRow, byte[] mask, byte[] current,
462       byte[] expected) {
463     KeyValue kv = KeyValue.createFirstOnRow(current);
464     byte[] nextForFuzzyRule = FuzzyRowFilter.getNextForFuzzyRule(reverse, kv.getRowArray(),
465         kv.getRowOffset(), kv.getRowLength(), fuzzyRow, mask);
466     Assert.assertEquals(Bytes.toStringBinary(expected), Bytes.toStringBinary(nextForFuzzyRule));
467   }
468 }