You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by le...@apache.org on 2020/05/27 15:34:15 UTC
[incubator-datasketches-java] 01/01: First round changes to extend
tuple sketch to allow set operations with a theta sketch.
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
commit d1d6b4caa9f22cae8f1e7362160f442cef2199c8
Author: Lee Rhodes <le...@users.noreply.github.com>
AuthorDate: Wed May 27 08:33:03 2020 -0700
First round changes to extend tuple sketch to allow set operations with
a theta sketch.
---
.../java/org/apache/datasketches/tuple/AnotB.java | 352 ++++++++++++++++++---
.../apache/datasketches/tuple/Intersection.java | 79 ++++-
.../datasketches/tuple/QuickSelectSketch.java | 2 +-
.../java/org/apache/datasketches/tuple/Union.java | 24 ++
.../tuple/adouble/AdoubleAnotBTest.java | 245 ++++++++++++++
.../UpdatableSketchWithDoubleSummaryTest.java | 189 -----------
.../tuple/aninteger/IntegerSketchTest.java | 30 +-
.../tuple/arrayofdoubles/package-info.java | 24 --
8 files changed, 678 insertions(+), 267 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/tuple/AnotB.java b/src/main/java/org/apache/datasketches/tuple/AnotB.java
index c3db651..cd9f3f6 100644
--- a/src/main/java/org/apache/datasketches/tuple/AnotB.java
+++ b/src/main/java/org/apache/datasketches/tuple/AnotB.java
@@ -22,45 +22,327 @@ package org.apache.datasketches.tuple;
import static org.apache.datasketches.Util.MIN_LG_NOM_LONGS;
import static org.apache.datasketches.Util.REBUILD_THRESHOLD;
import static org.apache.datasketches.Util.ceilingPowerOf2;
+import static org.apache.datasketches.Util.simpleIntLog2;
import java.lang.reflect.Array;
import java.util.Arrays;
import org.apache.datasketches.HashOperations;
+import org.apache.datasketches.theta.HashIterator;
/**
- * Computes a set difference of two generic tuple sketches
+ * Computes a set difference, A-AND-NOT-B, of two generic tuple sketches
* @param <S> Type of Summary
*/
public final class AnotB<S extends Summary> {
- private boolean isEmpty_ = true;
- private long theta_ = Long.MAX_VALUE;
- private long[] keys_;
- private S[] summaries_;
- private int count_;
+ private boolean empty_ = true;
+ private long thetaLong_ = Long.MAX_VALUE;
+ private long[] keys_ = null; //always in compact form, not necessarily sorted
+ private S[] summaries_ = null; //always in compact form, not necessarily sorted
+ private int count_ = 0;
+
+ /**
+ * Sets the given Tuple sketch as the first argument <i>A</i>. This overwrites the internal state of
+ * this AnotB operator with the contents of the given sketch. This sets the stage for multiple
+ * following <i>notB</i> operations.
+ * @param skA The incoming sketch for the first argument, <i>A</i>.
+ */
+ public void setA(final Sketch<S> skA) {
+ if ((skA == null) || skA.isEmpty()) { return; }
+ //skA is not empty
+ empty_ = false;
+ thetaLong_ = skA.getThetaLong();
+ final CompactSketch<S> cskA = (skA instanceof CompactSketch)
+ ? (CompactSketch<S>)skA
+ : ((QuickSelectSketch<S>)skA).compact();
+ keys_ = cskA.keys_;
+ summaries_ = cskA.summaries_;
+ count_ = cskA.getRetainedEntries();
+ }
+
+ /**
+ * Performs an <i>AND NOT</i> operation with the existing internal state of this AnoB operator.
+ * @param skB The incoming Tuple sketch for the second (or following) argument <i>B</i>.
+ */
+ @SuppressWarnings("unchecked")
+ public void notB(final Sketch<S> skB) {
+ if (empty_) { return; }
+ if ((skB == null) || skB.isEmpty()) { return; }
+ //skB is not empty
+ final long thetaLongB = skB.getThetaLong();
+ thetaLong_ = Math.min(thetaLong_, thetaLongB);
+ //Build hashtable and removes keys of skB >= theta
+ final int countB = skB.getRetainedEntries();
+ final long[] hashTableKeysB = convertToHashTable(skB.keys_, countB, thetaLong_);
+
+ //build temporary arrays of skA
+ final long[] tmpKeysA = new long[count_];
+ final S[] tmpSummariesA =
+ (S[]) Array.newInstance(summaries_.getClass().getComponentType(), count_);
+
+ //search for non matches and build temp arrays
+ int nonMatches = 0;
+ for (int i = 0; i < count_; i++) {
+ final long key = keys_[i];
+ if ((key != 0) && (key < thetaLong_)) { //skips keys of A >= theta
+ final int index =
+ HashOperations.hashSearch(hashTableKeysB, simpleIntLog2(hashTableKeysB.length), key);
+ if (index == -1) {
+ tmpKeysA[nonMatches] = key;
+ tmpSummariesA[nonMatches] = summaries_[i];
+ nonMatches++;
+ }
+ }
+ }
+ keys_ = Arrays.copyOfRange(tmpKeysA, 0, nonMatches);
+ summaries_ = Arrays.copyOfRange(tmpSummariesA, 0, nonMatches);
+ count_ = nonMatches;
+ }
+
+ /**
+ * Performs an <i>AND NOT</i> operation with the existing internal state of this AnoB operator.
+ * @param skB The incoming Theta sketch for the second (or following) argument <i>B</i>.
+ */
+ @SuppressWarnings("unchecked")
+ public void notB(final org.apache.datasketches.theta.Sketch skB) {
+ if (empty_) { return; }
+ if ((skB == null) || skB.isEmpty()) { return; }
+ //skB is not empty
+ final long thetaLongB = skB.getThetaLong();
+ thetaLong_ = Math.min(thetaLong_, thetaLongB);
+ //Build hashtable and removes keys of skB >= theta
+ final int countB = skB.getRetainedEntries();
+ final long[] hashTableKeysB =
+ convertToHashTable(extractThetaHashArray(skB, countB), countB, thetaLong_);
+
+ //build temporary arrays of skA
+ final long[] tmpKeysA = new long[count_];
+ final S[] tmpSummariesA =
+ (S[]) Array.newInstance(summaries_.getClass().getComponentType(), count_);
+
+ //search for non matches and build temp arrays
+ int nonMatches = 0;
+ for (int i = 0; i < count_; i++) {
+ final long key = keys_[i];
+ if ((key != 0) && (key < thetaLong_)) { //skips keys of A >= theta
+ final int index =
+ HashOperations.hashSearch(hashTableKeysB, simpleIntLog2(hashTableKeysB.length), key);
+ if (index == -1) {
+ tmpKeysA[nonMatches] = key;
+ tmpSummariesA[nonMatches] = summaries_[i];
+ nonMatches++;
+ }
+ }
+ }
+ keys_ = Arrays.copyOfRange(tmpKeysA, 0, nonMatches);
+ summaries_ = Arrays.copyOfRange(tmpSummariesA, 0, nonMatches);
+ count_ = nonMatches;
+ }
+
+
+ /**
+ * Returns the A-and-not-B set operation on the two given sketches.
+ * A null sketch argument is interpreted as an empty sketch.
+ * This is not an accumulating update.
+ *
+ * @param skA The incoming sketch for the first argument
+ * @param skB The incoming sketch for the second argument
+ * @param <S> Type of Summary
+ * @return the result as a compact sketch
+ */
+ @SuppressWarnings("unchecked")
+ public static <S extends Summary>
+ CompactSketch<S> aNotB(final Sketch<S> skA, final Sketch<S> skB) {
+ if ((skA == null) || skA.isEmpty()) {
+ return new CompactSketch<>(null, null, Long.MAX_VALUE, true);
+ }
+ //skA is not empty
+ final boolean empty = false;
+ final long thetaLongA = skA.getThetaLong();
+ final CompactSketch<S> cskA = (skA instanceof CompactSketch)
+ ? (CompactSketch<S>)skA
+ : ((QuickSelectSketch<S>)skA).compact();
+ final long[] keysA = cskA.keys_;
+ final S[] summariesA = cskA.summaries_;
+ final int countA = cskA.getRetainedEntries();
+
+ if ((skB == null) || skB.isEmpty()) {
+ return new CompactSketch<>(keysA, summariesA, thetaLongA, empty);
+ }
+ //skB is not empty
+ final long thetaLongB = skB.getThetaLong();
+ final long thetaLong = Math.min(thetaLongA, thetaLongB);
+ //Build hashtable and removes keys of skB >= theta
+ final int countB = skB.getRetainedEntries();
+ final long[] hashTableKeysB =
+ convertToHashTable(skB.keys_, countB, thetaLong);
+
+ //build temporary arrays of skA
+ final long[] tmpKeysA = new long[countA];
+ final S[] tmpSummariesA =
+ (S[]) Array.newInstance(summariesA.getClass().getComponentType(), countA);
+
+ //search for non matches and build temp arrays
+ int nonMatches = 0;
+ for (int i = 0; i < countA; i++) {
+ final long key = keysA[i];
+ if ((key != 0) && (key < thetaLong)) { //skips keys of A >= theta
+ final int index =
+ HashOperations.hashSearch(hashTableKeysB, simpleIntLog2(hashTableKeysB.length), key);
+ if (index == -1) {
+ tmpKeysA[nonMatches] = key;
+ tmpSummariesA[nonMatches] = summariesA[i];
+ nonMatches++;
+ }
+ }
+ }
+ final long[] keys = Arrays.copyOfRange(tmpKeysA, 0, nonMatches);
+ final S[] summaries = Arrays.copyOfRange(tmpSummariesA, 0, nonMatches);
+ final CompactSketch<S> result =
+ new CompactSketch<>(keys, summaries, thetaLong, empty);
+ return result;
+ }
+
+ /**
+ * Returns the A-and-not-B set operation on a Tuple sketch and a Theta sketch.
+ * A null sketch argument is interpreted as an empty sketch.
+ * This is not an accumulating update.
+ *
+ * @param skA The incoming Tuple sketch for the first argument
+ * @param skB The incoming Theta sketch for the second argument
+ * @param <S> Type of Summary
+ * @return the result as a compact sketch
+ */
+ @SuppressWarnings("unchecked")
+ public static <S extends Summary>
+ CompactSketch<S> aNotB(final Sketch<S> skA, final org.apache.datasketches.theta.Sketch skB) {
+ if ((skA == null) || skA.isEmpty()) {
+ return new CompactSketch<>(null, null, Long.MAX_VALUE, true);
+ }
+ //skA is not empty
+ final boolean empty = false;
+ final long thetaLongA = skA.getThetaLong();
+ final CompactSketch<S> cskA = (skA instanceof CompactSketch)
+ ? (CompactSketch<S>)skA
+ : ((QuickSelectSketch<S>)skA).compact();
+ final long[] keysA = cskA.keys_;
+ final S[] summariesA = cskA.summaries_;
+ final int countA = cskA.getRetainedEntries();
+
+ if ((skB == null) || skB.isEmpty()) {
+ return new CompactSketch<>(keysA, summariesA, thetaLongA, empty);
+ }
+ //skB is not empty
+ final long thetaLongB = skB.getThetaLong();
+ final long thetaLong = Math.min(thetaLongA, thetaLongB);
+ //Build hashtable and removes keys of skB >= theta
+ final int countB = skB.getRetainedEntries();
+ final long[] hashTableKeysB =
+ convertToHashTable(extractThetaHashArray(skB, countB), countB, thetaLong);
+
+ //build temporary arrays of skA
+ final long[] tmpKeysA = new long[countA];
+ final S[] tmpSummariesA =
+ (S[]) Array.newInstance(summariesA.getClass().getComponentType(), countA);
+
+ //search for non matches and build temp arrays
+ int nonMatches = 0;
+ for (int i = 0; i < countA; i++) {
+ final long key = keysA[i];
+ if ((key != 0) && (key < thetaLong)) { //skips keys of A >= theta
+ final int index =
+ HashOperations.hashSearch(hashTableKeysB, simpleIntLog2(hashTableKeysB.length), key);
+ if (index == -1) {
+ tmpKeysA[nonMatches] = key;
+ tmpSummariesA[nonMatches] = summariesA[i];
+ nonMatches++;
+ }
+ }
+ }
+ final long[] keys = Arrays.copyOfRange(tmpKeysA, 0, nonMatches);
+ final S[] summaries = Arrays.copyOfRange(tmpSummariesA, 0, nonMatches);
+ final CompactSketch<S> result =
+ new CompactSketch<>(keys, summaries, thetaLong, empty);
+ return result;
+ }
+
+ /**
+ * Gets the result of this operation.
+ * @param reset if true, clears this operator to the empty state after result is returned.
+ * @return the result of this operation as a CompactSketch.
+ */
+ public CompactSketch<S> getResult(final boolean reset) {
+ if (count_ == 0) {
+ return new CompactSketch<>(null, null, thetaLong_, empty_);
+ }
+ final CompactSketch<S> result =
+ new CompactSketch<>(Arrays.copyOfRange(keys_, 0, count_),
+ Arrays.copyOfRange(summaries_, 0, count_), thetaLong_, empty_);
+ if (reset) { reset(); }
+ return result;
+ }
+
+ private static long[] extractThetaHashArray(
+ final org.apache.datasketches.theta.Sketch sketch,
+ final int count) {
+ final HashIterator itr = sketch.iterator();
+ final long[] hashArr = new long[count];
+ int ctr = 0;
+ while (itr.next()) {
+ hashArr[ctr++] = itr.get();
+ }
+ assert ctr == count;
+ return hashArr;
+ }
+
+ private static long[] convertToHashTable(final long[] keysArr, final int count, final long thetaLong) {
+ final int size = Math.max(
+ ceilingPowerOf2((int) Math.ceil(count / REBUILD_THRESHOLD)),
+ 1 << MIN_LG_NOM_LONGS
+ );
+ final long[] hashTable = new long[size];
+ HashOperations.hashArrayInsert(
+ keysArr, hashTable, Integer.numberOfTrailingZeros(size), thetaLong);
+ return hashTable;
+ }
+
+ private void reset() {
+ empty_ = true;
+ thetaLong_ = Long.MAX_VALUE;
+ keys_ = null;
+ summaries_ = null;
+ count_ = 0;
+ }
+
+ //Deprecated methods
/**
* Perform A-and-not-B set operation on the two given sketches.
* A null sketch is interpreted as an empty sketch.
- * This is not an accumulating update. Calling update() more than once
- * without calling getResult() will discard the result of previous update()
+ * This is not an accumulating update. Calling this update() more than once
+ * without calling getResult() will discard the result of previous update() by this method.
+ * The result is obtained by calling getResult();
*
* @param a The incoming sketch for the first argument
* @param b The incoming sketch for the second argument
+ * @deprecated After release 2.0.0. Instead please use {@link #aNotB(Sketch, Sketch)}
+ * or a combination of {@link #setA(Sketch)} and
+ * {@link #notB(Sketch)} with {@link #getResult(boolean)}.
*/
@SuppressWarnings("unchecked")
+ @Deprecated
public void update(final Sketch<S> a, final Sketch<S> b) {
- if (a != null) { isEmpty_ = a.isEmpty(); } //stays this way even if we end up with no result entries
+ if (a != null) { empty_ = a.isEmpty(); } //stays this way even if we end up with no result entries
final long thetaA = a == null ? Long.MAX_VALUE : a.getThetaLong();
final long thetaB = b == null ? Long.MAX_VALUE : b.getThetaLong();
- theta_ = Math.min(thetaA, thetaB);
- if (a == null || a.getRetainedEntries() == 0) { return; }
- if (b == null || b.getRetainedEntries() == 0) {
- getNoMatchSetFromSketch(a);
+ thetaLong_ = Math.min(thetaA, thetaB);
+ if ((a == null) || (a.getRetainedEntries() == 0)) { return; }
+ if ((b == null) || (b.getRetainedEntries() == 0)) {
+ loadCompactedArrays(a);
} else {
final long[] hashTable;
if (b instanceof CompactSketch) {
- hashTable = convertToHashTable(b);
+ hashTable = convertToHashTable(b.keys_, b.getRetainedEntries(), thetaLong_);
} else {
hashTable = b.keys_;
}
@@ -69,7 +351,7 @@ public final class AnotB<S extends Summary> {
keys_ = new long[noMatchSize];
summaries_ = (S[]) Array.newInstance(a.summaries_.getClass().getComponentType(), noMatchSize);
for (int i = 0; i < a.keys_.length; i++) {
- if (a.keys_[i] != 0 && a.keys_[i] < theta_) {
+ if ((a.keys_[i] != 0) && (a.keys_[i] < thetaLong_)) {
final int index = HashOperations.hashSearch(hashTable, lgHashTableSize, a.keys_[i]);
if (index == -1) {
keys_[count_] = a.keys_[i];
@@ -82,40 +364,31 @@ public final class AnotB<S extends Summary> {
}
/**
- * Gets the result of this operation
+ * Gets the result of this operation. This clears the state of this operator after the result is
+ * returned.
* @return the result of this operation as a CompactSketch
+ * @deprecated Only used with deprecated {@link #update(Sketch,Sketch)}.
+ * Instead use {@link #aNotB(Sketch, Sketch)} or a combination of {@link #setA(Sketch)} and
+ * {@link #notB(Sketch)} with {@link #getResult(boolean)}.
*/
+ @Deprecated
public CompactSketch<S> getResult() {
if (count_ == 0) {
- return new CompactSketch<S>(null, null, theta_, isEmpty_);
+ return new CompactSketch<>(null, null, thetaLong_, empty_);
}
final CompactSketch<S> result =
- new CompactSketch<S>(Arrays.copyOfRange(keys_, 0, count_),
- Arrays.copyOfRange(summaries_, 0, count_), theta_, isEmpty_);
+ new CompactSketch<>(Arrays.copyOfRange(keys_, 0, count_),
+ Arrays.copyOfRange(summaries_, 0, count_), thetaLong_, empty_);
reset();
return result;
}
- private long[] convertToHashTable(final Sketch<S> sketch) {
- final int size = Math.max(
- ceilingPowerOf2((int) Math.ceil(sketch.getRetainedEntries() / REBUILD_THRESHOLD)),
- 1 << MIN_LG_NOM_LONGS
- );
- final long[] hashTable = new long[size];
- HashOperations.hashArrayInsert(
- sketch.keys_, hashTable, Integer.numberOfTrailingZeros(size), theta_);
- return hashTable;
- }
-
- private void reset() {
- isEmpty_ = true;
- theta_ = Long.MAX_VALUE;
- keys_ = null;
- summaries_ = null;
- count_ = 0;
- }
-
- private void getNoMatchSetFromSketch(final Sketch<S> sketch) {
+ /**
+ * Only used by deprecated {@link #update(Sketch, Sketch)}.
+ * Remove at the same time other deprecated methods are removed.
+ * @param sketch the given sketch to extract arrays from.
+ */
+ private void loadCompactedArrays(final Sketch<S> sketch) {
if (sketch instanceof CompactSketch) {
keys_ = sketch.keys_.clone();
summaries_ = sketch.summaries_.clone();
@@ -126,4 +399,5 @@ public final class AnotB<S extends Summary> {
}
count_ = sketch.getRetainedEntries();
}
+
}
diff --git a/src/main/java/org/apache/datasketches/tuple/Intersection.java b/src/main/java/org/apache/datasketches/tuple/Intersection.java
index 826d241..0c32089 100644
--- a/src/main/java/org/apache/datasketches/tuple/Intersection.java
+++ b/src/main/java/org/apache/datasketches/tuple/Intersection.java
@@ -71,7 +71,6 @@ public class Intersection<S extends Summary> {
sketch_ = null;
return;
}
- // assumes that constructor of QuickSelectSketch bumps the requested size up to the nearest power of 2
if (isFirstCall) {
sketch_ = new QuickSelectSketch<>(sketchIn.getRetainedEntries(), ResizeFactor.X1.lg(), null);
final SketchIterator<S> it = sketchIn.iterator();
@@ -89,19 +88,21 @@ public class Intersection<S extends Summary> {
int matchCount = 0;
final SketchIterator<S> it = sketchIn.iterator();
while (it.next()) {
- final S summary = sketch_.find(it.getKey());
- if (summary != null) {
- matchKeys[matchCount] = it.getKey();
+ final long key = it.getKey();
+ final S summary = sketch_.find(key);
+ if (summary != null) { //key found
+ matchKeys[matchCount] = key;
if (matchSummaries == null) {
matchSummaries = (S[]) Array.newInstance(summary.getClass(), matchSize);
}
- matchSummaries[matchCount] =
- summarySetOps_.intersection(summary, it.getSummary());
+ matchSummaries[matchCount] = summarySetOps_.intersection(summary, it.getSummary());
matchCount++;
}
}
sketch_ = null;
- if (matchCount > 0) {
+ if (matchCount > 0) { //therefore matchSummaries != null.
+ // assumes that constructor of QuickSelectSketch bumps the requested size
+ // up to the nearest power of 2
sketch_ = new QuickSelectSketch<>(matchCount, ResizeFactor.X1.lg(), null);
for (int i = 0; i < matchCount; i++) {
sketch_.insert(matchKeys[i], matchSummaries[i]);
@@ -115,6 +116,70 @@ public class Intersection<S extends Summary> {
}
/**
+ * Updates the internal set by intersecting it with the given Theta sketch
+ * @param sketchIn input Theta Sketch to intersect with the internal set
+ * @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;
+ if (sketchIn == null) {
+ isEmpty_ = true;
+ sketch_ = null;
+ return;
+ }
+ theta_ = min(theta_, sketchIn.getThetaLong());
+ isEmpty_ |= sketchIn.isEmpty();
+ if (isEmpty_ || (sketchIn.getRetainedEntries() == 0)) {
+ sketch_ = null;
+ return;
+ }
+ if (isFirstCall) {
+ sketch_ = new QuickSelectSketch<>(sketchIn.getRetainedEntries(), ResizeFactor.X1.lg(), null);
+ final org.apache.datasketches.theta.HashIterator it = sketchIn.iterator();
+ while (it.next()) {
+ sketch_.insert(it.get(), (S)summary.copy());
+ }
+ } else {
+ if (sketch_ == null) {
+ return;
+ }
+ final int matchSize = min(sketch_.getRetainedEntries(), sketchIn.getRetainedEntries());
+ final long[] matchKeys = new long[matchSize];
+ S[] matchSummaries = null;
+ int matchCount = 0;
+ final org.apache.datasketches.theta.HashIterator it = sketchIn.iterator();
+ while (it.next()) {
+ final long key = it.get();
+ 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[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
+ sketch_ = new QuickSelectSketch<>(matchCount, ResizeFactor.X1.lg(), null);
+ for (int i = 0; i < matchCount; i++) {
+ sketch_.insert(matchKeys[i], matchSummaries[i]);
+ }
+ }
+ }
+ if (sketch_ != null) {
+ sketch_.setThetaLong(theta_);
+ sketch_.setNotEmpty();
+ }
+ }
+
+
+ /**
* Gets the internal set as a CompactSketch
* @return result of the intersections so far
*/
diff --git a/src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java b/src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java
index a50d920..be41ed0 100644
--- a/src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java
+++ b/src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java
@@ -375,7 +375,7 @@ class QuickSelectSketch<S extends Summary> extends Sketch<S> {
if (key < theta_) {
final int index = findOrInsert(key);
if (index < 0) {
- insertSummary(~index, (S)summary.copy());
+ insertSummary(~index, (S)summary.copy()); //did not find so insert
} else {
insertSummary(index, summarySetOps.union(summaries_[index], summary));
}
diff --git a/src/main/java/org/apache/datasketches/tuple/Union.java b/src/main/java/org/apache/datasketches/tuple/Union.java
index 7800b55..d691cc4 100644
--- a/src/main/java/org/apache/datasketches/tuple/Union.java
+++ b/src/main/java/org/apache/datasketches/tuple/Union.java
@@ -25,6 +25,7 @@ import static org.apache.datasketches.Util.DEFAULT_NOMINAL_ENTRIES;
import java.lang.reflect.Array;
import org.apache.datasketches.QuickSelect;
+import org.apache.datasketches.SketchesArgumentException;
/**
* Compute a union of two or more tuple sketches.
@@ -78,6 +79,29 @@ public class Union<S extends Summary> {
}
/**
+ * Updates the internal set by combining entries using the hash keys from the Theta Sketch and
+ * summary values from the given summary and rules from the summarySetOps defined by the
+ * Union constructor.
+ * @param sketchIn the given Theta Sketch input.
+ * @param summary the given proxy summary for the Theta Sketch, which doesn't have one.
+ */
+ @SuppressWarnings("unchecked")
+ public void update(final org.apache.datasketches.theta.Sketch sketchIn, final S summary) {
+ if ((sketchIn == null) || sketchIn.isEmpty()) { return; }
+ if (summary == null) { throw new SketchesArgumentException("Summary cannot be null."); }
+ isEmpty_ = false;
+ final long thetaIn = sketchIn.getThetaLong();
+ if (thetaIn < theta_) { theta_ = thetaIn; }
+ final org.apache.datasketches.theta.HashIterator it = sketchIn.iterator();
+ while (it.next()) {
+ sketch_.merge(it.get(), (S)summary.copy(), summarySetOps_);
+ }
+ if (sketch_.theta_ < theta_) {
+ theta_ = sketch_.theta_;
+ }
+ }
+
+ /**
* Gets the internal set as a CompactSketch
* @return result of the unions so far
*/
diff --git a/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleAnotBTest.java b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleAnotBTest.java
new file mode 100644
index 0000000..bd9d630
--- /dev/null
+++ b/src/test/java/org/apache/datasketches/tuple/adouble/AdoubleAnotBTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import org.apache.datasketches.theta.UpdateSketch;
+import org.apache.datasketches.theta.UpdateSketchBuilder;
+import org.apache.datasketches.tuple.AnotB;
+import org.apache.datasketches.tuple.CompactSketch;
+import org.apache.datasketches.tuple.Sketch;
+import org.apache.datasketches.tuple.SketchIterator;
+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 AdoubleAnotBTest {
+ private final DoubleSummary.Mode mode = Mode.Sum;
+ private final Results results = new Results();
+
+ private static void threeMethodsWithTheta(
+ final AnotB<DoubleSummary> aNotB,
+ final Sketch<DoubleSummary> sketchA,
+ final Sketch<DoubleSummary> sketchB,
+ final org.apache.datasketches.theta.Sketch skThetaB,
+ final Results results) {
+ //deprecated
+ aNotB.update(sketchA, sketchB);
+ CompactSketch<DoubleSummary> result = aNotB.getResult();
+ results.check(result);
+ //Stateless
+ result = AnotB.aNotB(sketchA, sketchB);
+ results.check(result);
+ result = AnotB.aNotB(sketchA, skThetaB);
+ //Stateful w B = Tuple
+ aNotB.setA(sketchA);
+ aNotB.notB(sketchB);
+ result = aNotB.getResult(true);
+ results.check(result);
+ //Stateful w B = Theta
+ aNotB.setA(sketchA);
+ aNotB.notB(skThetaB);
+ result = aNotB.getResult(true);
+ results.check(result);
+ }
+
+ private static class Results {
+ private int retEnt = 0;
+ private boolean empty = true;
+ private double expect = 0.0;
+ private double toll = 0.0;
+ private double sum = 0.0;
+
+ Results() {}
+
+ Results set(final int retEnt, final boolean empty,
+ final double expect, final double toll, final double sum) {
+ this.retEnt = retEnt;
+ this.empty = empty;
+ this.expect = expect;
+ this.toll = toll;
+ this.sum = sum;
+ return this;
+ }
+
+ void check(final CompactSketch<DoubleSummary> result) {
+ assertEquals(result.getRetainedEntries(), retEnt);
+ assertEquals(result.isEmpty(), empty);
+ if (result.getTheta() < 1.0) {
+ double est = result.getEstimate();
+ assertEquals(est, expect, expect * toll);
+ assertTrue(result.getUpperBound(1) > est);
+ assertTrue(result.getLowerBound(1) <= est);
+ } else {
+ assertEquals(result.getEstimate(), expect, 0.0);
+ assertEquals(result.getUpperBound(1), expect, 0.0);
+ assertEquals(result.getLowerBound(1), expect, 0.0);
+ }
+ SketchIterator<DoubleSummary> it = result.iterator();
+ while (it.next()) {
+ Assert.assertEquals(it.getSummary().getValue(), sum);
+ }
+ }
+ }
+
+ private UpdatableSketch<Double, DoubleSummary> buildUpdatableTuple() {
+ return new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
+ }
+
+ private static UpdateSketch buildUpdateTheta() {
+ return new UpdateSketchBuilder().build();
+ }
+
+ /*****************************************/
+
+ @Test
+ public void aNotBNullEmptyCombinations() {
+ AnotB<DoubleSummary> aNotB = new AnotB<>();
+ // calling getResult() before calling update() should yield an empty set
+ CompactSketch<DoubleSummary> result = aNotB.getResult();
+ results.set(0, true, 0.0, 0.0, 0.0).check(result);
+
+ UpdatableSketch<Double, DoubleSummary> sketch = buildUpdatableTuple();
+ UpdateSketch skTheta = buildUpdateTheta();
+
+ threeMethodsWithTheta(aNotB, null, null, null, results);
+ threeMethodsWithTheta(aNotB, sketch, null, null, results);
+ threeMethodsWithTheta(aNotB, null, sketch, null, results);
+ threeMethodsWithTheta(aNotB, sketch, sketch, null, results);
+ threeMethodsWithTheta(aNotB, null, null, skTheta, results);
+ threeMethodsWithTheta(aNotB, sketch, null, skTheta, results);
+ threeMethodsWithTheta(aNotB, null, sketch, skTheta, results);
+ threeMethodsWithTheta(aNotB, sketch, sketch, skTheta, results);
+ }
+
+ @Test
+ public void aNotBEmptyExact() {
+ UpdatableSketch<Double, DoubleSummary> sketchA = buildUpdatableTuple();
+ UpdatableSketch<Double, DoubleSummary> sketchB = buildUpdatableTuple();
+ sketchB.update(1, 1.0);
+ sketchB.update(2, 1.0);
+ UpdateSketch skThetaB = buildUpdateTheta();
+ skThetaB.update(1);
+ skThetaB.update(2);
+
+ AnotB<DoubleSummary> aNotB = new AnotB<>();
+ results.set(0, true, 0.0, 0.0, 0.0);
+ threeMethodsWithTheta(aNotB, sketchA, sketchB, skThetaB, results);
+ }
+
+ @Test
+ public void aNotBExactEmpty() {
+ UpdatableSketch<Double, DoubleSummary> sketchA = buildUpdatableTuple();
+ sketchA.update(1, 1.0);
+ sketchA.update(2, 1.0);
+ UpdatableSketch<Double, DoubleSummary> sketchB = buildUpdatableTuple();
+ UpdateSketch skThetaB = buildUpdateTheta();
+
+ AnotB<DoubleSummary> aNotB = new AnotB<>();
+ results.set(2, false, 2.0, 0.0, 1.0);
+ threeMethodsWithTheta(aNotB, sketchA, sketchB, skThetaB, results);
+
+ // same thing, but compact sketches
+ threeMethodsWithTheta(aNotB, sketchA.compact(), sketchB.compact(), skThetaB.compact(), results);
+ }
+
+ @Test
+ public void aNotBExactOverlap() {
+ UpdatableSketch<Double, DoubleSummary> sketchA = buildUpdatableTuple();
+ sketchA.update(1, 1.0);
+ sketchA.update(1, 1.0);
+ sketchA.update(2, 1.0);
+ sketchA.update(2, 1.0);
+
+ UpdatableSketch<Double, DoubleSummary> sketchB = buildUpdatableTuple();
+ sketchB.update(2, 1.0);
+ sketchB.update(2, 1.0);
+ sketchB.update(3, 1.0);
+ sketchB.update(3, 1.0);
+
+ UpdateSketch skThetaB = buildUpdateTheta();
+ skThetaB.update(2);
+ skThetaB.update(3);
+
+ AnotB<DoubleSummary> aNotB = new AnotB<>();
+ results.set(1, false, 1.0, 0.0, 2.0);
+ threeMethodsWithTheta(aNotB, sketchA, sketchB, skThetaB, results);
+ }
+
+ @Test
+ public void aNotBEstimationOverlap() {
+ UpdatableSketch<Double, DoubleSummary> sketchA = buildUpdatableTuple();
+ for (int i = 0; i < 8192; i++) {
+ sketchA.update(i, 1.0);
+ }
+
+ UpdatableSketch<Double, DoubleSummary> sketchB = buildUpdatableTuple();
+ for (int i = 0; i < 4096; i++) {
+ sketchB.update(i, 1.0);
+ }
+
+ UpdateSketch skThetaB = buildUpdateTheta();
+ for (int i = 0; i < 4096; i++) {
+ skThetaB.update(i);
+ }
+
+ AnotB<DoubleSummary> aNotB = new AnotB<>();
+ results.set(2124, false, 4096.0, 0.03, 1.0);
+ threeMethodsWithTheta(aNotB, sketchA, sketchB, skThetaB, results);
+
+ // same thing, but compact sketches
+ threeMethodsWithTheta(aNotB, sketchA.compact(), sketchB.compact(), skThetaB.compact(), results);
+ }
+
+ @Test
+ public void aNotBEstimationOverlapLargeB() {
+ UpdatableSketch<Double, DoubleSummary> sketchA = buildUpdatableTuple();
+ for (int i = 0; i < 10_000; i++) {
+ sketchA.update(i, 1.0);
+ }
+
+ UpdatableSketch<Double, DoubleSummary> sketchB = buildUpdatableTuple();
+ for (int i = 0; i < 100_000; i++) {
+ sketchB.update(i + 8000, 1.0);
+ }
+
+ UpdateSketch skThetaB = buildUpdateTheta();
+ for (int i = 0; i < 100_000; i++) {
+ skThetaB.update(i + 8000);
+ }
+
+ final int expected = 8_000;
+ AnotB<DoubleSummary> aNotB = new AnotB<>();
+ results.set(376, false, expected, 0.1, 1.0);
+ threeMethodsWithTheta(aNotB, sketchA, sketchB, skThetaB, results);
+
+ // same thing, but compact sketches
+ threeMethodsWithTheta(aNotB, sketchA.compact(), sketchB.compact(), skThetaB.compact(), results);
+ }
+
+}
diff --git a/src/test/java/org/apache/datasketches/tuple/adouble/UpdatableSketchWithDoubleSummaryTest.java b/src/test/java/org/apache/datasketches/tuple/adouble/UpdatableSketchWithDoubleSummaryTest.java
index e78e404..2d5e075 100644
--- a/src/test/java/org/apache/datasketches/tuple/adouble/UpdatableSketchWithDoubleSummaryTest.java
+++ b/src/test/java/org/apache/datasketches/tuple/adouble/UpdatableSketchWithDoubleSummaryTest.java
@@ -24,7 +24,6 @@ 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.AnotB;
import org.apache.datasketches.tuple.CompactSketch;
import org.apache.datasketches.tuple.Intersection;
import org.apache.datasketches.tuple.Sketch;
@@ -691,194 +690,6 @@ public class UpdatableSketchWithDoubleSummaryTest {
}
}
- @Test
- public void aNotBEmpty() {
- AnotB<DoubleSummary> aNotB = new AnotB<>();
- // calling getResult() before calling update() should yield an empty set
- CompactSketch<DoubleSummary> result = aNotB.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);
-
- aNotB.update(null, null);
- result = aNotB.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);
-
- UpdatableSketch<Double, DoubleSummary> sketch =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- aNotB.update(sketch, sketch);
- result = aNotB.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 aNotBEmptyA() {
- UpdatableSketch<Double, DoubleSummary> sketchA =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
-
- UpdatableSketch<Double, DoubleSummary> sketchB =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketchB.update(1, 1.0);
- sketchB.update(2, 1.0);
-
- AnotB<DoubleSummary> aNotB = new AnotB<>();
- aNotB.update(sketchA, sketchB);
- CompactSketch<DoubleSummary> result = aNotB.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 aNotBEmptyB() {
- UpdatableSketch<Double, DoubleSummary> sketchA =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketchA.update(1, 1.0);
- sketchA.update(2, 1.0);
-
- UpdatableSketch<Double, DoubleSummary> sketchB =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
-
- AnotB<DoubleSummary> aNotB = new AnotB<>();
- aNotB.update(sketchA, sketchB);
- CompactSketch<DoubleSummary> result = aNotB.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 2);
- Assert.assertFalse(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 2.0);
- Assert.assertEquals(result.getLowerBound(1), 2.0);
- Assert.assertEquals(result.getUpperBound(1), 2.0);
-
- // same thing, but compact sketches
- aNotB.update(sketchA.compact(), sketchB.compact());
- result = aNotB.getResult();
- Assert.assertEquals(result.getRetainedEntries(), 2);
- Assert.assertFalse(result.isEmpty());
- Assert.assertEquals(result.getEstimate(), 2.0);
- Assert.assertEquals(result.getLowerBound(1), 2.0);
- Assert.assertEquals(result.getUpperBound(1), 2.0);
- }
-
- @Test
- public void aNotBExactMode() {
- UpdatableSketch<Double, DoubleSummary> sketchA =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketchA.update(1, 1.0);
- sketchA.update(1, 1.0);
- sketchA.update(2, 1.0);
- sketchA.update(2, 1.0);
-
- UpdatableSketch<Double, DoubleSummary> sketchB =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- sketchB.update(2, 1.0);
- sketchB.update(2, 1.0);
- sketchB.update(3, 1.0);
- sketchB.update(3, 1.0);
-
- AnotB<DoubleSummary> aNotB = new AnotB<>();
- aNotB.update(sketchA, sketchB);
- CompactSketch<DoubleSummary> result = aNotB.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(), 2.0);
- Assert.assertFalse(it.next());
- }
-
- @Test
- public void aNotBEstimationMode() {
- int key = 0;
- UpdatableSketch<Double, DoubleSummary> sketchA =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 8192; i++) {
- sketchA.update(key++, 1.0);
- }
-
- key -= 4096; // overlap half of the entries
- UpdatableSketch<Double, DoubleSummary> sketchB =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 8192; i++) {
- sketchB.update(key++, 1.0);
- }
-
- AnotB<DoubleSummary> aNotB = new AnotB<>();
- aNotB.update(sketchA, sketchB);
- CompactSketch<DoubleSummary> result = aNotB.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(), 1.0);
- }
-
- // same thing, but compact sketches
- aNotB.update(sketchA.compact(), sketchB.compact());
- result = aNotB.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());
- it = result.iterator();
- while (it.next()) {
- Assert.assertEquals(it.getSummary().getValue(), 1.0);
- }
- }
-
- @Test
- public void aNotBEstimationModeLargeB() {
- int key = 0;
- UpdatableSketch<Double, DoubleSummary> sketchA =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 10000; i++) {
- sketchA.update(key++, 1.0);
- }
-
- key -= 2000; // overlap
- UpdatableSketch<Double, DoubleSummary> sketchB =
- new UpdatableSketchBuilder<>(new DoubleSummaryFactory(mode)).build();
- for (int i = 0; i < 100000; i++) {
- sketchB.update(key++, 1.0);
- }
-
- final int expected = 10000 - 2000;
- AnotB<DoubleSummary> aNotB = new AnotB<>();
- aNotB.update(sketchA, sketchB);
- CompactSketch<DoubleSummary> result = aNotB.getResult();
- Assert.assertFalse(result.isEmpty());
- // crude estimate of RSE(95%) = 2 / sqrt(result.getRetainedEntries())
- Assert.assertEquals(result.getEstimate(), expected, expected * 0.1);
- Assert.assertTrue(result.getLowerBound(1) <= result.getEstimate());
- Assert.assertTrue(result.getUpperBound(1) > result.getEstimate());
-
- // same thing, but compact sketches
- aNotB.update(sketchA.compact(), sketchB.compact());
- result = aNotB.getResult();
- Assert.assertFalse(result.isEmpty());
- // crude estimate of RSE(95%) = 2 / sqrt(result.getRetainedEntries())
- Assert.assertEquals(result.getEstimate(), expected, expected * 0.1);
- Assert.assertTrue(result.getLowerBound(1) <= result.getEstimate());
- Assert.assertTrue(result.getUpperBound(1) > result.getEstimate());
- }
-
@Test(expectedExceptions = SketchesArgumentException.class)
public void invalidSamplingProbability() {
new UpdatableSketchBuilder<>
diff --git a/src/test/java/org/apache/datasketches/tuple/aninteger/IntegerSketchTest.java b/src/test/java/org/apache/datasketches/tuple/aninteger/IntegerSketchTest.java
index 34b586f..217b066 100644
--- a/src/test/java/org/apache/datasketches/tuple/aninteger/IntegerSketchTest.java
+++ b/src/test/java/org/apache/datasketches/tuple/aninteger/IntegerSketchTest.java
@@ -22,6 +22,7 @@ package org.apache.datasketches.tuple.aninteger;
import static org.testng.Assert.assertEquals;
import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.tuple.AnotB;
import org.apache.datasketches.tuple.CompactSketch;
import org.apache.datasketches.tuple.Intersection;
import org.testng.annotations.Test;
@@ -39,8 +40,8 @@ public class IntegerSketchTest {
IntegerSummary.Mode a1Mode = IntegerSummary.Mode.AlwaysOne;
IntegerSketch a1Sk = new IntegerSketch(lgK, a1Mode);
int m = 2 * K;
- for (int key = 0; key < m; key++) {
- a1Sk.update(key, 1);
+ for (int i = 0; i < m; i++) {
+ a1Sk.update(i, 1);
}
double est1 = a1Sk.getEstimate();
Memory mem = Memory.wrap(a1Sk.toByteArray());
@@ -57,9 +58,9 @@ public class IntegerSketchTest {
IntegerSketch a1Sk1 = new IntegerSketch(lgK, a1Mode);
IntegerSketch a1Sk2 = new IntegerSketch(lgK, a1Mode);
int m = 2 * K;
- for (int key = 0; key < m; key++) {
- a1Sk1.update(key, 1);
- a1Sk2.update(key + (m/2), 1);
+ for (int i = 0; i < m; i++) {
+ a1Sk1.update(i, 1);
+ a1Sk2.update(i + (m/2), 1);
}
Intersection<IntegerSummary> inter =
new Intersection<>(new IntegerSummarySetOperations(a1Mode, a1Mode));
@@ -70,6 +71,21 @@ public class IntegerSketchTest {
}
@Test
+ public void aNotBTest() {
+ int lgK = 4;
+ //int m = 2 * K;
+ IntegerSummary.Mode a1Mode = IntegerSummary.Mode.AlwaysOne;
+ IntegerSketch a1Sk1 = new IntegerSketch(lgK, a1Mode);
+ IntegerSketch a1Sk2 = null;//new IntegerSketch(lgK, a1Mode);
+ AnotB<IntegerSummary> anotb = new AnotB<>();
+ for (int i = 0; i < 5; i++) {
+ a1Sk1.update(i, 1);
+ }
+ anotb.update(a1Sk1, a1Sk2);
+ CompactSketch<IntegerSummary> cSk = anotb.getResult();
+ }
+
+ @Test
public void checkMinMaxMode() {
int lgK = 12;
int K = 1 << lgK;
@@ -108,7 +124,7 @@ public class IntegerSketchTest {
* @param o object to print
*/
static void println(Object o) {
- //System.out.println(o.toString()); //Disable
+ System.out.println(o.toString()); //Disable
}
/**
@@ -116,6 +132,6 @@ public class IntegerSketchTest {
* @param args arguments
*/
static void printf(String fmt, Object ... args) {
- //System.out.printf(fmt, args); //Disable
+ System.out.printf(fmt, args); //Disable
}
}
diff --git a/src/test/java/org/apache/datasketches/tuple/arrayofdoubles/package-info.java b/src/test/java/org/apache/datasketches/tuple/arrayofdoubles/package-info.java
deleted file mode 100644
index 3810001..0000000
--- a/src/test/java/org/apache/datasketches/tuple/arrayofdoubles/package-info.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @author Lee Rhodes
- */
-
-package org.apache.datasketches.tuple.arrayofdoubles;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org