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.Objects; 024 025import org.apache.hadoop.hbase.Cell; 026import org.apache.yetus.audience.InterfaceAudience; 027import org.apache.hadoop.hbase.exceptions.DeserializationException; 028import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 029import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos; 030import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 031 032/** 033 * A wrapper filter that returns true from {@link #filterAllRemaining()} as soon 034 * as the wrapped filters {@link Filter#filterRowKey(byte[], int, int)}, 035 * {@link Filter#filterCell(org.apache.hadoop.hbase.Cell)}, 036 * {@link org.apache.hadoop.hbase.filter.Filter#filterRow()} or 037 * {@link org.apache.hadoop.hbase.filter.Filter#filterAllRemaining()} methods 038 * returns true. 039 */ 040@InterfaceAudience.Public 041public class WhileMatchFilter extends FilterBase { 042 private boolean filterAllRemaining = false; 043 private Filter filter; 044 045 public WhileMatchFilter(Filter filter) { 046 this.filter = filter; 047 } 048 049 public Filter getFilter() { 050 return filter; 051 } 052 053 @Override 054 public void reset() throws IOException { 055 this.filter.reset(); 056 } 057 058 private void changeFAR(boolean value) { 059 filterAllRemaining = filterAllRemaining || value; 060 } 061 062 @Override 063 public boolean filterAllRemaining() throws IOException { 064 return this.filterAllRemaining || this.filter.filterAllRemaining(); 065 } 066 067 @Override 068 public boolean filterRowKey(byte[] buffer, int offset, int length) throws IOException { 069 boolean value = filter.filterRowKey(buffer, offset, length); 070 changeFAR(value); 071 return value; 072 } 073 074 @Override 075 public boolean filterRowKey(Cell cell) throws IOException { 076 if (filterAllRemaining()) return true; 077 boolean value = filter.filterRowKey(cell); 078 changeFAR(value); 079 return value; 080 } 081 082 @Deprecated 083 @Override 084 public ReturnCode filterKeyValue(final Cell c) throws IOException { 085 return filterCell(c); 086 } 087 088 @Override 089 public ReturnCode filterCell(final Cell c) throws IOException { 090 ReturnCode code = filter.filterCell(c); 091 changeFAR(code != ReturnCode.INCLUDE); 092 return code; 093 } 094 095 @Override 096 public Cell transformCell(Cell v) throws IOException { 097 return filter.transformCell(v); 098 } 099 100 @Override 101 public boolean filterRow() throws IOException { 102 boolean filterRow = this.filter.filterRow(); 103 changeFAR(filterRow); 104 return filterRow; 105 } 106 107 @Override 108 public boolean hasFilterRow() { 109 return true; 110 } 111 112 /** 113 * @return The filter serialized using pb 114 */ 115 @Override 116 public byte[] toByteArray() throws IOException { 117 FilterProtos.WhileMatchFilter.Builder builder = 118 FilterProtos.WhileMatchFilter.newBuilder(); 119 builder.setFilter(ProtobufUtil.toFilter(this.filter)); 120 return builder.build().toByteArray(); 121 } 122 123 /** 124 * @param pbBytes A pb serialized {@link WhileMatchFilter} instance 125 * @return An instance of {@link WhileMatchFilter} made from <code>bytes</code> 126 * @throws org.apache.hadoop.hbase.exceptions.DeserializationException 127 * @see #toByteArray 128 */ 129 public static WhileMatchFilter parseFrom(final byte [] pbBytes) 130 throws DeserializationException { 131 FilterProtos.WhileMatchFilter proto; 132 try { 133 proto = FilterProtos.WhileMatchFilter.parseFrom(pbBytes); 134 } catch (InvalidProtocolBufferException e) { 135 throw new DeserializationException(e); 136 } 137 try { 138 return new WhileMatchFilter(ProtobufUtil.toFilter(proto.getFilter())); 139 } catch (IOException ioe) { 140 throw new DeserializationException(ioe); 141 } 142 } 143 144 /** 145 * @param o the other filter to compare with 146 * @return true if and only if the fields of the filter that are serialized 147 * are equal to the corresponding fields in other. Used for testing. 148 */ 149 @Override 150 boolean areSerializedFieldsEqual(Filter o) { 151 if (o == this) return true; 152 if (!(o instanceof WhileMatchFilter)) return false; 153 154 WhileMatchFilter other = (WhileMatchFilter)o; 155 return getFilter().areSerializedFieldsEqual(other.getFilter()); 156 } 157 158 @Override 159 public boolean isFamilyEssential(byte[] name) throws IOException { 160 return filter.isFamilyEssential(name); 161 } 162 163 @Override 164 public String toString() { 165 return this.getClass().getSimpleName() + " " + this.filter.toString(); 166 } 167 168 @Override 169 public boolean equals(Object obj) { 170 return obj instanceof Filter && areSerializedFieldsEqual((Filter) obj); 171 } 172 173 @Override 174 public int hashCode() { 175 return Objects.hash(this.filter); 176 } 177}