You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ja...@apache.org on 2017/11/07 07:08:44 UTC

hbase git commit: HBASE-19103 Add BigDecimalComparator for filter

Repository: hbase
Updated Branches:
  refs/heads/master d1b6d8c90 -> 0356674cd


HBASE-19103 Add BigDecimalComparator for filter

Signed-off-by: Jan Hentschel <ja...@ultratendency.com>


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/0356674c
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/0356674c
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/0356674c

Branch: refs/heads/master
Commit: 0356674cd1f59b10ab515058efa948e556fbc79e
Parents: d1b6d8c
Author: QilinCao <ca...@zte.com.cn>
Authored: Mon Oct 30 20:55:11 2017 +0800
Committer: Jan Hentschel <ja...@ultratendency.com>
Committed: Tue Nov 7 08:07:58 2017 +0100

----------------------------------------------------------------------
 .../hbase/filter/BigDecimalComparator.java      | 116 ++++++++++++++++++
 .../src/main/protobuf/Comparator.proto          |   4 +
 .../src/main/protobuf/Comparator.proto          |   4 +
 .../hbase/filter/TestBigDecimalComparator.java  | 118 +++++++++++++++++++
 .../filter/TestComparatorSerialization.java     |   9 ++
 .../hadoop/hbase/regionserver/TestHRegion.java  |  43 +++++++
 6 files changed, 294 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/0356674c/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/BigDecimalComparator.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/BigDecimalComparator.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/BigDecimalComparator.java
new file mode 100644
index 0000000..5da366f
--- /dev/null
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/BigDecimalComparator.java
@@ -0,0 +1,116 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.filter;
+
+import java.math.BigDecimal;
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+import org.apache.hadoop.hbase.exceptions.DeserializationException;
+import org.apache.hadoop.hbase.shaded.com.google.protobuf.InvalidProtocolBufferException;
+import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.ComparatorProtos;
+import org.apache.hadoop.hbase.util.ByteBufferUtils;
+import org.apache.hadoop.hbase.util.Bytes;
+
+import org.apache.yetus.audience.InterfaceAudience;
+
+/**
+ * A BigDecimal comparator which numerical compares against the specified byte array
+ */
+@InterfaceAudience.Public
+public class BigDecimalComparator extends ByteArrayComparable {
+  private BigDecimal bigDecimal;
+
+  public BigDecimalComparator(BigDecimal value) {
+    super(Bytes.toBytes(value));
+    this.bigDecimal = value;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null || !(obj instanceof BigDecimalComparator)) {
+      return false;
+    }
+    if (this == obj) {
+      return true;
+    }
+    BigDecimalComparator bdc = (BigDecimalComparator) obj;
+    return this.bigDecimal.equals(bdc.bigDecimal);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(this.bigDecimal);
+  }
+
+  @Override
+  public int compareTo(byte[] value, int offset, int length) {
+    BigDecimal that = Bytes.toBigDecimal(value, offset, length);
+    return this.bigDecimal.compareTo(that);
+  }
+
+  @Override
+  public int compareTo(ByteBuffer value, int offset, int length) {
+    BigDecimal that = ByteBufferUtils.toBigDecimal(value, offset, length);
+    return this.bigDecimal.compareTo(that);
+  }
+
+  /**
+   * @return The comparator serialized using pb
+   */
+  @Override
+  public byte[] toByteArray() {
+    ComparatorProtos.BigDecimalComparator.Builder builder =
+        ComparatorProtos.BigDecimalComparator.newBuilder();
+    builder.setComparable(ProtobufUtil.toByteArrayComparable(this.value));
+    return builder.build().toByteArray();
+  }
+
+  /**
+   * @param pbBytes A pb serialized {@link BigDecimalComparator} instance
+   * @return An instance of {@link BigDecimalComparator} made from <code>bytes</code>
+   * @throws DeserializationException A deserialization exception
+   * @see #toByteArray
+   */
+  public static BigDecimalComparator parseFrom(final byte[] pbBytes)
+      throws DeserializationException {
+    ComparatorProtos.BigDecimalComparator proto;
+    try {
+      proto = ComparatorProtos.BigDecimalComparator.parseFrom(pbBytes);
+    } catch (InvalidProtocolBufferException e) {
+      throw new DeserializationException(e);
+    }
+    return new BigDecimalComparator(Bytes.toBigDecimal(proto.getComparable().getValue()
+        .toByteArray()));
+  }
+
+  /**
+   * @param other the other comparator
+   * @return true if and only if the fields of the comparator that are serialized are equal to the
+   *         corresponding fields in other. Used for testing.
+   */
+  boolean areSerializedFieldsEqual(BigDecimalComparator other) {
+    if (other == this) {
+      return true;
+    }
+    return super.areSerializedFieldsEqual(other);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/0356674c/hbase-protocol-shaded/src/main/protobuf/Comparator.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol-shaded/src/main/protobuf/Comparator.proto b/hbase-protocol-shaded/src/main/protobuf/Comparator.proto
index 822fd2b..55253aa 100644
--- a/hbase-protocol-shaded/src/main/protobuf/Comparator.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/Comparator.proto
@@ -73,3 +73,7 @@ message RegexStringComparator {
 message SubstringComparator {
   required string substr = 1;
 }
+
+message BigDecimalComparator {
+  required ByteArrayComparable comparable = 1;
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/0356674c/hbase-protocol/src/main/protobuf/Comparator.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol/src/main/protobuf/Comparator.proto b/hbase-protocol/src/main/protobuf/Comparator.proto
index 496b68d..878a179 100644
--- a/hbase-protocol/src/main/protobuf/Comparator.proto
+++ b/hbase-protocol/src/main/protobuf/Comparator.proto
@@ -72,3 +72,7 @@ message RegexStringComparator {
 message SubstringComparator {
   required string substr = 1;
 }
+
+message BigDecimalComparator {
+  required ByteArrayComparable comparable = 1;
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/0356674c/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestBigDecimalComparator.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestBigDecimalComparator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestBigDecimalComparator.java
new file mode 100644
index 0000000..76a9721
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestBigDecimalComparator.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hadoop.hbase.filter;
+
+import java.math.BigDecimal;
+
+import org.apache.hadoop.hbase.testclassification.FilterTests;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category({ FilterTests.class, SmallTests.class })
+public class TestBigDecimalComparator {
+
+  @Test
+  public void testObjectEquals() {
+    BigDecimal bd = new BigDecimal(Double.MIN_VALUE);
+    // Check that equals returns true for identical objects
+    final BigDecimalComparator bdc = new BigDecimalComparator(bd);
+    Assert.assertTrue(bdc.equals(bdc));
+    Assert.assertEquals(bdc.hashCode(), bdc.hashCode());
+
+    // Check that equals returns true for the same object
+    final BigDecimalComparator bdc1 = new BigDecimalComparator(bd);
+    final BigDecimalComparator bdc2 = new BigDecimalComparator(bd);
+    Assert.assertTrue(bdc1.equals(bdc2));
+    Assert.assertEquals(bdc1.hashCode(), bdc2.hashCode());
+
+    // Check that equals returns false for different objects
+    final BigDecimalComparator bdc3 = new BigDecimalComparator(bd);
+    final BigDecimalComparator bdc4 = new BigDecimalComparator(new BigDecimal(Long.MIN_VALUE));
+    Assert.assertFalse(bdc3.equals(bdc4));
+    Assert.assertNotEquals(bdc3.hashCode(), bdc4.hashCode());
+
+    // Check that equals returns false for a different type
+    final BigDecimalComparator bdc5 = new BigDecimalComparator(bd);
+    Assert.assertFalse(bdc5.equals(0));
+  }
+
+  @Test
+  public void testEqualsValue() {
+    // given
+    BigDecimal bd1 = new BigDecimal(Double.MAX_VALUE);
+    BigDecimal bd2 = new BigDecimal(Double.MIN_VALUE);
+    byte[] value1 = Bytes.toBytes(bd1);
+    byte[] value2 = Bytes.toBytes(bd2);
+    BigDecimalComparator comparator1 = new BigDecimalComparator(bd1);
+    BigDecimalComparator comparator2 = new BigDecimalComparator(bd2);
+
+    // when
+    int comp1 = comparator1.compareTo(value1);
+    int comp2 = comparator2.compareTo(value2);
+
+    // then
+    Assert.assertEquals(0, comp1);
+    Assert.assertEquals(0, comp2);
+  }
+
+  @Test
+  public void testGreaterThanValue() {
+    // given
+    byte[] val1 = Bytes.toBytes(new BigDecimal("1000000000000000000000000000000.9999999999999999"));
+    byte[] val2 = Bytes.toBytes(new BigDecimal(0));
+    byte[] val3 = Bytes.toBytes(new BigDecimal(Double.MIN_VALUE));
+    BigDecimal bd = new BigDecimal(Double.MAX_VALUE);
+    BigDecimalComparator comparator = new BigDecimalComparator(bd);
+
+    // when
+    int comp1 = comparator.compareTo(val1);
+    int comp2 = comparator.compareTo(val2);
+    int comp3 = comparator.compareTo(val3);
+
+    // then
+    Assert.assertEquals(1, comp1);
+    Assert.assertEquals(1, comp2);
+    Assert.assertEquals(1, comp3);
+  }
+
+  @Test
+  public void testLessThanValue() {
+    // given
+    byte[] val1 = Bytes.toBytes(new BigDecimal("-1000000000000000000000000000000"));
+    byte[] val2 = Bytes.toBytes(new BigDecimal(0));
+    byte[] val3 = Bytes.toBytes(new BigDecimal(1));
+    BigDecimal bd = new BigDecimal("-1000000000000000000000000000000.0000000000000001");
+    BigDecimalComparator comparator = new BigDecimalComparator(bd);
+
+    // when
+    int comp1 = comparator.compareTo(val1);
+    int comp2 = comparator.compareTo(val2);
+    int comp3 = comparator.compareTo(val3);
+
+    // then
+    Assert.assertEquals(-1, comp1);
+    Assert.assertEquals(-1, comp2);
+    Assert.assertEquals(-1, comp3);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/0356674c/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestComparatorSerialization.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestComparatorSerialization.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestComparatorSerialization.java
index 2befef0..fef699b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestComparatorSerialization.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestComparatorSerialization.java
@@ -22,6 +22,7 @@ package org.apache.hadoop.hbase.filter;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import java.math.BigDecimal;
 import java.util.regex.Pattern;
 
 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
@@ -86,4 +87,12 @@ public class TestComparatorSerialization {
       ProtobufUtil.toComparator(ProtobufUtil.toComparator(substringComparator))));
   }
 
+  @Test
+  public void testBigDecimalComparator() throws Exception {
+    BigDecimal bigDecimal = new BigDecimal(Double.MIN_VALUE);
+    BigDecimalComparator bigDecimalComparator = new BigDecimalComparator(bigDecimal);
+    assertTrue(bigDecimalComparator.areSerializedFieldsEqual(ProtobufUtil.toComparator(ProtobufUtil
+        .toComparator(bigDecimalComparator))));
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/0356674c/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java
index 2e3edf1..fec7151 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java
@@ -42,6 +42,7 @@ import static org.mockito.Mockito.when;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
+import java.math.BigDecimal;
 import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -113,6 +114,7 @@ import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.client.Table;
 import org.apache.hadoop.hbase.client.TableDescriptor;
 import org.apache.hadoop.hbase.exceptions.FailedSanityCheckException;
+import org.apache.hadoop.hbase.filter.BigDecimalComparator;
 import org.apache.hadoop.hbase.filter.BinaryComparator;
 import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;
 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
@@ -1783,6 +1785,8 @@ public class TestHRegion {
     byte[] qf1 = Bytes.toBytes("qualifier");
     byte[] val1 = Bytes.toBytes("value1");
     byte[] val2 = Bytes.toBytes("value2");
+    BigDecimal bd1 = new BigDecimal(Double.MAX_VALUE);
+    BigDecimal bd2 = new BigDecimal(Double.MIN_VALUE);
 
     // Setting up region
     this.region = initHRegion(tableName, method, CONF, fam1);
@@ -1803,6 +1807,25 @@ public class TestHRegion {
       res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val2),
           put, true);
       assertEquals(false, res);
+
+      // Putting data in key
+      put = new Put(row1);
+      put.addColumn(fam1, qf1, Bytes.toBytes(bd1));
+      region.put(put);
+
+      // checkAndPut with wrong value
+      res =
+          region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BigDecimalComparator(
+              bd2), put, true);
+      assertEquals(false, res);
+
+      // checkAndDelete with wrong value
+      delete = new Delete(row1);
+      delete.addFamily(fam1);
+      res =
+          region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BigDecimalComparator(
+              bd2), put, true);
+      assertEquals(false, res);
     } finally {
       HBaseTestingUtility.closeRegionAndWAL(this.region);
       this.region = null;
@@ -1815,6 +1838,7 @@ public class TestHRegion {
     byte[] fam1 = Bytes.toBytes("fam1");
     byte[] qf1 = Bytes.toBytes("qualifier");
     byte[] val1 = Bytes.toBytes("value1");
+    BigDecimal bd1 = new BigDecimal(Double.MIN_VALUE);
 
     // Setting up region
     this.region = initHRegion(tableName, method, CONF, fam1);
@@ -1835,6 +1859,25 @@ public class TestHRegion {
       res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val1),
           delete, true);
       assertEquals(true, res);
+
+      // Putting data in key
+      put = new Put(row1);
+      put.addColumn(fam1, qf1, Bytes.toBytes(bd1));
+      region.put(put);
+
+      // checkAndPut with correct value
+      res =
+          region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BigDecimalComparator(
+              bd1), put, true);
+      assertEquals(true, res);
+
+      // checkAndDelete with correct value
+      delete = new Delete(row1);
+      delete.addColumn(fam1, qf1);
+      res =
+          region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BigDecimalComparator(
+              bd1), delete, true);
+      assertEquals(true, res);
     } finally {
       HBaseTestingUtility.closeRegionAndWAL(this.region);
       this.region = null;