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.testclassification.SmallTests;
21  import org.apache.hadoop.hbase.util.Bytes;
22  import org.junit.Assert;
23  import org.junit.Test;
24  import org.junit.experimental.categories.Category;
25  
26  @Category(SmallTests.class)
27  public class TestFuzzyRowFilter {
28    @Test
29    public void testSatisfiesForward() {
30      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
31              FuzzyRowFilter.satisfies(false,
32                                       new byte[]{1, (byte) -128, 0, 0, 1}, // row to check
33                                       new byte[]{1, 0, 1}, // fuzzy row
34                                       new byte[]{0, 1, 0})); // mask
35  
36      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
37              FuzzyRowFilter.satisfies(false,
38                                       new byte[]{1, (byte) -128, 1, 0, 1},
39                                       new byte[]{1, 0, 1},
40                                       new byte[]{0, 1, 0}));
41  
42      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
43              FuzzyRowFilter.satisfies(false,
44                                       new byte[]{1, (byte) -128, 2, 0, 1},
45                                       new byte[]{1, 0, 1},
46                                       new byte[]{0, 1, 0}));
47  
48      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NO_NEXT,
49              FuzzyRowFilter.satisfies(false,
50                                       new byte[]{2, 3, 1, 1, 1},
51                                       new byte[]{1, 0, 1},
52                                       new byte[]{0, 1, 0}));
53  
54      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
55              FuzzyRowFilter.satisfies(false,
56                                       new byte[]{1, 2, 1, 3, 3},
57                                       new byte[]{1, 2, 0, 3},
58                                       new byte[]{0, 0, 1, 0}));
59  
60      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
61              FuzzyRowFilter.satisfies(false,
62                                       new byte[]{1, 1, 1, 3, 0}, // row to check
63                                       new byte[]{1, 2, 0, 3}, // fuzzy row
64                                       new byte[]{0, 0, 1, 0})); // mask
65  
66      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
67              FuzzyRowFilter.satisfies(false,
68                                       new byte[]{1, 1, 1, 3, 0},
69                                       new byte[]{1, (byte) 245, 0, 3},
70                                       new byte[]{0, 0, 1, 0}));
71  
72      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NO_NEXT,
73              FuzzyRowFilter.satisfies(false,
74                                       new byte[]{1, (byte) 245, 1, 3, 0},
75                                       new byte[]{1, 1, 0, 3},
76                                       new byte[]{0, 0, 1, 0}));
77  
78      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NO_NEXT,
79              FuzzyRowFilter.satisfies(false,
80                                       new byte[]{1, 3, 1, 3, 0},
81                                       new byte[]{1, 2, 0, 3},
82                                       new byte[]{0, 0, 1, 0}));
83  
84      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NO_NEXT,
85              FuzzyRowFilter.satisfies(false,
86                                       new byte[]{2, 1, 1, 1, 0},
87                                       new byte[]{1, 2, 0, 3},
88                                       new byte[]{0, 0, 1, 0}));
89  
90      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
91              FuzzyRowFilter.satisfies(false,
92                                       new byte[]{1, 2, 1, 0, 1},
93                                       new byte[]{0, 1, 2},
94                                       new byte[]{1, 0, 0}));
95    }
96  
97    @Test
98    public void testSatisfiesReverse() {
99      Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NO_NEXT,
100       FuzzyRowFilter.satisfies(true,
101         new byte[]{1, (byte) -128, 0, 0, 1}, // row to check
102         new byte[]{1, 0, 1}, // fuzzy row
103         new byte[]{0, 1, 0})); // mask
104 
105     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
106       FuzzyRowFilter.satisfies(true,
107         new byte[]{1, (byte) -128, 1, 0, 1},
108         new byte[]{1, 0, 1},
109         new byte[]{0, 1, 0}));
110 
111     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
112       FuzzyRowFilter.satisfies(true,
113         new byte[]{1, (byte) -128, 2, 0, 1},
114         new byte[]{1, 0, 1},
115         new byte[]{0, 1, 0}));
116 
117     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
118       FuzzyRowFilter.satisfies(true,
119         new byte[]{2, 3, 1, 1, 1},
120         new byte[]{1, 0, 1},
121         new byte[]{0, 1, 0}));
122 
123     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES,
124       FuzzyRowFilter.satisfies(true,
125         new byte[]{1, 2, 1, 3, 3},
126         new byte[]{1, 2, 0, 3},
127         new byte[]{0, 0, 1, 0}));
128 
129     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NO_NEXT,
130       FuzzyRowFilter.satisfies(true,
131         new byte[]{1, 1, 1, 3, 0}, // row to check
132         new byte[]{1, 2, 0, 3}, // fuzzy row
133         new byte[]{0, 0, 1, 0})); // mask
134 
135     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NO_NEXT,
136       FuzzyRowFilter.satisfies(true,
137         new byte[]{1, 1, 1, 3, 0},
138         new byte[]{1, (byte) 245, 0, 3},
139         new byte[]{0, 0, 1, 0}));
140 
141     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
142       FuzzyRowFilter.satisfies(true,
143         new byte[]{1, (byte) 245, 1, 3, 0},
144         new byte[]{1, 1, 0, 3},
145         new byte[]{0, 0, 1, 0}));
146 
147     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
148       FuzzyRowFilter.satisfies(true,
149         new byte[]{1, 3, 1, 3, 0},
150         new byte[]{1, 2, 0, 3},
151         new byte[]{0, 0, 1, 0}));
152 
153     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
154       FuzzyRowFilter.satisfies(true,
155         new byte[]{2, 1, 1, 1, 0},
156         new byte[]{1, 2, 0, 3},
157         new byte[]{0, 0, 1, 0}));
158 
159     Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS,
160       FuzzyRowFilter.satisfies(true,
161         new byte[]{1, 2, 1, 0, 1},
162         new byte[]{0, 1, 2},
163         new byte[]{1, 0, 0}));
164   }
165 
166   @Test
167   public void testGetNextForFuzzyRuleForward() {
168     assertNext(false,
169             new byte[]{0, 1, 2}, // fuzzy row
170             new byte[]{1, 0, 0}, // mask
171             new byte[]{1, 2, 1, 0, 1}, // current
172             new byte[]{2, 1, 2, 0, 0}); // expected next
173 
174     assertNext(false,
175             new byte[]{0, 1, 2}, // fuzzy row
176             new byte[]{1, 0, 0}, // mask
177             new byte[]{1, 1, 2, 0, 1}, // current
178             new byte[]{1, 1, 2, 0, 2}); // expected next
179 
180     assertNext(false,
181             new byte[]{0, 1, 0, 2, 0}, // fuzzy row
182             new byte[]{1, 0, 1, 0, 1}, // mask
183             new byte[]{1, 0, 2, 0, 1}, // current
184             new byte[]{1, 1, 0, 2, 0}); // expected next
185 
186     assertNext(false,
187             new byte[]{1, 0, 1},
188             new byte[]{0, 1, 0},
189             new byte[]{1, (byte) 128, 2, 0, 1},
190             new byte[]{1, (byte) 129, 1, 0, 0});
191 
192     assertNext(false,
193             new byte[]{0, 1, 0, 1},
194             new byte[]{1, 0, 1, 0},
195             new byte[]{5, 1, 0, 1},
196             new byte[]{5, 1, 1, 1});
197 
198     assertNext(false,
199             new byte[]{0, 1, 0, 1},
200             new byte[]{1, 0, 1, 0},
201             new byte[]{5, 1, 0, 1, 1},
202             new byte[]{5, 1, 0, 1, 2});
203 
204     assertNext(false,
205             new byte[]{0, 1, 0, 0}, // fuzzy row
206             new byte[]{1, 0, 1, 1}, // mask
207             new byte[]{5, 1, (byte) 255, 1}, // current
208             new byte[]{5, 1, (byte) 255, 2}); // expected next
209 
210     assertNext(false,
211             new byte[]{0, 1, 0, 1}, // fuzzy row
212             new byte[]{1, 0, 1, 0}, // mask
213             new byte[]{5, 1, (byte) 255, 1}, // current
214             new byte[]{6, 1, 0, 1}); // expected next
215 
216     assertNext(false,
217             new byte[]{0, 1, 0, 1}, // fuzzy row
218             new byte[]{1, 0, 1, 0}, // mask
219             new byte[]{5, 1, (byte) 255, 0}, // current
220             new byte[]{5, 1, (byte) 255, 1}); // expected next
221 
222     assertNext(false,
223             new byte[]{5, 1, 1, 0},
224             new byte[]{0, 0, 1, 1},
225             new byte[]{5, 1, (byte) 255, 1},
226             new byte[]{5, 1, (byte) 255, 2});
227 
228     assertNext(false,
229             new byte[]{1, 1, 1, 1},
230             new byte[]{0, 0, 1, 1},
231             new byte[]{1, 1, 2, 2},
232             new byte[]{1, 1, 2, 3});
233 
234     assertNext(false,
235             new byte[]{1, 1, 1, 1},
236             new byte[]{0, 0, 1, 1},
237             new byte[]{1, 1, 3, 2},
238             new byte[]{1, 1, 3, 3});
239 
240     assertNext(false,
241             new byte[]{1, 1, 1, 1},
242             new byte[]{1, 1, 1, 1},
243             new byte[]{1, 1, 2, 3},
244             new byte[]{1, 1, 2, 4});
245 
246     assertNext(false,
247             new byte[]{1, 1, 1, 1},
248             new byte[]{1, 1, 1, 1},
249             new byte[]{1, 1, 3, 2},
250             new byte[]{1, 1, 3, 3});
251 
252     assertNext(false,
253             new byte[]{1, 1, 0, 0},
254             new byte[]{0, 0, 1, 1},
255             new byte[]{0, 1, 3, 2},
256             new byte[]{1, 1, 0, 0});
257 
258     // No next for this one
259     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
260             new byte[]{2, 3, 1, 1, 1}, // row to check
261             new byte[]{1, 0, 1}, // fuzzy row
262             new byte[]{0, 1, 0})); // mask
263     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
264             new byte[]{1, (byte) 245, 1, 3, 0},
265             new byte[]{1, 1, 0, 3},
266             new byte[]{0, 0, 1, 0}));
267     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
268             new byte[]{1, 3, 1, 3, 0},
269             new byte[]{1, 2, 0, 3},
270             new byte[]{0, 0, 1, 0}));
271     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(
272             new byte[]{2, 1, 1, 1, 0},
273             new byte[]{1, 2, 0, 3},
274             new byte[]{0, 0, 1, 0}));
275   }
276 
277   @Test
278   public void testGetNextForFuzzyRuleReverse() {
279     assertNext(true,
280       new byte[]{0, 1, 2}, // fuzzy row
281       new byte[]{1, 0, 0}, // mask
282       new byte[]{1, 2, 1, 0, 1}, // current
283       // TODO: should be {1, 1, 3} ?
284       new byte[]{1, 1, 2, (byte) 0xFF, (byte) 0xFF}); // expected next
285 
286     assertNext(true,
287       new byte[]{0, 1, 0, 2, 0}, // fuzzy row
288       new byte[]{1, 0, 1, 0, 1}, // mask
289       new byte[]{1, 2, 1, 3, 1}, // current
290       // TODO: should be {1, 1, 1, 3} ?
291       new byte[]{1, 1, 0, 2, 0}); // expected next
292 
293     assertNext(true,
294       new byte[]{1, 0, 1},
295       new byte[]{0, 1, 0},
296       new byte[]{1, (byte) 128, 2, 0, 1},
297       // TODO: should be {1, (byte) 128, 2} ?
298       new byte[]{1, (byte) 128, 1, (byte) 0xFF, (byte) 0xFF});
299 
300     assertNext(true,
301       new byte[]{0, 1, 0, 1},
302       new byte[]{1, 0, 1, 0},
303       new byte[]{5, 1, 0, 2, 1},
304       // TODO: should be {5, 1, 0, 2} ?
305       new byte[]{5, 1, 0, 1, (byte) 0xFF});
306 
307     assertNext(true,
308       new byte[]{0, 1, 0, 0}, // fuzzy row
309       new byte[]{1, 0, 1, 1}, // mask
310       new byte[]{5, 1, (byte) 255, 1}, // current
311       new byte[]{5, 1, (byte) 255, 0}); // expected next
312 
313     assertNext(true,
314       new byte[]{0, 1, 0, 1}, // fuzzy row
315       new byte[]{1, 0, 1, 0}, // mask
316       new byte[]{5, 1, 0, 1}, // current
317       new byte[]{4, 1, (byte) 255, 1}); // expected next
318 
319     assertNext(true,
320       new byte[]{0, 1, 0, 1}, // fuzzy row
321       new byte[]{1, 0, 1, 0}, // mask
322       new byte[]{5, 1, (byte) 255, 0}, // current
323       new byte[]{5, 1, (byte) 254, 1}); // expected next
324 
325     assertNext(true,
326       new byte[]{1, 1, 0, 0},
327       new byte[]{0, 0, 1, 1},
328       new byte[]{2, 1, 3, 2},
329       // TODO: should be {1, 0} ?
330       new byte[]{1, 1, 0, 0});
331 
332     assertNext(true,
333       new byte[]{1, 0, 1}, // fuzzy row
334       new byte[]{0, 1, 0}, // mask
335       new byte[]{2, 3, 1, 1, 1}, // row to check
336       // TODO: should be {1, (byte) 0xFF, 2} ?
337       new byte[]{1, 0, 1, (byte) 0xFF, (byte) 0xFF});
338 
339     assertNext(true,
340       new byte[]{1, 1, 0, 3},
341       new byte[]{0, 0, 1, 0},
342       new byte[]{1, (byte) 245, 1, 3, 0},
343       // TODO: should be {1, 1, (byte) 255, 4} ?
344       new byte[]{1, 1, 0, 3, (byte) 0xFF});
345 
346     assertNext(true,
347       new byte[]{1, 2, 0, 3},
348       new byte[]{0, 0, 1, 0},
349       new byte[]{1, 3, 1, 3, 0},
350       // TODO: should be 1, 2, (byte) 255, 4 ?
351       new byte[]{1, 2, 0, 3, (byte) 0xFF});
352 
353     assertNext(true,
354       new byte[]{1, 2, 0, 3},
355       new byte[]{0, 0, 1, 0},
356       new byte[]{2, 1, 1, 1, 0},
357       // TODO: should be {1, 2, (byte) 255, 4} ?
358       new byte[]{1, 2, 0, 3, (byte) 0xFF});
359 
360     assertNext(true,
361       // TODO: should be null?
362       new byte[]{1, 0, 1},
363       new byte[]{0, 1, 0},
364       new byte[]{1, (byte) 128, 2},
365       new byte[]{1, (byte) 128, 1});
366 
367     assertNext(true,
368       // TODO: should be null?
369       new byte[]{0, 1, 0, 1},
370       new byte[]{1, 0, 1, 0},
371       new byte[]{5, 1, 0, 2},
372       new byte[]{5, 1, 0, 1});
373 
374     assertNext(true,
375       // TODO: should be null?
376       new byte[]{5, 1, 1, 0},
377       new byte[]{0, 0, 1, 1},
378       new byte[]{5, 1, (byte) 0xFF, 1},
379       new byte[]{5, 1, (byte) 0xFF, 0});
380 
381     assertNext(true,
382       // TODO: should be null?
383       new byte[]{1, 1, 1, 1},
384       new byte[]{0, 0, 1, 1},
385       new byte[]{1, 1, 2, 2},
386       new byte[]{1, 1, 2, 1});
387 
388     assertNext(true,
389       // TODO: should be null?
390       new byte[]{1, 1, 1, 1},
391       new byte[]{1, 1, 1, 1},
392       new byte[]{1, 1, 2, 3},
393       new byte[]{1, 1, 2, 2});
394 
395     Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(true,
396       new byte[]{1, 1, 1, 3, 0},
397       new byte[]{1, 2, 0, 3},
398       new byte[]{0, 0, 1, 0}));
399   }
400 
401   private static void assertNext(boolean reverse, byte[] fuzzyRow, byte[] mask, byte[] current,
402       byte[] expected) {
403     byte[] nextForFuzzyRule = FuzzyRowFilter.getNextForFuzzyRule(reverse, current, fuzzyRow, mask);
404     Assert.assertEquals(Bytes.toStringBinary(expected), Bytes.toStringBinary(nextForFuzzyRule));
405   }
406 }