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 */ 018 019package org.apache.hadoop.hbase.filter; 020 021import java.util.Set; 022import java.util.TreeSet; 023 024import org.apache.hadoop.hbase.Cell; 025import org.apache.hadoop.hbase.CellUtil; 026import org.apache.yetus.audience.InterfaceAudience; 027import org.apache.hadoop.hbase.exceptions.DeserializationException; 028import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos; 029import org.apache.hadoop.hbase.util.Bytes; 030 031import org.apache.hbase.thirdparty.com.google.protobuf.ByteString; 032import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 033import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations; 034 035/** 036 * The filter looks for the given columns in KeyValue. Once there is a match for 037 * any one of the columns, it returns ReturnCode.NEXT_ROW for remaining 038 * KeyValues in the row. 039 * <p> 040 * Note : It may emit KVs which do not have the given columns in them, if 041 * these KVs happen to occur before a KV which does have a match. Given this 042 * caveat, this filter is only useful for special cases 043 * like org.apache.hadoop.hbase.mapreduce.RowCounter. 044 * <p> 045 * @deprecated Deprecated in 2.0. See HBASE-13347 046 */ 047@InterfaceAudience.Public 048@Deprecated 049public class FirstKeyValueMatchingQualifiersFilter extends FirstKeyOnlyFilter { 050 051 private Set<byte []> qualifiers; 052 053 /** 054 * Constructor which takes a set of columns. As soon as first KeyValue 055 * matching any of these columns is found, filter moves to next row. 056 * 057 * @param qualifiers the set of columns to me matched. 058 */ 059 public FirstKeyValueMatchingQualifiersFilter(Set<byte []> qualifiers) { 060 this.qualifiers = qualifiers; 061 } 062 063 @Deprecated 064 @Override 065 public ReturnCode filterKeyValue(final Cell c) { 066 return filterCell(c); 067 } 068 069 @Override 070 public ReturnCode filterCell(final Cell c) { 071 if (hasFoundKV()) { 072 return ReturnCode.NEXT_ROW; 073 } else if (hasOneMatchingQualifier(c)) { 074 setFoundKV(true); 075 } 076 return ReturnCode.INCLUDE; 077 } 078 079 private boolean hasOneMatchingQualifier(Cell c) { 080 for (byte[] q : qualifiers) { 081 if (CellUtil.matchingQualifier(c, q)) { 082 return true; 083 } 084 } 085 return false; 086 } 087 088 /** 089 * @return The filter serialized using pb 090 */ 091 @Override 092 public byte [] toByteArray() { 093 FilterProtos.FirstKeyValueMatchingQualifiersFilter.Builder builder = 094 FilterProtos.FirstKeyValueMatchingQualifiersFilter.newBuilder(); 095 for (byte[] qualifier : qualifiers) { 096 if (qualifier != null) builder.addQualifiers(UnsafeByteOperations.unsafeWrap(qualifier)); 097 } 098 return builder.build().toByteArray(); 099 } 100 101 /** 102 * @param pbBytes A pb serialized {@link FirstKeyValueMatchingQualifiersFilter} instance 103 * @return An instance of {@link FirstKeyValueMatchingQualifiersFilter} made from <code>bytes</code> 104 * @throws DeserializationException 105 * @see #toByteArray 106 */ 107 public static FirstKeyValueMatchingQualifiersFilter parseFrom(final byte [] pbBytes) 108 throws DeserializationException { 109 FilterProtos.FirstKeyValueMatchingQualifiersFilter proto; 110 try { 111 proto = FilterProtos.FirstKeyValueMatchingQualifiersFilter.parseFrom(pbBytes); 112 } catch (InvalidProtocolBufferException e) { 113 throw new DeserializationException(e); 114 } 115 116 TreeSet<byte []> qualifiers = new TreeSet<>(Bytes.BYTES_COMPARATOR); 117 for (ByteString qualifier : proto.getQualifiersList()) { 118 qualifiers.add(qualifier.toByteArray()); 119 } 120 return new FirstKeyValueMatchingQualifiersFilter(qualifiers); 121 } 122 123 /** 124 * @param o the other filter to compare with 125 * @return true if and only if the fields of the filter that are serialized 126 * are equal to the corresponding fields in other. Used for testing. 127 */ 128 @Override 129 boolean areSerializedFieldsEqual(Filter o) { 130 if (o == this) return true; 131 if (!(o instanceof FirstKeyValueMatchingQualifiersFilter)) return false; 132 133 FirstKeyValueMatchingQualifiersFilter other = (FirstKeyValueMatchingQualifiersFilter)o; 134 return this.qualifiers.equals(other.qualifiers); 135 } 136}