diff --git a/libraries/pom.xml b/libraries/pom.xml
index dfae8085bb..c3535f884a 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -485,22 +485,22 @@
org.eclipse.jetty.websocket
websocket-server
${jetty.version}
-
+
org.eclipse.jetty.websocket
websocket-client
${jetty.version}
-
+
org.eclipse.jetty.websocket
websocket-api
${jetty.version}
-
+
org.eclipse.jetty.websocket
websocket-common
${jetty.version}
-
+
org.eclipse.jetty
jetty-continuation
@@ -510,7 +510,7 @@
org.eclipse.jetty
jetty-util
${jetty.version}
-
+
org.seleniumhq.selenium
selenium-api
@@ -519,6 +519,11 @@
jar
+
+ net.agkn
+ hll
+ ${hll.version}
+
0.7.0
@@ -559,6 +564,7 @@
8.0.6
mytheme
+ 1.6.0
diff --git a/libraries/src/test/java/com/baeldung/hll/HLLUnitTest.java b/libraries/src/test/java/com/baeldung/hll/HLLUnitTest.java
new file mode 100644
index 0000000000..1d318b7e4e
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/hll/HLLUnitTest.java
@@ -0,0 +1,67 @@
+package com.baeldung.hll;
+
+
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
+import net.agkn.hll.HLL;
+import org.junit.Test;
+
+import java.util.stream.LongStream;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+
+public class HLLUnitTest {
+
+ @Test
+ public void givenHLL_whenAddHugeAmountOfNumbers_thenShouldReturnEstimatedCardinality() {
+ //given
+ int numberOfElements = 100_000_000;
+ int toleratedDifference = 1_000_000;
+ HashFunction hashFunction = Hashing.murmur3_128();
+ HLL hll = new HLL(14, 5);
+
+ //when
+ LongStream.range(0, numberOfElements).forEach(element -> {
+ long hashedValue = hashFunction.newHasher().putLong(element).hash().asLong();
+ hll.addRaw(hashedValue);
+ }
+ );
+
+ //then
+ long cardinality = hll.cardinality();
+ assertThat(isSimilarTo(cardinality, numberOfElements, toleratedDifference)).isTrue();
+ }
+
+ @Test
+ public void givenTwoHLLs_whenAddHugeAmountOfNumbers_thenShouldReturnEstimatedCardinalityForUnionOfHLLs() {
+ //given
+ int numberOfElements = 100_000_000;
+ int toleratedDifference = 1_000_000;
+ HashFunction hashFunction = Hashing.murmur3_128();
+ HLL firstHll = new HLL(15, 5);
+ HLL secondHLL = new HLL(15, 5);
+
+ //when
+ LongStream.range(0, numberOfElements).forEach(element -> {
+ long hashedValue = hashFunction.newHasher().putLong(element).hash().asLong();
+ firstHll.addRaw(hashedValue);
+ }
+ );
+
+ LongStream.range(numberOfElements, numberOfElements * 2).forEach(element -> {
+ long hashedValue = hashFunction.newHasher().putLong(element).hash().asLong();
+ secondHLL.addRaw(hashedValue);
+ }
+ );
+
+ //then
+ firstHll.union(secondHLL);
+ long cardinality = firstHll.cardinality();
+ assertThat(isSimilarTo(cardinality, numberOfElements * 2, toleratedDifference)).isTrue();
+ }
+
+ private boolean isSimilarTo(long cardinality, int numberOfElements, int maxToleratedDifference) {
+ System.out.println(cardinality);
+ return Math.abs(cardinality - numberOfElements) <= maxToleratedDifference;
+ }
+}