001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020package org.apache.hadoop.hbase.filter; 021 022import java.io.IOException; 023import java.util.ArrayList; 024 025import org.apache.hadoop.hbase.Cell; 026import org.apache.hadoop.hbase.CompareOperator; 027import org.apache.yetus.audience.InterfaceAudience; 028import org.apache.hadoop.hbase.exceptions.DeserializationException; 029import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 030import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos; 031import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 032 033/** 034 * This filter is used to filter based on the key. It takes an operator 035 * (equal, greater, not equal, etc) and a byte [] comparator for the row, 036 * and column qualifier portions of a key. 037 * <p> 038 * This filter can be wrapped with {@link WhileMatchFilter} to add more control. 039 * <p> 040 * Multiple filters can be combined using {@link FilterList}. 041 * <p> 042 * If an already known row range needs to be scanned, 043 * use {@link org.apache.hadoop.hbase.CellScanner} start 044 * and stop rows directly rather than a filter. 045 */ 046@InterfaceAudience.Public 047public class RowFilter extends CompareFilter { 048 049 private boolean filterOutRow = false; 050 051 /** 052 * Constructor. 053 * @param rowCompareOp the compare op for row matching 054 * @param rowComparator the comparator for row matching 055 * @deprecated Since 2.0.0. Will remove in 3.0.0. Use 056 * {@link #RowFilter(CompareOperator, ByteArrayComparable)}} instead. 057 */ 058 @Deprecated 059 public RowFilter(final CompareOp rowCompareOp, 060 final ByteArrayComparable rowComparator) { 061 super(rowCompareOp, rowComparator); 062 } 063 064 /** 065 * Constructor. 066 * @param op the compare op for row matching 067 * @param rowComparator the comparator for row matching 068 */ 069 public RowFilter(final CompareOperator op, 070 final ByteArrayComparable rowComparator) { 071 super(op, rowComparator); 072 } 073 074 @Override 075 public void reset() { 076 this.filterOutRow = false; 077 } 078 079 @Deprecated 080 @Override 081 public ReturnCode filterKeyValue(final Cell c) { 082 return filterCell(c); 083 } 084 085 @Override 086 public ReturnCode filterCell(final Cell v) { 087 if(this.filterOutRow) { 088 return ReturnCode.NEXT_ROW; 089 } 090 return ReturnCode.INCLUDE; 091 } 092 093 @Override 094 public boolean filterRowKey(Cell firstRowCell) { 095 if (compareRow(getCompareOperator(), this.comparator, firstRowCell)) { 096 this.filterOutRow = true; 097 } 098 return this.filterOutRow; 099 } 100 101 @Override 102 public boolean filterRow() { 103 return this.filterOutRow; 104 } 105 106 public static Filter createFilterFromArguments(ArrayList<byte []> filterArguments) { 107 @SuppressWarnings("rawtypes") // for arguments 108 ArrayList arguments = CompareFilter.extractArguments(filterArguments); 109 CompareOperator compareOp = (CompareOperator)arguments.get(0); 110 ByteArrayComparable comparator = (ByteArrayComparable)arguments.get(1); 111 return new RowFilter(compareOp, comparator); 112 } 113 114 /** 115 * @return The filter serialized using pb 116 */ 117 @Override 118 public byte [] toByteArray() { 119 FilterProtos.RowFilter.Builder builder = 120 FilterProtos.RowFilter.newBuilder(); 121 builder.setCompareFilter(super.convert()); 122 return builder.build().toByteArray(); 123 } 124 125 /** 126 * @param pbBytes A pb serialized {@link RowFilter} instance 127 * @return An instance of {@link RowFilter} made from <code>bytes</code> 128 * @throws DeserializationException 129 * @see #toByteArray 130 */ 131 public static RowFilter parseFrom(final byte [] pbBytes) 132 throws DeserializationException { 133 FilterProtos.RowFilter proto; 134 try { 135 proto = FilterProtos.RowFilter.parseFrom(pbBytes); 136 } catch (InvalidProtocolBufferException e) { 137 throw new DeserializationException(e); 138 } 139 final CompareOperator valueCompareOp = 140 CompareOperator.valueOf(proto.getCompareFilter().getCompareOp().name()); 141 ByteArrayComparable valueComparator = null; 142 try { 143 if (proto.getCompareFilter().hasComparator()) { 144 valueComparator = ProtobufUtil.toComparator(proto.getCompareFilter().getComparator()); 145 } 146 } catch (IOException ioe) { 147 throw new DeserializationException(ioe); 148 } 149 return new RowFilter(valueCompareOp,valueComparator); 150 } 151 152 /** 153 * @return true if and only if the fields of the filter that are serialized 154 * are equal to the corresponding fields in other. Used for testing. 155 */ 156 @Override 157 boolean areSerializedFieldsEqual(Filter o) { 158 if (o == this) return true; 159 if (!(o instanceof RowFilter)) return false; 160 161 return super.areSerializedFieldsEqual(o); 162 } 163 164 @Override 165 public boolean equals(Object obj) { 166 return obj instanceof Filter && areSerializedFieldsEqual((Filter) obj); 167 } 168 169 @Override 170 public int hashCode() { 171 return super.hashCode(); 172 } 173}