diff --git a/src/main/java/com/clearspring/analytics/stream/cardinality/HyperLogLog.java b/src/main/java/com/clearspring/analytics/stream/cardinality/HyperLogLog.java index 844e8ff72..7f9734638 100644 --- a/src/main/java/com/clearspring/analytics/stream/cardinality/HyperLogLog.java +++ b/src/main/java/com/clearspring/analytics/stream/cardinality/HyperLogLog.java @@ -16,16 +16,15 @@ package com.clearspring.analytics.stream.cardinality; -import com.clearspring.analytics.hash.MurmurHash; -import com.clearspring.analytics.util.Bits; -import com.clearspring.analytics.util.IBuilder; - -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.Serializable; +import java.nio.ByteBuffer; + +import com.clearspring.analytics.hash.MurmurHash; +import com.clearspring.analytics.util.Bits; +import com.clearspring.analytics.util.IBuilder; /** * Java implementation of HyperLogLog (HLL) algorithm from this paper: @@ -200,19 +199,18 @@ public int sizeof() } @Override - public byte[] getBytes() throws IOException + public byte[] getBytes() { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - - dos.writeInt(log2m); - dos.writeInt(registerSet.size * 4); - for (int x : registerSet.bits()) + ByteBuffer buffer = ByteBuffer.allocate(8 + registerSet.size * 4); + buffer.putInt(log2m); + buffer.putInt(registerSet.size * 4); + + for (int x : registerSet.bits()) { - dos.writeInt(x); + buffer.putInt(x); } - - return baos.toByteArray(); + + return buffer.array(); } /** Add all the elements of the other set to this set. @@ -278,14 +276,16 @@ public int sizeof() return RegisterSet.getBits(k) * 4; } - public static HyperLogLog build(byte[] bytes) throws IOException + public static HyperLogLog build(byte[] bytes) { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - DataInputStream oi = new DataInputStream(bais); - int log2m = oi.readInt(); - int size = oi.readInt(); + ByteBuffer buffer = ByteBuffer.wrap(bytes); + int log2m = buffer.getInt(); + int size = buffer.getInt(); + byte[] longArrayBytes = new byte[size]; - oi.readFully(longArrayBytes); + + buffer.get(longArrayBytes, 0, size); + return new HyperLogLog(log2m, new RegisterSet((int) Math.pow(2, log2m), Bits.getBits(longArrayBytes))); } } diff --git a/src/main/java/com/clearspring/analytics/util/Bits.java b/src/main/java/com/clearspring/analytics/util/Bits.java index 10c029cbe..6e07dbb74 100644 --- a/src/main/java/com/clearspring/analytics/util/Bits.java +++ b/src/main/java/com/clearspring/analytics/util/Bits.java @@ -16,22 +16,22 @@ package com.clearspring.analytics.util; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; +import java.nio.ByteBuffer; public class Bits { - public static int[] getBits(byte[] mBytes) throws IOException + public static int[] getBits(byte[] mBytes) { int bitSize = mBytes.length / 4; int[] bits = new int[bitSize]; - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(mBytes)); + ByteBuffer buffer = ByteBuffer.wrap(mBytes); + for (int i = 0; i < bitSize; i++) { - bits[i] = dis.readInt(); + bits[i] = buffer.getInt(); } + return bits; }