You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fluo.apache.org by kt...@apache.org on 2017/10/04 14:18:12 UTC

[fluo] branch master updated: fixes #924 add byte[] compare to Bytes (#934)

This is an automated email from the ASF dual-hosted git repository.

kturner pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/fluo.git


The following commit(s) were added to refs/heads/master by this push:
     new 7c16599  fixes #924 add byte[] compare to Bytes (#934)
7c16599 is described below

commit 7c165999f278d96cfb98be6c54ff683e7a534adc
Author: Joseph Koshakow <ko...@gmail.com>
AuthorDate: Wed Oct 4 10:09:59 2017 -0400

    fixes #924 add byte[] compare to Bytes (#934)
    
    Squashed commit of the following:
    
    commit dad21cedc9aa263f874426a9f98edaa9e618870c
    Author: Joseph Koshakow <ko...@gmail.com>
    Date:   Tue Oct 3 23:24:14 2017 -0400
    
        Added the following methods:
          private int compareToUnchecked(byte[] bytes, int offset, int len){...}
          private boolean contentEqualsUnchecked(byte[] bytes, int offset, int len){...}
        Refactored the following methods:
          public final int compareTo(Bytes other){...}
          public int compareTo(byte[] bytes){...}
          public int compareTo(byte[] bytes, int offset, int len){...}
          public final boolean equals(Object other){...}
          public boolean contentEquals(byte[] bytes){...}
          public boolean contentEquals(byte[] bytes, int offset, int len){...}
        Added tests to test offsets greater than 0
    
    commit b3038ddccd3fac57604e8f5b53ab38423d146e62
    Author: Joseph Koshakow <ko...@gmail.com>
    Date:   Mon Oct 2 23:44:33 2017 -0400
    
        Modified precondition for contentEquals(byte[] bytes, int offset, int len){...}
    
    commit ad5f06c4aa1eb44559270f5d62396a1eff82e632
    Author: Joseph Koshakow <ko...@gmail.com>
    Date:   Mon Oct 2 23:37:04 2017 -0400
    
        Added @since 1.2.0 tags to new methods
        Added a Precondition.checkArgument to methods that take offset and len
        Added tests for different length Bytes and byte[] and empty Bytes and byte[]
        Added tests for invalid arguments
    
    commit d0033f5dd23144d703643492b55246bf1dd0c4c4
    Author: Joseph Koshakow <ko...@gmail.com>
    Date:   Mon Oct 2 20:17:32 2017 -0400
    
        Created the following methods and corresponding unit tests for them:
          public boolean contentEquals(byte[] bytes){...}
          public boolean contentEquals(byte[] bytes, int offset, int len){...}
          public int compareTo(byte[] bytes){...}
          public int compareTo(byte[] bytes, int offset, int len){...}
        Refactored the following methods:
          public final int compareTo(Bytes other){...}
          public final boolean equals(Object other){...}
---
 .../main/java/org/apache/fluo/api/data/Bytes.java  | 108 ++++++++++++++++++---
 .../java/org/apache/fluo/api/data/BytesTest.java   |  73 ++++++++++++++
 2 files changed, 165 insertions(+), 16 deletions(-)

diff --git a/modules/api/src/main/java/org/apache/fluo/api/data/Bytes.java b/modules/api/src/main/java/org/apache/fluo/api/data/Bytes.java
index 2df25cc..dd79c86 100644
--- a/modules/api/src/main/java/org/apache/fluo/api/data/Bytes.java
+++ b/modules/api/src/main/java/org/apache/fluo/api/data/Bytes.java
@@ -187,31 +187,80 @@ public final class Bytes implements Comparable<Bytes>, Serializable {
   }
 
   /**
+  * Compares this to the passed bytes, byte by byte, returning a negative, zero, or positive result
+  * if the first sequence is less than, equal to, or greater than the second. The comparison is
+  * performed starting with the first byte of each sequence, and proceeds until a pair of bytes
+  * differs, or one sequence runs out of byte (is shorter). A shorter sequence is considered less
+  * than a longer one.
+  *
+  * @return comparison result
+  */
+  @Override
+  public final int compareTo(Bytes other) {
+    if (this == other) {
+      return 0;
+    } else {
+      return compareToUnchecked(other.data, other.offset, other.length);
+    }
+  }
+
+  /**
    * Compares this to the passed bytes, byte by byte, returning a negative, zero, or positive result
    * if the first sequence is less than, equal to, or greater than the second. The comparison is
    * performed starting with the first byte of each sequence, and proceeds until a pair of bytes
    * differs, or one sequence runs out of byte (is shorter). A shorter sequence is considered less
    * than a longer one.
    *
+   * @since 1.2.0
    * @return comparison result
    */
-  @Override
-  public final int compareTo(Bytes other) {
-    if (this == other) {
-      return 0;
-    } else if (this.length == this.data.length && other.length == other.data.length) {
-      return UnsignedBytes.lexicographicalComparator().compare(this.data, other.data);
+  public int compareTo(byte[] bytes) {
+    return compareToUnchecked(bytes, 0, bytes.length);
+  }
+
+  /**
+   * Compares this to the passed bytes, byte by byte, returning a negative, zero, or positive result
+   * if the first sequence is less than, equal to, or greater than the second. The comparison is
+   * performed starting with the first byte of each sequence, and proceeds until a pair of bytes
+   * differs, or one sequence runs out of byte (is shorter). A shorter sequence is considered less
+   * than a longer one.
+   *
+   * This method checks the arguments passed to it.
+   *
+   * @since 1.2.0
+   * @return comparison result
+   */
+  public int compareTo(byte[] bytes, int offset, int len) {
+    Preconditions.checkArgument(offset >= 0 && len >= 0 && offset + len <= bytes.length);
+    return compareToUnchecked(bytes, offset, len);
+  }
+
+  /**
+   * Compares this to the passed bytes, byte by byte, returning a negative, zero, or positive result
+   * if the first sequence is less than, equal to, or greater than the second. The comparison is
+   * performed starting with the first byte of each sequence, and proceeds until a pair of bytes
+   * differs, or one sequence runs out of byte (is shorter). A shorter sequence is considered less
+   * than a longer one.
+   *
+   * This method does not check the arguments passed to it.
+   *
+   * @since 1.2.0
+   * @return comparison result
+   */
+  private int compareToUnchecked(byte[] bytes, int offset, int len) {
+    if (this.length == this.data.length && len == bytes.length) {
+      int res = UnsignedBytes.lexicographicalComparator().compare(this.data, bytes);
+      return UnsignedBytes.lexicographicalComparator().compare(this.data, bytes);
     } else {
-      int minLen = Math.min(this.length, other.length);
-      for (int i = this.offset, j = other.offset; i < minLen; i++, j++) {
+      int minLen = Math.min(this.length, len);
+      for (int i = this.offset, j = offset; i < minLen; i++, j++) {
         int a = (this.data[i] & 0xff);
-        int b = (other.data[j] & 0xff);
-
+        int b = (bytes[j] & 0xff);
         if (a != b) {
           return a - b;
         }
       }
-      return this.length - other.length;
+      return this.length - len;
     }
   }
 
@@ -228,15 +277,42 @@ public final class Bytes implements Comparable<Bytes>, Serializable {
     if (other instanceof Bytes) {
       Bytes ob = (Bytes) other;
 
-      if (length != ob.length) {
-        return false;
-      }
-
-      return compareTo(ob) == 0;
+      return contentEqualsUnchecked(ob.data, ob.offset, ob.length);
     }
     return false;
   }
 
+  /**
+   * Returns true if this Bytes object equals another.
+   * @since 1.2.0
+   */
+  public boolean contentEquals(byte[] bytes) {
+    return contentEqualsUnchecked(bytes, 0, bytes.length);
+  }
+
+  /**
+   * Returns true if this Bytes object equals another.
+   * This method checks it's arguments.
+   * @since 1.2.0
+   */
+  public boolean contentEquals(byte[] bytes, int offset, int len) {
+    Preconditions.checkArgument(len >= 0 && offset >= 0 && offset + len <= bytes.length);
+    return contentEqualsUnchecked(bytes, offset, len);
+  }
+
+  /**
+   * Returns true if this Bytes object equals another.
+   * This method doesn't check it's arguments.
+   * @since 1.2.0
+   */
+  private boolean contentEqualsUnchecked(byte[] bytes, int offset, int len) {
+    if (length != len) {
+      return false;
+    }
+
+    return compareToUnchecked(bytes, offset, len) == 0;
+  }
+
   @Override
   public final int hashCode() {
     if (hashCode == 0) {
diff --git a/modules/api/src/test/java/org/apache/fluo/api/data/BytesTest.java b/modules/api/src/test/java/org/apache/fluo/api/data/BytesTest.java
index 142cc44..8742a1c 100644
--- a/modules/api/src/test/java/org/apache/fluo/api/data/BytesTest.java
+++ b/modules/api/src/test/java/org/apache/fluo/api/data/BytesTest.java
@@ -17,6 +17,7 @@ package org.apache.fluo.api.data;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.lang.IllegalArgumentException;
 import java.nio.ByteBuffer;
 import java.nio.ReadOnlyBufferException;
 import java.nio.charset.StandardCharsets;
@@ -109,6 +110,30 @@ public class BytesTest {
   }
 
   @Test
+  public void testContentEquals() {
+    Bytes b1 = Bytes.of("a");
+    byte[] b2 = b1.toArray();
+    byte[] b3 = Bytes.of("b").toArray();
+    Bytes b5 = Bytes.of("qwerty");
+    byte[] b6 = b5.toArray();
+    Bytes b7 = Bytes.of("");
+    byte[] b8 = b7.toArray();
+
+
+    Assert.assertTrue(b1.contentEquals(b2));
+    Assert.assertTrue(b5.contentEquals(b6));
+    Assert.assertTrue(b7.contentEquals(b8));
+
+    Assert.assertFalse(b1.contentEquals(b3));
+    Assert.assertFalse(b1.contentEquals(b6));
+    Assert.assertFalse(b5.contentEquals(b2));
+    Assert.assertFalse(b1.contentEquals(b8));
+    Assert.assertFalse(b5.contentEquals(b8));
+    Assert.assertFalse(b7.contentEquals(b2));
+    Assert.assertFalse(b7.contentEquals(b6));
+  }
+
+  @Test
   public void testCompare() {
     Bytes b1 = Bytes.of("a");
     Bytes b2 = Bytes.of("b");
@@ -118,6 +143,54 @@ public class BytesTest {
     Assert.assertEquals(0, b1.compareTo(b3));
     Assert.assertEquals(0, b1.compareTo(b1));
     Assert.assertEquals(1, b1.compareTo(Bytes.EMPTY));
+
+    byte[] b1Arr = b1.toArray();
+    byte[] b2Arr = b2.toArray();
+    byte[] b3Arr = b3.toArray();
+    Assert.assertEquals(-1, b1.compareTo(b2Arr));
+    Assert.assertEquals(1, b2.compareTo(b1Arr));
+    Assert.assertEquals(0, b1.compareTo(b3Arr));
+    Assert.assertEquals(0, b1.compareTo(b1Arr));
+    Assert.assertEquals(1, b1.compareTo(Bytes.EMPTY));
+
+    Bytes b4 = Bytes.of("abc");
+    byte[] b4Arr = b4.toArray();
+    Bytes b5 = Bytes.of("baz");
+    byte[] b5Arr = b5.toArray();
+    Bytes b6 = Bytes.of("ab");
+    byte[] b7Arr = Bytes.of("dabc").toArray();
+
+    Assert.assertEquals(0, b4.compareTo(b4Arr, 0, 3));
+    Assert.assertTrue(b4.compareTo(b4Arr, 1, 2) < 0);
+    Assert.assertTrue(b5.compareTo(b4Arr, 1, 2) < 0);
+    Assert.assertTrue(b5.compareTo(b5Arr, 1, 2) > 0);
+    Assert.assertTrue(b4.compareTo(b4Arr, 0, 2) > 0);
+    Assert.assertTrue(b6.compareTo(b7Arr, 1, 3) < 0);
+    Assert.assertTrue(b6.compareTo(b1Arr) > 0);
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testCompareNegOffset() {
+    Bytes b1 = Bytes.of("abc");
+    byte[] b2 = b1.toArray();
+
+    b1.compareTo(b2, -4, 1);
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testCompareNegLen() {
+    Bytes b1 = Bytes.of("abc");
+    byte[] b2 = b1.toArray();
+
+    b1.compareTo(b2, 0, -1);
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testCompareBadArgs() {
+    Bytes b1 = Bytes.of("abc");
+    byte[] b2 = b1.toArray();
+
+    b1.compareTo(b2, 2, 2);
   }
 
   @Test

-- 
To stop receiving notification emails like this one, please contact
['"commits@fluo.apache.org" <co...@fluo.apache.org>'].