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.math.BigDecimal;
023import java.nio.ByteBuffer;
024import java.util.Objects;
025
026import org.apache.hadoop.hbase.exceptions.DeserializationException;
027import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException;
028import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
029import org.apache.hadoop.hbase.shaded.protobuf.generated.ComparatorProtos;
030import org.apache.hadoop.hbase.util.ByteBufferUtils;
031import org.apache.hadoop.hbase.util.Bytes;
032
033import org.apache.yetus.audience.InterfaceAudience;
034
035/**
036 * A BigDecimal comparator which numerical compares against the specified byte array
037 */
038@InterfaceAudience.Public
039@SuppressWarnings("ComparableType") // Should this move to Comparator usage?
040public class BigDecimalComparator extends ByteArrayComparable {
041  private BigDecimal bigDecimal;
042
043  public BigDecimalComparator(BigDecimal value) {
044    super(Bytes.toBytes(value));
045    this.bigDecimal = value;
046  }
047
048  @Override
049  public boolean equals(Object obj) {
050    if (obj == null || !(obj instanceof BigDecimalComparator)) {
051      return false;
052    }
053    if (this == obj) {
054      return true;
055    }
056    BigDecimalComparator bdc = (BigDecimalComparator) obj;
057    return this.bigDecimal.equals(bdc.bigDecimal);
058  }
059
060  @Override
061  public int hashCode() {
062    return Objects.hash(this.bigDecimal);
063  }
064
065  @Override
066  public int compareTo(byte[] value, int offset, int length) {
067    BigDecimal that = Bytes.toBigDecimal(value, offset, length);
068    return this.bigDecimal.compareTo(that);
069  }
070
071  @Override
072  public int compareTo(ByteBuffer value, int offset, int length) {
073    BigDecimal that = ByteBufferUtils.toBigDecimal(value, offset, length);
074    return this.bigDecimal.compareTo(that);
075  }
076
077  /**
078   * @return The comparator serialized using pb
079   */
080  @Override
081  public byte[] toByteArray() {
082    ComparatorProtos.BigDecimalComparator.Builder builder =
083        ComparatorProtos.BigDecimalComparator.newBuilder();
084    builder.setComparable(ProtobufUtil.toByteArrayComparable(this.value));
085    return builder.build().toByteArray();
086  }
087
088  /**
089   * @param pbBytes A pb serialized {@link BigDecimalComparator} instance
090   * @return An instance of {@link BigDecimalComparator} made from <code>bytes</code>
091   * @throws DeserializationException A deserialization exception
092   * @see #toByteArray
093   */
094  public static BigDecimalComparator parseFrom(final byte[] pbBytes)
095      throws DeserializationException {
096    ComparatorProtos.BigDecimalComparator proto;
097    try {
098      proto = ComparatorProtos.BigDecimalComparator.parseFrom(pbBytes);
099    } catch (InvalidProtocolBufferException e) {
100      throw new DeserializationException(e);
101    }
102    return new BigDecimalComparator(Bytes.toBigDecimal(proto.getComparable().getValue()
103        .toByteArray()));
104  }
105
106  /**
107   * @param other the other comparator
108   * @return true if and only if the fields of the comparator that are serialized are equal to the
109   *         corresponding fields in other. Used for testing.
110   */
111  boolean areSerializedFieldsEqual(BigDecimalComparator other) {
112    if (other == this) {
113      return true;
114    }
115    return super.areSerializedFieldsEqual(other);
116  }
117}