001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.filter; 019 020import static org.junit.Assert.assertFalse; 021import static org.junit.Assert.assertTrue; 022 023import java.io.IOException; 024import java.nio.ByteBuffer; 025import java.util.regex.Pattern; 026import org.apache.hadoop.hbase.ByteBufferKeyValue; 027import org.apache.hadoop.hbase.Cell; 028import org.apache.hadoop.hbase.CompareOperator; 029import org.apache.hadoop.hbase.HBaseClassTestRule; 030import org.apache.hadoop.hbase.KeyValue; 031import org.apache.hadoop.hbase.testclassification.FilterTests; 032import org.apache.hadoop.hbase.testclassification.SmallTests; 033import org.apache.hadoop.hbase.util.Bytes; 034import org.junit.Before; 035import org.junit.ClassRule; 036import org.junit.Test; 037import org.junit.experimental.categories.Category; 038 039/** 040 * Tests the value filter 041 */ 042@Category({FilterTests.class, SmallTests.class}) 043public class TestSingleColumnValueFilter { 044 045 @ClassRule 046 public static final HBaseClassTestRule CLASS_RULE = 047 HBaseClassTestRule.forClass(TestSingleColumnValueFilter.class); 048 049 private static final byte[] ROW = Bytes.toBytes("test"); 050 private static final byte[] COLUMN_FAMILY = Bytes.toBytes("test"); 051 private static final byte [] COLUMN_QUALIFIER = Bytes.toBytes("foo"); 052 private static final byte[] VAL_1 = Bytes.toBytes("a"); 053 private static final byte[] VAL_2 = Bytes.toBytes("ab"); 054 private static final byte[] VAL_3 = Bytes.toBytes("abc"); 055 private static final byte[] VAL_4 = Bytes.toBytes("abcd"); 056 private static final byte[] FULLSTRING_1 = 057 Bytes.toBytes("The quick brown fox jumps over the lazy dog."); 058 private static final byte[] FULLSTRING_2 = 059 Bytes.toBytes("The slow grey fox trips over the lazy dog."); 060 private static final String QUICK_SUBSTR = "quick"; 061 private static final String QUICK_REGEX = ".+quick.+"; 062 private static final Pattern QUICK_PATTERN = Pattern.compile("QuIcK", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); 063 064 Filter basicFilter; 065 Filter nullFilter; 066 Filter substrFilter; 067 Filter regexFilter; 068 Filter regexPatternFilter; 069 070 @Before 071 public void setUp() throws Exception { 072 basicFilter = basicFilterNew(); 073 nullFilter = nullFilterNew(); 074 substrFilter = substrFilterNew(); 075 regexFilter = regexFilterNew(); 076 regexPatternFilter = regexFilterNew(QUICK_PATTERN); 077 } 078 079 private Filter basicFilterNew() { 080 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, 081 CompareOperator.GREATER_OR_EQUAL, VAL_2); 082 } 083 084 private Filter nullFilterNew() { 085 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.NOT_EQUAL, 086 new NullComparator()); 087 } 088 089 private Filter substrFilterNew() { 090 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, 091 CompareOperator.EQUAL, 092 new SubstringComparator(QUICK_SUBSTR)); 093 } 094 095 private Filter regexFilterNew() { 096 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, 097 CompareOperator.EQUAL, 098 new RegexStringComparator(QUICK_REGEX)); 099 } 100 101 private Filter regexFilterNew(Pattern pattern) { 102 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, 103 CompareOperator.EQUAL, 104 new RegexStringComparator(pattern.pattern(), pattern.flags())); 105 } 106 107 @Test 108 public void testLongComparator() throws IOException { 109 Filter filter = new SingleColumnValueFilter(COLUMN_FAMILY, 110 COLUMN_QUALIFIER, CompareOperator.GREATER, new LongComparator(100L)); 111 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, 112 Bytes.toBytes(1L)); 113 assertTrue("less than", filter.filterCell(cell) == Filter.ReturnCode.NEXT_ROW); 114 filter.reset(); 115 byte[] buffer = cell.getBuffer(); 116 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 117 assertTrue("less than", filter.filterCell(c) == Filter.ReturnCode.NEXT_ROW); 118 filter.reset(); 119 120 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, 121 Bytes.toBytes(100L)); 122 assertTrue("Equals 100", filter.filterCell(cell) == Filter.ReturnCode.NEXT_ROW); 123 filter.reset(); 124 buffer = cell.getBuffer(); 125 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 126 assertTrue("Equals 100", filter.filterCell(c) == Filter.ReturnCode.NEXT_ROW); 127 filter.reset(); 128 129 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, 130 Bytes.toBytes(120L)); 131 assertTrue("include 120", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 132 filter.reset(); 133 buffer = cell.getBuffer(); 134 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 135 assertTrue("include 120", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 136 } 137 138 private void basicFilterTests(SingleColumnValueFilter filter) 139 throws Exception { 140 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 141 assertTrue("basicFilter1", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 142 byte[] buffer = cell.getBuffer(); 143 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 144 assertTrue("basicFilter1", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 145 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_3); 146 assertTrue("basicFilter2", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 147 buffer = cell.getBuffer(); 148 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 149 assertTrue("basicFilter2", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 150 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_4); 151 assertTrue("basicFilter3", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 152 buffer = cell.getBuffer(); 153 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 154 assertTrue("basicFilter3", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 155 assertFalse("basicFilterNotNull", filter.filterRow()); 156 filter.reset(); 157 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1); 158 assertTrue("basicFilter4", filter.filterCell(cell) == Filter.ReturnCode.NEXT_ROW); 159 buffer = cell.getBuffer(); 160 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 161 assertTrue("basicFilter4", filter.filterCell(c) == Filter.ReturnCode.NEXT_ROW); 162 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 163 assertTrue("basicFilter4", filter.filterCell(cell) == Filter.ReturnCode.NEXT_ROW); 164 buffer = cell.getBuffer(); 165 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 166 assertTrue("basicFilter4", filter.filterCell(c) == Filter.ReturnCode.NEXT_ROW); 167 assertFalse("basicFilterAllRemaining", filter.filterAllRemaining()); 168 assertTrue("basicFilterNotNull", filter.filterRow()); 169 filter.reset(); 170 filter.setLatestVersionOnly(false); 171 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1); 172 assertTrue("basicFilter5", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 173 buffer = cell.getBuffer(); 174 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 175 assertTrue("basicFilter5", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 176 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 177 assertTrue("basicFilter5", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 178 buffer = cell.getBuffer(); 179 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 180 assertTrue("basicFilter5", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 181 assertFalse("basicFilterNotNull", filter.filterRow()); 182 } 183 184 private void nullFilterTests(Filter filter) throws Exception { 185 ((SingleColumnValueFilter) filter).setFilterIfMissing(true); 186 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 187 assertTrue("null1", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 188 byte[] buffer = cell.getBuffer(); 189 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 190 assertTrue("null1", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 191 assertFalse("null1FilterRow", filter.filterRow()); 192 filter.reset(); 193 cell = new KeyValue(ROW, COLUMN_FAMILY, Bytes.toBytes("qual2"), FULLSTRING_2); 194 assertTrue("null2", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 195 buffer = cell.getBuffer(); 196 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 197 assertTrue("null2", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 198 assertTrue("null2FilterRow", filter.filterRow()); 199 } 200 201 private void substrFilterTests(Filter filter) 202 throws Exception { 203 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, 204 FULLSTRING_1); 205 assertTrue("substrTrue", 206 filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 207 byte[] buffer = cell.getBuffer(); 208 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 209 assertTrue("substrTrue", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 210 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, 211 FULLSTRING_2); 212 assertTrue("substrFalse", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 213 buffer = cell.getBuffer(); 214 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 215 assertTrue("substrFalse", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 216 assertFalse("substrFilterAllRemaining", filter.filterAllRemaining()); 217 assertFalse("substrFilterNotNull", filter.filterRow()); 218 } 219 220 private void regexFilterTests(Filter filter) 221 throws Exception { 222 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, 223 FULLSTRING_1); 224 assertTrue("regexTrue", 225 filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 226 byte[] buffer = cell.getBuffer(); 227 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 228 assertTrue("regexTrue", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 229 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, 230 FULLSTRING_2); 231 assertTrue("regexFalse", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 232 buffer = cell.getBuffer(); 233 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 234 assertTrue("regexFalse", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 235 assertFalse("regexFilterAllRemaining", filter.filterAllRemaining()); 236 assertFalse("regexFilterNotNull", filter.filterRow()); 237 } 238 239 private void regexPatternFilterTests(Filter filter) 240 throws Exception { 241 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, 242 FULLSTRING_1); 243 assertTrue("regexTrue", 244 filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 245 byte[] buffer = cell.getBuffer(); 246 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 247 assertTrue("regexTrue", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 248 assertFalse("regexFilterAllRemaining", filter.filterAllRemaining()); 249 assertFalse("regexFilterNotNull", filter.filterRow()); 250 } 251 252 private Filter serializationTest(Filter filter) 253 throws Exception { 254 // Decompose filter to bytes. 255 byte[] buffer = filter.toByteArray(); 256 257 // Recompose filter. 258 Filter newFilter = SingleColumnValueFilter.parseFrom(buffer); 259 return newFilter; 260 } 261 262 /** 263 * Tests identification of the stop row 264 * @throws Exception 265 */ 266 @Test 267 public void testStop() throws Exception { 268 basicFilterTests((SingleColumnValueFilter) basicFilter); 269 nullFilterTests(nullFilter); 270 substrFilterTests(substrFilter); 271 regexFilterTests(regexFilter); 272 regexPatternFilterTests(regexPatternFilter); 273 } 274 275 /** 276 * Tests serialization 277 * @throws Exception 278 */ 279 @Test 280 public void testSerialization() throws Exception { 281 Filter newFilter = serializationTest(basicFilter); 282 basicFilterTests((SingleColumnValueFilter)newFilter); 283 newFilter = serializationTest(nullFilter); 284 nullFilterTests(newFilter); 285 newFilter = serializationTest(substrFilter); 286 substrFilterTests(newFilter); 287 newFilter = serializationTest(regexFilter); 288 regexFilterTests(newFilter); 289 newFilter = serializationTest(regexPatternFilter); 290 regexPatternFilterTests(newFilter); 291 } 292 293} 294