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