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