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 java.io.IOException; 021import java.util.ArrayList; 022import java.util.Iterator; 023import java.util.List; 024import org.apache.hadoop.hbase.Cell; 025import org.apache.hadoop.hbase.CellUtil; 026import org.apache.hadoop.hbase.CompareOperator; 027import org.apache.hadoop.hbase.exceptions.DeserializationException; 028import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; 029import org.apache.yetus.audience.InterfaceAudience; 030 031import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 032 033import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 034import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos; 035 036/** 037 * A {@link Filter} that checks a single column value, but does not emit the tested column. This 038 * will enable a performance boost over {@link SingleColumnValueFilter}, if the tested column value 039 * is not actually needed as input (besides for the filtering itself). 040 */ 041@InterfaceAudience.Public 042public class SingleColumnValueExcludeFilter extends SingleColumnValueFilter { 043 044 /** 045 * Constructor for binary compare of the value of a single column. If the column is found and the 046 * condition passes, all columns of the row will be emitted; except for the tested column value. 047 * If the column is not found or the condition fails, the row will not be emitted. 048 * @param family name of column family 049 * @param qualifier name of column qualifier 050 * @param compareOp operator 051 * @param value value to compare column values against 052 * {@link #SingleColumnValueExcludeFilter(byte[], byte[], CompareOperator, byte[])} 053 */ 054 @Deprecated 055 public SingleColumnValueExcludeFilter(byte[] family, byte[] qualifier, CompareOp compareOp, 056 byte[] value) { 057 super(family, qualifier, compareOp, value); 058 } 059 060 /** 061 * Constructor for binary compare of the value of a single column. If the column is found and the 062 * condition passes, all columns of the row will be emitted; except for the tested column value. 063 * If the column is not found or the condition fails, the row will not be emitted. 064 * @param family name of column family 065 * @param qualifier name of column qualifier 066 * @param op operator 067 * @param value value to compare column values against 068 */ 069 public SingleColumnValueExcludeFilter(byte[] family, byte[] qualifier, CompareOperator op, 070 byte[] value) { 071 super(family, qualifier, op, value); 072 } 073 074 /** 075 * Constructor for binary compare of the value of a single column. If the column is found and the 076 * condition passes, all columns of the row will be emitted; except for the tested column value. 077 * If the condition fails, the row will not be emitted. 078 * <p> 079 * Use the filterIfColumnMissing flag to set whether the rest of the columns in a row will be 080 * emitted if the specified column to check is not found in the row. 081 * @param family name of column family 082 * @param qualifier name of column qualifier 083 * @param compareOp operator 084 * @param comparator Comparator to use. 085 * @deprecated Since 2.0.0. Will be removed in 3.0.0. Use 086 * {@link #SingleColumnValueExcludeFilter(byte[], byte[], CompareOperator, ByteArrayComparable)} 087 */ 088 @Deprecated 089 public SingleColumnValueExcludeFilter(byte[] family, byte[] qualifier, CompareOp compareOp, 090 ByteArrayComparable comparator) { 091 super(family, qualifier, compareOp, comparator); 092 } 093 094 /** 095 * Constructor for binary compare of the value of a single column. If the column is found and the 096 * condition passes, all columns of the row will be emitted; except for the tested column value. 097 * If the condition fails, the row will not be emitted. 098 * <p> 099 * Use the filterIfColumnMissing flag to set whether the rest of the columns in a row will be 100 * emitted if the specified column to check is not found in the row. 101 * @param family name of column family 102 * @param qualifier name of column qualifier 103 * @param op operator 104 * @param comparator Comparator to use. 105 */ 106 public SingleColumnValueExcludeFilter(byte[] family, byte[] qualifier, CompareOperator op, 107 ByteArrayComparable comparator) { 108 super(family, qualifier, op, comparator); 109 } 110 111 /** 112 * Constructor for protobuf deserialization only. nnnnnn * @deprecated Since 2.0.0. Will be 113 * removed in 3.0.0. Use 114 * {@link #SingleColumnValueExcludeFilter(byte[], byte[], CompareOperator, ByteArrayComparable, boolean, boolean)} 115 */ 116 @Deprecated 117 protected SingleColumnValueExcludeFilter(final byte[] family, final byte[] qualifier, 118 final CompareOp compareOp, ByteArrayComparable comparator, final boolean filterIfMissing, 119 final boolean latestVersionOnly) { 120 this(family, qualifier, CompareOperator.valueOf(compareOp.name()), comparator, filterIfMissing, 121 latestVersionOnly); 122 } 123 124 /** 125 * Constructor for protobuf deserialization only. nnnnnn 126 */ 127 protected SingleColumnValueExcludeFilter(final byte[] family, final byte[] qualifier, 128 final CompareOperator op, ByteArrayComparable comparator, final boolean filterIfMissing, 129 final boolean latestVersionOnly) { 130 super(family, qualifier, op, comparator, filterIfMissing, latestVersionOnly); 131 } 132 133 // We cleaned result row in FilterRow to be consistent with scanning process. 134 @Override 135 public boolean hasFilterRow() { 136 return true; 137 } 138 139 // Here we remove from row all key values from testing column 140 @Override 141 public void filterRowCells(List<Cell> kvs) { 142 Iterator<? extends Cell> it = kvs.iterator(); 143 while (it.hasNext()) { 144 // If the current column is actually the tested column, 145 // we will skip it instead. 146 if (CellUtil.matchingColumn(it.next(), this.columnFamily, this.columnQualifier)) { 147 it.remove(); 148 } 149 } 150 } 151 152 public static Filter createFilterFromArguments(ArrayList<byte[]> filterArguments) { 153 SingleColumnValueFilter tempFilter = 154 (SingleColumnValueFilter) SingleColumnValueFilter.createFilterFromArguments(filterArguments); 155 SingleColumnValueExcludeFilter filter = 156 new SingleColumnValueExcludeFilter(tempFilter.getFamily(), tempFilter.getQualifier(), 157 tempFilter.getOperator(), tempFilter.getComparator()); 158 159 if (filterArguments.size() == 6) { 160 filter.setFilterIfMissing(tempFilter.getFilterIfMissing()); 161 filter.setLatestVersionOnly(tempFilter.getLatestVersionOnly()); 162 } 163 return filter; 164 } 165 166 /** Returns The filter serialized using pb */ 167 @Override 168 public byte[] toByteArray() { 169 FilterProtos.SingleColumnValueExcludeFilter.Builder builder = 170 FilterProtos.SingleColumnValueExcludeFilter.newBuilder(); 171 builder.setSingleColumnValueFilter(super.convert()); 172 return builder.build().toByteArray(); 173 } 174 175 /** 176 * Parse a serialized representation of {@link SingleColumnValueExcludeFilter} 177 * @param pbBytes A pb serialized {@link SingleColumnValueExcludeFilter} instance 178 * @return An instance of {@link SingleColumnValueExcludeFilter} made from <code>bytes</code> 179 * @throws DeserializationException if an error occurred 180 * @see #toByteArray 181 */ 182 public static SingleColumnValueExcludeFilter parseFrom(final byte[] pbBytes) 183 throws DeserializationException { 184 FilterProtos.SingleColumnValueExcludeFilter proto; 185 try { 186 proto = FilterProtos.SingleColumnValueExcludeFilter.parseFrom(pbBytes); 187 } catch (InvalidProtocolBufferException e) { 188 throw new DeserializationException(e); 189 } 190 191 FilterProtos.SingleColumnValueFilter parentProto = proto.getSingleColumnValueFilter(); 192 final CompareOperator compareOp = CompareOperator.valueOf(parentProto.getCompareOp().name()); 193 final ByteArrayComparable comparator; 194 try { 195 comparator = ProtobufUtil.toComparator(parentProto.getComparator()); 196 } catch (IOException ioe) { 197 throw new DeserializationException(ioe); 198 } 199 200 return new SingleColumnValueExcludeFilter( 201 parentProto.hasColumnFamily() ? parentProto.getColumnFamily().toByteArray() : null, 202 parentProto.hasColumnQualifier() ? parentProto.getColumnQualifier().toByteArray() : null, 203 compareOp, comparator, parentProto.getFilterIfMissing(), parentProto.getLatestVersionOnly()); 204 } 205 206 /** 207 * Returns true if and only if the fields of the filter that are serialized are equal to the 208 * corresponding fields in other. Used for testing. 209 */ 210 @Override 211 boolean areSerializedFieldsEqual(Filter o) { 212 if (o == this) { 213 return true; 214 } 215 if (!(o instanceof SingleColumnValueExcludeFilter)) { 216 return false; 217 } 218 return super.areSerializedFieldsEqual(o); 219 } 220 221 @Override 222 public boolean equals(Object obj) { 223 return obj instanceof Filter && areSerializedFieldsEqual((Filter) obj); 224 } 225 226 @Override 227 public int hashCode() { 228 return super.hashCode(); 229 } 230}