This is an automated email from the ASF dual-hosted git repository.
leerho pushed a commit to branch Tuple_Theta_Extension
in repository
https://gitbox.apache.org/repos/asf/incubator-datasketches-java.git
The following commit(s) were added to refs/heads/Tuple_Theta_Extension by this
push:
new cec94de Multiple corrections to Intersection and to AnotB.
cec94de is described below
commit cec94de8bf8b1b6ca8b99d03a668204e27a66c97
Author: Lee Rhodes <[email protected]>
AuthorDate: Sat May 30 16:34:00 2020 -0700
Multiple corrections to Intersection and to AnotB.
Much improved unit tests.
---
.../java/org/apache/datasketches/tuple/Filter.java | 2 +-
.../apache/datasketches/tuple/Intersection.java | 119 ++++----
.../datasketches/tuple/QuickSelectSketch.java | 5 +-
.../apache/datasketches/tuple/UpdatableSketch.java | 2 +-
.../tuple/CompactSketchWithDoubleSummaryTest.java | 1 +
.../org/apache/datasketches/tuple/MiscTest.java | 53 ++++
.../tuple/SerializerDeserializerTest.java | 12 +-
.../tuple/adouble/AdoubleAnotBTest.java | 2 +
.../tuple/adouble/AdoubleIntersectionTest.java | 332 +++++++++++++++++++++
...WithDoubleSummaryTest.java => AdoubleTest.java} | 309 +------------------
.../tuple/adouble/AdoubleUnionTest.java | 161 ++++++++++
11 files changed, 639 insertions(+), 359 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/tuple/Filter.java
b/src/main/java/org/apache/datasketches/tuple/Filter.java
index db975ae..5f7b096 100644
--- a/src/main/java/org/apache/datasketches/tuple/Filter.java
+++ b/src/main/java/org/apache/datasketches/tuple/Filter.java
@@ -65,7 +65,7 @@ public class Filter<T extends Summary> {
sketch.setThetaLong(sketchIn.getThetaLong());
if (!sketchIn.isEmpty()) {
- sketch.setNotEmpty();
+ sketch.setEmpty(false);
}
return sketch.compact();
diff --git a/src/main/java/org/apache/datasketches/tuple/Intersection.java
b/src/main/java/org/apache/datasketches/tuple/Intersection.java
index 0c32089..4fe6eb3 100644
--- a/src/main/java/org/apache/datasketches/tuple/Intersection.java
+++ b/src/main/java/org/apache/datasketches/tuple/Intersection.java
@@ -28,18 +28,18 @@ import org.apache.datasketches.SketchesStateException;
/**
* Computes an intersection of two or more generic tuple sketches.
- * A new instance represents the Universal Set.
- * Every update() computes an intersection with the internal set
- * and can only reduce the internal set.
+ * A new instance represents the Universal Set. Because the Universal Set
+ * cannot be realized a <i>getResult()</i> on a new instance will produce an
error.
+ * Every update() computes an intersection with the internal state, which will
never
+ * grow larger and may be reduced to zero.
* @param <S> Type of Summary
*/
public class Intersection<S extends Summary> {
-
private final SummarySetOperations<S> summarySetOps_;
private QuickSelectSketch<S> sketch_;
- private boolean isEmpty_;
- private long theta_;
- private boolean isFirstCall_;
+ private boolean empty_;
+ private long thetaLong_;
+ private boolean firstCall_;
/**
* Creates new instance
@@ -47,59 +47,63 @@ public class Intersection<S extends Summary> {
*/
public Intersection(final SummarySetOperations<S> summarySetOps) {
summarySetOps_ = summarySetOps;
- isEmpty_ = false; // universal set at the start
- theta_ = Long.MAX_VALUE;
- isFirstCall_ = true;
+ sketch_ = null;
+ empty_ = false; // universal set at the start
+ thetaLong_ = Long.MAX_VALUE;
+ firstCall_ = true;
}
/**
- * Updates the internal set by intersecting it with the given sketch
- * @param sketchIn input sketch to intersect with the internal set
+ * Updates the internal state by intersecting it with the given sketch
+ * @param sketchIn input sketch to intersect with the internal state
*/
@SuppressWarnings({ "unchecked", "null" })
public void update(final Sketch<S> sketchIn) {
- final boolean isFirstCall = isFirstCall_;
- isFirstCall_ = false;
+ final boolean firstCall = firstCall_;
+ firstCall_ = false;
if (sketchIn == null) {
- isEmpty_ = true;
+ empty_ = (thetaLong_ == Long.MAX_VALUE);
sketch_ = null;
return;
}
- theta_ = min(theta_, sketchIn.getThetaLong());
- isEmpty_ |= sketchIn.isEmpty();
- if (isEmpty_ || (sketchIn.getRetainedEntries() == 0)) {
+ thetaLong_ = min(thetaLong_, sketchIn.getThetaLong()); //Theta rule
+ empty_ |= sketchIn.isEmpty(); //Empty rule
+ if (empty_ || (sketchIn.getRetainedEntries() == 0)) {
+ empty_ = (thetaLong_ == Long.MAX_VALUE);
sketch_ = null;
return;
}
- if (isFirstCall) {
+ if (firstCall) {
sketch_ = new QuickSelectSketch<>(sketchIn.getRetainedEntries(),
ResizeFactor.X1.lg(), null);
final SketchIterator<S> it = sketchIn.iterator();
while (it.next()) {
- final S summary = (S)it.getSummary().copy();
- sketch_.insert(it.getKey(), summary);
+ sketch_.insert(it.getKey(), (S)it.getSummary().copy());
}
} else {
if (sketch_ == null) {
+ empty_ = (thetaLong_ == Long.MAX_VALUE);
return;
}
- final int matchSize = min(sketch_.getRetainedEntries(),
sketchIn.getRetainedEntries());
- final long[] matchKeys = new long[matchSize];
+ final int maxMatchSize = min(sketch_.getRetainedEntries(),
sketchIn.getRetainedEntries());
+ final long[] matchKeys = new long[maxMatchSize];
S[] matchSummaries = null;
int matchCount = 0;
final SketchIterator<S> it = sketchIn.iterator();
while (it.next()) {
final long key = it.getKey();
- final S summary = sketch_.find(key);
- if (summary != null) { //key found
+ if (key >= thetaLong_) {
+ continue;
+ }
+ final S mySummary = sketch_.find(key);
+ if (mySummary != null) { //key found
matchKeys[matchCount] = key;
if (matchSummaries == null) {
- matchSummaries = (S[]) Array.newInstance(summary.getClass(),
matchSize);
+ matchSummaries = (S[]) Array.newInstance(mySummary.getClass(),
maxMatchSize);
}
- matchSummaries[matchCount] = summarySetOps_.intersection(summary,
it.getSummary());
+ matchSummaries[matchCount] = summarySetOps_.intersection(mySummary,
it.getSummary());
matchCount++;
}
}
- sketch_ = null;
if (matchCount > 0) { //therefore matchSummaries != null.
// assumes that constructor of QuickSelectSketch bumps the requested
size
// up to the nearest power of 2
@@ -107,35 +111,38 @@ public class Intersection<S extends Summary> {
for (int i = 0; i < matchCount; i++) {
sketch_.insert(matchKeys[i], matchSummaries[i]);
}
+ sketch_.setThetaLong(thetaLong_);
+ empty_ = (thetaLong_ == Long.MAX_VALUE) &&
(sketch_.getRetainedEntries() == 0);
+ sketch_.setEmpty(empty_);
+ } else {
+ sketch_ = null;
+ empty_ = (thetaLong_ == Long.MAX_VALUE);
}
}
- if (sketch_ != null) {
- sketch_.setThetaLong(theta_);
- sketch_.setNotEmpty();
- }
}
/**
* Updates the internal set by intersecting it with the given Theta sketch
- * @param sketchIn input Theta Sketch to intersect with the internal set
+ * @param sketchIn input Theta Sketch to intersect with the internal state.
* @param summary the given proxy summary for the Theta Sketch, which
doesn't have one.
*/
@SuppressWarnings({ "unchecked", "null" })
public void update(final org.apache.datasketches.theta.Sketch sketchIn,
final S summary) {
- final boolean isFirstCall = isFirstCall_;
- isFirstCall_ = false;
+ final boolean firstCall = firstCall_;
+ firstCall_ = false;
if (sketchIn == null) {
- isEmpty_ = true;
+ empty_ = (thetaLong_ == Long.MAX_VALUE);
sketch_ = null;
return;
}
- theta_ = min(theta_, sketchIn.getThetaLong());
- isEmpty_ |= sketchIn.isEmpty();
- if (isEmpty_ || (sketchIn.getRetainedEntries() == 0)) {
+ thetaLong_ = min(thetaLong_, sketchIn.getThetaLong()); //Theta rule
+ empty_ |= sketchIn.isEmpty(); //Empty rule
+ if (empty_ || (sketchIn.getRetainedEntries() == 0)) {
+ empty_ = (thetaLong_ == Long.MAX_VALUE);
sketch_ = null;
return;
}
- if (isFirstCall) {
+ if (firstCall) {
sketch_ = new QuickSelectSketch<>(sketchIn.getRetainedEntries(),
ResizeFactor.X1.lg(), null);
final org.apache.datasketches.theta.HashIterator it =
sketchIn.iterator();
while (it.next()) {
@@ -143,26 +150,29 @@ public class Intersection<S extends Summary> {
}
} else {
if (sketch_ == null) {
+ empty_ = (thetaLong_ == Long.MAX_VALUE);
return;
}
- final int matchSize = min(sketch_.getRetainedEntries(),
sketchIn.getRetainedEntries());
- final long[] matchKeys = new long[matchSize];
+ final int maxMatchSize = min(sketch_.getRetainedEntries(),
sketchIn.getRetainedEntries());
+ final long[] matchKeys = new long[maxMatchSize];
S[] matchSummaries = null;
int matchCount = 0;
final org.apache.datasketches.theta.HashIterator it =
sketchIn.iterator();
while (it.next()) {
final long key = it.get();
+ if (key >= thetaLong_) {
+ continue;
+ }
final S mySummary = sketch_.find(key);
if (mySummary != null) { //key found
matchKeys[matchCount] = key;
if (matchSummaries == null) {
- matchSummaries = (S[]) Array.newInstance(mySummary.getClass(),
matchSize);
+ matchSummaries = (S[]) Array.newInstance(mySummary.getClass(),
maxMatchSize);
}
matchSummaries[matchCount] = summarySetOps_.intersection(mySummary,
(S)summary.copy());
matchCount++;
}
}
- sketch_ = null;
if (matchCount > 0) { //therefore matchSummaries != null.
// assumes that constructor of QuickSelectSketch bumps the requested
size
// up to the nearest power of 2
@@ -170,26 +180,27 @@ public class Intersection<S extends Summary> {
for (int i = 0; i < matchCount; i++) {
sketch_.insert(matchKeys[i], matchSummaries[i]);
}
+ sketch_.setThetaLong(thetaLong_);
+ empty_ = (thetaLong_ == Long.MAX_VALUE) &&
(sketch_.getRetainedEntries() == 0);
+ sketch_.setEmpty(empty_);
+ } else {
+ sketch_ = null;
+ empty_ = (thetaLong_ == Long.MAX_VALUE);
}
}
- if (sketch_ != null) {
- sketch_.setThetaLong(theta_);
- sketch_.setNotEmpty();
- }
}
-
/**
* Gets the internal set as a CompactSketch
* @return result of the intersections so far
*/
public CompactSketch<S> getResult() {
- if (isFirstCall_) {
+ if (firstCall_) {
throw new SketchesStateException(
"getResult() with no intervening intersections is not a legal
result.");
}
if (sketch_ == null) {
- return new CompactSketch<>(null, null, theta_, isEmpty_);
+ return new CompactSketch<>(null, null, thetaLong_, empty_);
}
return sketch_.compact();
}
@@ -198,9 +209,9 @@ public class Intersection<S extends Summary> {
* Resets the internal set to the initial state, which represents the
Universal Set
*/
public void reset() {
- isEmpty_ = false;
- theta_ = Long.MAX_VALUE;
+ empty_ = false;
+ thetaLong_ = Long.MAX_VALUE;
sketch_ = null;
- isFirstCall_ = true;
+ firstCall_ = true;
}
}
diff --git a/src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java
b/src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java
index be41ed0..1fe0fb7 100644
--- a/src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java
+++ b/src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java
@@ -391,8 +391,8 @@ class QuickSelectSketch<S extends Summary> extends
Sketch<S> {
theta_ = theta;
}
- void setNotEmpty() {
- isEmpty_ = false;
+ void setEmpty(final boolean value) {
+ isEmpty_ = value;
}
SummaryFactory<S> getSummaryFactory() {
@@ -434,6 +434,7 @@ class QuickSelectSketch<S extends Summary> extends
Sketch<S> {
final int index = HashOperations.hashInsertOnly(keys_, lgCurrentCapacity_,
key);
insertSummary(index, summary);
count_++;
+ isEmpty_ = false;
}
private void updateTheta() {
diff --git a/src/main/java/org/apache/datasketches/tuple/UpdatableSketch.java
b/src/main/java/org/apache/datasketches/tuple/UpdatableSketch.java
index 174e282..fd37888 100644
--- a/src/main/java/org/apache/datasketches/tuple/UpdatableSketch.java
+++ b/src/main/java/org/apache/datasketches/tuple/UpdatableSketch.java
@@ -141,7 +141,7 @@ public class UpdatableSketch<U, S extends
UpdatableSummary<U>> extends QuickSele
}
private void insertOrIgnore(final long key, final U value) {
- setNotEmpty();
+ setEmpty(false);
if (key >= getThetaLong()) { return; }
int index = findOrInsert(key);
if (index < 0) {
diff --git
a/src/test/java/org/apache/datasketches/tuple/CompactSketchWithDoubleSummaryTest.java
b/src/test/java/org/apache/datasketches/tuple/CompactSketchWithDoubleSummaryTest.java
index c1820f3..b068ea8 100644
---
a/src/test/java/org/apache/datasketches/tuple/CompactSketchWithDoubleSummaryTest.java
+++
b/src/test/java/org/apache/datasketches/tuple/CompactSketchWithDoubleSummaryTest.java
@@ -49,6 +49,7 @@ public class CompactSketchWithDoubleSummaryTest {
SketchIterator<DoubleSummary> it = sketch.iterator();
Assert.assertNotNull(it);
Assert.assertFalse(it.next());
+ sketch.toString();
}
@Test
diff --git a/src/test/java/org/apache/datasketches/tuple/MiscTest.java
b/src/test/java/org/apache/datasketches/tuple/MiscTest.java
new file mode 100644
index 0000000..1863930
--- /dev/null
+++ b/src/test/java/org/apache/datasketches/tuple/MiscTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.datasketches.tuple;
+
+import org.apache.datasketches.tuple.adouble.DoubleSummary;
+import org.apache.datasketches.tuple.adouble.DoubleSummary.Mode;
+import org.apache.datasketches.tuple.adouble.DoubleSummaryFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * @author Lee Rhodes
+ */
+@SuppressWarnings("javadoc")
+public class MiscTest {
+
+ @Test
+ public void checkUpdatableSketchBuilderReset() {
+ final DoubleSummary.Mode mode = Mode.Sum;
+ UpdatableSketchBuilder<Double, DoubleSummary> bldr =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode));
+ bldr.reset();
+ }
+
+ @Test
+ public void checkStringToByteArray() {
+ Util.stringToByteArray("");
+ }
+
+ @Test
+ public void checkDoubleToLongArray() {
+ final long[] v = Util.doubleToLongArray(-0.0);
+ Assert.assertEquals(v[0], 0);
+ }
+
+}
diff --git
a/src/test/java/org/apache/datasketches/tuple/SerializerDeserializerTest.java
b/src/test/java/org/apache/datasketches/tuple/SerializerDeserializerTest.java
index 61ab3fd..49863f2 100644
---
a/src/test/java/org/apache/datasketches/tuple/SerializerDeserializerTest.java
+++
b/src/test/java/org/apache/datasketches/tuple/SerializerDeserializerTest.java
@@ -19,12 +19,11 @@
package org.apache.datasketches.tuple;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.Family;
import org.apache.datasketches.SketchesArgumentException;
+import org.apache.datasketches.memory.Memory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
@SuppressWarnings("javadoc")
public class SerializerDeserializerTest {
@@ -58,4 +57,9 @@ public class SerializerDeserializerTest {
public void validateFamilyWrongPreambleLength() {
SerializerDeserializer.validateFamily((byte) Family.TUPLE.getID(), (byte)
0);
}
+
+ @Test(expectedExceptions = SketchesArgumentException.class)
+ public void checkBadSeedHash() {
+ org.apache.datasketches.tuple.Util.computeSeedHash(50541);
+ }
}
diff --git
a/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleAnotBTest.java
b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleAnotBTest.java
index bd9d630..2490f5f 100644
--- a/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleAnotBTest.java
+++ b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleAnotBTest.java
@@ -64,6 +64,8 @@ public class AdoubleAnotBTest {
//Stateful w B = Theta
aNotB.setA(sketchA);
aNotB.notB(skThetaB);
+ result = aNotB.getResult(false);
+ results.check(result);
result = aNotB.getResult(true);
results.check(result);
}
diff --git
a/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleIntersectionTest.java
b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleIntersectionTest.java
new file mode 100644
index 0000000..7f8662a
--- /dev/null
+++
b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleIntersectionTest.java
@@ -0,0 +1,332 @@
+/*
+ * 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.datasketches.tuple.adouble;
+
+import static org.testng.Assert.fail;
+
+import org.apache.datasketches.SketchesStateException;
+import org.apache.datasketches.theta.UpdateSketch;
+import org.apache.datasketches.theta.UpdateSketchBuilder;
+import org.apache.datasketches.tuple.CompactSketch;
+import org.apache.datasketches.tuple.Intersection;
+import org.apache.datasketches.tuple.Sketch;
+import org.apache.datasketches.tuple.SketchIterator;
+import org.apache.datasketches.tuple.Sketches;
+import org.apache.datasketches.tuple.UpdatableSketch;
+import org.apache.datasketches.tuple.UpdatableSketchBuilder;
+import org.apache.datasketches.tuple.adouble.DoubleSummary.Mode;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * @author Lee Rhodes
+ */
+@SuppressWarnings("javadoc")
+public class AdoubleIntersectionTest {
+ private final DoubleSummary.Mode mode = Mode.Sum;
+
+ @Test
+ public void intersectionNotEmptyNoEntries() {
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>
+ (new
DoubleSummaryFactory(mode)).setSamplingProbability(0.01f).build();
+ sketch1.update("a", 1.0); // this happens to get rejected because of
sampling with low probability
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ intersection.update(sketch1);
+ CompactSketch<DoubleSummary> result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ Assert.assertFalse(result.isEmpty());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ Assert.assertEquals(result.getLowerBound(1), 0.0, 0.0001);
+ Assert.assertTrue(result.getUpperBound(1) > 0);
+ }
+
+ @Test
+ public void intersectionExactWithNull() {
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ sketch1.update(1, 1.0);
+ sketch1.update(2, 1.0);
+ sketch1.update(3, 1.0);
+
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ intersection.update(sketch1);
+ intersection.update(null);
+ CompactSketch<DoubleSummary> result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ Assert.assertTrue(result.isEmpty());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ Assert.assertEquals(result.getLowerBound(1), 0.0);
+ Assert.assertEquals(result.getUpperBound(1), 0.0);
+ }
+
+ @Test
+ public void intersectionExactWithEmpty() {
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ sketch1.update(1, 1.0);
+ sketch1.update(2, 1.0);
+ sketch1.update(3, 1.0);
+
+ Sketch<DoubleSummary> sketch2 = Sketches.createEmptySketch();
+
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ intersection.update(sketch1);
+ intersection.update(sketch2);
+ CompactSketch<DoubleSummary> result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ Assert.assertTrue(result.isEmpty());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ Assert.assertEquals(result.getLowerBound(1), 0.0);
+ Assert.assertEquals(result.getUpperBound(1), 0.0);
+ }
+
+ @Test
+ public void intersectionExactMode() {
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ sketch1.update(1, 1.0);
+ sketch1.update(1, 1.0);
+ sketch1.update(2, 1.0);
+ sketch1.update(2, 1.0);
+
+ UpdatableSketch<Double, DoubleSummary> sketch2 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ sketch2.update(2, 1.0);
+ sketch2.update(2, 1.0);
+ sketch2.update(3, 1.0);
+ sketch2.update(3, 1.0);
+
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ intersection.update(sketch1);
+ intersection.update(sketch2);
+ CompactSketch<DoubleSummary> result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 1);
+ Assert.assertFalse(result.isEmpty());
+ Assert.assertEquals(result.getEstimate(), 1.0);
+ Assert.assertEquals(result.getLowerBound(1), 1.0);
+ Assert.assertEquals(result.getUpperBound(1), 1.0);
+ SketchIterator<DoubleSummary> it = result.iterator();
+ Assert.assertTrue(it.next());
+ Assert.assertEquals(it.getSummary().getValue(), 4.0);
+ Assert.assertFalse(it.next());
+
+ intersection.reset();
+ intersection.update(null);
+ result = intersection.getResult();
+ Assert.assertTrue(result.isEmpty());
+ Assert.assertFalse(result.isEstimationMode());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ Assert.assertEquals(result.getUpperBound(1), 0.0);
+ Assert.assertEquals(result.getLowerBound(1), 0.0);
+ Assert.assertEquals(result.getTheta(), 1.0);
+}
+
+ @Test
+ public void intersectionDisjointEstimationMode() {
+ int key = 0;
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ for (int i = 0; i < 8192; i++) {
+ sketch1.update(key++, 1.0);
+ }
+
+ UpdatableSketch<Double, DoubleSummary> sketch2 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ for (int i = 0; i < 8192; i++) {
+ sketch2.update(key++, 1.0);
+ }
+
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ intersection.update(sketch1);
+ intersection.update(sketch2);
+ CompactSketch<DoubleSummary> result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ Assert.assertFalse(result.isEmpty());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ Assert.assertEquals(result.getLowerBound(1), 0.0);
+ Assert.assertTrue(result.getUpperBound(1) > 0);
+
+ // an intersection with no entries must survive more updates
+ intersection.update(sketch1);
+ result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ Assert.assertFalse(result.isEmpty());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ Assert.assertEquals(result.getLowerBound(1), 0.0);
+ Assert.assertTrue(result.getUpperBound(1) > 0);
+ }
+
+ @Test
+ public void intersectionEstimationMode() {
+ int key = 0;
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ for (int i = 0; i < 8192; i++) {
+ sketch1.update(key++, 1.0);
+ }
+
+ key -= 4096; // overlap half of the entries
+ UpdatableSketch<Double, DoubleSummary> sketch2 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ for (int i = 0; i < 8192; i++) {
+ sketch2.update(key++, 1.0);
+ }
+
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ intersection.update(sketch1);
+ intersection.update(sketch2);
+ CompactSketch<DoubleSummary> result = intersection.getResult();
+ Assert.assertFalse(result.isEmpty());
+ // crude estimate of RSE(95%) = 2 / sqrt(result.getRetainedEntries())
+ Assert.assertEquals(result.getEstimate(), 4096.0, 4096 * 0.03);
+ Assert.assertTrue(result.getLowerBound(1) <= result.getEstimate());
+ Assert.assertTrue(result.getUpperBound(1) > result.getEstimate());
+ SketchIterator<DoubleSummary> it = result.iterator();
+ while (it.next()) {
+ Assert.assertEquals(it.getSummary().getValue(), 2.0);
+ }
+ }
+
+ @Test
+ public void checkExactIntersectionWithTheta() {
+ UpdateSketch thSkNull = null;
+ UpdateSketch thSkEmpty = new UpdateSketchBuilder().build();
+ UpdateSketch thSk10 = new UpdateSketchBuilder().build();
+ UpdateSketch thSk15 = new UpdateSketchBuilder().build();
+ for (int i = 0; i < 10; i++) { thSk10.update(i); }
+ for (int i = 0; i < 10; i++) { thSk15.update(i + 5); } //overlap = 5
+
+ DoubleSummary dsum = new DoubleSummaryFactory(mode).newSummary();
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ CompactSketch<DoubleSummary> result;
+
+ try { intersection.getResult(); fail(); }
+ catch (SketchesStateException e ) { } //OK.
+
+ intersection.update(thSkNull, dsum);
+ result = intersection.getResult();
+ Assert.assertTrue(result.isEmpty()); //Empty after null first call
+ intersection.reset();
+
+ intersection.update(thSkEmpty, dsum);
+ result = intersection.getResult();
+ Assert.assertTrue(result.isEmpty()); //Empty after empty first call
+ intersection.reset();
+
+ intersection.update(thSk10, dsum);
+ result = intersection.getResult();
+ Assert.assertEquals(result.getEstimate(), 10.0); //Returns valid first call
+ intersection.reset();
+
+ intersection.update(thSk10, dsum); // Valid first call
+ intersection.update(thSkNull, dsum);
+ result = intersection.getResult();
+ Assert.assertTrue(result.isEmpty()); //Returns Empty after null second call
+ intersection.reset();
+
+ intersection.update(thSk10, dsum); // Valid first call
+ intersection.update(thSkEmpty, dsum);
+ result = intersection.getResult();
+ Assert.assertTrue(result.isEmpty()); //Returns Empty after empty second
call
+ intersection.reset();
+
+ intersection.update(thSk10, dsum);
+ intersection.update(thSk15, dsum);
+ result = intersection.getResult();
+ Assert.assertEquals(result.getEstimate(), 5.0); //Returns intersection
+ intersection.reset();
+ }
+
+ @Test
+ public void checkExactIntersectionWithThetaDisjoint() {
+ UpdateSketch thSkA = new
UpdateSketchBuilder().setLogNominalEntries(10).build();
+ UpdateSketch thSkB = new
UpdateSketchBuilder().setLogNominalEntries(10).build();
+ int key = 0;
+ for (int i = 0; i < 32; i++) { thSkA.update(key++); }
+ for (int i = 0; i < 32; i++) { thSkB.update(key++); }
+
+ DoubleSummary dsum = new DoubleSummaryFactory(mode).newSummary();
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ CompactSketch<DoubleSummary> result;
+
+ intersection.update(thSkA, dsum);
+ intersection.update(thSkB, dsum);
+ result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+
+ // an intersection with no entries must survive more updates
+ intersection.update(thSkA, dsum);
+ result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ intersection.reset();
+ }
+
+ @Test
+ public void checkEstimatingIntersectionWithThetaOverlapping() {
+ UpdateSketch thSkA = new
UpdateSketchBuilder().setLogNominalEntries(4).build();
+ UpdateSketch thSkB = new
UpdateSketchBuilder().setLogNominalEntries(10).build();
+ for (int i = 0; i < 64; i++) { thSkA.update(i); } //dense mode, low theta
+ for (int i = 32; i < 96; i++) { thSkB.update(i); } //exact overlapping
+
+ DoubleSummary dsum = new DoubleSummaryFactory(mode).newSummary();
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ CompactSketch<DoubleSummary> result;
+
+ intersection.update(thSkA, dsum);
+ intersection.update(thSkB, dsum);
+ result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 14);
+
+ thSkB.reset();
+ for (int i = 100; i < 164; i++) { thSkB.update(i); } //exact, disjoint
+ intersection.update(thSkB, dsum); //remove existing entries
+ result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ intersection.update(thSkB, dsum);
+ result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ }
+
+ @Test
+ public void intersectionEmpty() {
+ UpdatableSketch<Double, DoubleSummary> sketch =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ Intersection<DoubleSummary> intersection =
+ new Intersection<>(new DoubleSummarySetOperations(mode, mode));
+ intersection.update(sketch);
+ CompactSketch<DoubleSummary> result = intersection.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ Assert.assertTrue(result.isEmpty());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ Assert.assertEquals(result.getLowerBound(1), 0.0);
+ Assert.assertEquals(result.getUpperBound(1), 0.0);
+ }
+
+}
diff --git
a/src/test/java/org/apache/datasketches/tuple/adouble/UpdatableSketchWithDoubleSummaryTest.java
b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleTest.java
similarity index 54%
rename from
src/test/java/org/apache/datasketches/tuple/adouble/UpdatableSketchWithDoubleSummaryTest.java
rename to src/test/java/org/apache/datasketches/tuple/adouble/AdoubleTest.java
index e60a19f..882707f 100644
---
a/src/test/java/org/apache/datasketches/tuple/adouble/UpdatableSketchWithDoubleSummaryTest.java
+++ b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleTest.java
@@ -24,12 +24,9 @@ import static org.testng.Assert.assertEquals;
import org.apache.datasketches.ResizeFactor;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.tuple.CompactSketch;
-import org.apache.datasketches.tuple.Intersection;
import org.apache.datasketches.tuple.Sketch;
import org.apache.datasketches.tuple.SketchIterator;
import org.apache.datasketches.tuple.Sketches;
-import org.apache.datasketches.tuple.Union;
import org.apache.datasketches.tuple.UpdatableSketch;
import org.apache.datasketches.tuple.UpdatableSketchBuilder;
import org.apache.datasketches.tuple.adouble.DoubleSummary.Mode;
@@ -37,7 +34,7 @@ import org.testng.Assert;
import org.testng.annotations.Test;
@SuppressWarnings("javadoc")
-public class UpdatableSketchWithDoubleSummaryTest {
+public class AdoubleTest {
private final DoubleSummary.Mode mode = Mode.Sum;
@Test
@@ -395,299 +392,17 @@ public class UpdatableSketchWithDoubleSummaryTest {
}
@Test
- public void unionEmptySampling() {
- UpdatableSketch<Double, DoubleSummary> sketch =
- new UpdatableSketchBuilder<>(new
DoubleSummaryFactory(mode)).setSamplingProbability(0.01f).build();
- sketch.update(1, 1.0);
- Assert.assertEquals(sketch.getRetainedEntries(), 0); // not retained due
to low sampling probability
-
- Union<DoubleSummary> union = new Union<>(new
DoubleSummarySetOperations(mode, mode));
- union.update(sketch);
- CompactSketch<DoubleSummary> result = union.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 0);
- Assert.assertFalse(result.isEmpty());
- Assert.assertTrue(result.isEstimationMode());
- Assert.assertEquals(result.getEstimate(), 0.0);
- }
-
- @Test
- public void unionExactMode() {
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketch1.update(1, 1.0);
- sketch1.update(1, 1.0);
- sketch1.update(1, 1.0);
- sketch1.update(2, 1.0);
-
- UpdatableSketch<Double, DoubleSummary> sketch2 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketch2.update(2, 1.0);
- sketch2.update(2, 1.0);
- sketch2.update(3, 1.0);
- sketch2.update(3, 1.0);
- sketch2.update(3, 1.0);
-
- Union<DoubleSummary> union = new Union<>(new
DoubleSummarySetOperations(mode, mode));
- union.update(sketch1);
- union.update(sketch2);
- CompactSketch<DoubleSummary> result = union.getResult();
- Assert.assertEquals(result.getEstimate(), 3.0);
-
- SketchIterator<DoubleSummary> it = result.iterator();
- Assert.assertTrue(it.next());
- Assert.assertEquals(it.getSummary().getValue(), 3.0);
- Assert.assertTrue(it.next());
- Assert.assertEquals(it.getSummary().getValue(), 3.0);
- Assert.assertTrue(it.next());
- Assert.assertEquals(it.getSummary().getValue(), 3.0);
- Assert.assertFalse(it.next());
-
- union.reset();
- result = union.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 0);
- Assert.assertTrue(result.isEmpty());
- Assert.assertFalse(result.isEstimationMode());
- Assert.assertEquals(result.getEstimate(), 0.0);
- Assert.assertEquals(result.getLowerBound(1), 0.0);
- Assert.assertEquals(result.getUpperBound(1), 0.0);
- Assert.assertEquals(result.getTheta(), 1.0);
- }
-
- @Test
- public void unionEstimationMode() {
- int key = 0;
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 8192; i++) {
- sketch1.update(key++, 1.0);
- }
-
- key -= 4096; // overlap half of the entries
- UpdatableSketch<Double, DoubleSummary> sketch2 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 8192; i++) {
- sketch2.update(key++, 1.0);
- }
-
- Union<DoubleSummary> union = new Union<>(4096, new
DoubleSummarySetOperations(mode, mode));
- union.update(sketch1);
- union.update(sketch2);
- CompactSketch<DoubleSummary> result = union.getResult();
- Assert.assertEquals(result.getEstimate(), 12288.0, 12288 * 0.01);
- Assert.assertTrue(result.getLowerBound(1) <= result.getEstimate());
- Assert.assertTrue(result.getUpperBound(1) > result.getEstimate());
- }
-
- @Test
- public void unionMixedMode() {
- int key = 0;
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 1000; i++) {
- sketch1.update(key++, 1.0);
- //System.out.println("theta1=" + sketch1.getTheta() + " " +
sketch1.getThetaLong());
- }
-
- key -= 500; // overlap half of the entries
- UpdatableSketch<Double, DoubleSummary> sketch2 =
- new UpdatableSketchBuilder<>
- (new
DoubleSummaryFactory(mode)).setSamplingProbability(0.2f).build();
- for (int i = 0; i < 20000; i++) {
- sketch2.update(key++, 1.0);
- //System.out.println("theta2=" + sketch2.getTheta() + " " +
sketch2.getThetaLong());
- }
-
- Union<DoubleSummary> union = new Union<>(4096, new
DoubleSummarySetOperations(mode, mode));
- union.update(sketch1);
- union.update(sketch2);
- CompactSketch<DoubleSummary> result = union.getResult();
- Assert.assertEquals(result.getEstimate(), 20500.0, 20500 * 0.01);
- Assert.assertTrue(result.getLowerBound(1) <= result.getEstimate());
- Assert.assertTrue(result.getUpperBound(1) > result.getEstimate());
- }
-
- @Test
- public void intersectionEmpty() {
- UpdatableSketch<Double, DoubleSummary> sketch =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- Intersection<DoubleSummary> intersection =
- new Intersection<>(new DoubleSummarySetOperations(mode, mode));
- intersection.update(sketch);
- CompactSketch<DoubleSummary> result = intersection.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 0);
- Assert.assertTrue(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 0.0);
- Assert.assertEquals(result.getLowerBound(1), 0.0);
- Assert.assertEquals(result.getUpperBound(1), 0.0);
- }
-
- @Test
- public void intersectionNotEmptyNoEntries() {
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>
- (new
DoubleSummaryFactory(mode)).setSamplingProbability(0.01f).build();
- sketch1.update("a", 1.0); // this happens to get rejected because of
sampling with low probability
- Intersection<DoubleSummary> intersection =
- new Intersection<>(new DoubleSummarySetOperations(mode, mode));
- intersection.update(sketch1);
- CompactSketch<DoubleSummary> result = intersection.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 0);
- Assert.assertFalse(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 0.0);
- Assert.assertEquals(result.getLowerBound(1), 0.0, 0.0001);
- Assert.assertTrue(result.getUpperBound(1) > 0);
- }
-
- @Test
- public void intersectionExactWithNull() {
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketch1.update(1, 1.0);
- sketch1.update(2, 1.0);
- sketch1.update(3, 1.0);
-
- Intersection<DoubleSummary> intersection =
- new Intersection<>(new DoubleSummarySetOperations(mode, mode));
- intersection.update(sketch1);
- intersection.update(null);
- CompactSketch<DoubleSummary> result = intersection.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 0);
- Assert.assertTrue(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 0.0);
- Assert.assertEquals(result.getLowerBound(1), 0.0);
- Assert.assertEquals(result.getUpperBound(1), 0.0);
- }
-
- @Test
- public void intersectionExactWithEmpty() {
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketch1.update(1, 1.0);
- sketch1.update(2, 1.0);
- sketch1.update(3, 1.0);
-
- Sketch<DoubleSummary> sketch2 = Sketches.createEmptySketch();
-
- Intersection<DoubleSummary> intersection =
- new Intersection<>(new DoubleSummarySetOperations(mode, mode));
- intersection.update(sketch1);
- intersection.update(sketch2);
- CompactSketch<DoubleSummary> result = intersection.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 0);
- Assert.assertTrue(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 0.0);
- Assert.assertEquals(result.getLowerBound(1), 0.0);
- Assert.assertEquals(result.getUpperBound(1), 0.0);
- }
-
- @Test
- public void intersectionExactMode() {
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketch1.update(1, 1.0);
- sketch1.update(1, 1.0);
- sketch1.update(2, 1.0);
- sketch1.update(2, 1.0);
-
- UpdatableSketch<Double, DoubleSummary> sketch2 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketch2.update(2, 1.0);
- sketch2.update(2, 1.0);
- sketch2.update(3, 1.0);
- sketch2.update(3, 1.0);
-
- Intersection<DoubleSummary> intersection =
- new Intersection<>(new DoubleSummarySetOperations(mode, mode));
- intersection.update(sketch1);
- intersection.update(sketch2);
- CompactSketch<DoubleSummary> result = intersection.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 1);
- Assert.assertFalse(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 1.0);
- Assert.assertEquals(result.getLowerBound(1), 1.0);
- Assert.assertEquals(result.getUpperBound(1), 1.0);
- SketchIterator<DoubleSummary> it = result.iterator();
- Assert.assertTrue(it.next());
- Assert.assertEquals(it.getSummary().getValue(), 4.0);
- Assert.assertFalse(it.next());
-
- intersection.reset();
- intersection.update(null);
- result = intersection.getResult();
- Assert.assertTrue(result.isEmpty());
- Assert.assertFalse(result.isEstimationMode());
- Assert.assertEquals(result.getEstimate(), 0.0);
- Assert.assertEquals(result.getUpperBound(1), 0.0);
- Assert.assertEquals(result.getLowerBound(1), 0.0);
- Assert.assertEquals(result.getTheta(), 1.0);
-}
-
- @Test
- public void intersectionDisjointEstimationMode() {
- int key = 0;
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 8192; i++) {
- sketch1.update(key++, 1.0);
- }
-
- UpdatableSketch<Double, DoubleSummary> sketch2 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 8192; i++) {
- sketch2.update(key++, 1.0);
- }
-
- Intersection<DoubleSummary> intersection =
- new Intersection<>(new DoubleSummarySetOperations(mode, mode));
- intersection.update(sketch1);
- intersection.update(sketch2);
- CompactSketch<DoubleSummary> result = intersection.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 0);
- Assert.assertFalse(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 0.0);
- Assert.assertEquals(result.getLowerBound(1), 0.0);
- Assert.assertTrue(result.getUpperBound(1) > 0);
-
- // an intersection with no entries must survive more updates
- intersection.update(sketch1);
- result = intersection.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 0);
- Assert.assertFalse(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 0.0);
- Assert.assertEquals(result.getLowerBound(1), 0.0);
- Assert.assertTrue(result.getUpperBound(1) > 0);
- }
-
- @Test
- public void intersectionEstimationMode() {
- int key = 0;
- UpdatableSketch<Double, DoubleSummary> sketch1 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 8192; i++) {
- sketch1.update(key++, 1.0);
- }
-
- key -= 4096; // overlap half of the entries
- UpdatableSketch<Double, DoubleSummary> sketch2 =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 8192; i++) {
- sketch2.update(key++, 1.0);
- }
-
- Intersection<DoubleSummary> intersection =
- new Intersection<>(new DoubleSummarySetOperations(mode, mode));
- intersection.update(sketch1);
- intersection.update(sketch2);
- CompactSketch<DoubleSummary> result = intersection.getResult();
- Assert.assertFalse(result.isEmpty());
- // crude estimate of RSE(95%) = 2 / sqrt(result.getRetainedEntries())
- Assert.assertEquals(result.getEstimate(), 4096.0, 4096 * 0.03);
- Assert.assertTrue(result.getLowerBound(1) <= result.getEstimate());
- Assert.assertTrue(result.getUpperBound(1) > result.getEstimate());
- SketchIterator<DoubleSummary> it = result.iterator();
- while (it.next()) {
- Assert.assertEquals(it.getSummary().getValue(), 2.0);
- }
+ public void checkUpdatableSketch() {
+ DoubleSummaryFactory dsumFact = new DoubleSummaryFactory(mode);
+ //DoubleSummary dsum = dsumFact.newSummary();
+ UpdatableSketchBuilder<Double, DoubleSummary> bldr = new
UpdatableSketchBuilder<>(dsumFact);
+ UpdatableSketch<Double, DoubleSummary> usk = bldr.build();
+ final byte[] byteArr = new byte[0];
+ usk.update(byteArr, new Double(0));
+ final int[] intArr = new int[0];
+ usk.update(intArr, new Double(1));
+ final long[] longArr = new long[0];
+ usk.update(longArr, new Double(2));
}
@Test(expectedExceptions = SketchesArgumentException.class)
diff --git
a/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleUnionTest.java
b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleUnionTest.java
new file mode 100644
index 0000000..2ef2485
--- /dev/null
+++ b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleUnionTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.datasketches.tuple.adouble;
+
+import org.apache.datasketches.theta.UpdateSketch;
+import org.apache.datasketches.theta.UpdateSketchBuilder;
+import org.apache.datasketches.tuple.CompactSketch;
+import org.apache.datasketches.tuple.SketchIterator;
+import org.apache.datasketches.tuple.Union;
+import org.apache.datasketches.tuple.UpdatableSketch;
+import org.apache.datasketches.tuple.UpdatableSketchBuilder;
+import org.apache.datasketches.tuple.adouble.DoubleSummary.Mode;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * @author Lee Rhodes
+ */
+@SuppressWarnings("javadoc")
+public class AdoubleUnionTest {
+ private final DoubleSummary.Mode mode = Mode.Sum;
+
+ @Test
+ public void unionEmptySampling() {
+ UpdatableSketch<Double, DoubleSummary> sketch =
+ new UpdatableSketchBuilder<>(new
DoubleSummaryFactory(mode)).setSamplingProbability(0.01f).build();
+ sketch.update(1, 1.0);
+ Assert.assertEquals(sketch.getRetainedEntries(), 0); // not retained due
to low sampling probability
+
+ Union<DoubleSummary> union = new Union<>(new
DoubleSummarySetOperations(mode, mode));
+ union.update(sketch);
+ CompactSketch<DoubleSummary> result = union.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ Assert.assertFalse(result.isEmpty());
+ Assert.assertTrue(result.isEstimationMode());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ }
+
+ @Test
+ public void unionExactMode() {
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ sketch1.update(1, 1.0);
+ sketch1.update(1, 1.0);
+ sketch1.update(1, 1.0);
+ sketch1.update(2, 1.0);
+
+ UpdatableSketch<Double, DoubleSummary> sketch2 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ sketch2.update(2, 1.0);
+ sketch2.update(2, 1.0);
+ sketch2.update(3, 1.0);
+ sketch2.update(3, 1.0);
+ sketch2.update(3, 1.0);
+
+ Union<DoubleSummary> union = new Union<>(new
DoubleSummarySetOperations(mode, mode));
+ union.update(sketch1);
+ union.update(sketch2);
+ CompactSketch<DoubleSummary> result = union.getResult();
+ Assert.assertEquals(result.getEstimate(), 3.0);
+
+ SketchIterator<DoubleSummary> it = result.iterator();
+ Assert.assertTrue(it.next());
+ Assert.assertEquals(it.getSummary().getValue(), 3.0);
+ Assert.assertTrue(it.next());
+ Assert.assertEquals(it.getSummary().getValue(), 3.0);
+ Assert.assertTrue(it.next());
+ Assert.assertEquals(it.getSummary().getValue(), 3.0);
+ Assert.assertFalse(it.next());
+
+ union.reset();
+ result = union.getResult();
+ Assert.assertEquals(result.getRetainedEntries(), 0);
+ Assert.assertTrue(result.isEmpty());
+ Assert.assertFalse(result.isEstimationMode());
+ Assert.assertEquals(result.getEstimate(), 0.0);
+ Assert.assertEquals(result.getLowerBound(1), 0.0);
+ Assert.assertEquals(result.getUpperBound(1), 0.0);
+ Assert.assertEquals(result.getTheta(), 1.0);
+ }
+
+ @Test
+ public void unionEstimationMode() {
+ int key = 0;
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ for (int i = 0; i < 8192; i++) {
+ sketch1.update(key++, 1.0);
+ }
+
+ key -= 4096; // overlap half of the entries
+ UpdatableSketch<Double, DoubleSummary> sketch2 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ for (int i = 0; i < 8192; i++) {
+ sketch2.update(key++, 1.0);
+ }
+
+ Union<DoubleSummary> union = new Union<>(4096, new
DoubleSummarySetOperations(mode, mode));
+ union.update(sketch1);
+ union.update(sketch2);
+ CompactSketch<DoubleSummary> result = union.getResult();
+ Assert.assertEquals(result.getEstimate(), 12288.0, 12288 * 0.01);
+ Assert.assertTrue(result.getLowerBound(1) <= result.getEstimate());
+ Assert.assertTrue(result.getUpperBound(1) > result.getEstimate());
+ }
+
+ @Test
+ public void unionMixedMode() {
+ int key = 0;
+ UpdatableSketch<Double, DoubleSummary> sketch1 =
+ new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ for (int i = 0; i < 1000; i++) {
+ sketch1.update(key++, 1.0);
+ //System.out.println("theta1=" + sketch1.getTheta() + " " +
sketch1.getThetaLong());
+ }
+
+ key -= 500; // overlap half of the entries
+ UpdatableSketch<Double, DoubleSummary> sketch2 =
+ new UpdatableSketchBuilder<>
+ (new
DoubleSummaryFactory(mode)).setSamplingProbability(0.2f).build();
+ for (int i = 0; i < 20000; i++) {
+ sketch2.update(key++, 1.0);
+ //System.out.println("theta2=" + sketch2.getTheta() + " " +
sketch2.getThetaLong());
+ }
+
+ Union<DoubleSummary> union = new Union<>(4096, new
DoubleSummarySetOperations(mode, mode));
+ union.update(sketch1);
+ union.update(sketch2);
+ CompactSketch<DoubleSummary> result = union.getResult();
+ Assert.assertEquals(result.getEstimate(), 20500.0, 20500 * 0.01);
+ Assert.assertTrue(result.getLowerBound(1) <= result.getEstimate());
+ Assert.assertTrue(result.getUpperBound(1) > result.getEstimate());
+ }
+
+ @Test
+ public void checkUnionUpdate() {
+ Union<DoubleSummary> union = new Union<>(new
DoubleSummarySetOperations(mode, mode));
+ DoubleSummary dsum = new DoubleSummaryFactory(mode).newSummary();
+ UpdateSketch usk = new UpdateSketchBuilder().build();
+ for (int i = 0; i < 10; i++) { usk.update(i); }
+ union.update(usk, dsum);
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]