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}