View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.filter;
20  
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.io.IOException;
25  import java.util.regex.Pattern;
26  
27  import org.apache.hadoop.hbase.KeyValue;
28  import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
29  import org.apache.hadoop.hbase.testclassification.SmallTests;
30  import org.apache.hadoop.hbase.util.Bytes;
31  import org.junit.Before;
32  import org.junit.Test;
33  import org.junit.experimental.categories.Category;
34  
35  /**
36   * Tests the value filter
37   */
38  @Category(SmallTests.class)
39  public class TestSingleColumnValueFilter {
40    private static final byte[] ROW = Bytes.toBytes("test");
41    private static final byte[] COLUMN_FAMILY = Bytes.toBytes("test");
42    private static final byte [] COLUMN_QUALIFIER = Bytes.toBytes("foo");
43    private static final byte[] VAL_1 = Bytes.toBytes("a");
44    private static final byte[] VAL_2 = Bytes.toBytes("ab");
45    private static final byte[] VAL_3 = Bytes.toBytes("abc");
46    private static final byte[] VAL_4 = Bytes.toBytes("abcd");
47    private static final byte[] FULLSTRING_1 =
48      Bytes.toBytes("The quick brown fox jumps over the lazy dog.");
49    private static final byte[] FULLSTRING_2 =
50      Bytes.toBytes("The slow grey fox trips over the lazy dog.");
51    private static final String QUICK_SUBSTR = "quick";
52    private static final String QUICK_REGEX = ".+quick.+";
53    private static final Pattern QUICK_PATTERN = Pattern.compile("QuIcK", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
54  
55    Filter basicFilter;
56    Filter nullFilter;
57    Filter substrFilter;
58    Filter regexFilter;
59    Filter regexPatternFilter;
60  
61    @Before
62    public void setUp() throws Exception {
63      basicFilter = basicFilterNew();
64      nullFilter = nullFilterNew();
65      substrFilter = substrFilterNew();
66      regexFilter = regexFilterNew();
67      regexPatternFilter = regexFilterNew(QUICK_PATTERN);
68    }
69  
70    private Filter basicFilterNew() {
71      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
72        CompareOp.GREATER_OR_EQUAL, VAL_2);
73    }
74  
75    private Filter nullFilterNew() {
76      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOp.NOT_EQUAL,
77          new NullComparator());
78    }
79  
80    private Filter substrFilterNew() {
81      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
82        CompareOp.EQUAL,
83        new SubstringComparator(QUICK_SUBSTR));
84    }
85  
86    private Filter regexFilterNew() {
87      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
88        CompareOp.EQUAL,
89        new RegexStringComparator(QUICK_REGEX));
90    }
91  
92    private Filter regexFilterNew(Pattern pattern) {
93      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
94          CompareOp.EQUAL,
95          new RegexStringComparator(pattern.pattern(), pattern.flags()));
96    }
97  
98    @Test
99    public void testLongComparator() throws IOException {
100     Filter filter = new SingleColumnValueFilter(COLUMN_FAMILY,
101         COLUMN_QUALIFIER, CompareOp.GREATER, new LongComparator(100L));
102     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
103       Bytes.toBytes(1L));
104     assertTrue("less than", filter.filterKeyValue(kv) == Filter.ReturnCode.NEXT_ROW);
105     filter.reset();
106 
107     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
108       Bytes.toBytes(100L));
109     assertTrue("Equals 100", filter.filterKeyValue(kv) == Filter.ReturnCode.NEXT_ROW);
110     filter.reset();
111 
112     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
113       Bytes.toBytes(120L));
114     assertTrue("include 120", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
115   }
116 
117   private void basicFilterTests(SingleColumnValueFilter filter)
118       throws Exception {
119     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
120     assertTrue("basicFilter1", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
121     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_3);
122     assertTrue("basicFilter2", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
123     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_4);
124     assertTrue("basicFilter3", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
125     assertFalse("basicFilterNotNull", filter.filterRow());
126     filter.reset();
127     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1);
128     assertTrue("basicFilter4", filter.filterKeyValue(kv) == Filter.ReturnCode.NEXT_ROW);
129     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
130     assertTrue("basicFilter4", filter.filterKeyValue(kv) == Filter.ReturnCode.NEXT_ROW);
131     assertFalse("basicFilterAllRemaining", filter.filterAllRemaining());
132     assertTrue("basicFilterNotNull", filter.filterRow());
133     filter.reset();
134     filter.setLatestVersionOnly(false);
135     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1);
136     assertTrue("basicFilter5", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
137     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
138     assertTrue("basicFilter5", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
139     assertFalse("basicFilterNotNull", filter.filterRow());
140   }
141 
142   private void nullFilterTests(Filter filter) throws Exception {
143     ((SingleColumnValueFilter) filter).setFilterIfMissing(true);
144     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1);
145     assertTrue("null1", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
146     assertFalse("null1FilterRow", filter.filterRow());
147     filter.reset();
148     kv = new KeyValue(ROW, COLUMN_FAMILY, Bytes.toBytes("qual2"), FULLSTRING_2);
149     assertTrue("null2", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
150     assertTrue("null2FilterRow", filter.filterRow());
151   }
152 
153   private void substrFilterTests(Filter filter)
154       throws Exception {
155     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
156       FULLSTRING_1);
157     assertTrue("substrTrue",
158       filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
159     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
160       FULLSTRING_2);
161     assertTrue("substrFalse", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
162     assertFalse("substrFilterAllRemaining", filter.filterAllRemaining());
163     assertFalse("substrFilterNotNull", filter.filterRow());
164   }
165 
166   private void regexFilterTests(Filter filter)
167       throws Exception {
168     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
169       FULLSTRING_1);
170     assertTrue("regexTrue",
171       filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
172     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
173       FULLSTRING_2);
174     assertTrue("regexFalse", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
175     assertFalse("regexFilterAllRemaining", filter.filterAllRemaining());
176     assertFalse("regexFilterNotNull", filter.filterRow());
177   }
178 
179   private void regexPatternFilterTests(Filter filter)
180       throws Exception {
181     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
182       FULLSTRING_1);
183     assertTrue("regexTrue",
184       filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
185     assertFalse("regexFilterAllRemaining", filter.filterAllRemaining());
186     assertFalse("regexFilterNotNull", filter.filterRow());
187   }
188 
189   private Filter serializationTest(Filter filter)
190       throws Exception {
191     // Decompose filter to bytes.
192     byte[] buffer = filter.toByteArray();
193 
194     // Recompose filter.
195     Filter newFilter = SingleColumnValueFilter.parseFrom(buffer);
196     return newFilter;
197   }
198 
199   /**
200    * Tests identification of the stop row
201    * @throws Exception
202    */
203   @Test
204   public void testStop() throws Exception {
205     basicFilterTests((SingleColumnValueFilter) basicFilter);
206     nullFilterTests(nullFilter);
207     substrFilterTests(substrFilter);
208     regexFilterTests(regexFilter);
209     regexPatternFilterTests(regexPatternFilter);
210   }
211 
212   /**
213    * Tests serialization
214    * @throws Exception
215    */
216   @Test
217   public void testSerialization() throws Exception {
218     Filter newFilter = serializationTest(basicFilter);
219     basicFilterTests((SingleColumnValueFilter)newFilter);
220     newFilter = serializationTest(nullFilter);
221     nullFilterTests(newFilter);
222     newFilter = serializationTest(substrFilter);
223     substrFilterTests(newFilter);
224     newFilter = serializationTest(regexFilter);
225     regexFilterTests(newFilter);
226     newFilter = serializationTest(regexPatternFilter);
227     regexPatternFilterTests(newFilter);
228   }
229 
230 }
231