You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2017/09/26 12:17:07 UTC

[2/9] brooklyn-server git commit: add Streams.compare function

add Streams.compare function


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/3816fb7d
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/3816fb7d
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/3816fb7d

Branch: refs/heads/master
Commit: 3816fb7d7b5e167fd74bb156f26f1c8450136c1a
Parents: 277cb22
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Sep 21 13:06:21 2017 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Sep 21 13:17:07 2017 +0100

----------------------------------------------------------------------
 .../apache/brooklyn/util/stream/Streams.java    | 39 +++++++++++++++++++-
 .../brooklyn/util/stream/StreamsTest.java       | 17 +++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3816fb7d/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java b/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
index ccfa1cc..907edfe 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
@@ -29,6 +29,7 @@ import java.io.OutputStream;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.Writer;
+import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
@@ -104,6 +105,18 @@ public class Streams {
         }
     }
     
+    /** reads the input stream fully into the given byte buffer or until the supplied buffer is full,
+     * returning the number of bytes read */
+    public static int readFully(InputStream s, byte[] buf) throws IOException {
+        int count = 0;
+        while (count < buf.length) {
+            int countHere = s.read(buf, count, buf.length-count);
+            if (countHere<=0) return count;
+            count += countHere;
+        }
+        return count;
+    }
+    
     public static byte[] readFullyAndClose(InputStream is) {
         try {
             return readFully(is);
@@ -234,5 +247,29 @@ public class Streams {
         }
         return result.toString().toUpperCase();
     }
-    
+
+    /** True iff the input streams read to completion give identical contents. Streams are closed afterwards. */
+    public static boolean compare(InputStream s1, InputStream s2) throws IOException {
+        try {
+            if (s1==null || s2==null) {
+                return s1==null && s2==null;
+            }
+            byte[] buf1 = new byte[4096], buf2 = new byte[4096];
+            while (true) {
+                int r1 = readFully(s1, buf1);
+                int r2 = readFully(s2, buf2);
+                // do this in case HeapByteBuffer.equals has an efficient intrinsic comparison;
+                // curiously there is no efficient array-compare a la System.arraycopy;
+                // the only thing I've found is that Arrays.equals(char[], char[]) is optimized/intrinsic,
+                // and allegedly 8 times faster than all other array comparison routines!
+                // https://stackoverflow.com/questions/41153992/why-is-arrays-equalschar-char-8-times-faster-than-all-the-other-versions
+                if (!ByteBuffer.wrap(buf1,0,r1).equals(ByteBuffer.wrap(buf2,0,r2))) return false;
+                if (r1<4096) return true;
+            }
+        } finally {
+            closeQuietly(s1);
+            closeQuietly(s2);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3816fb7d/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamsTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamsTest.java
index 37340f4..cb480ce 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamsTest.java
@@ -19,7 +19,9 @@
 package org.apache.brooklyn.util.stream;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 
+import org.apache.brooklyn.util.text.Strings;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -33,4 +35,19 @@ public class StreamsTest {
             );
 
     }
+    
+    @Test
+    public void testComparison() throws IOException {
+        Assert.assertTrue(Streams.compare(Streams.newInputStreamWithContents("hello"), Streams.newInputStreamWithContents("hello")));
+        Assert.assertFalse(Streams.compare(Streams.newInputStreamWithContents("hello"), Streams.newInputStreamWithContents("hello2")));
+        Assert.assertFalse(Streams.compare(Streams.newInputStreamWithContents("hello2"), Streams.newInputStreamWithContents("hello")));
+        Assert.assertFalse(Streams.compare(null, Streams.newInputStreamWithContents("hello")));
+        Assert.assertTrue(Streams.compare(null, null));
+        // test across byte buffers
+        Assert.assertTrue(Streams.compare(Streams.newInputStreamWithContents(Strings.repeat("hello", 1000)), 
+            Streams.newInputStreamWithContents(Strings.repeat("hello", 1000))));
+        Assert.assertFalse(Streams.compare(Streams.newInputStreamWithContents(Strings.repeat("hello", 1000)+"1"), 
+            Streams.newInputStreamWithContents(Strings.repeat("hello", 1000)+"2")));
+    }
+
 }