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 org.apache.hadoop.hbase.Cell; 023import org.apache.hadoop.hbase.CompareOperator; 024import org.apache.hadoop.hbase.exceptions.DeserializationException; 025import org.apache.yetus.audience.InterfaceAudience; 026 027import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 028 029import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 030import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos; 031 032/** 033 * <p> 034 * This filter is used to filter based on the column family. It takes an operator (equal, greater, 035 * not equal, etc) and a byte [] comparator for the column family portion of a key. 036 * </p> 037 * <p> 038 * This filter can be wrapped with {@link org.apache.hadoop.hbase.filter.WhileMatchFilter} and 039 * {@link org.apache.hadoop.hbase.filter.SkipFilter} to add more control. 040 * </p> 041 * <p> 042 * Multiple filters can be combined using {@link org.apache.hadoop.hbase.filter.FilterList}. 043 * </p> 044 * If an already known column family is looked for, use 045 * {@link org.apache.hadoop.hbase.client.Get#addFamily(byte[])} directly rather than a filter. 046 */ 047@InterfaceAudience.Public 048public class FamilyFilter extends CompareFilter { 049 /** 050 * Constructor. 051 * @param op the compare op for column family matching 052 * @param familyComparator the comparator for column family matching 053 */ 054 public FamilyFilter(final CompareOperator op, final ByteArrayComparable familyComparator) { 055 super(op, familyComparator); 056 } 057 058 @Override 059 public ReturnCode filterCell(final Cell c) { 060 int familyLength = c.getFamilyLength(); 061 if (familyLength > 0) { 062 if (compareFamily(getCompareOperator(), this.comparator, c)) { 063 return ReturnCode.NEXT_ROW; 064 } 065 } 066 return ReturnCode.INCLUDE; 067 } 068 069 public static Filter createFilterFromArguments(ArrayList<byte[]> filterArguments) { 070 ArrayList<?> arguments = CompareFilter.extractArguments(filterArguments); 071 CompareOperator compareOp = (CompareOperator) arguments.get(0); 072 ByteArrayComparable comparator = (ByteArrayComparable) arguments.get(1); 073 return new FamilyFilter(compareOp, comparator); 074 } 075 076 /** Returns The filter serialized using pb */ 077 @Override 078 public byte[] toByteArray() { 079 FilterProtos.FamilyFilter.Builder builder = FilterProtos.FamilyFilter.newBuilder(); 080 builder.setCompareFilter(super.convert()); 081 return builder.build().toByteArray(); 082 } 083 084 /** 085 * Parse the serialized representation of {@link FamilyFilter} 086 * @param pbBytes A pb serialized {@link FamilyFilter} instance 087 * @return An instance of {@link FamilyFilter} made from <code>bytes</code> 088 * @throws DeserializationException if an error occurred 089 * @see #toByteArray 090 */ 091 public static FamilyFilter parseFrom(final byte[] pbBytes) throws DeserializationException { 092 FilterProtos.FamilyFilter proto; 093 try { 094 proto = FilterProtos.FamilyFilter.parseFrom(pbBytes); 095 } catch (InvalidProtocolBufferException e) { 096 throw new DeserializationException(e); 097 } 098 final CompareOperator valueCompareOp = 099 CompareOperator.valueOf(proto.getCompareFilter().getCompareOp().name()); 100 ByteArrayComparable valueComparator = null; 101 try { 102 if (proto.getCompareFilter().hasComparator()) { 103 valueComparator = ProtobufUtil.toComparator(proto.getCompareFilter().getComparator()); 104 } 105 } catch (IOException ioe) { 106 throw new DeserializationException(ioe); 107 } 108 return new FamilyFilter(valueCompareOp, valueComparator); 109 } 110 111 /** 112 * Returns true if and only if the fields of the filter that are serialized are equal to the 113 * corresponding fields in other. Used for testing. 114 */ 115 @Override 116 boolean areSerializedFieldsEqual(Filter o) { 117 if (o == this) { 118 return true; 119 } 120 if (!(o instanceof FamilyFilter)) { 121 return false; 122 } 123 FamilyFilter other = (FamilyFilter) o; 124 return super.areSerializedFieldsEqual(other); 125 } 126 127 @Override 128 public boolean equals(Object obj) { 129 return obj instanceof Filter && areSerializedFieldsEqual((Filter) obj); 130 } 131 132 @Override 133 public int hashCode() { 134 return super.hashCode(); 135 } 136}