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 com.google.protobuf.ByteString;
023import com.google.protobuf.InvalidProtocolBufferException;
024import org.apache.hadoop.hbase.exceptions.DeserializationException;
025import org.apache.hadoop.hbase.protobuf.generated.ComparatorProtos;
026import org.apache.hadoop.hbase.util.Bytes;
027import org.apache.yetus.audience.InterfaceAudience;
028
029/**
030 * A comparator which compares against a specified byte array, but only
031 * compares specific portion of the byte array. For the rest it is similar to
032 * {@link BinaryComparator}.
033 */
034@InterfaceAudience.Public
035@SuppressWarnings("ComparableType")
036public class BinaryComponentComparator extends ByteArrayComparable {
037  private int offset; //offset of component from beginning.
038
039  /**
040   * Constructor
041   *
042   * @param value  value of the component
043   * @param offset offset of the component from begining
044   */
045  public BinaryComponentComparator(byte[] value, int offset) {
046    super(value);
047    this.offset = offset;
048  }
049
050  @Override
051  public int compareTo(byte[] value) {
052    return compareTo(value, 0, value.length);
053  }
054
055  @Override
056  public int compareTo(byte[] value, int offset, int length) {
057    return Bytes.compareTo(this.value, 0, this.value.length, value, offset + this.offset,
058        this.value.length);
059  }
060
061  @Override
062  public boolean equals(Object other) {
063    if (other == this){
064      return true;
065    }
066    if (!(other instanceof BinaryComponentComparator)){
067      return false;
068    }
069    BinaryComponentComparator bcc = (BinaryComponentComparator)other;
070    return offset == bcc.offset &&
071         (compareTo(bcc.value) == 0);
072  }
073
074  @Override
075  public int hashCode() {
076    int result = super.hashCode();
077    result = 31 * result + offset;
078    return result;
079  }
080
081  /**
082   * @return The comparator serialized using pb
083   */
084  @Override
085  public byte[] toByteArray() {
086    ComparatorProtos.BinaryComponentComparator.Builder builder =
087        ComparatorProtos.BinaryComponentComparator.newBuilder();
088    builder.setValue(ByteString.copyFrom(this.value));
089    builder.setOffset(this.offset);
090    return builder.build().toByteArray();
091  }
092
093  /**
094   * @param pbBytes A pb serialized {@link BinaryComponentComparator} instance
095   * @return An instance of {@link BinaryComponentComparator} made from <code>bytes</code>
096   * @throws DeserializationException DeserializationException
097   * @see #toByteArray
098   */
099  public static BinaryComponentComparator parseFrom(final byte[] pbBytes)
100      throws DeserializationException {
101    ComparatorProtos.BinaryComponentComparator proto;
102    try {
103      proto = ComparatorProtos.BinaryComponentComparator.parseFrom(pbBytes);
104    } catch (InvalidProtocolBufferException e) {
105      throw new DeserializationException(e);
106    }
107    return new BinaryComponentComparator(proto.getValue().toByteArray(), proto.getOffset());
108  }
109
110  /**
111   * @param other paramemter to compare against
112   * @return true if and only if the fields of the comparator that are
113   *         serialized are equal to the corresponding fields in other. Used for testing.
114   */
115  @Override
116  boolean areSerializedFieldsEqual(ByteArrayComparable other) {
117    if (other == this){
118      return true;
119    }
120    if (!(other instanceof BinaryComponentComparator)){
121      return false;
122    }
123    return super.areSerializedFieldsEqual(other);
124  }
125}