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 = 063 Pattern.compile("QuIcK", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); 064 065 Filter basicFilter; 066 Filter nullFilter; 067 Filter substrFilter; 068 Filter regexFilter; 069 Filter regexPatternFilter; 070 071 @Before 072 public void setUp() throws Exception { 073 basicFilter = basicFilterNew(); 074 nullFilter = nullFilterNew(); 075 substrFilter = substrFilterNew(); 076 regexFilter = regexFilterNew(); 077 regexPatternFilter = regexFilterNew(QUICK_PATTERN); 078 } 079 080 private Filter basicFilterNew() { 081 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, 082 CompareOperator.GREATER_OR_EQUAL, VAL_2); 083 } 084 085 private Filter nullFilterNew() { 086 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.NOT_EQUAL, 087 new NullComparator()); 088 } 089 090 private Filter substrFilterNew() { 091 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.EQUAL, 092 new SubstringComparator(QUICK_SUBSTR)); 093 } 094 095 private Filter regexFilterNew() { 096 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.EQUAL, 097 new RegexStringComparator(QUICK_REGEX)); 098 } 099 100 private Filter regexFilterNew(Pattern pattern) { 101 return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOperator.EQUAL, 102 new RegexStringComparator(pattern.pattern(), pattern.flags())); 103 } 104 105 @Test 106 public void testLongComparator() throws IOException { 107 Filter filter = new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, 108 CompareOperator.GREATER, new LongComparator(100L)); 109 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, Bytes.toBytes(1L)); 110 assertTrue("less than", filter.filterCell(cell) == Filter.ReturnCode.NEXT_ROW); 111 filter.reset(); 112 byte[] buffer = cell.getBuffer(); 113 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 114 assertTrue("less than", filter.filterCell(c) == Filter.ReturnCode.NEXT_ROW); 115 filter.reset(); 116 117 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, Bytes.toBytes(100L)); 118 assertTrue("Equals 100", filter.filterCell(cell) == Filter.ReturnCode.NEXT_ROW); 119 filter.reset(); 120 buffer = cell.getBuffer(); 121 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 122 assertTrue("Equals 100", filter.filterCell(c) == Filter.ReturnCode.NEXT_ROW); 123 filter.reset(); 124 125 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, Bytes.toBytes(120L)); 126 assertTrue("include 120", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 127 filter.reset(); 128 buffer = cell.getBuffer(); 129 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 130 assertTrue("include 120", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 131 } 132 133 private void basicFilterTests(SingleColumnValueFilter filter) throws Exception { 134 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 135 assertTrue("basicFilter1", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 136 byte[] buffer = cell.getBuffer(); 137 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 138 assertTrue("basicFilter1", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 139 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_3); 140 assertTrue("basicFilter2", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 141 buffer = cell.getBuffer(); 142 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 143 assertTrue("basicFilter2", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 144 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_4); 145 assertTrue("basicFilter3", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 146 buffer = cell.getBuffer(); 147 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 148 assertTrue("basicFilter3", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 149 assertFalse("basicFilterNotNull", filter.filterRow()); 150 filter.reset(); 151 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1); 152 assertTrue("basicFilter4", filter.filterCell(cell) == Filter.ReturnCode.NEXT_ROW); 153 buffer = cell.getBuffer(); 154 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 155 assertTrue("basicFilter4", filter.filterCell(c) == Filter.ReturnCode.NEXT_ROW); 156 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 157 assertTrue("basicFilter4", filter.filterCell(cell) == Filter.ReturnCode.NEXT_ROW); 158 buffer = cell.getBuffer(); 159 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 160 assertTrue("basicFilter4", filter.filterCell(c) == Filter.ReturnCode.NEXT_ROW); 161 assertFalse("basicFilterAllRemaining", filter.filterAllRemaining()); 162 assertTrue("basicFilterNotNull", filter.filterRow()); 163 filter.reset(); 164 filter.setLatestVersionOnly(false); 165 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1); 166 assertTrue("basicFilter5", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 167 buffer = cell.getBuffer(); 168 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 169 assertTrue("basicFilter5", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 170 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2); 171 assertTrue("basicFilter5", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 172 buffer = cell.getBuffer(); 173 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 174 assertTrue("basicFilter5", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 175 assertFalse("basicFilterNotNull", filter.filterRow()); 176 } 177 178 private void nullFilterTests(Filter filter) throws Exception { 179 ((SingleColumnValueFilter) filter).setFilterIfMissing(true); 180 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 181 assertTrue("null1", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 182 byte[] buffer = cell.getBuffer(); 183 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 184 assertTrue("null1", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 185 assertFalse("null1FilterRow", filter.filterRow()); 186 filter.reset(); 187 cell = new KeyValue(ROW, COLUMN_FAMILY, Bytes.toBytes("qual2"), FULLSTRING_2); 188 assertTrue("null2", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 189 buffer = cell.getBuffer(); 190 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 191 assertTrue("null2", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 192 assertTrue("null2FilterRow", filter.filterRow()); 193 } 194 195 private void substrFilterTests(Filter filter) throws Exception { 196 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 197 assertTrue("substrTrue", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 198 byte[] buffer = cell.getBuffer(); 199 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 200 assertTrue("substrTrue", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 201 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_2); 202 assertTrue("substrFalse", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 203 buffer = cell.getBuffer(); 204 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 205 assertTrue("substrFalse", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 206 assertFalse("substrFilterAllRemaining", filter.filterAllRemaining()); 207 assertFalse("substrFilterNotNull", filter.filterRow()); 208 } 209 210 private void regexFilterTests(Filter filter) throws Exception { 211 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 212 assertTrue("regexTrue", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 213 byte[] buffer = cell.getBuffer(); 214 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 215 assertTrue("regexTrue", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 216 cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_2); 217 assertTrue("regexFalse", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 218 buffer = cell.getBuffer(); 219 c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 220 assertTrue("regexFalse", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 221 assertFalse("regexFilterAllRemaining", filter.filterAllRemaining()); 222 assertFalse("regexFilterNotNull", filter.filterRow()); 223 } 224 225 private void regexPatternFilterTests(Filter filter) throws Exception { 226 KeyValue cell = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1); 227 assertTrue("regexTrue", filter.filterCell(cell) == Filter.ReturnCode.INCLUDE); 228 byte[] buffer = cell.getBuffer(); 229 Cell c = new ByteBufferKeyValue(ByteBuffer.wrap(buffer), 0, buffer.length); 230 assertTrue("regexTrue", filter.filterCell(c) == Filter.ReturnCode.INCLUDE); 231 assertFalse("regexFilterAllRemaining", filter.filterAllRemaining()); 232 assertFalse("regexFilterNotNull", filter.filterRow()); 233 } 234 235 private Filter serializationTest(Filter filter) throws Exception { 236 // Decompose filter to bytes. 237 byte[] buffer = filter.toByteArray(); 238 239 // Recompose filter. 240 Filter newFilter = SingleColumnValueFilter.parseFrom(buffer); 241 return newFilter; 242 } 243 244 /** 245 * Tests identification of the stop row 246 */ 247 @Test 248 public void testStop() throws Exception { 249 basicFilterTests((SingleColumnValueFilter) basicFilter); 250 nullFilterTests(nullFilter); 251 substrFilterTests(substrFilter); 252 regexFilterTests(regexFilter); 253 regexPatternFilterTests(regexPatternFilter); 254 } 255 256 /** 257 * Tests serialization 258 */ 259 @Test 260 public void testSerialization() throws Exception { 261 Filter newFilter = serializationTest(basicFilter); 262 basicFilterTests((SingleColumnValueFilter) newFilter); 263 newFilter = serializationTest(nullFilter); 264 nullFilterTests(newFilter); 265 newFilter = serializationTest(substrFilter); 266 substrFilterTests(newFilter); 267 newFilter = serializationTest(regexFilter); 268 regexFilterTests(newFilter); 269 newFilter = serializationTest(regexPatternFilter); 270 regexPatternFilterTests(newFilter); 271 } 272 273}