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 2019/12/17 18:05:52 UTC

[incubator-datasketches-java] 07/10: Updating UnionLogic

This is an automated email from the ASF dual-hosted git repository.

leerho pushed a commit to branch NewHllIterator
in repository https://gitbox.apache.org/repos/asf/incubator-datasketches-java.git

commit baa9da42eb2badfd1b1cbd437170d660e566d325
Author: Lee Rhodes <le...@users.noreply.github.com>
AuthorDate: Thu Dec 5 14:58:54 2019 -0800

    Updating UnionLogic
---
 .../cpc/IconPolynomialCoefficients.java            |   4 +-
 .../hll/CompositeInterpolationXTable.java          |   4 +-
 .../org/apache/datasketches/hll/CouponList.java    |   6 +-
 .../apache/datasketches/hll/DirectCouponList.java  |   6 +-
 .../apache/datasketches/hll/DirectHll4Array.java   |   6 +-
 .../apache/datasketches/hll/DirectHll6Array.java   |   7 +-
 .../apache/datasketches/hll/DirectHll8Array.java   |   6 +-
 .../org/apache/datasketches/hll/Hll4Array.java     |   6 +-
 .../org/apache/datasketches/hll/Hll6Array.java     |   6 +-
 .../org/apache/datasketches/hll/Hll8Array.java     |  18 ++-
 .../org/apache/datasketches/hll/HllEstimators.java |   1 +
 .../org/apache/datasketches/hll/HllSketchImpl.java |   2 +-
 .../java/org/apache/datasketches/hll/Union.java    | 134 ++++++++++-----------
 13 files changed, 97 insertions(+), 109 deletions(-)

diff --git a/src/main/java/org/apache/datasketches/cpc/IconPolynomialCoefficients.java b/src/main/java/org/apache/datasketches/cpc/IconPolynomialCoefficients.java
index 27cad7a..6c08528 100644
--- a/src/main/java/org/apache/datasketches/cpc/IconPolynomialCoefficients.java
+++ b/src/main/java/org/apache/datasketches/cpc/IconPolynomialCoefficients.java
@@ -31,7 +31,7 @@ final class IconPolynomialCoefficients {
   static final int iconPolynomialNumCoefficients = 1 + iconPolynomialDegree;
   static final int iconTableSize = iconPolynomialNumCoefficients * ((1 + maxLgK) - minLgK);
 
-  // CHECKSTYLE:OFF LineLength
+  //CHECKSTYLE.OFF: LineLength
   static final double[] iconPolynomialCoefficents = new double[] {
     // log K = 4
     0.9895027971889700513, 0.3319496644645180128, 0.1242818722715769986, -0.03324149686026930256, -0.2985637298081619817,
@@ -171,5 +171,5 @@ final class IconPolynomialCoefficients {
     -18.29035093605569884, 15.28892246224570073, -9.724916375991760731, 4.6978877652334603, -1.707974125916829955,
     0.4588937864564729963, -0.08824617586088029375, 0.01147732114826570046, -0.00090384524860747295, 3.253252703695579795e-05,
   };
-  // CHECKSTYLE:ON LineLength
+  //CHECKSTYLE.ON: LineLength
 }
diff --git a/src/main/java/org/apache/datasketches/hll/CompositeInterpolationXTable.java b/src/main/java/org/apache/datasketches/hll/CompositeInterpolationXTable.java
index 47726ab..119f1c7 100644
--- a/src/main/java/org/apache/datasketches/hll/CompositeInterpolationXTable.java
+++ b/src/main/java/org/apache/datasketches/hll/CompositeInterpolationXTable.java
@@ -25,7 +25,7 @@ package org.apache.datasketches.hll;
  */
 final class CompositeInterpolationXTable {
 
-  // CHECKSTYLE:OFF LineLength
+  //CHECKSTYLE.OFF: LineLength
   /**
    * 18 Values, index 0 is LgK = 4, index 17 is LgK = 21.
    */
@@ -779,5 +779,5 @@ final class CompositeInterpolationXTable {
     20970344.006053
   }
   };
-  // CHECKSTYLE:ON LineLength
+  //CHECKSTYLE.ON: LineLength
 }
diff --git a/src/main/java/org/apache/datasketches/hll/CouponList.java b/src/main/java/org/apache/datasketches/hll/CouponList.java
index 6c67b73..7fc363e 100644
--- a/src/main/java/org/apache/datasketches/hll/CouponList.java
+++ b/src/main/java/org/apache/datasketches/hll/CouponList.java
@@ -206,15 +206,13 @@ class CouponList extends AbstractCoupons {
   }
 
   @Override
-  HllSketchImpl mergeTo(final HllSketchImpl impl) {
-    HllSketchImpl out = impl;
+  void mergeTo(final HllSketchImpl that) {
     final int arrLen = couponIntArr.length;
     for (int i = 0; i < arrLen; i++) {
       final int pair = couponIntArr[i];
       if (pair == 0) { continue; }
-      out = out.couponUpdate(pair);
+      that.couponUpdate(pair);
     }
-    return out;
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/DirectCouponList.java b/src/main/java/org/apache/datasketches/hll/DirectCouponList.java
index 9d26d4d..4cc8acb 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectCouponList.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectCouponList.java
@@ -224,16 +224,14 @@ class DirectCouponList extends AbstractCoupons {
   }
 
   @Override
-  HllSketchImpl mergeTo(final HllSketchImpl impl) {
-    HllSketchImpl out = impl;
+  void mergeTo(final HllSketchImpl that) {
     final int lenInts = (compact) ? getCouponCount() : 1 << getLgCouponArrInts();
     final int dataStart = getMemDataStart();
     for (int i = 0; i < lenInts; i++) {
       final int pair = mem.getInt(dataStart + (i << 2));
       if (pair == 0) { continue; }
-      out = out.couponUpdate(pair);
+      that.couponUpdate(pair);
     }
-    return out;
   }
 
   @Override //not used on the direct side
diff --git a/src/main/java/org/apache/datasketches/hll/DirectHll4Array.java b/src/main/java/org/apache/datasketches/hll/DirectHll4Array.java
index e016b58..900b637 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectHll4Array.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectHll4Array.java
@@ -119,8 +119,7 @@ class DirectHll4Array extends DirectHllArray {
   }
 
   @Override
-  HllSketchImpl mergeTo(final HllSketchImpl impl) {
-    HllSketchImpl out = impl;
+  void mergeTo(final HllSketchImpl that) {
     final int slots = 1 << lgConfigK;
     for (int slotNo = 0; slotNo < slots; slotNo++) {
       int value = mem.getByte(HLL_BYTE_ARR_START + (slotNo >>> 1)) & 0xFF;
@@ -132,9 +131,8 @@ class DirectHll4Array extends DirectHllArray {
         value = nib;
       }
       if (value == 0) { continue; }
-      out = out.couponUpdate((value << KEY_BITS_26) | (slotNo & KEY_MASK_26));
+      that.couponUpdate((value << KEY_BITS_26) | (slotNo & KEY_MASK_26));
     }
-    return out;
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/DirectHll6Array.java b/src/main/java/org/apache/datasketches/hll/DirectHll6Array.java
index d69d2ed..2a13dbf 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectHll6Array.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectHll6Array.java
@@ -86,18 +86,15 @@ class DirectHll6Array extends DirectHllArray {
   }
 
   @Override
-  HllSketchImpl mergeTo(final HllSketchImpl impl) {
-    HllSketchImpl out = impl;
+  void mergeTo(final HllSketchImpl that) {
     final int slots = 1 << lgConfigK;
     for (int slotNo = 0, bitOffset = 0; slotNo < slots; slotNo++, bitOffset += 6) {
       final int tmp = mem.getShort(HLL_BYTE_ARR_START + (bitOffset / 8));
       final int shift = (bitOffset % 8) & 0X7;
       final int value = (tmp >>> shift) & VAL_MASK_6;
       if (value == 0) { continue; }
-      out = out.couponUpdate((value << KEY_BITS_26) | (slotNo & KEY_MASK_26));
-      System.out.println(out.curMode.toString()); //TODO
+      that.couponUpdate((value << KEY_BITS_26) | (slotNo & KEY_MASK_26));
     }
-    return out;
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/DirectHll8Array.java b/src/main/java/org/apache/datasketches/hll/DirectHll8Array.java
index 938ad8c..77fe08d 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectHll8Array.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectHll8Array.java
@@ -88,15 +88,13 @@ class DirectHll8Array extends DirectHllArray {
   }
 
   @Override
-  HllSketchImpl mergeTo(final HllSketchImpl impl) {
-    HllSketchImpl out = impl;
+  void mergeTo(final HllSketchImpl that) {
     final int slots = 1 << lgConfigK;
     for (int i = 0; i < slots; i++ ) {
       final int value = mem.getByte(HLL_BYTE_ARR_START + i) & VAL_MASK_6;
       if (value == 0) { continue; }
-      out = out.couponUpdate((value << KEY_BITS_26) | (i & KEY_MASK_26));
+      that.couponUpdate((value << KEY_BITS_26) | (i & KEY_MASK_26));
     }
-    return out;
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/Hll4Array.java b/src/main/java/org/apache/datasketches/hll/Hll4Array.java
index 5c4af9d..d9f74a6 100644
--- a/src/main/java/org/apache/datasketches/hll/Hll4Array.java
+++ b/src/main/java/org/apache/datasketches/hll/Hll4Array.java
@@ -116,8 +116,7 @@ class Hll4Array extends HllArray {
   }
 
   @Override
-  HllSketchImpl mergeTo(final HllSketchImpl impl) {
-    HllSketchImpl out = impl;
+  void mergeTo(final HllSketchImpl that) {
     final int slots = 1 << lgConfigK;
     for (int slotNo = 0; slotNo < slots; slotNo++) {
       int value = hllByteArr[slotNo >>> 1] & 0xFF;
@@ -129,9 +128,8 @@ class Hll4Array extends HllArray {
         value = nib;
       }
       if (value == 0) { continue; }
-      out = out.couponUpdate((value << KEY_BITS_26) | (slotNo & KEY_MASK_26));
+      that.couponUpdate((value << KEY_BITS_26) | (slotNo & KEY_MASK_26));
     }
-    return out;
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/Hll6Array.java b/src/main/java/org/apache/datasketches/hll/Hll6Array.java
index 495b54a..f8d17d4 100644
--- a/src/main/java/org/apache/datasketches/hll/Hll6Array.java
+++ b/src/main/java/org/apache/datasketches/hll/Hll6Array.java
@@ -95,17 +95,15 @@ class Hll6Array extends HllArray {
   }
 
   @Override
-  HllSketchImpl mergeTo(final HllSketchImpl impl) {
-    HllSketchImpl out = impl;
+  void mergeTo(final HllSketchImpl that) {
     final int slots = 1 << lgConfigK;
     for (int slotNo = 0, bitOffset = 0; slotNo < slots; slotNo++, bitOffset += 6) {
       final int tmp = mem.getShort(bitOffset / 8);
       final int shift = (bitOffset % 8) & 0X7;
       final int value = (tmp >>> shift) & VAL_MASK_6;
       if (value == 0) { continue; }
-      out = out.couponUpdate((value << KEY_BITS_26) | (slotNo & KEY_MASK_26));
+      that.couponUpdate((value << KEY_BITS_26) | (slotNo & KEY_MASK_26));
     }
-    return out;
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/Hll8Array.java b/src/main/java/org/apache/datasketches/hll/Hll8Array.java
index f810f1c..535df45 100644
--- a/src/main/java/org/apache/datasketches/hll/Hll8Array.java
+++ b/src/main/java/org/apache/datasketches/hll/Hll8Array.java
@@ -92,15 +92,21 @@ class Hll8Array extends HllArray {
   }
 
   @Override
-  HllSketchImpl mergeTo(final HllSketchImpl impl) {
-    HllSketchImpl out = impl;
-    final int slots = 1 << lgConfigK;
-    for (int i = 0; i < slots; i++ ) {
+  void mergeTo(final HllSketchImpl that) {
+    final int thisK = 1 << lgConfigK;
+    if ((thisK == that.getLgConfigK()) && (that instanceof Hll8Array)) {
+      final byte[] thisArr = hllByteArr;
+      final byte[] thatArr = ((Hll8Array) that).hllByteArr;
+      for (int i = 0; i < thisK; i++) {
+        thatArr[i] = (thisArr[i] > thatArr[i]) ? thisArr[i] : thatArr[i];
+      }
+      return;
+    }
+    for (int i = 0; i < thisK; i++ ) {
       final int value = hllByteArr[i] & VAL_MASK_6;
       if (value == 0) { continue; }
-      out = out.couponUpdate((value << KEY_BITS_26) | (i & KEY_MASK_26));
+      that.couponUpdate((value << KEY_BITS_26) | (i & KEY_MASK_26));
     }
-    return out;
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/HllEstimators.java b/src/main/java/org/apache/datasketches/hll/HllEstimators.java
index f77b299..4aed96d 100644
--- a/src/main/java/org/apache/datasketches/hll/HllEstimators.java
+++ b/src/main/java/org/apache/datasketches/hll/HllEstimators.java
@@ -97,6 +97,7 @@ class HllEstimators {
   //In C: again-two-registers.c hhb_get_composite_estimate L1489
   static final double hllCompositeEstimate(final AbstractHllArray absHllArr) {
     final int lgConfigK = absHllArr.getLgConfigK();
+    //TODO Rebuild KxQ registers.
     final double rawEst = getHllRawEstimate(lgConfigK, absHllArr.getKxQ0() + absHllArr.getKxQ1());
 
     final double[] xArr = CompositeInterpolationXTable.xArrs[lgConfigK - MIN_LOG_K];
diff --git a/src/main/java/org/apache/datasketches/hll/HllSketchImpl.java b/src/main/java/org/apache/datasketches/hll/HllSketchImpl.java
index 15497c5..09f47fa 100644
--- a/src/main/java/org/apache/datasketches/hll/HllSketchImpl.java
+++ b/src/main/java/org/apache/datasketches/hll/HllSketchImpl.java
@@ -98,7 +98,7 @@ abstract class HllSketchImpl {
 
   abstract PairIterator iterator();
 
-  abstract HllSketchImpl mergeTo(HllSketchImpl impl);
+  abstract void mergeTo(HllSketchImpl impl);
 
   abstract void putEmptyFlag(boolean empty);
 
diff --git a/src/main/java/org/apache/datasketches/hll/Union.java b/src/main/java/org/apache/datasketches/hll/Union.java
index 1a58984..3611c23 100644
--- a/src/main/java/org/apache/datasketches/hll/Union.java
+++ b/src/main/java/org/apache/datasketches/hll/Union.java
@@ -298,18 +298,17 @@ public class Union extends BaseHllSketch {
    * perform the union. This may involve swapping, down-sampling, transforming, and / or
    * copying one of the arguments and may completely replace the internals of the union.
    *
-   * <p>Copies or downsamples the given HLLmode sketch to tgtLgK, HLL_8.</p>
-   *
    * <p>A swap in update direction is required:</p>
-   * <ul><li>If Gadget is in LIST, SET or EMPTY mode, AND </li>
-   * <li>(The incoming source sketch is in HLL mode and not empty,</li>
-   * <li>OR, if both source and Gadget are in HLL mode and src LgK &lt; Gadget LgK.)</li>
+   * <ul><li>If the Gadget is in LIST, SET or EMPTY mode, AND
+   * The source sketch is in HLL mode.
+   * The source sketch will need to be copied or downsampled to the heap in HLL_8 mode if it is
+   * larger than maxLgK, and then replace the Gadget. If the Gadget was Memory, the resulting
+   * heap object will need to be converted to Memory form.</li>
    * </ul>
    *
-   * <p>A downsample or copy is required:</p>
-   * <ul><li>If swap is required, AND</li>
-   * <li>(If source lgK &gt; destination LgK OR if source sketch is not type HLL_8),</li>
-   * <li>OR, if source lgK &gt maxLgK.</li>
+   * <p>A downsample of gadget is required:</p>
+   * <ul><li>If both source and Gadget are in HLL mode AND source LgK <b>less than</b> Gadget LgK.
+   * Downsample Gadget, convert back to memory form if required, update gadget from source.</li>
    * </ul>
    *
    * @param incoming the given incoming sketch, which may not be modified.
@@ -324,7 +323,7 @@ public class Union extends BaseHllSketch {
     assert gadget.getTgtHllType() == HLL_8;
     if ((incoming == null) || incoming.isEmpty()) { return gadget.hllSketchImpl; }
     final HllSketchImpl srcImpl = incoming.hllSketchImpl;
-    HllSketchImpl dstImpl = gadget.hllSketchImpl;
+    HllSketchImpl gdtImpl = gadget.hllSketchImpl;
     final int inLgK = incoming.getLgConfigK();
     final int gadgetLgK = gadget.getLgConfigK();
 
@@ -333,139 +332,136 @@ public class Union extends BaseHllSketch {
     final int sw = (hi2bits << 2) | lo2bits;
     switch (sw) {
       case 0: { //src: LIST, gadget: LIST
-        dstImpl = srcImpl.mergeTo(dstImpl);
+        srcImpl.mergeTo(gdtImpl);
         //whichever is True wins:
-        dstImpl.putOutOfOrderFlag(dstImpl.isOutOfOrderFlag() | srcImpl.isOutOfOrderFlag());
+        gdtImpl.putOutOfOrderFlag(gdtImpl.isOutOfOrderFlag() | srcImpl.isOutOfOrderFlag());
         break;
       }
       case 1: { //src: SET, gadget: LIST
-        dstImpl = srcImpl.mergeTo(dstImpl);
-        dstImpl.putOutOfOrderFlag(true); //SET oooFlag is always true
+        srcImpl.mergeTo(gdtImpl);
+        gdtImpl.putOutOfOrderFlag(true); //SET oooFlag is always true
         break;
       }
       case 2: { //src: HLL, gadget: LIST; Swap, Downsample if srcLgK > maxLgK
-        final HllSketchImpl heapSrcHll8 = srcImpl.copyAs(HLL_8); //to heap, whether HLL8 or not
-        HllSketchImpl dstImplTmp = dstImpl.mergeTo(heapSrcHll8); //reverse merge
+        final HllSketchImpl srcHll8HeapCopy = srcImpl.copyAs(HLL_8); //to heap HLL8
+        final boolean gdtIsMem = gdtImpl.isMemory();
+        gdtImpl.mergeTo(srcHll8HeapCopy); //reverse merge
+        //srcHll8HeapCopy now has the right merged data.
+
+        HllSketchImpl gdtImplTmp = gdtImpl;
 
         if (inLgK > lgMaxK) { //downsample
-          dstImplTmp = copyOrDownsampleHll(dstImplTmp, lgMaxK);
+          gdtImplTmp = copyOrDownsampleHll(gdtImplTmp, lgMaxK);
         }
-        if (dstImpl.isMemory()) {
-          final byte[] byteArr = dstImplTmp.toUpdatableByteArray();
-          final WritableMemory wmem = dstImpl.getWritableMemory(); //use the original wmem
+        if (gdtIsMem) {
+          final byte[] byteArr = gdtImplTmp.toUpdatableByteArray();
+          final WritableMemory wmem = gdtImpl.getWritableMemory(); //use the original wmem
           wmem.putByteArray(0, byteArr, 0, byteArr.length); //replace old data with new
-          dstImplTmp = HllSketch.writableWrap(wmem).hllSketchImpl;
+          gdtImplTmp = HllSketch.writableWrap(wmem).hllSketchImpl;
         }
-        dstImpl = dstImplTmp;
+        gdtImpl = gdtImplTmp;
         //whichever is True wins:
-        dstImpl.putOutOfOrderFlag(srcImpl.isOutOfOrderFlag() | dstImpl.isOutOfOrderFlag());
+        gdtImpl.putOutOfOrderFlag(srcImpl.isOutOfOrderFlag() | gdtImpl.isOutOfOrderFlag());
         break;
       }
       case 4: { //src: LIST, gadget: SET
-        dstImpl = srcImpl.mergeTo(dstImpl);
-        dstImpl.putOutOfOrderFlag(true); //SET oooFlag is always true
+        srcImpl.mergeTo(gdtImpl);
+        gdtImpl.putOutOfOrderFlag(true); //SET oooFlag is always true
         break;
       }
       case 5: { //src: SET, gadget: SET
-        dstImpl = srcImpl.mergeTo(dstImpl);
-        dstImpl.putOutOfOrderFlag(true); //SET oooFlag is always true
+        srcImpl.mergeTo(gdtImpl);
+        gdtImpl.putOutOfOrderFlag(true); //SET oooFlag is always true
         break;
       }
       case 6: { //src: HLL, gadget: SET
         final HllSketchImpl heapSrcHll8 = srcImpl.copyAs(HLL_8); //to heap, whether HLL8 or not
-        HllSketchImpl dstImplTmp = dstImpl.mergeTo(heapSrcHll8); //reverse merge
+        final boolean memory = gdtImpl.isMemory();
+        gdtImpl.mergeTo(heapSrcHll8); //reverse merge
+        HllSketchImpl dstImplTmp = gdtImpl;
 
         if (inLgK > lgMaxK) { //downsample
-          dstImplTmp = copyOrDownsampleHll(dstImplTmp, lgMaxK);
+          dstImplTmp = copyOrDownsampleHll(gdtImpl, lgMaxK);
         }
-        if (dstImpl.isMemory()) {
+        if (memory) {
           final byte[] byteArr = dstImplTmp.toUpdatableByteArray();
-          final WritableMemory wmem = dstImpl.getWritableMemory(); //use the original wmem
+          final WritableMemory wmem = gdtImpl.getWritableMemory(); //use the original wmem
           wmem.putByteArray(0, byteArr, 0, byteArr.length); //replace old data with new
           dstImplTmp = HllSketch.writableWrap(wmem).hllSketchImpl;
         }
-        dstImpl = dstImplTmp;
-        dstImpl.putOutOfOrderFlag(true); //merging SET into non-empty HLL -> true
+        gdtImpl = dstImplTmp;
+        gdtImpl.putOutOfOrderFlag(true); //merging SET into non-empty HLL -> true
         break;
       }
       case 8: { //src: LIST, gadget: HLL
-        dstImpl = srcImpl.mergeTo(dstImpl);
+        srcImpl.mergeTo(gdtImpl);
         //whichever is True wins:
-        dstImpl.putOutOfOrderFlag(dstImpl.isOutOfOrderFlag() | srcImpl.isOutOfOrderFlag());
+        gdtImpl.putOutOfOrderFlag(gdtImpl.isOutOfOrderFlag() | srcImpl.isOutOfOrderFlag());
         break;
       }
       case 9: { //src: SET, gadget: HLL
-        dstImpl = srcImpl.mergeTo(dstImpl);
-        dstImpl.putOutOfOrderFlag(true); //merging SET into existing HLL -> true
+        srcImpl.mergeTo(gdtImpl);
+        gdtImpl.putOutOfOrderFlag(true); //merging SET into existing HLL -> true
         break;
       }
       case 10: { //src: HLL, gadget: HLL
         if (inLgK >= gadgetLgK) {
-          dstImpl = srcImpl.mergeTo(dstImpl); //normal merge direction
-          dstImpl.putOutOfOrderFlag(true); //union of two HLL modes is always true
+          srcImpl.mergeTo(gdtImpl); //normal merge direction
+          gdtImpl.putOutOfOrderFlag(true); //union of two HLL modes is always true
           break; //done
         }
+        final boolean memory = gdtImpl.isMemory();
         //inLgK < gadgetLgK, must reverse merge to src copy, then downsample gadget to inLgK
         final HllSketchImpl heapSrcHll8 = srcImpl.copyAs(HLL_8); //to heap, whether HLL8 or not
-        HllSketchImpl dstImplTmp = dstImpl.mergeTo(heapSrcHll8); //swap merge direction
-        dstImplTmp = copyOrDownsampleHll(dstImplTmp, inLgK); //heap, HLL8, inLgK
+        gdtImpl.mergeTo(heapSrcHll8); //swap merge direction
+        HllSketchImpl dstImplTmp = copyOrDownsampleHll(heapSrcHll8, inLgK); //heap, HLL8, inLgK
 
-        if (dstImpl.isMemory()) {
+        if (memory) {
           final byte[] byteArr = dstImplTmp.toUpdatableByteArray();
-          final WritableMemory wmem = dstImpl.getWritableMemory(); //need to use the original wmem
+          final WritableMemory wmem = gdtImpl.getWritableMemory(); //need to use the original wmem
           wmem.putByteArray(0, byteArr, 0, byteArr.length); //replace old data with new
           dstImplTmp = HllSketch.writableWrap(wmem).hllSketchImpl;
         }
-        dstImpl = dstImplTmp;
-        dstImpl.putOutOfOrderFlag(true); //union of two HLL modes is always true
+        gdtImpl = dstImplTmp;
+        gdtImpl.putOutOfOrderFlag(true); //union of two HLL modes is always true
         break;
       }
       case 12: { //src: LIST, gadget: empty
-        dstImpl = srcImpl.mergeTo(dstImpl);
-        dstImpl.putOutOfOrderFlag(srcImpl.isOutOfOrderFlag()); //whatever source is
+        srcImpl.mergeTo(gdtImpl);
+        gdtImpl.putOutOfOrderFlag(srcImpl.isOutOfOrderFlag()); //whatever source is
         break;
       }
       case 13: { //src: SET, gadget: empty
-        dstImpl = srcImpl.mergeTo(dstImpl);
-        dstImpl.putOutOfOrderFlag(true); //SET oooFlag is always true
+        srcImpl.mergeTo(gdtImpl);
+        gdtImpl.putOutOfOrderFlag(true); //SET oooFlag is always true
         break;
       }
       case 14: { //src: HLL, gadget: empty; Downsample if srcLgK > maxLgK
         final HllSketchImpl heapSrcHll8 = srcImpl.copyAs(HLL_8); //to heap, whether HLL8 or not
+        final boolean memory = gdtImpl.isMemory();
         HllSketchImpl dstImplTmp = heapSrcHll8; //no merge
 
         if (inLgK > lgMaxK) { //downsample
           dstImplTmp = copyOrDownsampleHll(dstImplTmp, lgMaxK);
         }
-        if (dstImpl.isMemory()) {
+        if (memory) {
           final byte[] byteArr = dstImplTmp.toUpdatableByteArray();
-          final WritableMemory wmem = dstImpl.getWritableMemory(); //use the original wmem
+          final WritableMemory wmem = gdtImpl.getWritableMemory(); //use the original wmem
           wmem.putByteArray(0, byteArr, 0, byteArr.length); //replace old data with new
           dstImplTmp = HllSketch.writableWrap(wmem).hllSketchImpl;
         }
-        dstImpl = dstImplTmp;
-        dstImpl.putOutOfOrderFlag(srcImpl.isOutOfOrderFlag()); //whatever source is.
+        gdtImpl = dstImplTmp;
+        gdtImpl.putOutOfOrderFlag(srcImpl.isOutOfOrderFlag()); //whatever source is.
         break;
       }
     }
-    return dstImpl;
+    return gdtImpl;
   }
 
   //Used by union operator.  Always copies or downsamples to Heap HLL_8.
   //Caller must ultimately manage oooFlag, as caller has more context.
   /**
-   * Copies or downsamples the given HLLmode sketch to tgtLgK, HLL_8.
-   *
-   * <p>A swap in update direction is required:</p>
-   * <ul><li>If Gadget is in LIST, SET or EMPTY mode, AND </li>
-   * <li>The incoming source sketch is in HLL mode and not empty.</li>
-   * <li>Or, if both source and Gadget are in HLL mode and src LgK &lt; Gadget LgK.</li>
-   * </ul>
-   *
-   * <p>A downsample is required:</p>
-   * <ul><li>If swap is required, AND</li>
-   * <li>If source lgK &gt; Gadget LgK OR if source sketch is not type HLL_8.</li>
-   * </ul>
+   * Copies or downsamples the given HLLmode sketch to tgtLgK, HLL_8, on the heap.
    *
    * @param srcImpl the HllSketchImpl to possibly downsample
    * @param tgtLgK the LgK to downsample to.
@@ -473,11 +469,11 @@ public class Union extends BaseHllSketch {
    */
   private static final HllSketchImpl copyOrDownsampleHll(
       final HllSketchImpl srcImpl, final int tgtLgK) {
-    assert srcImpl.getCurMode() == HLL;
+    assert (srcImpl.getCurMode() == HLL) && (!srcImpl.isEmpty());
     final AbstractHllArray src = (AbstractHllArray) srcImpl;
     final int srcLgK = src.getLgConfigK();
     if ((srcLgK <= tgtLgK) && (src.getTgtHllType() == TgtHllType.HLL_8)) {
-      return src.copy();
+      return src.copy(); //on heap
     }
     final int minLgK = Math.min(srcLgK, tgtLgK);
     final HllArray tgtHllArr = HllArray.newHeapHll(minLgK, TgtHllType.HLL_8);
@@ -488,7 +484,7 @@ public class Union extends BaseHllSketch {
     //both of these are required for isomorphism
     tgtHllArr.putHipAccum(src.getHipAccum());
     tgtHllArr.putOutOfOrderFlag(src.isOutOfOrderFlag());
-    return tgtHllArr;
+    return tgtHllArr; //on heap
   }
 
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org