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 column value. It takes an
035 * operator (equal, greater, not equal, etc) and a byte [] comparator for the
036 * cell value.
037 * <p>
038 * This filter can be wrapped with {@link WhileMatchFilter} and {@link SkipFilter}
039 * to add more control.
040 * <p>
041 * Multiple filters can be combined using {@link FilterList}.
042 * <p>
043 * To test the value of a single qualifier when scanning multiple qualifiers,
044 * use {@link SingleColumnValueFilter}.
045 */
046@InterfaceAudience.Public
047public class ValueFilter extends CompareFilter {
048
049  /**
050   * Constructor.
051   * @param valueCompareOp the compare op for value matching
052   * @param valueComparator the comparator for value matching
053   * @deprecated Since 2.0.0. Will be removed in 3.0.0.
054   * Use {@link #ValueFilter(CompareOperator, ByteArrayComparable)}
055   */
056  public ValueFilter(final CompareOp valueCompareOp,
057      final ByteArrayComparable valueComparator) {
058    super(valueCompareOp, valueComparator);
059  }
060
061  /**
062   * Constructor.
063   * @param valueCompareOp the compare op for value matching
064   * @param valueComparator the comparator for value matching
065   */
066  public ValueFilter(final CompareOperator valueCompareOp,
067                     final ByteArrayComparable valueComparator) {
068    super(valueCompareOp, valueComparator);
069  }
070
071  @Deprecated
072  @Override
073  public ReturnCode filterKeyValue(final Cell c) {
074    return filterCell(c);
075  }
076
077  @Override
078  public ReturnCode filterCell(final Cell c) {
079    if (compareValue(getCompareOperator(), this.comparator, c)) {
080      return ReturnCode.SKIP;
081    }
082    return ReturnCode.INCLUDE;
083  }
084
085  public static Filter createFilterFromArguments(ArrayList<byte []> filterArguments) {
086    @SuppressWarnings("rawtypes")  // for arguments
087    ArrayList arguments = CompareFilter.extractArguments(filterArguments);
088    CompareOperator compareOp = (CompareOperator)arguments.get(0);
089    ByteArrayComparable comparator = (ByteArrayComparable)arguments.get(1);
090    return new ValueFilter(compareOp, comparator);
091  }
092
093  /**
094   * @return The filter serialized using pb
095   */
096  @Override
097  public byte [] toByteArray() {
098    FilterProtos.ValueFilter.Builder builder =
099      FilterProtos.ValueFilter.newBuilder();
100    builder.setCompareFilter(super.convert());
101    return builder.build().toByteArray();
102  }
103
104  /**
105   * @param pbBytes A pb serialized {@link ValueFilter} instance
106   * @return An instance of {@link ValueFilter} made from <code>bytes</code>
107   * @throws DeserializationException
108   * @see #toByteArray
109   */
110  public static ValueFilter parseFrom(final byte [] pbBytes)
111  throws DeserializationException {
112    FilterProtos.ValueFilter proto;
113    try {
114      proto = FilterProtos.ValueFilter.parseFrom(pbBytes);
115    } catch (InvalidProtocolBufferException e) {
116      throw new DeserializationException(e);
117    }
118    final CompareOperator valueCompareOp =
119      CompareOperator.valueOf(proto.getCompareFilter().getCompareOp().name());
120    ByteArrayComparable valueComparator = null;
121    try {
122      if (proto.getCompareFilter().hasComparator()) {
123        valueComparator = ProtobufUtil.toComparator(proto.getCompareFilter().getComparator());
124      }
125    } catch (IOException ioe) {
126      throw new DeserializationException(ioe);
127    }
128    return new ValueFilter(valueCompareOp,valueComparator);
129  }
130
131  /**
132   * @return true if and only if the fields of the filter that are serialized
133   * are equal to the corresponding fields in other.  Used for testing.
134   */
135  @Override
136  boolean areSerializedFieldsEqual(Filter o) {
137    if (o == this) return true;
138    if (!(o instanceof ValueFilter)) return false;
139
140    return super.areSerializedFieldsEqual(o);
141  }
142
143  @Override
144  public boolean equals(Object obj) {
145    return obj instanceof Filter && areSerializedFieldsEqual((Filter) obj);
146  }
147
148  @Override
149  public int hashCode() {
150    return super.hashCode();
151  }
152}