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 2022/04/07 04:12:48 UTC

[datasketches-java] branch DirectKllDoubleV2 updated: Major refactoring completed.

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

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


The following commit(s) were added to refs/heads/DirectKllDoubleV2 by this push:
     new f3d80294 Major refactoring completed.
f3d80294 is described below

commit f3d80294e1e34278d1cd7a46071929ae267d633c
Author: Lee Rhodes <le...@users.noreply.github.com>
AuthorDate: Wed Apr 6 21:12:41 2022 -0700

    Major refactoring completed.
---
 .../datasketches/kll/KllDirectDoublesSketch.java   | 365 +++-----------------
 .../datasketches/kll/KllDirectFloatsSketch.java    | 367 +++------------------
 ...eapDoublesSketch.java => KllDoublesSketch.java} | 268 ++++-----------
 ...lHeapFloatsSketch.java => KllFloatsSketch.java} | 282 ++++------------
 .../datasketches/kll/KllHeapDoublesSketch.java     | 338 +++----------------
 .../datasketches/kll/KllHeapFloatsSketch.java      | 340 +++----------------
 .../kll/KllDirectDoublesSketchIteratorTest.java    |  12 +-
 .../kll/KllDirectDoublesSketchTest.java            | 130 ++++----
 .../kll/KllDirectFloatsSketchIteratorTest.java     |  12 +-
 .../kll/KllDirectFloatsSketchTest.java             | 120 +++----
 .../kll/KllDoublesSketchIteratorTest.java          |   6 +-
 .../datasketches/kll/KllDoublesSketchTest.java     |  64 ++--
 .../datasketches/kll/KllDoublesValidationTest.java |   2 +-
 .../kll/KllFloatsSketchIteratorTest.java           |   6 +-
 .../datasketches/kll/KllFloatsSketchTest.java      |  68 ++--
 .../datasketches/kll/KllFloatsValidationTest.java  |   2 +-
 .../org/apache/datasketches/kll/KllHelperTest.java |   8 +-
 .../datasketches/kll/KllMemoryValidateTest.java    |  24 +-
 .../datasketches/kll/MiscDirectDoublesTest.java    |  60 ++--
 .../datasketches/kll/MiscDirectFloatsTest.java     |  60 ++--
 .../apache/datasketches/kll/MiscDoublesTest.java   | 118 +++----
 .../apache/datasketches/kll/MiscFloatsTest.java    | 120 +++----
 22 files changed, 738 insertions(+), 2034 deletions(-)

diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 3c3598c4..225830d7 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -19,8 +19,6 @@
 
 package org.apache.datasketches.kll;
 
-import static java.lang.Math.max;
-import static java.lang.Math.min;
 import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
 import static org.apache.datasketches.kll.KllPreambleUtil.DOUBLES_SKETCH_BIT_MASK;
 import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
@@ -42,13 +40,10 @@ import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryN;
 import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryNumLevels;
 import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
 import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
-import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DOUBLE;
 import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
 import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
 
 import org.apache.datasketches.Family;
-import org.apache.datasketches.memory.Memory;
 import org.apache.datasketches.memory.MemoryRequestServer;
 import org.apache.datasketches.memory.WritableMemory;
 
@@ -60,7 +55,11 @@ import org.apache.datasketches.memory.WritableMemory;
  *
  * @author Lee Rhodes, Kevin Lang
  */
-public final class KllDirectDoublesSketch extends KllSketch {
+final class KllDirectDoublesSketch extends KllDoublesSketch {
+  final boolean updatableMemory;
+  WritableMemory levelsArrUpdatable;
+  WritableMemory minMaxArrUpdatable;
+  WritableMemory itemsArrUpdatable;
 
   /**
    * The actual constructor.
@@ -68,7 +67,7 @@ public final class KllDirectDoublesSketch extends KllSketch {
    * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
    * @param memVal the MemoryValadate object
    */
-  private KllDirectDoublesSketch(final WritableMemory wmem, final MemoryRequestServer memReqSvr,
+  KllDirectDoublesSketch(final WritableMemory wmem, final MemoryRequestServer memReqSvr,
       final KllMemoryValidate memVal) {
     super(SketchType.DOUBLES_SKETCH, wmem, memReqSvr);
     updatableMemory = memVal.updatableMemory && memReqSvr != null;
@@ -77,27 +76,6 @@ public final class KllDirectDoublesSketch extends KllSketch {
     itemsArrUpdatable = memVal.itemsArrUpdatable;
   }
 
-  /**
-   * Heapifies the given Memory object and returns a KllDoublesSketch
-   * @param mem the given Memory object.
-   * @return a KllDoublesSketch
-   */
-  public static KllHeapDoublesSketch heapify(final Memory mem) {
-    return KllHeapDoublesSketch.heapify(mem);
-  }
-
-  /**
-   * Create a new instance of this sketch using the default <i>m</i> of 8.
-   * @param k parameter that controls size of the sketch and accuracy of estimates
-   * @param dstMem the given destination WritableMemory object for use by the sketch
-   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
-   * @return a new instance of this sketch
-   */
-  public static KllDirectDoublesSketch newInstance(final int k, final WritableMemory dstMem,
-      final MemoryRequestServer memReqSvr) {
-    return newInstance(k, KllSketch.DEFAULT_M, dstMem, memReqSvr);
-  }
-
   /**
    * Create a new instance of this sketch.
    * @param k parameter that controls size of the sketch and accuracy of estimates
@@ -106,7 +84,7 @@ public final class KllDirectDoublesSketch extends KllSketch {
    * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
    * @return a new instance of this sketch
    */
-  static KllDirectDoublesSketch newInstance(final int k, final int m, final WritableMemory dstMem,
+  static KllDirectDoublesSketch newDirectInstance(final int k, final int m, final WritableMemory dstMem,
       final MemoryRequestServer memReqSvr) {
     setMemoryPreInts(dstMem, PREAMBLE_INTS_FULL);
     setMemorySerVer(dstMem, SERIAL_VERSION_UPDATABLE);
@@ -127,288 +105,6 @@ public final class KllDirectDoublesSketch extends KllSketch {
     return new KllDirectDoublesSketch(dstMem, memReqSvr, memVal);
   }
 
-  /**
-   * Wrap a sketch around the given source Memory containing sketch data that originated from
-   * this sketch.
-   * @param srcMem a WritableMemory that contains data.
-   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
-   * @return instance of this sketch
-   */
-  public static KllDirectDoublesSketch writableWrap(final WritableMemory srcMem, final MemoryRequestServer memReqSvr) {
-    final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
-    return new KllDirectDoublesSketch(srcMem, memReqSvr, memVal);
-  }
-
-  /**
-   * Returns an approximation to the Cumulative Distribution Function (CDF), which is the
-   * cumulative analog of the PMF, of the input stream given a set of splitPoint (values).
-   *
-   * <p>The resulting approximations have a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(false) function.
-   *
-   * <p>If the sketch is empty this returns null.</p>
-   *
-   * @param splitPoints an array of <i>m</i> unique, monotonically increasing double values
-   * that divide the real number line into <i>m+1</i> consecutive disjoint intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint (or minimum value) and
-   * exclusive of the right splitPoint, with the exception that the last interval will include
-   * the maximum value.
-   * It is not necessary to include either the min or max values in these split points.
-   *
-   * @return an array of m+1 double values on the interval [0.0, 1.0),
-   * which are a consecutive approximation to the CDF of the input stream given the splitPoints.
-   * The value at array position j of the returned CDF array is the sum of the returned values
-   * in positions 0 through j of the returned PMF array.
-   */
-  public double[] getCDF(final double[] splitPoints) {
-    return KllDoublesHelper.getDoublesPmfOrCdf(this, splitPoints, true);
-  }
-
-  /**
-   * Returns the max value of the stream.
-   * If the sketch is empty this returns NaN.
-   *
-   * @return the max value of the stream
-   */
-  public double getMaxValue() { return getMaxDoubleValue(); }
-
-  /**
-   * Returns the min value of the stream.
-   * If the sketch is empty this returns NaN.
-   *
-   * @return the min value of the stream
-   */
-  public double getMinValue() { return getMinDoubleValue(); }
-
-  /**
-   * Returns an approximation to the Probability Mass Function (PMF) of the input stream
-   * given a set of splitPoints (values).
-   *
-   * <p>The resulting approximations have a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(true) function.
-   *
-   * <p>If the sketch is empty this returns null.</p>
-   *
-   * @param splitPoints an array of <i>m</i> unique, monotonically increasing double values
-   * that divide the real number line into <i>m+1</i> consecutive disjoint intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint (or minimum value) and
-   * exclusive of the right splitPoint, with the exception that the last interval will include
-   * the maximum value.
-   * It is not necessary to include either the min or max values in these split points.
-   *
-   * @return an array of m+1 doubles on the interval [0.0, 1.0),
-   * each of which is an approximation to the fraction of the total input stream values
-   * (the mass) that fall into one of those intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint and exclusive of the right
-   * splitPoint, with the exception that the last interval will include maximum value.
-   */
-  public double[] getPMF(final double[] splitPoints) {
-    return KllDoublesHelper.getDoublesPmfOrCdf(this, splitPoints, false);
-  }
-
-  /**
-   * Returns an approximation to the value of the data item
-   * that would be preceded by the given fraction of a hypothetical sorted
-   * version of the input stream so far.
-   *
-   * <p>We note that this method has a fairly large overhead (microseconds instead of nanoseconds)
-   * so it should not be called multiple times to get different quantiles from the same
-   * sketch. Instead use getQuantiles(), which pays the overhead only once.
-   *
-   * <p>If the sketch is empty this returns NaN.
-   *
-   * @param fraction the specified fractional position in the hypothetical sorted stream.
-   * These are also called normalized ranks or fractional ranks.
-   * If fraction = 0.0, the true minimum value of the stream is returned.
-   * If fraction = 1.0, the true maximum value of the stream is returned.
-   *
-   * @return the approximation to the value at the given fraction
-   */
-  public double getQuantile(final double fraction) {
-    return KllDoublesHelper.getDoublesQuantile(this, fraction);
-  }
-
-  /**
-   * Gets the lower bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%.
-   * @param fraction the given normalized rank as a fraction
-   * @return the lower bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
-   */
-  public double getQuantileLowerBound(final double fraction) {
-    return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getMinK(), false)));
-  }
-
-  /**
-   * This is a more efficient multiple-query version of getQuantile().
-   *
-   * <p>This returns an array that could have been generated by using getQuantile() with many
-   * different fractional ranks, but would be very inefficient.
-   * This method incurs the internal set-up overhead once and obtains multiple quantile values in
-   * a single query. It is strongly recommend that this method be used instead of multiple calls
-   * to getQuantile().
-   *
-   * <p>If the sketch is empty this returns null.
-   *
-   * @param fractions given array of fractional positions in the hypothetical sorted stream.
-   * These are also called normalized ranks or fractional ranks.
-   * These fractions must be in the interval [0.0, 1.0], inclusive.
-   *
-   * @return array of approximations to the given fractions in the same order as given fractions
-   * array.
-   */
-  public double[] getQuantiles(final double[] fractions) {
-    return KllDoublesHelper.getDoublesQuantiles(this, fractions);
-  }
-
-  /**
-   * This is also a more efficient multiple-query version of getQuantile() and allows the caller to
-   * specify the number of evenly spaced fractional ranks.
-   *
-   * <p>If the sketch is empty this returns null.
-   *
-   * @param numEvenlySpaced an integer that specifies the number of evenly spaced fractional ranks.
-   * This must be a positive integer greater than 0. A value of 1 will return the min value.
-   * A value of 2 will return the min and the max value. A value of 3 will return the min,
-   * the median and the max value, etc.
-   *
-   * @return array of approximations to the given fractions in the same order as given fractions
-   * array.
-   */
-  public double[] getQuantiles(final int numEvenlySpaced) {
-    if (isEmpty()) { return null; }
-    return getQuantiles(org.apache.datasketches.Util.evenlySpaced(0.0, 1.0, numEvenlySpaced));
-  }
-
-  /**
-   * Gets the upper bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%.
-   * @param fraction the given normalized rank as a fraction
-   * @return the upper bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
-   */
-  public double getQuantileUpperBound(final double fraction) {
-    return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getMinK(), false)));
-  }
-
-  /**
-   * Returns an approximation to the normalized (fractional) rank of the given value from 0 to 1,
-   * inclusive.
-   *
-   * <p>The resulting approximation has a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(false) function.
-   *
-   * <p>If the sketch is empty this returns NaN.</p>
-   *
-   * @param value to be ranked
-   * @return an approximate rank of the given value
-   */
-  public double getRank(final double value) {
-    return KllDoublesHelper.getDoubleRank(this, value);
-  }
-
-  /**
-   * @return the iterator for this class
-   */
-  public KllDoublesSketchIterator iterator() {
-    return new KllDoublesSketchIterator(getDoubleItemsArray(), getLevelsArray(), getNumLevels());
-  }
-
-  /**
-   * Merges another sketch into this one.
-   * @param other sketch to merge into this one
-   */
-  public void merge(final KllSketch other) {
-    if (!other.isDoublesSketch()) { kllSketchThrow(SRC_MUST_BE_DOUBLE); }
-    KllDoublesHelper.mergeDoubleImpl(this, other);
-  }
-
-  /**
-   * Updates this sketch with the given data item.
-   *
-   * @param value an item from a stream of items. NaNs are ignored.
-   */
-  public void update(final double value) {
-    KllDoublesHelper.updateDouble(this, value);
-  }
-
-  @Override
-  double[] getDoubleItemsArray() {
-    final int items = getItemsArrLengthItems();
-    final double[] itemsArr = new double[items];
-    itemsArrUpdatable.getDoubleArray(0, itemsArr, 0, items);
-    return itemsArr;
-  }
-
-  @Override
-  double getDoubleItemsArrayAt(final int index) {
-    return itemsArrUpdatable.getDouble((long)index * Double.BYTES);
-  }
-
-  @Override
-  float[] getFloatItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
-
-  @Override
-  float getFloatItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
-
-  @Override
-  double getMaxDoubleValue() {
-    return minMaxArrUpdatable.getDouble(Double.BYTES);
-  }
-
-  @Override
-  float getMaxFloatValue() { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
-
-  @Override
-  double getMinDoubleValue() {
-    return minMaxArrUpdatable.getDouble(0);
-  }
-
-  @Override
-  float getMinFloatValue() { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
-
-  @Override
-  void setDoubleItemsArray(final double[] doubleItems) {
-    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
-    itemsArrUpdatable.putDoubleArray(0, doubleItems, 0, doubleItems.length);
-  }
-
-  @Override
-  void setDoubleItemsArrayAt(final int index, final double value) {
-    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
-    itemsArrUpdatable.putDouble((long)index * Double.BYTES, value);
-  }
-
-  @Override
-  void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override
-  void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override
-  void setMaxDoubleValue(final double value) {
-    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
-    minMaxArrUpdatable.putDouble(Double.BYTES, value);
-  }
-
-  @Override
-  void setMaxFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override
-  void setMinDoubleValue(final double value) {
-    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
-    minMaxArrUpdatable.putDouble(0, value);
-  }
-
-  @Override
-  void setMinFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  //**********************************************************************************
-  final boolean updatableMemory;
-  WritableMemory levelsArrUpdatable;
-  WritableMemory minMaxArrUpdatable;
-  WritableMemory itemsArrUpdatable;
-
   @Override
   public int getK() {
     return getMemoryK(wmem);
@@ -449,6 +145,19 @@ public final class KllDirectDoublesSketch extends KllSketch {
     return byteArr;
   }
 
+  @Override
+  double[] getDoubleItemsArray() {
+    final int items = getItemsArrLengthItems();
+    final double[] itemsArr = new double[items];
+    itemsArrUpdatable.getDoubleArray(0, itemsArr, 0, items);
+    return itemsArr;
+  }
+
+  @Override
+  double getDoubleItemsArrayAt(final int index) {
+    return itemsArrUpdatable.getDouble((long)index * Double.BYTES);
+  }
+
   int getItemsArrLengthItems() {
     return getLevelsArray()[getNumLevels()];
   }
@@ -471,6 +180,16 @@ public final class KllDirectDoublesSketch extends KllSketch {
     return getMemoryM(wmem);
   }
 
+  @Override
+  double getMaxDoubleValue() {
+    return minMaxArrUpdatable.getDouble(Double.BYTES);
+  }
+
+  @Override
+  double getMinDoubleValue() {
+    return minMaxArrUpdatable.getDouble(0);
+  }
+
   @Override
   int getMinK() {
     return getMemoryMinK(wmem);
@@ -500,6 +219,18 @@ public final class KllDirectDoublesSketch extends KllSketch {
     return getMemoryLevelZeroSortedFlag(wmem);
   }
 
+  @Override
+  void setDoubleItemsArray(final double[] doubleItems) {
+    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+    itemsArrUpdatable.putDoubleArray(0, doubleItems, 0, doubleItems.length);
+  }
+
+  @Override
+  void setDoubleItemsArrayAt(final int index, final double value) {
+    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+    itemsArrUpdatable.putDouble((long)index * Double.BYTES, value);
+  }
+
   @Override
   void setItemsArrayUpdatable(final WritableMemory itemsMem) {
     if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
@@ -546,6 +277,18 @@ public final class KllDirectDoublesSketch extends KllSketch {
     setMemoryLevelZeroSortedFlag(wmem, sorted);
   }
 
+  @Override
+  void setMaxDoubleValue(final double value) {
+    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+    minMaxArrUpdatable.putDouble(Double.BYTES, value);
+  }
+
+  @Override
+  void setMinDoubleValue(final double value) {
+    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+    minMaxArrUpdatable.putDouble(0, value);
+  }
+
   @Override
   void setMinK(final int minK) {
     if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index fb2588a7..e3f77a9a 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -19,8 +19,6 @@
 
 package org.apache.datasketches.kll;
 
-import static java.lang.Math.max;
-import static java.lang.Math.min;
 import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
 import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
 import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
@@ -41,17 +39,14 @@ import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryN;
 import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryNumLevels;
 import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
 import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
-import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_FLOAT;
 import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
 import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
 
 import org.apache.datasketches.Family;
-import org.apache.datasketches.memory.Memory;
 import org.apache.datasketches.memory.MemoryRequestServer;
 import org.apache.datasketches.memory.WritableMemory;
 
-//Intentional extra blank line so the code lines up with KllDirectDoublesSketch
+//intentional extra line
 /**
  * This class implements an off-heap floats KllSketch via a WritableMemory instance of the sketch.
  *
@@ -60,7 +55,11 @@ import org.apache.datasketches.memory.WritableMemory;
  *
  * @author Lee Rhodes, Kevin Lang
  */
-public final class KllDirectFloatsSketch extends KllSketch {
+final class KllDirectFloatsSketch extends KllFloatsSketch {
+  final boolean updatableMemory;
+  WritableMemory levelsArrUpdatable;
+  WritableMemory minMaxArrUpdatable;
+  WritableMemory itemsArrUpdatable;
 
   /**
    * The actual constructor
@@ -68,7 +67,7 @@ public final class KllDirectFloatsSketch extends KllSketch {
    * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
    * @param memVal the MemoryValadate object
    */
-  private KllDirectFloatsSketch(final WritableMemory wmem, final MemoryRequestServer memReqSvr,
+  KllDirectFloatsSketch(final WritableMemory wmem, final MemoryRequestServer memReqSvr,
    final KllMemoryValidate memVal) {
    super(SketchType.FLOATS_SKETCH, wmem, memReqSvr);
    updatableMemory = memVal.updatableMemory && memReqSvr != null;
@@ -77,27 +76,6 @@ public final class KllDirectFloatsSketch extends KllSketch {
    itemsArrUpdatable = memVal.itemsArrUpdatable;
   }
 
-  /**
-   * Heapifies the given Memory object and returns a KllFloatsSketch
-   * @param mem the given Memory object.
-   * @return a KllFloatsSketch
-   */
-  public static KllHeapFloatsSketch heapify(final Memory mem) {
-    return KllHeapFloatsSketch.heapify(mem);
-  }
-
-  /**
-   * Create a new instance of this sketch using the default <i>m</i> of 8.
-   * @param k parameter that controls size of the sketch and accuracy of estimates
-   * @param dstMem the given destination WritableMemory object for use by the sketch
-   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
-   * @return a new instance of this sketch
-   */
-  public static KllDirectFloatsSketch newInstance(final int k, final WritableMemory dstMem,
-      final MemoryRequestServer memReqSvr) {
-    return newInstance(k, KllSketch.DEFAULT_M, dstMem, memReqSvr);
-  }
-
   /**
    * Create a new instance of this sketch.
    * @param k parameter that controls size of the sketch and accuracy of estimates
@@ -106,7 +84,7 @@ public final class KllDirectFloatsSketch extends KllSketch {
    * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
    * @return a new instance of this sketch
    */
-  static KllDirectFloatsSketch newInstance(final int k, final int m, final WritableMemory dstMem,
+  static KllDirectFloatsSketch newDirectInstance(final int k, final int m, final WritableMemory dstMem,
       final MemoryRequestServer memReqSvr) {
     setMemoryPreInts(dstMem, PREAMBLE_INTS_FULL);
     setMemorySerVer(dstMem, SERIAL_VERSION_UPDATABLE);
@@ -127,288 +105,6 @@ public final class KllDirectFloatsSketch extends KllSketch {
     return new KllDirectFloatsSketch(dstMem, memReqSvr, memVal);
   }
 
-  /**
-   * Wrap a sketch around the given source Memory containing sketch data that originated from
-   * this sketch.
-   * @param srcMem a WritableMemory that contains data.
-   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
-   * @return instance of this sketch
-   */
-  public static KllDirectFloatsSketch writableWrap(final WritableMemory srcMem, final MemoryRequestServer memReqSvr) {
-    final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
-    return new KllDirectFloatsSketch(srcMem, memReqSvr, memVal);
-  }
-
-  /**
-   * Returns an approximation to the Cumulative Distribution Function (CDF), which is the
-   * cumulative analog of the PMF, of the input stream given a set of splitPoint (values).
-   *
-   * <p>The resulting approximations have a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(false) function.
-   *
-   * <p>If the sketch is empty this returns null.</p>
-   *
-   * @param splitPoints an array of <i>m</i> unique, monotonically increasing float values
-   * that divide the real number line into <i>m+1</i> consecutive disjoint intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint (or minimum value) and
-   * exclusive of the right splitPoint, with the exception that the last interval will include
-   * the maximum value.
-   * It is not necessary to include either the min or max values in these split points.
-   *
-   * @return an array of m+1 double values on the interval [0.0, 1.0),
-   * which are a consecutive approximation to the CDF of the input stream given the splitPoints.
-   * The value at array position j of the returned CDF array is the sum of the returned values
-   * in positions 0 through j of the returned PMF array.
-   */
-  public double[] getCDF(final float[] splitPoints) {
-    return KllFloatsHelper.getFloatsPmfOrCdf(this, splitPoints, true);
-  }
-
-  /**
-   * Returns the max value of the stream.
-   * If the sketch is empty this returns NaN.
-   *
-   * @return the max value of the stream
-   */
-  public float getMaxValue() { return getMaxFloatValue(); }
-
-  /**
-   * Returns the min value of the stream.
-   * If the sketch is empty this returns NaN.
-   *
-   * @return the min value of the stream
-   */
-  public float getMinValue() { return getMinFloatValue(); }
-
-  /**
-   * Returns an approximation to the Probability Mass Function (PMF) of the input stream
-   * given a set of splitPoints (values).
-   *
-   * <p>The resulting approximations have a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(true) function.
-   *
-   * <p>If the sketch is empty this returns null.</p>
-   *
-   * @param splitPoints an array of <i>m</i> unique, monotonically increasing float values
-   * that divide the real number line into <i>m+1</i> consecutive disjoint intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint (or minimum value) and
-   * exclusive of the right splitPoint, with the exception that the last interval will include
-   * the maximum value.
-   * It is not necessary to include either the min or max values in these split points.
-   *
-   * @return an array of m+1 doubles on the interval [0.0, 1.0),
-   * each of which is an approximation to the fraction of the total input stream values
-   * (the mass) that fall into one of those intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint and exclusive of the right
-   * splitPoint, with the exception that the last interval will include maximum value.
-   */
-  public double[] getPMF(final float[] splitPoints) {
-    return KllFloatsHelper.getFloatsPmfOrCdf(this, splitPoints, false);
-  }
-
-  /**
-   * Returns an approximation to the value of the data item
-   * that would be preceded by the given fraction of a hypothetical sorted
-   * version of the input stream so far.
-   *
-   * <p>We note that this method has a fairly large overhead (microseconds instead of nanoseconds)
-   * so it should not be called multiple times to get different quantiles from the same
-   * sketch. Instead use getQuantiles(), which pays the overhead only once.
-   *
-   * <p>If the sketch is empty this returns NaN.
-   *
-   * @param fraction the specified fractional position in the hypothetical sorted stream.
-   * These are also called normalized ranks or fractional ranks.
-   * If fraction = 0.0, the true minimum value of the stream is returned.
-   * If fraction = 1.0, the true maximum value of the stream is returned.
-   *
-   * @return the approximation to the value at the given fraction
-   */
-  public float getQuantile(final double fraction) {
-    return KllFloatsHelper.getFloatsQuantile(this, fraction);
-  }
-
-  /**
-   * Gets the lower bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%.
-   * @param fraction the given normalized rank as a fraction
-   * @return the lower bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
-   */
-  public float getQuantileLowerBound(final double fraction) {
-    return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getMinK(), false)));
-  }
-
-  /**
-   * This is a more efficient multiple-query version of getQuantile().
-   *
-   * <p>This returns an array that could have been generated by using getQuantile() with many
-   * different fractional ranks, but would be very inefficient.
-   * This method incurs the internal set-up overhead once and obtains multiple quantile values in
-   * a single query. It is strongly recommend that this method be used instead of multiple calls
-   * to getQuantile().
-   *
-   * <p>If the sketch is empty this returns null.
-   *
-   * @param fractions given array of fractional positions in the hypothetical sorted stream.
-   * These are also called normalized ranks or fractional ranks.
-   * These fractions must be in the interval [0.0, 1.0], inclusive.
-   *
-   * @return array of approximations to the given fractions in the same order as given fractions
-   * array.
-   */
-  public float[] getQuantiles(final double[] fractions) {
-    return KllFloatsHelper.getFloatsQuantiles(this, fractions);
-  }
-
-  /**
-   * This is also a more efficient multiple-query version of getQuantile() and allows the caller to
-   * specify the number of evenly spaced fractional ranks.
-   *
-   * <p>If the sketch is empty this returns null.
-   *
-   * @param numEvenlySpaced an integer that specifies the number of evenly spaced fractional ranks.
-   * This must be a positive integer greater than 0. A value of 1 will return the min value.
-   * A value of 2 will return the min and the max value. A value of 3 will return the min,
-   * the median and the max value, etc.
-   *
-   * @return array of approximations to the given fractions in the same order as given fractions
-   * array.
-   */
-  public float[] getQuantiles(final int numEvenlySpaced) {
-    if (isEmpty()) { return null; }
-    return getQuantiles(org.apache.datasketches.Util.evenlySpaced(0.0, 1.0, numEvenlySpaced));
-  }
-
-  /**
-   * Gets the upper bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%.
-   * @param fraction the given normalized rank as a fraction
-   * @return the upper bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
-   */
-  public float getQuantileUpperBound(final double fraction) {
-    return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getMinK(), false)));
-  }
-
-  /**
-   * Returns an approximation to the normalized (fractional) rank of the given value from 0 to 1,
-   * inclusive.
-   *
-   * <p>The resulting approximation has a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(false) function.
-   *
-   * <p>If the sketch is empty this returns NaN.</p>
-   *
-   * @param value to be ranked
-   * @return an approximate rank of the given value
-   */
-  public double getRank(final float value) {
-    return KllFloatsHelper.getFloatRank(this, value);
-  }
-
-  /**
-   * @return the iterator for this class
-   */
-  public KllFloatsSketchIterator iterator() {
-    return new KllFloatsSketchIterator(getFloatItemsArray(), getLevelsArray(), getNumLevels());
-  }
-
-  /**
-   * Merges another sketch into this one.
-   * @param other sketch to merge into this one
-   */
-  public void merge(final KllSketch other) {
-    if (!other.isFloatsSketch()) { kllSketchThrow(SRC_MUST_BE_FLOAT); }
-    KllFloatsHelper.mergeFloatImpl(this, other);
-  }
-
-  /**
-   * Updates this sketch with the given data item.
-   *
-   * @param value an item from a stream of items. NaNs are ignored.
-   */
-  public void update(final float value) {
-    KllFloatsHelper.updateFloat(this, value);
-  }
-
-  @Override
-  double[] getDoubleItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
-
-  @Override
-  double getDoubleItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
-
-  @Override
-  float[] getFloatItemsArray() {
-    final int items = getItemsArrLengthItems();
-    final float[] itemsArr = new float[items];
-    itemsArrUpdatable.getFloatArray(0, itemsArr, 0, items);
-    return itemsArr;
-  }
-
-  @Override
-  float getFloatItemsArrayAt(final int index) {
-    return itemsArrUpdatable.getFloat((long)index * Float.BYTES);
-  }
-
-  @Override
-  double getMaxDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
-
-  @Override
-  float getMaxFloatValue() {
-    return minMaxArrUpdatable.getFloat(Float.BYTES);
-  }
-
-  @Override
-  double getMinDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
-
-  @Override
-  float getMinFloatValue() {
-    return minMaxArrUpdatable.getFloat(0);
-  }
-
-  @Override
-  void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override
-  void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override
-  void setFloatItemsArray(final float[] floatItems) {
-    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
-    itemsArrUpdatable.putFloatArray(0, floatItems, 0, floatItems.length);
-  }
-
-  @Override
-  void setFloatItemsArrayAt(final int index, final float value) {
-    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
-    itemsArrUpdatable.putFloat((long)index * Float.BYTES, value);
-  }
-
-  @Override
-  void setMaxDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override
-  void setMaxFloatValue(final float value) {
-    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
-    minMaxArrUpdatable.putFloat(Float.BYTES, value);
-  }
-
-  @Override
-  void setMinDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override
-  void setMinFloatValue(final float value) {
-    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
-    minMaxArrUpdatable.putFloat(0, value);
-  }
-
-  //**********************************************************************************
-  final boolean updatableMemory;
-  WritableMemory levelsArrUpdatable;
-  WritableMemory minMaxArrUpdatable;
-  WritableMemory itemsArrUpdatable;
-
   @Override
   public int getK() {
     return getMemoryK(wmem);
@@ -449,6 +145,19 @@ public final class KllDirectFloatsSketch extends KllSketch {
     return byteArr;
   }
 
+  @Override
+  float[] getFloatItemsArray() {
+    final int items = getItemsArrLengthItems();
+    final float[] itemsArr = new float[items];
+    itemsArrUpdatable.getFloatArray(0, itemsArr, 0, items);
+    return itemsArr;
+  }
+
+  @Override
+  float getFloatItemsArrayAt(final int index) {
+    return itemsArrUpdatable.getFloat((long)index * Float.BYTES);
+  }
+
   int getItemsArrLengthItems() {
     return getLevelsArray()[getNumLevels()];
   }
@@ -471,6 +180,16 @@ public final class KllDirectFloatsSketch extends KllSketch {
     return getMemoryM(wmem);
   }
 
+  @Override
+  float getMaxFloatValue() {
+    return minMaxArrUpdatable.getFloat(Float.BYTES);
+  }
+
+  @Override
+  float getMinFloatValue() {
+    return minMaxArrUpdatable.getFloat(0);
+  }
+
   @Override
   int getMinK() {
     return getMemoryMinK(wmem);
@@ -500,6 +219,18 @@ public final class KllDirectFloatsSketch extends KllSketch {
     return getMemoryLevelZeroSortedFlag(wmem);
   }
 
+  @Override
+  void setFloatItemsArray(final float[] floatItems) {
+    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+    itemsArrUpdatable.putFloatArray(0, floatItems, 0, floatItems.length);
+  }
+
+  @Override
+  void setFloatItemsArrayAt(final int index, final float value) {
+    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+    itemsArrUpdatable.putFloat((long)index * Float.BYTES, value);
+  }
+
   @Override
   void setItemsArrayUpdatable(final WritableMemory itemsMem) {
     if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
@@ -546,6 +277,18 @@ public final class KllDirectFloatsSketch extends KllSketch {
     setMemoryLevelZeroSortedFlag(wmem, sorted);
   }
 
+  @Override
+  void setMaxFloatValue(final float value) {
+    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+    minMaxArrUpdatable.putFloat(Float.BYTES, value);
+  }
+
+  @Override
+  void setMinFloatValue(final float value) {
+    if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+    minMaxArrUpdatable.putFloat(0, value);
+  }
+
   @Override
   void setMinK(final int minK) {
     if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
similarity index 67%
copy from src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java
copy to src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index e2f84626..d8a51a5a 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -21,94 +21,96 @@ package org.apache.datasketches.kll;
 
 import static java.lang.Math.max;
 import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DOUBLE;
 import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DOUBLE;
 import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
 
 import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryRequestServer;
 import org.apache.datasketches.memory.WritableMemory;
 
-/**
- * This class implements an on-heap doubles KllSketch.
- *
- * <p>Please refer to the documentation in the package-info:<br>
- * {@link org.apache.datasketches.kll}</p>
- *
- * @author Lee Rhodes, Kevin Lang
- */
-public final class KllHeapDoublesSketch extends KllSketch {
-  private double[] doubleItems_;
-  private double minDoubleValue_;
-  private double maxDoubleValue_;
+public abstract class KllDoublesSketch extends KllSketch {
+
+  KllDoublesSketch(final SketchType sketchType, final WritableMemory wmem, final MemoryRequestServer memReqSvr) {
+    super(sketchType, wmem, memReqSvr);
+  }
 
   /**
-   * Private heapify constructor.
-   * @param mem Memory object that contains data serialized by this sketch.
-   * @param memVal the MemoryCheck object
+   * Factory heapify takes the sketch image in Memory and instantiates an on-heap sketch.
+   * The resulting sketch will not retain any link to the source Memory.
+   * @param mem a Memory image of a sketch serialized by this sketch.
+   * <a href="{@docRoot}/resources/dictionary.html#mem">See Memory</a>
+   * @return a heap-based sketch based on the given Memory.
    */
-  private KllHeapDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
-    super(SketchType.DOUBLES_SKETCH,null, null );
-    k = memVal.k;
-    m = memVal.m;
-    KllHelper.buildHeapKllSketchFromMemory(this, memVal);
+  public static KllDoublesSketch heapify(final Memory mem) {
+    final KllMemoryValidate memChk = new KllMemoryValidate(mem);
+    if (!memChk.doublesSketch) { Error.kllSketchThrow(SRC_MUST_BE_DOUBLE); }
+    return new KllHeapDoublesSketch(mem, memChk);
   }
 
   /**
-   * Heap constructor with the default <em>k = 200</em>.
+   * Create a new heap instance of this sketch with the default <em>k = 200</em>.
+   * The default <em>k</em> = 200 results in a normalized rank error of about
+   * 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
    * This will have a rank error of about 1.65%.
+   * @return new KllDoublesSketch on the heap.
    */
-  public KllHeapDoublesSketch() {
-    this(KllSketch.DEFAULT_K, KllSketch.DEFAULT_M);
+  public static KllDoublesSketch  newHeapInstance() {
+    return new KllHeapDoublesSketch(DEFAULT_K, DEFAULT_M);
   }
 
   /**
-   * Heap constructor with a given parameter <em>k</em>. <em>k</em> can be any value between DEFAULT_M and
-   * 65535, inclusive. The default <em>k</em> = 200 results in a normalized rank error of about
+   * Create a new heap instance of this sketch with a given parameter <em>k</em>.
+   * <em>k</em> can be any value between DEFAULT_M and 65535, inclusive.
+   * The default <em>k</em> = 200 results in a normalized rank error of about
    * 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
-   * @param k parameter that controls size of the sketch and accuracy of estimates
+   * @param k parameter that controls size of the sketch and accuracy of estimates.
+   * @return new KllDoublesSketch on the heap.
    */
-  public KllHeapDoublesSketch(final int k) {
-    this(k, KllSketch.DEFAULT_M);
+  public static KllDoublesSketch newHeapInstance(final int k) {
+    return new KllHeapDoublesSketch(k, DEFAULT_M);
   }
 
   /**
-   * Heap constructor with a given parameters <em>k</em> and <em>m</em>.
-   *
+   * Create a new direct instance of this sketch with the default <em>k</em>.
+   * The default <em>k</em> = 200 results in a normalized rank error of about
+   * 1.65%. Higher values of <em>k</em> will have smaller error but the sketch will be larger (and slower).
+   * @param dstMem the given destination WritableMemory object for use by the sketch
+   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
+   * @return a new direct instance of this sketch
+   */
+  public static KllDoublesSketch newDirectInstance(
+      final WritableMemory dstMem,
+      final MemoryRequestServer memReqSvr) {
+    return KllDirectDoublesSketch.newDirectInstance(DEFAULT_K, DEFAULT_M, dstMem, memReqSvr);
+  }
+
+  /**
+   * Create a new direct instance of this sketch with a given <em>k</em>.
    * @param k parameter that controls size of the sketch and accuracy of estimates.
-   * <em>k</em> can be any value between <em>m</em> and 65535, inclusive.
-   * The default <em>k</em> = 200 results in a normalized rank error of about 1.65%.
-   * Higher values of <em>k</em> will have smaller error but the sketch will be larger (and slower).
-   * @param m parameter controls the minimum level width in items. It can be 2, 4, 6 or 8.
-   * The DEFAULT_M, which is 8 is recommended. Other values of <em>m</em> should be considered
-   * experimental as they have not been as well characterized.
+   * @param dstMem the given destination WritableMemory object for use by the sketch
+   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
+   * @return a new direct instance of this sketch
    */
-  KllHeapDoublesSketch(final int k, final int m) {
-    super(SketchType.DOUBLES_SKETCH, null, null);
-    KllHelper.checkM(m);
-    KllHelper.checkK(k, m);
-    this.k = k;
-    this.m = m;
-    n_ = 0;
-    minK_ = k;
-    numLevels_ = 1;
-    levels_ = new int[] {k, k};
-    isLevelZeroSorted_ = false;
-    doubleItems_ = new double[k];
-    minDoubleValue_ = Double.NaN;
-    maxDoubleValue_ = Double.NaN;
+  public static KllDoublesSketch newDirectInstance(
+      final int k,
+      final WritableMemory dstMem,
+      final MemoryRequestServer memReqSvr) {
+    return KllDirectDoublesSketch.newDirectInstance(k, DEFAULT_M, dstMem, memReqSvr);
   }
 
   /**
-   * Factory heapify takes the sketch image in Memory and instantiates an on-heap sketch.
-   * The resulting sketch will not retain any link to the source Memory.
-   * @param mem a Memory image of a sketch serialized by this sketch.
-   * <a href="{@docRoot}/resources/dictionary.html#mem">See Memory</a>
-   * @return a heap-based sketch based on the given Memory.
+   * Wrap a sketch around the given source Memory containing sketch data that originated from
+   * this sketch.
+   * @param srcMem a WritableMemory that contains data.
+   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
+   * @return instance of this sketch
    */
-  public static KllHeapDoublesSketch heapify(final Memory mem) {
-    final KllMemoryValidate memChk = new KllMemoryValidate(mem);
-    if (!memChk.doublesSketch) { Error.kllSketchThrow(SRC_MUST_BE_DOUBLE); }
-    return new KllHeapDoublesSketch(mem, memChk);
+  public static KllDoublesSketch writableWrap(
+      final WritableMemory srcMem,
+      final MemoryRequestServer memReqSvr) {
+    final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
+    return new KllDirectDoublesSketch(srcMem, memReqSvr, memVal);
   }
 
   /**
@@ -295,19 +297,6 @@ public final class KllHeapDoublesSketch extends KllSketch {
     KllDoublesHelper.mergeDoubleImpl(this, other);
   }
 
-  @Override
-  public void reset() {
-    final int k = getK();
-    setN(0);
-    setMinK(k);
-    setNumLevels(1);
-    setLevelsArray(new int[] {k, k});
-    setLevelZeroSorted(false);
-    doubleItems_ = new double[k];
-    minDoubleValue_ = Double.NaN;
-    maxDoubleValue_ = Double.NaN;
-  }
-
   /**
    * Updates this sketch with the given data item.
    *
@@ -317,35 +306,17 @@ public final class KllHeapDoublesSketch extends KllSketch {
     KllDoublesHelper.updateDouble(this, value);
   }
 
-  @Override //Used internally
-  double[] getDoubleItemsArray() { return doubleItems_; }
-
-  @Override
-  double getDoubleItemsArrayAt(final int index) { return doubleItems_[index]; }
-
   @Override //Dummy
   float[] getFloatItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
 
   @Override //Dummy
   float getFloatItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
 
-  @Override //Used internally
-  double getMaxDoubleValue() { return maxDoubleValue_; }
-
   @Override //Dummy
-  float getMaxFloatValue() { kllSketchThrow(MUST_NOT_CALL); return (float) maxDoubleValue_; }
-
-  @Override //Used internally
-  double getMinDoubleValue() { return minDoubleValue_; }
+  float getMaxFloatValue() { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
 
   @Override //Dummy
-  float getMinFloatValue() { kllSketchThrow(MUST_NOT_CALL); return (float) minDoubleValue_; }
-
-  @Override //Used internally
-  void setDoubleItemsArray(final double[] doubleItems) { doubleItems_ = doubleItems; }
-
-  @Override //Used internally
-  void setDoubleItemsArrayAt(final int index, final double value) { doubleItems_[index] = value; }
+  float getMinFloatValue() { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
 
   @Override //Dummy
   void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(MUST_NOT_CALL); }
@@ -353,120 +324,11 @@ public final class KllHeapDoublesSketch extends KllSketch {
   @Override //Dummy
   void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(MUST_NOT_CALL); }
 
-  @Override //Used internally
-  void setMaxDoubleValue(final double value) { maxDoubleValue_ = value; }
-
   @Override //Dummy
   void setMaxFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
 
-  @Override //Used internally
-  void setMinDoubleValue(final double value) { minDoubleValue_ = value; }
-
   @Override //Dummy
   void setMinFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
 
-  //************************************************************************************************
-  private final int k;    // configured value of K.
-  private final int m;    // configured value of M.
-  private long n_;        // number of items input into this sketch.
-  private int minK_;    // dynamic minK for error estimation after merging with different k.
-  private int numLevels_; // one-based number of current levels.
-  private int[] levels_;  // array of index offsets into the items[]. Size = numLevels + 1.
-  private boolean isLevelZeroSorted_;
-
-  @Override
-  public int getK() {
-    return k;
-  }
-
-  @Override
-  public long getN() {
-    return n_;
-  }
-
-  @Override
-  int[] getLevelsArray() {
-    return levels_;
-  }
-
-  @Override
-  int getLevelsArrayAt(final int index) { return levels_[index]; }
-
-  @Override
-  int getM() {
-    return m;
-  }
-
-  @Override
-  int getMinK() {
-    return minK_;
-  }
-
-  @Override
-  int getNumLevels() {
-    return numLevels_;
-  }
-
-  @Override
-  void incN() {
-    n_++;
-  }
-
-  @Override
-  void incNumLevels() {
-    numLevels_++;
-  }
-
-  @Override
-  boolean isLevelZeroSorted() {
-    return isLevelZeroSorted_;
-  }
-
-  @Override
-  void setItemsArrayUpdatable(final WritableMemory itemsMem) { } //dummy
-
-  @Override
-  void setLevelsArray(final int[] levelsArr) {
-    levels_ = levelsArr;
-  }
-
-  @Override
-  void setLevelsArrayAt(final int index, final int value) { levels_[index] = value; }
-
-  @Override
-  void setLevelsArrayAtMinusEq(final int index, final int minusEq) {
-    levels_[index] -= minusEq;
-  }
-
-  @Override
-  void setLevelsArrayAtPlusEq(final int index, final int plusEq) {
-    levels_[index] += plusEq;
-  }
-
-  @Override
-  void setLevelsArrayUpdatable(final WritableMemory levelsMem) { } //dummy
-
-  @Override
-  void setLevelZeroSorted(final boolean sorted) {
-    this.isLevelZeroSorted_ = sorted;
-  }
-
-  @Override
-  void setMinK(final int minK) {
-    minK_ = minK;
-  }
-
-  @Override
-  void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) { } //dummy
-
-  @Override
-  void setN(final long n) {
-    n_ = n;
-  }
-
-  @Override
-  void setNumLevels(final int numLevels) {
-    numLevels_ = numLevels;
-  }
-
 }
+
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
similarity index 65%
copy from src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java
copy to src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 030ad4e5..f4702c30 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -21,94 +21,96 @@ package org.apache.datasketches.kll;
 
 import static java.lang.Math.max;
 import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_FLOAT;
 import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_FLOAT;
 import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
 
 import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryRequestServer;
 import org.apache.datasketches.memory.WritableMemory;
 
-/**
- * This class implements an on-heap floats KllSketch.
- *
- * <p>Please refer to the documentation in the package-info:<br>
- * {@link org.apache.datasketches.kll}</p>
- *
- * @author Lee Rhodes, Kevin Lang
- */
-public final class KllHeapFloatsSketch extends KllSketch {
-  private float[] floatItems_;
-  private float minFloatValue_;
-  private float maxFloatValue_;
+public abstract class KllFloatsSketch extends KllSketch {
+
+  KllFloatsSketch(final SketchType sketchType, final WritableMemory wmem, final MemoryRequestServer memReqSvr) {
+    super(sketchType, wmem, memReqSvr);
+  }
 
   /**
-   * Private heapify constructor.
-   * @param mem Memory object that contains data serialized by this sketch.
-   * @param memVal the MemoryCheck object
+   * Factory heapify takes the sketch image in Memory and instantiates an on-heap sketch.
+   * The resulting sketch will not retain any link to the source Memory.
+   * @param mem a Memory image of a sketch serialized by this sketch.
+   * <a href="{@docRoot}/resources/dictionary.html#mem">See Memory</a>
+   * @return a heap-based sketch based on the given Memory.
    */
-  private KllHeapFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
-    super(SketchType.FLOATS_SKETCH, null, null);
-    k = memVal.k;
-    m = memVal.m;
-    KllHelper.buildHeapKllSketchFromMemory(this, memVal);
+  public static KllFloatsSketch heapify(final Memory mem) {
+    final KllMemoryValidate memChk = new KllMemoryValidate(mem);
+    if (memChk.doublesSketch) { Error.kllSketchThrow(SRC_MUST_BE_FLOAT); }
+    return new KllHeapFloatsSketch(mem, memChk);
   }
 
   /**
-   * Heap constructor with the default <em>k = 200</em>.
+   * Create a new heap instance of this sketch with the default <em>k = 200</em>.
+   * The default <em>k</em> = 200 results in a normalized rank error of about
+   * 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
    * This will have a rank error of about 1.65%.
+   * @return new KllFloatsSketch on the heap.
    */
-  public KllHeapFloatsSketch() {
-    this(KllSketch.DEFAULT_K, KllSketch.DEFAULT_M);
+  public static KllFloatsSketch  newHeapInstance() {
+    return new KllHeapFloatsSketch(DEFAULT_K, DEFAULT_M);
   }
 
   /**
-   * Heap constructor with a given parameter <em>k</em>. <em>k</em> can be any value between 8 and
-   * 65535, inclusive. The default <em>k</em> = 200 results in a normalized rank error of about
+   * Create a new heap instance of this sketch with a given parameter <em>k</em>.
+   * <em>k</em> can be any value between DEFAULT_M and 65535, inclusive.
+   * The default <em>k</em> = 200 results in a normalized rank error of about
    * 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
-   * @param k parameter that controls size of the sketch and accuracy of estimates
+   * @param k parameter that controls size of the sketch and accuracy of estimates.
+   * @return new KllFloatsSketch on the heap.
    */
-  public KllHeapFloatsSketch(final int k) {
-    this(k, KllSketch.DEFAULT_M);
+  public static KllFloatsSketch newHeapInstance(final int k) {
+    return new KllHeapFloatsSketch(k, DEFAULT_M);
   }
 
   /**
-   * Heap constructor with a given parameters <em>k</em> and <em>m</em>.
-   *
+   * Create a new direct instance of this sketch with the default <em>k</em>.
+   * The default <em>k</em> = 200 results in a normalized rank error of about
+   * 1.65%. Higher values of <em>k</em> will have smaller error but the sketch will be larger (and slower).
+   * @param dstMem the given destination WritableMemory object for use by the sketch
+   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
+   * @return a new direct instance of this sketch
+   */
+  public static KllFloatsSketch newDirectInstance(
+      final WritableMemory dstMem,
+      final MemoryRequestServer memReqSvr) {
+    return KllDirectFloatsSketch.newDirectInstance(DEFAULT_K, DEFAULT_M, dstMem, memReqSvr);
+  }
+
+  /**
+   * Create a new direct instance of this sketch with a given <em>k</em>.
    * @param k parameter that controls size of the sketch and accuracy of estimates.
-   * <em>k</em> can be any value between <em>m</em> and 65535, inclusive.
-   * The default <em>k</em> = 200 results in a normalized rank error of about 1.65%.
-   * Higher values of <em>k</em> will have smaller error but the sketch will be larger (and slower).
-   * @param m parameter that controls the minimum level width in items. It can be 2, 4, 6 or 8.
-   * The DEFAULT_M, which is 8 is recommended. Other values of <em>m</em> should be considered
-   * experimental as they have not been as well characterized.
+   * @param dstMem the given destination WritableMemory object for use by the sketch
+   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
+   * @return a new direct instance of this sketch
    */
-  KllHeapFloatsSketch(final int k, final int m) {
-    super(SketchType.FLOATS_SKETCH, null, null);
-    KllHelper.checkM(m);
-    KllHelper.checkK(k, m);
-    this.k = k;
-    this.m = m;
-    n_ = 0;
-    minK_ = k;
-    numLevels_ = 1;
-    levels_ = new int[] {k, k};
-    isLevelZeroSorted_ = false;
-    floatItems_ = new float[k];
-    minFloatValue_ = Float.NaN;
-    maxFloatValue_ = Float.NaN;
+  public static KllFloatsSketch newDirectInstance(
+      final int k,
+      final WritableMemory dstMem,
+      final MemoryRequestServer memReqSvr) {
+    return KllDirectFloatsSketch.newDirectInstance(k, DEFAULT_M, dstMem, memReqSvr);
   }
 
   /**
-   * Factory heapify takes the sketch image in Memory and instantiates an on-heap sketch.
-   * The resulting sketch will not retain any link to the source Memory.
-   * @param mem a Memory image of a sketch serialized by this sketch.
-   * <a href="{@docRoot}/resources/dictionary.html#mem">See Memory</a>
-   * @return a heap-based sketch based on the given Memory.
+   * Wrap a sketch around the given source Memory containing sketch data that originated from
+   * this sketch.
+   * @param srcMem a WritableMemory that contains data.
+   * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
+   * @return instance of this sketch
    */
-  public static KllHeapFloatsSketch heapify(final Memory mem) {
-    final KllMemoryValidate memVal = new KllMemoryValidate(mem);
-    if (memVal.doublesSketch) { Error.kllSketchThrow(SRC_MUST_BE_FLOAT); }
-    return new KllHeapFloatsSketch(mem, memVal);
+  public static KllFloatsSketch writableWrap(
+      final WritableMemory srcMem,
+      final MemoryRequestServer memReqSvr) {
+    final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
+    return new KllDirectFloatsSketch(srcMem, memReqSvr, memVal);
   }
 
   /**
@@ -290,24 +292,11 @@ public final class KllHeapFloatsSketch extends KllSketch {
    * Merges another sketch into this one.
    * @param other sketch to merge into this one
    */
-  public void merge(final KllHeapFloatsSketch other) {
+  public void merge(final KllSketch other) {
     if (!other.isFloatsSketch()) { kllSketchThrow(SRC_MUST_BE_FLOAT); }
     KllFloatsHelper.mergeFloatImpl(this, other);
   }
 
-  @Override
-  public void reset() {
-    final int k = getK();
-    setN(0);
-    setMinK(k);
-    setNumLevels(1);
-    setLevelsArray(new int[] {k, k});
-    setLevelZeroSorted(false);
-    floatItems_ = new float[k];
-    minFloatValue_ = Float.NaN;
-    maxFloatValue_ = Float.NaN;
-  }
-
   /**
    * Updates this sketch with the given data item.
    *
@@ -317,156 +306,29 @@ public final class KllHeapFloatsSketch extends KllSketch {
     KllFloatsHelper.updateFloat(this, value);
   }
 
-  @Override //Dummy
-  double[] getDoubleItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
-
-  @Override //Dummy
-  double getDoubleItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
-
-  @Override //Used internally
-  float[] getFloatItemsArray() { return floatItems_; }
-
-  @Override //Used internally
-  float getFloatItemsArrayAt(final int index) { return floatItems_[index]; }
-
-  @Override //Dummy
-  double getMaxDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return maxFloatValue_; }
-
-  @Override //Used internally
-  float getMaxFloatValue() { return maxFloatValue_; }
-
-  @Override //Dummy
-  double getMinDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return minFloatValue_; }
-
-  @Override //Used internally
-  float getMinFloatValue() { return minFloatValue_; }
-
-  @Override //Dummy
-  void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Dummy
-  void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Used internally
-  void setFloatItemsArray(final float[] floatItems) { floatItems_ = floatItems; }
-
-  @Override //Used internally
-  void setFloatItemsArrayAt(final int index, final float value) { floatItems_[index] = value; }
-
-  @Override //Dummy
-  void setMaxDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Used internally
-  void setMaxFloatValue(final float value) { maxFloatValue_ = value; }
-
-  @Override //Dummy
-  void setMinDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Used internally
-  void setMinFloatValue(final float value) { minFloatValue_ = value; }
-
-  //************************************************************************************************
-  private final int k;    // configured value of K.
-  private final int m;    // configured value of M.
-  private long n_;        // number of items input into this sketch.
-  private int minK_;    // dynamic minK for error estimation after merging with different k.
-  private int numLevels_; // one-based number of current levels.
-  private int[] levels_;  // array of index offsets into the items[]. Size = numLevels + 1.
-  private boolean isLevelZeroSorted_;
-
   @Override
-  public int getK() {
-    return k;
-  }
-
-  @Override
-  public long getN() {
-    return n_;
-  }
-
-  @Override
-  int[] getLevelsArray() {
-    return levels_;
-  }
-
-  @Override
-  int getLevelsArrayAt(final int index) { return levels_[index]; }
-
-  @Override
-  int getM() {
-    return m;
-  }
-
-  @Override
-  int getMinK() {
-    return minK_;
-  }
-
-  @Override
-  int getNumLevels() {
-    return numLevels_;
-  }
-
-  @Override
-  void incN() {
-    n_++;
-  }
-
-  @Override
-  void incNumLevels() {
-    numLevels_++;
-  }
-
-  @Override
-  boolean isLevelZeroSorted() {
-    return isLevelZeroSorted_;
-  }
-
-  @Override
-  void setItemsArrayUpdatable(final WritableMemory itemsMem) { } //dummy
-
-  @Override
-  void setLevelsArray(final int[] levelsArr) {
-    levels_ = levelsArr;
-  }
-
-  @Override
-  void setLevelsArrayAt(final int index, final int value) { levels_[index] = value; }
-
-  @Override
-  void setLevelsArrayAtMinusEq(final int index, final int minusEq) {
-    levels_[index] -= minusEq;
-  }
+  double[] getDoubleItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
 
   @Override
-  void setLevelsArrayAtPlusEq(final int index, final int plusEq) {
-    levels_[index] += plusEq;
-  }
+  double getDoubleItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
 
   @Override
-  void setLevelsArrayUpdatable(final WritableMemory levelsMem) { } //dummy
+  double getMaxDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
 
   @Override
-  void setLevelZeroSorted(final boolean sorted) {
-    this.isLevelZeroSorted_ = sorted;
-  }
+  double getMinDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
 
   @Override
-  void setMinK(final int minK) {
-    minK_ = minK;
-  }
+  void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(MUST_NOT_CALL); }
 
   @Override
-  void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) { } //dummy
+  void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(MUST_NOT_CALL); }
 
   @Override
-  void setN(final long n) {
-    n_ = n;
-  }
+  void setMaxDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
 
   @Override
-  void setNumLevels(final int numLevels) {
-    numLevels_ = numLevels;
-  }
+  void setMinDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
 
 }
+
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java
index e2f84626..367a1815 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java
@@ -19,12 +19,6 @@
 
 package org.apache.datasketches.kll;
 
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DOUBLE;
-import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
-import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
-
 import org.apache.datasketches.memory.Memory;
 import org.apache.datasketches.memory.WritableMemory;
 
@@ -36,41 +30,18 @@ import org.apache.datasketches.memory.WritableMemory;
  *
  * @author Lee Rhodes, Kevin Lang
  */
-public final class KllHeapDoublesSketch extends KllSketch {
+final class KllHeapDoublesSketch extends KllDoublesSketch {
+  private final int k;    // configured value of K.
+  private final int m;    // configured value of M.
+  private long n_;        // number of items input into this sketch.
+  private int minK_;    // dynamic minK for error estimation after merging with different k.
+  private int numLevels_; // one-based number of current levels.
+  private int[] levels_;  // array of index offsets into the items[]. Size = numLevels + 1.
+  private boolean isLevelZeroSorted_;
   private double[] doubleItems_;
   private double minDoubleValue_;
   private double maxDoubleValue_;
 
-  /**
-   * Private heapify constructor.
-   * @param mem Memory object that contains data serialized by this sketch.
-   * @param memVal the MemoryCheck object
-   */
-  private KllHeapDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
-    super(SketchType.DOUBLES_SKETCH,null, null );
-    k = memVal.k;
-    m = memVal.m;
-    KllHelper.buildHeapKllSketchFromMemory(this, memVal);
-  }
-
-  /**
-   * Heap constructor with the default <em>k = 200</em>.
-   * This will have a rank error of about 1.65%.
-   */
-  public KllHeapDoublesSketch() {
-    this(KllSketch.DEFAULT_K, KllSketch.DEFAULT_M);
-  }
-
-  /**
-   * Heap constructor with a given parameter <em>k</em>. <em>k</em> can be any value between DEFAULT_M and
-   * 65535, inclusive. The default <em>k</em> = 200 results in a normalized rank error of about
-   * 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
-   * @param k parameter that controls size of the sketch and accuracy of estimates
-   */
-  public KllHeapDoublesSketch(final int k) {
-    this(k, KllSketch.DEFAULT_M);
-  }
-
   /**
    * Heap constructor with a given parameters <em>k</em> and <em>m</em>.
    *
@@ -99,200 +70,25 @@ public final class KllHeapDoublesSketch extends KllSketch {
   }
 
   /**
-   * Factory heapify takes the sketch image in Memory and instantiates an on-heap sketch.
-   * The resulting sketch will not retain any link to the source Memory.
-   * @param mem a Memory image of a sketch serialized by this sketch.
-   * <a href="{@docRoot}/resources/dictionary.html#mem">See Memory</a>
-   * @return a heap-based sketch based on the given Memory.
-   */
-  public static KllHeapDoublesSketch heapify(final Memory mem) {
-    final KllMemoryValidate memChk = new KllMemoryValidate(mem);
-    if (!memChk.doublesSketch) { Error.kllSketchThrow(SRC_MUST_BE_DOUBLE); }
-    return new KllHeapDoublesSketch(mem, memChk);
-  }
-
-  /**
-   * Returns an approximation to the Cumulative Distribution Function (CDF), which is the
-   * cumulative analog of the PMF, of the input stream given a set of splitPoint (values).
-   *
-   * <p>The resulting approximations have a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(false) function.
-   *
-   * <p>If the sketch is empty this returns null.</p>
-   *
-   * @param splitPoints an array of <i>m</i> unique, monotonically increasing double values
-   * that divide the real number line into <i>m+1</i> consecutive disjoint intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint (or minimum value) and
-   * exclusive of the right splitPoint, with the exception that the last interval will include
-   * the maximum value.
-   * It is not necessary to include either the min or max values in these split points.
-   *
-   * @return an array of m+1 double values on the interval [0.0, 1.0),
-   * which are a consecutive approximation to the CDF of the input stream given the splitPoints.
-   * The value at array position j of the returned CDF array is the sum of the returned values
-   * in positions 0 through j of the returned PMF array.
-   */
-  public double[] getCDF(final double[] splitPoints) {
-    return KllDoublesHelper.getDoublesPmfOrCdf(this, splitPoints, true);
-  }
-
-  /**
-   * Returns the max value of the stream.
-   * If the sketch is empty this returns NaN.
-   *
-   * @return the max value of the stream
-   */
-  public double getMaxValue() { return getMaxDoubleValue(); }
-
-  /**
-   * Returns the min value of the stream.
-   * If the sketch is empty this returns NaN.
-   *
-   * @return the min value of the stream
-   */
-  public double getMinValue() { return getMinDoubleValue(); }
-
-  /**
-   * Returns an approximation to the Probability Mass Function (PMF) of the input stream
-   * given a set of splitPoints (values).
-   *
-   * <p>The resulting approximations have a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(true) function.
-   *
-   * <p>If the sketch is empty this returns null.</p>
-   *
-   * @param splitPoints an array of <i>m</i> unique, monotonically increasing double values
-   * that divide the real number line into <i>m+1</i> consecutive disjoint intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint (or minimum value) and
-   * exclusive of the right splitPoint, with the exception that the last interval will include
-   * the maximum value.
-   * It is not necessary to include either the min or max values in these split points.
-   *
-   * @return an array of m+1 doubles on the interval [0.0, 1.0),
-   * each of which is an approximation to the fraction of the total input stream values
-   * (the mass) that fall into one of those intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint and exclusive of the right
-   * splitPoint, with the exception that the last interval will include maximum value.
-   */
-  public double[] getPMF(final double[] splitPoints) {
-    return KllDoublesHelper.getDoublesPmfOrCdf(this, splitPoints, false);
-  }
-
-  /**
-   * Returns an approximation to the value of the data item
-   * that would be preceded by the given fraction of a hypothetical sorted
-   * version of the input stream so far.
-   *
-   * <p>We note that this method has a fairly large overhead (microseconds instead of nanoseconds)
-   * so it should not be called multiple times to get different quantiles from the same
-   * sketch. Instead use getQuantiles(), which pays the overhead only once.
-   *
-   * <p>If the sketch is empty this returns NaN.
-   *
-   * @param fraction the specified fractional position in the hypothetical sorted stream.
-   * These are also called normalized ranks or fractional ranks.
-   * If fraction = 0.0, the true minimum value of the stream is returned.
-   * If fraction = 1.0, the true maximum value of the stream is returned.
-   *
-   * @return the approximation to the value at the given fraction
-   */
-  public double getQuantile(final double fraction) {
-    return KllDoublesHelper.getDoublesQuantile(this, fraction);
-  }
-
-  /**
-   * Gets the lower bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%.
-   * @param fraction the given normalized rank as a fraction
-   * @return the lower bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
-   */
-  public double getQuantileLowerBound(final double fraction) {
-    return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getMinK(), false)));
-  }
-
-  /**
-   * This is a more efficient multiple-query version of getQuantile().
-   *
-   * <p>This returns an array that could have been generated by using getQuantile() with many
-   * different fractional ranks, but would be very inefficient.
-   * This method incurs the internal set-up overhead once and obtains multiple quantile values in
-   * a single query. It is strongly recommend that this method be used instead of multiple calls
-   * to getQuantile().
-   *
-   * <p>If the sketch is empty this returns null.
-   *
-   * @param fractions given array of fractional positions in the hypothetical sorted stream.
-   * These are also called normalized ranks or fractional ranks.
-   * These fractions must be in the interval [0.0, 1.0], inclusive.
-   *
-   * @return array of approximations to the given fractions in the same order as given fractions
-   * array.
-   */
-  public double[] getQuantiles(final double[] fractions) {
-    return KllDoublesHelper.getDoublesQuantiles(this, fractions);
-  }
-
-  /**
-   * This is also a more efficient multiple-query version of getQuantile() and allows the caller to
-   * specify the number of evenly spaced fractional ranks.
-   *
-   * <p>If the sketch is empty this returns null.
-   *
-   * @param numEvenlySpaced an integer that specifies the number of evenly spaced fractional ranks.
-   * This must be a positive integer greater than 0. A value of 1 will return the min value.
-   * A value of 2 will return the min and the max value. A value of 3 will return the min,
-   * the median and the max value, etc.
-   *
-   * @return array of approximations to the given fractions in the same order as given fractions
-   * array.
-   */
-  public double[] getQuantiles(final int numEvenlySpaced) {
-    if (isEmpty()) { return null; }
-    return getQuantiles(org.apache.datasketches.Util.evenlySpaced(0.0, 1.0, numEvenlySpaced));
-  }
-
-  /**
-   * Gets the upper bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%.
-   * @param fraction the given normalized rank as a fraction
-   * @return the upper bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
-   */
-  public double getQuantileUpperBound(final double fraction) {
-    return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getMinK(), false)));
-  }
-
-  /**
-   * Returns an approximation to the normalized (fractional) rank of the given value from 0 to 1,
-   * inclusive.
-   *
-   * <p>The resulting approximation has a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(false) function.
-   *
-   * <p>If the sketch is empty this returns NaN.</p>
-   *
-   * @param value to be ranked
-   * @return an approximate rank of the given value
+   * Heapify constructor.
+   * @param mem Memory object that contains data serialized by this sketch.
+   * @param memVal the MemoryCheck object
    */
-  public double getRank(final double value) {
-    return KllDoublesHelper.getDoubleRank(this, value);
+  KllHeapDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
+    super(SketchType.DOUBLES_SKETCH,null, null );
+    k = memVal.k;
+    m = memVal.m;
+    KllHelper.buildHeapKllSketchFromMemory(this, memVal);
   }
 
-  /**
-   * @return the iterator for this class
-   */
-  public KllDoublesSketchIterator iterator() {
-    return new KllDoublesSketchIterator(getDoubleItemsArray(), getLevelsArray(), getNumLevels());
+  @Override
+  public int getK() {
+    return k;
   }
 
-  /**
-   * Merges another sketch into this one.
-   * @param other sketch to merge into this one
-   */
-  public void merge(final KllSketch other) {
-    if (!other.isDoublesSketch()) { kllSketchThrow(SRC_MUST_BE_DOUBLE); }
-    KllDoublesHelper.mergeDoubleImpl(this, other);
+  @Override
+  public long getN() {
+    return n_;
   }
 
   @Override
@@ -308,82 +104,12 @@ public final class KllHeapDoublesSketch extends KllSketch {
     maxDoubleValue_ = Double.NaN;
   }
 
-  /**
-   * Updates this sketch with the given data item.
-   *
-   * @param value an item from a stream of items. NaNs are ignored.
-   */
-  public void update(final double value) {
-    KllDoublesHelper.updateDouble(this, value);
-  }
-
-  @Override //Used internally
+  @Override
   double[] getDoubleItemsArray() { return doubleItems_; }
 
   @Override
   double getDoubleItemsArrayAt(final int index) { return doubleItems_[index]; }
 
-  @Override //Dummy
-  float[] getFloatItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
-
-  @Override //Dummy
-  float getFloatItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
-
-  @Override //Used internally
-  double getMaxDoubleValue() { return maxDoubleValue_; }
-
-  @Override //Dummy
-  float getMaxFloatValue() { kllSketchThrow(MUST_NOT_CALL); return (float) maxDoubleValue_; }
-
-  @Override //Used internally
-  double getMinDoubleValue() { return minDoubleValue_; }
-
-  @Override //Dummy
-  float getMinFloatValue() { kllSketchThrow(MUST_NOT_CALL); return (float) minDoubleValue_; }
-
-  @Override //Used internally
-  void setDoubleItemsArray(final double[] doubleItems) { doubleItems_ = doubleItems; }
-
-  @Override //Used internally
-  void setDoubleItemsArrayAt(final int index, final double value) { doubleItems_[index] = value; }
-
-  @Override //Dummy
-  void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Dummy
-  void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Used internally
-  void setMaxDoubleValue(final double value) { maxDoubleValue_ = value; }
-
-  @Override //Dummy
-  void setMaxFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Used internally
-  void setMinDoubleValue(final double value) { minDoubleValue_ = value; }
-
-  @Override //Dummy
-  void setMinFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  //************************************************************************************************
-  private final int k;    // configured value of K.
-  private final int m;    // configured value of M.
-  private long n_;        // number of items input into this sketch.
-  private int minK_;    // dynamic minK for error estimation after merging with different k.
-  private int numLevels_; // one-based number of current levels.
-  private int[] levels_;  // array of index offsets into the items[]. Size = numLevels + 1.
-  private boolean isLevelZeroSorted_;
-
-  @Override
-  public int getK() {
-    return k;
-  }
-
-  @Override
-  public long getN() {
-    return n_;
-  }
-
   @Override
   int[] getLevelsArray() {
     return levels_;
@@ -397,6 +123,12 @@ public final class KllHeapDoublesSketch extends KllSketch {
     return m;
   }
 
+  @Override
+  double getMaxDoubleValue() { return maxDoubleValue_; }
+
+  @Override
+  double getMinDoubleValue() { return minDoubleValue_; }
+
   @Override
   int getMinK() {
     return minK_;
@@ -422,6 +154,12 @@ public final class KllHeapDoublesSketch extends KllSketch {
     return isLevelZeroSorted_;
   }
 
+  @Override
+  void setDoubleItemsArray(final double[] doubleItems) { doubleItems_ = doubleItems; }
+
+  @Override
+  void setDoubleItemsArrayAt(final int index, final double value) { doubleItems_[index] = value; }
+
   @Override
   void setItemsArrayUpdatable(final WritableMemory itemsMem) { } //dummy
 
@@ -451,6 +189,12 @@ public final class KllHeapDoublesSketch extends KllSketch {
     this.isLevelZeroSorted_ = sorted;
   }
 
+  @Override
+  void setMaxDoubleValue(final double value) { maxDoubleValue_ = value; }
+
+  @Override
+  void setMinDoubleValue(final double value) { minDoubleValue_ = value; }
+
   @Override
   void setMinK(final int minK) {
     minK_ = minK;
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java
index 030ad4e5..d2045900 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java
@@ -19,12 +19,6 @@
 
 package org.apache.datasketches.kll;
 
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_FLOAT;
-import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
-import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
-
 import org.apache.datasketches.memory.Memory;
 import org.apache.datasketches.memory.WritableMemory;
 
@@ -36,41 +30,18 @@ import org.apache.datasketches.memory.WritableMemory;
  *
  * @author Lee Rhodes, Kevin Lang
  */
-public final class KllHeapFloatsSketch extends KllSketch {
+final class KllHeapFloatsSketch extends KllFloatsSketch {
+  private final int k;    // configured value of K.
+  private final int m;    // configured value of M.
+  private long n_;        // number of items input into this sketch.
+  private int minK_;    // dynamic minK for error estimation after merging with different k.
+  private int numLevels_; // one-based number of current levels.
+  private int[] levels_;  // array of index offsets into the items[]. Size = numLevels + 1.
+  private boolean isLevelZeroSorted_;
   private float[] floatItems_;
   private float minFloatValue_;
   private float maxFloatValue_;
 
-  /**
-   * Private heapify constructor.
-   * @param mem Memory object that contains data serialized by this sketch.
-   * @param memVal the MemoryCheck object
-   */
-  private KllHeapFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
-    super(SketchType.FLOATS_SKETCH, null, null);
-    k = memVal.k;
-    m = memVal.m;
-    KllHelper.buildHeapKllSketchFromMemory(this, memVal);
-  }
-
-  /**
-   * Heap constructor with the default <em>k = 200</em>.
-   * This will have a rank error of about 1.65%.
-   */
-  public KllHeapFloatsSketch() {
-    this(KllSketch.DEFAULT_K, KllSketch.DEFAULT_M);
-  }
-
-  /**
-   * Heap constructor with a given parameter <em>k</em>. <em>k</em> can be any value between 8 and
-   * 65535, inclusive. The default <em>k</em> = 200 results in a normalized rank error of about
-   * 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
-   * @param k parameter that controls size of the sketch and accuracy of estimates
-   */
-  public KllHeapFloatsSketch(final int k) {
-    this(k, KllSketch.DEFAULT_M);
-  }
-
   /**
    * Heap constructor with a given parameters <em>k</em> and <em>m</em>.
    *
@@ -99,200 +70,25 @@ public final class KllHeapFloatsSketch extends KllSketch {
   }
 
   /**
-   * Factory heapify takes the sketch image in Memory and instantiates an on-heap sketch.
-   * The resulting sketch will not retain any link to the source Memory.
-   * @param mem a Memory image of a sketch serialized by this sketch.
-   * <a href="{@docRoot}/resources/dictionary.html#mem">See Memory</a>
-   * @return a heap-based sketch based on the given Memory.
-   */
-  public static KllHeapFloatsSketch heapify(final Memory mem) {
-    final KllMemoryValidate memVal = new KllMemoryValidate(mem);
-    if (memVal.doublesSketch) { Error.kllSketchThrow(SRC_MUST_BE_FLOAT); }
-    return new KllHeapFloatsSketch(mem, memVal);
-  }
-
-  /**
-   * Returns an approximation to the Cumulative Distribution Function (CDF), which is the
-   * cumulative analog of the PMF, of the input stream given a set of splitPoint (values).
-   *
-   * <p>The resulting approximations have a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(false) function.
-   *
-   * <p>If the sketch is empty this returns null.</p>
-   *
-   * @param splitPoints an array of <i>m</i> unique, monotonically increasing float values
-   * that divide the real number line into <i>m+1</i> consecutive disjoint intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint (or minimum value) and
-   * exclusive of the right splitPoint, with the exception that the last interval will include
-   * the maximum value.
-   * It is not necessary to include either the min or max values in these split points.
-   *
-   * @return an array of m+1 double values on the interval [0.0, 1.0),
-   * which are a consecutive approximation to the CDF of the input stream given the splitPoints.
-   * The value at array position j of the returned CDF array is the sum of the returned values
-   * in positions 0 through j of the returned PMF array.
-   */
-  public double[] getCDF(final float[] splitPoints) {
-    return KllFloatsHelper.getFloatsPmfOrCdf(this, splitPoints, true);
-  }
-
-  /**
-   * Returns the max value of the stream.
-   * If the sketch is empty this returns NaN.
-   *
-   * @return the max value of the stream
-   */
-  public float getMaxValue() { return getMaxFloatValue(); }
-
-  /**
-   * Returns the min value of the stream.
-   * If the sketch is empty this returns NaN.
-   *
-   * @return the min value of the stream
-   */
-  public float getMinValue() { return getMinFloatValue(); }
-
-  /**
-   * Returns an approximation to the Probability Mass Function (PMF) of the input stream
-   * given a set of splitPoints (values).
-   *
-   * <p>The resulting approximations have a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(true) function.
-   *
-   * <p>If the sketch is empty this returns null.</p>
-   *
-   * @param splitPoints an array of <i>m</i> unique, monotonically increasing float values
-   * that divide the real number line into <i>m+1</i> consecutive disjoint intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint (or minimum value) and
-   * exclusive of the right splitPoint, with the exception that the last interval will include
-   * the maximum value.
-   * It is not necessary to include either the min or max values in these split points.
-   *
-   * @return an array of m+1 doubles on the interval [0.0, 1.0),
-   * each of which is an approximation to the fraction of the total input stream values
-   * (the mass) that fall into one of those intervals.
-   * The definition of an "interval" is inclusive of the left splitPoint and exclusive of the right
-   * splitPoint, with the exception that the last interval will include maximum value.
-   */
-  public double[] getPMF(final float[] splitPoints) {
-    return KllFloatsHelper.getFloatsPmfOrCdf(this, splitPoints, false);
-  }
-
-  /**
-   * Returns an approximation to the value of the data item
-   * that would be preceded by the given fraction of a hypothetical sorted
-   * version of the input stream so far.
-   *
-   * <p>We note that this method has a fairly large overhead (microseconds instead of nanoseconds)
-   * so it should not be called multiple times to get different quantiles from the same
-   * sketch. Instead use getQuantiles(), which pays the overhead only once.
-   *
-   * <p>If the sketch is empty this returns NaN.
-   *
-   * @param fraction the specified fractional position in the hypothetical sorted stream.
-   * These are also called normalized ranks or fractional ranks.
-   * If fraction = 0.0, the true minimum value of the stream is returned.
-   * If fraction = 1.0, the true maximum value of the stream is returned.
-   *
-   * @return the approximation to the value at the given fraction
-   */
-  public float getQuantile(final double fraction) {
-    return KllFloatsHelper.getFloatsQuantile(this, fraction);
-  }
-
-  /**
-   * Gets the lower bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%.
-   * @param fraction the given normalized rank as a fraction
-   * @return the lower bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
-   */
-  public float getQuantileLowerBound(final double fraction) {
-    return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getMinK(), false)));
-  }
-
-  /**
-   * This is a more efficient multiple-query version of getQuantile().
-   *
-   * <p>This returns an array that could have been generated by using getQuantile() with many
-   * different fractional ranks, but would be very inefficient.
-   * This method incurs the internal set-up overhead once and obtains multiple quantile values in
-   * a single query. It is strongly recommend that this method be used instead of multiple calls
-   * to getQuantile().
-   *
-   * <p>If the sketch is empty this returns null.
-   *
-   * @param fractions given array of fractional positions in the hypothetical sorted stream.
-   * These are also called normalized ranks or fractional ranks.
-   * These fractions must be in the interval [0.0, 1.0], inclusive.
-   *
-   * @return array of approximations to the given fractions in the same order as given fractions
-   * array.
-   */
-  public float[] getQuantiles(final double[] fractions) {
-    return KllFloatsHelper.getFloatsQuantiles(this, fractions);
-  }
-
-  /**
-   * This is also a more efficient multiple-query version of getQuantile() and allows the caller to
-   * specify the number of evenly spaced fractional ranks.
-   *
-   * <p>If the sketch is empty this returns null.
-   *
-   * @param numEvenlySpaced an integer that specifies the number of evenly spaced fractional ranks.
-   * This must be a positive integer greater than 0. A value of 1 will return the min value.
-   * A value of 2 will return the min and the max value. A value of 3 will return the min,
-   * the median and the max value, etc.
-   *
-   * @return array of approximations to the given fractions in the same order as given fractions
-   * array.
-   */
-  public float[] getQuantiles(final int numEvenlySpaced) {
-    if (isEmpty()) { return null; }
-    return getQuantiles(org.apache.datasketches.Util.evenlySpaced(0.0, 1.0, numEvenlySpaced));
-  }
-
-  /**
-   * Gets the upper bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%.
-   * @param fraction the given normalized rank as a fraction
-   * @return the upper bound of the value interval in which the true quantile of the given rank
-   * exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
-   */
-  public float getQuantileUpperBound(final double fraction) {
-    return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getMinK(), false)));
-  }
-
-  /**
-   * Returns an approximation to the normalized (fractional) rank of the given value from 0 to 1,
-   * inclusive.
-   *
-   * <p>The resulting approximation has a probabilistic guarantee that can be obtained from the
-   * getNormalizedRankError(false) function.
-   *
-   * <p>If the sketch is empty this returns NaN.</p>
-   *
-   * @param value to be ranked
-   * @return an approximate rank of the given value
+   * Heapify constructor.
+   * @param mem Memory object that contains data serialized by this sketch.
+   * @param memVal the MemoryCheck object
    */
-  public double getRank(final float value) {
-    return KllFloatsHelper.getFloatRank(this, value);
+  KllHeapFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
+    super(SketchType.FLOATS_SKETCH, null, null);
+    k = memVal.k;
+    m = memVal.m;
+    KllHelper.buildHeapKllSketchFromMemory(this, memVal);
   }
 
-  /**
-   * @return the iterator for this class
-   */
-  public KllFloatsSketchIterator iterator() {
-    return new KllFloatsSketchIterator(getFloatItemsArray(), getLevelsArray(), getNumLevels());
+  @Override
+  public int getK() {
+    return k;
   }
 
-  /**
-   * Merges another sketch into this one.
-   * @param other sketch to merge into this one
-   */
-  public void merge(final KllHeapFloatsSketch other) {
-    if (!other.isFloatsSketch()) { kllSketchThrow(SRC_MUST_BE_FLOAT); }
-    KllFloatsHelper.mergeFloatImpl(this, other);
+  @Override
+  public long getN() {
+    return n_;
   }
 
   @Override
@@ -308,81 +104,11 @@ public final class KllHeapFloatsSketch extends KllSketch {
     maxFloatValue_ = Float.NaN;
   }
 
-  /**
-   * Updates this sketch with the given data item.
-   *
-   * @param value an item from a stream of items. NaNs are ignored.
-   */
-  public void update(final float value) {
-    KllFloatsHelper.updateFloat(this, value);
-  }
-
-  @Override //Dummy
-  double[] getDoubleItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
-
-  @Override //Dummy
-  double getDoubleItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
-
-  @Override //Used internally
-  float[] getFloatItemsArray() { return floatItems_; }
-
-  @Override //Used internally
-  float getFloatItemsArrayAt(final int index) { return floatItems_[index]; }
-
-  @Override //Dummy
-  double getMaxDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return maxFloatValue_; }
-
-  @Override //Used internally
-  float getMaxFloatValue() { return maxFloatValue_; }
-
-  @Override //Dummy
-  double getMinDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return minFloatValue_; }
-
-  @Override //Used internally
-  float getMinFloatValue() { return minFloatValue_; }
-
-  @Override //Dummy
-  void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Dummy
-  void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Used internally
-  void setFloatItemsArray(final float[] floatItems) { floatItems_ = floatItems; }
-
-  @Override //Used internally
-  void setFloatItemsArrayAt(final int index, final float value) { floatItems_[index] = value; }
-
-  @Override //Dummy
-  void setMaxDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Used internally
-  void setMaxFloatValue(final float value) { maxFloatValue_ = value; }
-
-  @Override //Dummy
-  void setMinDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
-
-  @Override //Used internally
-  void setMinFloatValue(final float value) { minFloatValue_ = value; }
-
-  //************************************************************************************************
-  private final int k;    // configured value of K.
-  private final int m;    // configured value of M.
-  private long n_;        // number of items input into this sketch.
-  private int minK_;    // dynamic minK for error estimation after merging with different k.
-  private int numLevels_; // one-based number of current levels.
-  private int[] levels_;  // array of index offsets into the items[]. Size = numLevels + 1.
-  private boolean isLevelZeroSorted_;
-
   @Override
-  public int getK() {
-    return k;
-  }
+  float[] getFloatItemsArray() { return floatItems_; }
 
   @Override
-  public long getN() {
-    return n_;
-  }
+  float getFloatItemsArrayAt(final int index) { return floatItems_[index]; }
 
   @Override
   int[] getLevelsArray() {
@@ -397,6 +123,12 @@ public final class KllHeapFloatsSketch extends KllSketch {
     return m;
   }
 
+  @Override
+  float getMaxFloatValue() { return maxFloatValue_; }
+
+  @Override
+  float getMinFloatValue() { return minFloatValue_; }
+
   @Override
   int getMinK() {
     return minK_;
@@ -422,6 +154,12 @@ public final class KllHeapFloatsSketch extends KllSketch {
     return isLevelZeroSorted_;
   }
 
+  @Override
+  void setFloatItemsArray(final float[] floatItems) { floatItems_ = floatItems; }
+
+  @Override
+  void setFloatItemsArrayAt(final int index, final float value) { floatItems_[index] = value; }
+
   @Override
   void setItemsArrayUpdatable(final WritableMemory itemsMem) { } //dummy
 
@@ -451,6 +189,12 @@ public final class KllHeapFloatsSketch extends KllSketch {
     this.isLevelZeroSorted_ = sorted;
   }
 
+  @Override
+  void setMaxFloatValue(final float value) { maxFloatValue_ = value; }
+
+  @Override
+  void setMinFloatValue(final float value) { minFloatValue_ = value; }
+
   @Override
   void setMinK(final int minK) {
     minK_ = minK;
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchIteratorTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchIteratorTest.java
index df66d57a..f41f5886 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchIteratorTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchIteratorTest.java
@@ -29,14 +29,14 @@ public class KllDirectDoublesSketchIteratorTest {
 
   @Test
   public void emptySketch() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     KllDoublesSketchIterator it = sketch.iterator();
     Assert.assertFalse(it.next());
   }
 
   @Test
   public void oneItemSketch() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     sketch.update(0);
     KllDoublesSketchIterator it = sketch.iterator();
     Assert.assertTrue(it.next());
@@ -48,7 +48,7 @@ public class KllDirectDoublesSketchIteratorTest {
   @Test
   public void bigSketches() {
     for (int n = 1000; n < 100000; n += 2000) {
-      final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+      final KllDoublesSketch sketch = getDDSketch(200, 0);
       for (int i = 0; i < n; i++) {
         sketch.update(i);
       }
@@ -64,13 +64,13 @@ public class KllDirectDoublesSketchIteratorTest {
     }
   }
 
-  private static KllDirectDoublesSketch getDDSketch(final int k, final int n) {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch(k);
+  private static KllDoublesSketch getDDSketch(final int k, final int n) {
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= n; i++) { sk.update(i); }
     byte[] byteArr = sk.toUpdatableByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
 
-    KllDirectDoublesSketch ddsk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    KllDoublesSketch ddsk = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     return ddsk;
   }
 
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
index 9665ea82..9232411e 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
@@ -42,7 +42,7 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void empty() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     sketch.update(Double.NaN); // this must not change anything
     assertTrue(sketch.isEmpty());
     assertEquals(sketch.getN(), 0);
@@ -59,21 +59,21 @@ public class KllDirectDoublesSketchTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void getQuantileInvalidArg() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     sketch.update(1);
     sketch.getQuantile(-1.0);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void getQuantilesInvalidArg() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     sketch.update(1);
     sketch.getQuantiles(new double[] {2.0});
   }
 
   @Test
   public void oneItem() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     sketch.update(1);
     assertFalse(sketch.isEmpty());
     assertEquals(sketch.getN(), 1);
@@ -87,7 +87,7 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void manyItemsEstimationMode() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     final int n = 1_000_000;
 
     for (int i = 0; i < n; i++) {
@@ -133,7 +133,7 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void getRankGetCdfGetPmfConsistency() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     final int n = 1000;
     final double[] values = new double[n];
     for (int i = 0; i < n; i++) {
@@ -156,8 +156,8 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void merge() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
-    final KllDirectDoublesSketch sketch2 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch2 = getDDSketch(200, 0);
     final int n = 10_000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i * 1.0);
@@ -181,8 +181,8 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void mergeLowerK() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(256, 0);
-    final KllDirectDoublesSketch sketch2 = getDDSketch(128, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(256, 0);
+    final KllDoublesSketch sketch2 = getDDSketch(128, 0);
     final int n = 10_000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -212,8 +212,8 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void mergeEmptyLowerK() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(256, 0);
-    final KllDirectDoublesSketch sketch2 = getDDSketch(128, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(256, 0);
+    final KllDoublesSketch sketch2 = getDDSketch(128, 0);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -241,8 +241,8 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void mergeExactModeLowerK() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(256, 0);
-    final KllDirectDoublesSketch sketch2 = getDDSketch(128, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(256, 0);
+    final KllDoublesSketch sketch2 = getDDSketch(128, 0);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -257,8 +257,8 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void mergeMinMinValueFromOther() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
-    final KllDirectDoublesSketch sketch2 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch2 = getDDSketch(200, 0);
     sketch1.update(1);
     sketch2.update(2);
     sketch2.merge(sketch1);
@@ -267,8 +267,8 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void mergeMinAndMaxFromOther() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
-    final KllDirectDoublesSketch sketch2 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch2 = getDDSketch(200, 0);
     for (int i = 1; i <= 1_000_000; i++) {
       sketch1.update(i);
     }
@@ -280,18 +280,18 @@ public class KllDirectDoublesSketchTest {
   @SuppressWarnings("unused")
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void kTooSmall() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(KllSketch.DEFAULT_M - 1, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(KllSketch.DEFAULT_M - 1, 0);
   }
 
   @SuppressWarnings("unused")
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void kTooLarge() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(KllSketch.MAX_K + 1, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(KllSketch.MAX_K + 1, 0);
   }
 
   @Test
   public void minK() {
-    final KllDirectDoublesSketch sketch = getDDSketch(KllSketch.DEFAULT_M, 0);
+    final KllDoublesSketch sketch = getDDSketch(KllSketch.DEFAULT_M, 0);
     for (int i = 0; i < 1000; i++) {
       sketch.update(i);
     }
@@ -301,7 +301,7 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void maxK() {
-    final KllDirectDoublesSketch sketch = getDDSketch(KllSketch.MAX_K, 0);
+    final KllDoublesSketch sketch = getDDSketch(KllSketch.MAX_K, 0);
     for (int i = 0; i < 1000; i++) {
       sketch.update(i);
     }
@@ -311,9 +311,9 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void serializeDeserializeEmptyViaCompactHeapify() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapDoublesSketch sketch2 = KllHeapDoublesSketch.heapify(Memory.wrap(bytes));
+    final KllDoublesSketch sketch2 = KllDoublesSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertTrue(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -326,10 +326,10 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void serializeDeserializeEmptyViaUpdatableWritableWrap() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
     final byte[] bytes = sketch1.toUpdatableByteArray();
-    final KllDirectDoublesSketch sketch2 =
-        KllDirectDoublesSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
+    final KllDoublesSketch sketch2 =
+        KllDoublesSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
     assertEquals(bytes.length, sketch1.getCurrentUpdatableSerializedSizeBytes());
     assertTrue(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -342,10 +342,10 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void serializeDeserializeOneItemViaCompactHeapify() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
     sketch1.update(1);
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapDoublesSketch sketch2 = KllHeapDoublesSketch.heapify(Memory.wrap(bytes));
+    final KllDoublesSketch sketch2 = KllDoublesSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), 1);
@@ -358,11 +358,11 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void serializeDeserializeOneItemViaUpdatableWritableWrap() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
     sketch1.update(1);
     final byte[] bytes = sketch1.toUpdatableByteArray();
-    final KllDirectDoublesSketch sketch2 =
-        KllDirectDoublesSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
+    final KllDoublesSketch sketch2 =
+        KllDoublesSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
     assertEquals(bytes.length, sketch1.getCurrentUpdatableSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), 1);
@@ -375,13 +375,13 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void serializeDeserializeFullViaCompactHeapify() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
     final int n = 1000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
     }
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapDoublesSketch sketch2 =  KllHeapDoublesSketch.heapify(Memory.wrap(bytes));
+    final KllDoublesSketch sketch2 =  KllDoublesSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -394,14 +394,14 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void serializeDeserializeFullViaUpdatableWritableWrap() {
-    final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
+    final KllDoublesSketch sketch1 = getDDSketch(200, 0);
     final int n = 1000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
     }
     final byte[] bytes = sketch1.toUpdatableByteArray();
-    final KllDirectDoublesSketch sketch2 =
-        KllDirectDoublesSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
+    final KllDoublesSketch sketch2 =
+        KllDoublesSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
     assertEquals(bytes.length, sketch1.getCurrentUpdatableSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -414,21 +414,21 @@ public class KllDirectDoublesSketchTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void outOfOrderSplitPoints() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     sketch.update(0);
     sketch.getCDF(new double[] {1, 0});
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void nanSplitPoint() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     sketch.update(0);
     sketch.getCDF(new double[] {Double.NaN});
   }
 
   @Test
   public void getQuantiles() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 0);
+    final KllDoublesSketch sketch = getDDSketch(200, 0);
     sketch.update(1);
     sketch.update(2);
     sketch.update(3);
@@ -445,8 +445,8 @@ public class KllDirectDoublesSketchTest {
     int k = 20;
     int n1 = 21;
     int n2 = 43;
-    KllHeapDoublesSketch sk1 = new KllHeapDoublesSketch(k);
-    KllHeapDoublesSketch sk2 = new KllHeapDoublesSketch(k);
+    KllDoublesSketch sk1 = KllDoublesSketch.newHeapInstance(k);
+    KllDoublesSketch sk2 =  KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= n1; i++) {
       sk1.update(i);
     }
@@ -459,8 +459,8 @@ public class KllDirectDoublesSketchTest {
     println(sk2.toString(true, true));
     WritableMemory wmem1 = WritableMemory.writableWrap(sk1.toUpdatableByteArray());
     WritableMemory wmem2 = WritableMemory.writableWrap(sk2.toUpdatableByteArray());
-    KllDirectDoublesSketch dsk1 = KllDirectDoublesSketch.writableWrap(wmem1, memReqSvr);
-    KllDirectDoublesSketch dsk2 = KllDirectDoublesSketch.writableWrap(wmem2, memReqSvr);
+    KllDoublesSketch dsk1 = KllDoublesSketch.writableWrap(wmem1, memReqSvr);
+    KllDoublesSketch dsk2 = KllDoublesSketch.writableWrap(wmem2, memReqSvr);
     println("BEFORE MERGE");
     println(dsk1.toString(true, true));
     dsk1.merge(dsk2);
@@ -471,19 +471,19 @@ public class KllDirectDoublesSketchTest {
   @Test
   public void checkSketchInitializeDirectDoubleUpdatableMem() {
     int k = 20; //don't change this
-    KllDirectDoublesSketch sk;
-    KllHeapDoublesSketch sk2;
+    KllDoublesSketch sk;
+    KllDoublesSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
     println("#### CASE: DOUBLE FULL DIRECT FROM UPDATABLE");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk2.update(i); }
     //println(sk2.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    sk = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -498,12 +498,12 @@ public class KllDirectDoublesSketchTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE EMPTY HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     //println(sk.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    sk = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -518,13 +518,13 @@ public class KllDirectDoublesSketchTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE SINGLE HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     sk2.update(1);
     //println(sk.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    sk = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -541,7 +541,7 @@ public class KllDirectDoublesSketchTest {
 
   @Test
   public void checkGetWritableMemory() {
-    final KllDirectDoublesSketch sketch = getDDSketch(200, 200);
+    final KllDoublesSketch sketch = getDDSketch(200, 200);
     assertEquals(sketch.getK(), 200);
     assertEquals(sketch.getN(), 200);
     assertFalse(sketch.isEmpty());
@@ -552,7 +552,7 @@ public class KllDirectDoublesSketchTest {
     assertFalse(sketch.isFloatsSketch());
 
     final WritableMemory wmem = sketch.getWritableMemory();
-    final KllHeapDoublesSketch sk = KllHeapDoublesSketch.heapify(wmem);
+    final KllDoublesSketch sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), 200);
     assertEquals(sk.getN(), 200);
     assertFalse(sk.isEmpty());
@@ -566,7 +566,7 @@ public class KllDirectDoublesSketchTest {
   @Test
   public void checkReset() {
     WritableMemory dstMem = WritableMemory.allocate(6000);
-    KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(20, dstMem, memReqSvr);
+    KllDoublesSketch sk = KllDoublesSketch.newDirectInstance(20, dstMem, memReqSvr);
     for (int i = 1; i <= 100; i++) { sk.update(i); }
     long n1 = sk.getN();
     double min1 = sk.getMinValue();
@@ -584,9 +584,9 @@ public class KllDirectDoublesSketchTest {
   @Test
   public void checkHeapify() {
     WritableMemory dstMem = WritableMemory.allocate(6000);
-    KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(20, dstMem, memReqSvr);
+    KllDoublesSketch sk = KllDoublesSketch.newDirectInstance(20, dstMem, memReqSvr);
     for (int i = 1; i <= 100; i++) { sk.update(i); }
-    KllHeapDoublesSketch sk2 = KllDirectDoublesSketch.heapify(dstMem);
+    KllDoublesSketch sk2 = KllDoublesSketch.heapify(dstMem);
     assertEquals(sk2.getMinValue(), 1.0);
     assertEquals(sk2.getMaxValue(), 100.0);
   }
@@ -594,9 +594,9 @@ public class KllDirectDoublesSketchTest {
   @Test
   public void checkMergeKllDoublesSketch() {
     WritableMemory dstMem = WritableMemory.allocate(6000);
-    KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(20, dstMem, memReqSvr);
+    KllDoublesSketch sk = KllDoublesSketch.newDirectInstance(20, dstMem, memReqSvr);
     for (int i = 1; i <= 21; i++) { sk.update(i); }
-    KllHeapDoublesSketch sk2 = new KllHeapDoublesSketch(20);
+    KllDoublesSketch sk2 = KllDoublesSketch.newHeapInstance(20);
     for (int i = 1; i <= 21; i++ ) { sk2.update(i + 100); }
     sk.merge(sk2);
   }
@@ -604,9 +604,9 @@ public class KllDirectDoublesSketchTest {
   @Test
   public void checkReverseMergeKllDoubleSketch() {
     WritableMemory dstMem = WritableMemory.allocate(6000);
-    KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(20, dstMem, memReqSvr);
+    KllDoublesSketch sk = KllDoublesSketch.newDirectInstance(20, dstMem, memReqSvr);
     for (int i = 1; i <= 21; i++) { sk.update(i); }
-    KllHeapDoublesSketch sk2 = new KllHeapDoublesSketch(20);
+    KllDoublesSketch sk2 = KllDoublesSketch.newHeapInstance(20);
     for (int i = 1; i <= 21; i++ ) { sk2.update(i + 100); }
     sk2.merge(sk);
   }
@@ -616,15 +616,15 @@ public class KllDirectDoublesSketchTest {
 //    KllDoublesSketch sk = new KllDoublesSketch(20);
 //    for (int i = 1; i <= 21; i++ ) { sk.update(i); }
 //    Memory srcMem = Memory.wrap(sk.toByteArray());
-//    KllDirectDoublesSketch sk2 = KllDirectDoublesSketch.writableWrap(srcMem, memReqSvr);
+//    KllDoublesSketch sk2 = KllDoublesSketch.writableWrap(srcMem, memReqSvr);
 //  }
 
-  private static KllDirectDoublesSketch getDDSketch(final int k, final int n) {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch(k);
+  private static KllDoublesSketch getDDSketch(final int k, final int n) {
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= n; i++) { sk.update(i); }
     byte[] byteArr = sk.toUpdatableByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
-    KllDirectDoublesSketch ddsk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    KllDoublesSketch ddsk = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     return ddsk;
   }
 
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchIteratorTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchIteratorTest.java
index bd29fe77..b416c664 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchIteratorTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchIteratorTest.java
@@ -29,14 +29,14 @@ public class KllDirectFloatsSketchIteratorTest {
 
   @Test
   public void emptySketch() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     KllFloatsSketchIterator it = sketch.iterator();
     Assert.assertFalse(it.next());
   }
 
   @Test
   public void oneItemSketch() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     sketch.update(0);
     KllFloatsSketchIterator it = sketch.iterator();
     Assert.assertTrue(it.next());
@@ -48,7 +48,7 @@ public class KllDirectFloatsSketchIteratorTest {
   @Test
   public void bigSketches() {
     for (int n = 1000; n < 100000; n += 2000) {
-      final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+      final KllFloatsSketch sketch = getDFSketch(200, 0);
       for (int i = 0; i < n; i++) {
         sketch.update(i);
       }
@@ -64,13 +64,13 @@ public class KllDirectFloatsSketchIteratorTest {
     }
   }
 
-  private static KllDirectFloatsSketch getDFSketch(final int k, final int n) {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch(k);
+  private static KllFloatsSketch getDFSketch(final int k, final int n) {
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= n; i++) { sk.update(i); }
     byte[] byteArr = sk.toUpdatableByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
 
-    KllDirectFloatsSketch dfsk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    KllFloatsSketch dfsk = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     return dfsk;
   }
 
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
index 7f174ecb..e844d079 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
@@ -41,7 +41,7 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void empty() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     sketch.update(Float.NaN); // this must not change anything
     assertTrue(sketch.isEmpty());
     assertEquals(sketch.getN(), 0);
@@ -58,21 +58,21 @@ public class KllDirectFloatsSketchTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void getQuantileInvalidArg() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     sketch.update(1);
     sketch.getQuantile(-1.0);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void getQuantilesInvalidArg() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     sketch.update(1);
     sketch.getQuantiles(new double[] {2.0});
   }
 
   @Test
   public void oneItem() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     sketch.update(1);
     assertFalse(sketch.isEmpty());
     assertEquals(sketch.getN(), 1);
@@ -86,7 +86,7 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void manyItemsEstimationMode() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     final int n = 1_000_000;
 
     for (int i = 0; i < n; i++) {
@@ -132,7 +132,7 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void getRankGetCdfGetPmfConsistency() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     final int n = 1000;
     final float[] values = new float[n];
     for (int i = 0; i < n; i++) {
@@ -155,8 +155,8 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void merge() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
-    final KllDirectFloatsSketch sketch2 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch2 = getDFSketch(200, 0);
     final int n = 10_000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i * 1.0F);
@@ -180,8 +180,8 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void mergeLowerK() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(256, 0);
-    final KllDirectFloatsSketch sketch2 = getDFSketch(128, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(256, 0);
+    final KllFloatsSketch sketch2 = getDFSketch(128, 0);
     final int n = 10_000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -211,8 +211,8 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void mergeEmptyLowerK() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(256, 0);
-    final KllDirectFloatsSketch sketch2 = getDFSketch(128, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(256, 0);
+    final KllFloatsSketch sketch2 = getDFSketch(128, 0);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -240,8 +240,8 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void mergeExactModeLowerK() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(256, 0);
-    final KllDirectFloatsSketch sketch2 = getDFSketch(128, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(256, 0);
+    final KllFloatsSketch sketch2 = getDFSketch(128, 0);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -256,8 +256,8 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void mergeMinMinValueFromOther() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
-    final KllDirectFloatsSketch sketch2 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch2 = getDFSketch(200, 0);
     sketch1.update(1);
     sketch2.update(2);
     sketch2.merge(sketch1);
@@ -266,8 +266,8 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void mergeMinAndMaxFromOther() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(8, 0); //was 200
-    final KllDirectFloatsSketch sketch2 = getDFSketch(8, 0); //was 200
+    final KllFloatsSketch sketch1 = getDFSketch(8, 0); //was 200
+    final KllFloatsSketch sketch2 = getDFSketch(8, 0); //was 200
     for (int i = 1; i <= 9; i++) { //was 1_000_000
       sketch1.update(i);
     }
@@ -280,18 +280,18 @@ public class KllDirectFloatsSketchTest {
   @SuppressWarnings("unused")
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void kTooSmall() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(KllSketch.DEFAULT_M - 1, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(KllSketch.DEFAULT_M - 1, 0);
   }
 
   @SuppressWarnings("unused")
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void kTooLarge() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(KllSketch.MAX_K + 1, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(KllSketch.MAX_K + 1, 0);
   }
 
   @Test
   public void minK() {
-    final KllDirectFloatsSketch sketch = getDFSketch(KllSketch.DEFAULT_M, 0);
+    final KllFloatsSketch sketch = getDFSketch(KllSketch.DEFAULT_M, 0);
     for (int i = 0; i < 1000; i++) {
       sketch.update(i);
     }
@@ -301,7 +301,7 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void maxK() {
-    final KllDirectFloatsSketch sketch = getDFSketch(KllSketch.MAX_K, 0);
+    final KllFloatsSketch sketch = getDFSketch(KllSketch.MAX_K, 0);
     for (int i = 0; i < 1000; i++) {
       sketch.update(i);
     }
@@ -311,9 +311,9 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void serializeDeserializeEmptyViaCompactHeapify() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(200, 0);
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapFloatsSketch sketch2 = KllHeapFloatsSketch.heapify(Memory.wrap(bytes));
+    final KllFloatsSketch sketch2 = KllFloatsSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertTrue(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -326,10 +326,10 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void serializeDeserializeEmptyViaUpdatableWritableWrap() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(200, 0);
     final byte[] bytes = sketch1.toUpdatableByteArray();
-    final KllDirectFloatsSketch sketch2 =
-        KllDirectFloatsSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
+    final KllFloatsSketch sketch2 =
+        KllFloatsSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
     assertEquals(bytes.length, sketch1.getCurrentUpdatableSerializedSizeBytes());
     assertTrue(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -342,10 +342,10 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void serializeDeserializeOneItemViaCompactHeapify() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(200, 0);
     sketch1.update(1);
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapFloatsSketch sketch2 = KllHeapFloatsSketch.heapify(Memory.wrap(bytes));
+    final KllFloatsSketch sketch2 = KllFloatsSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), 1);
@@ -358,11 +358,11 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void serializeDeserializeOneItemViaUpdatableWritableWrap() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(200, 0);
     sketch1.update(1);
     final byte[] bytes = sketch1.toUpdatableByteArray();
-    final KllDirectFloatsSketch sketch2 =
-        KllDirectFloatsSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
+    final KllFloatsSketch sketch2 =
+        KllFloatsSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
     assertEquals(bytes.length, sketch1.getCurrentUpdatableSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), 1);
@@ -375,11 +375,11 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void serializeDeserializeFullViaCompactHeapify() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(200, 0);
     final int n = 1000;
     for (int i = 0; i < n; i++) { sketch1.update(i); }
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapFloatsSketch sketch2 =  KllHeapFloatsSketch.heapify(Memory.wrap(bytes));
+    final KllFloatsSketch sketch2 =  KllFloatsSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -392,14 +392,14 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void serializeDeserializeFullViaUpdatableWritableWrap() {
-    final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
+    final KllFloatsSketch sketch1 = getDFSketch(200, 0);
     final int n = 1000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
     }
     final byte[] bytes = sketch1.toUpdatableByteArray();
-    final KllDirectFloatsSketch sketch2 =
-        KllDirectFloatsSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
+    final KllFloatsSketch sketch2 =
+        KllFloatsSketch.writableWrap(WritableMemory.writableWrap(bytes),memReqSvr);
     assertEquals(bytes.length, sketch1.getCurrentUpdatableSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -412,21 +412,21 @@ public class KllDirectFloatsSketchTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void outOfOrderSplitPoints() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     sketch.update(0);
     sketch.getCDF(new float[] {1, 0});
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void nanSplitPoint() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     sketch.update(0);
     sketch.getCDF(new float[] {Float.NaN});
   }
 
   @Test
   public void getQuantiles() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 0);
+    final KllFloatsSketch sketch = getDFSketch(200, 0);
     sketch.update(1);
     sketch.update(2);
     sketch.update(3);
@@ -443,8 +443,8 @@ public class KllDirectFloatsSketchTest {
     int k = 20;
     int n1 = 21;
     int n2 = 43;
-    KllHeapFloatsSketch sk1 = new KllHeapFloatsSketch(k);
-    KllHeapFloatsSketch sk2 = new KllHeapFloatsSketch(k);
+    KllFloatsSketch sk1 = KllFloatsSketch.newHeapInstance(k);
+    KllFloatsSketch sk2 = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= n1; i++) {
       sk1.update(i);
     }
@@ -457,8 +457,8 @@ public class KllDirectFloatsSketchTest {
     println(sk2.toString(true, true));
     WritableMemory wmem1 = WritableMemory.writableWrap(sk1.toUpdatableByteArray());
     WritableMemory wmem2 = WritableMemory.writableWrap(sk2.toUpdatableByteArray());
-    KllDirectFloatsSketch dsk1 = KllDirectFloatsSketch.writableWrap(wmem1, memReqSvr);
-    KllDirectFloatsSketch dsk2 = KllDirectFloatsSketch.writableWrap(wmem2, memReqSvr);
+    KllFloatsSketch dsk1 = KllFloatsSketch.writableWrap(wmem1, memReqSvr);
+    KllFloatsSketch dsk2 = KllFloatsSketch.writableWrap(wmem2, memReqSvr);
     println("BEFORE MERGE");
     println(dsk1.toString(true, true));
     dsk1.merge(dsk2);
@@ -469,19 +469,19 @@ public class KllDirectFloatsSketchTest {
   @Test
   public void checkSketchInitializeDirectDoubleUpdatableMem() {
     int k = 20; //don't change this
-    KllDirectFloatsSketch sk;
-    KllHeapFloatsSketch sk2;
+    KllFloatsSketch sk;
+    KllFloatsSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
     println("#### CASE: DOUBLE FULL DIRECT FROM UPDATABLE");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk2.update(i); }
     //println(sk2.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    sk = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -496,12 +496,12 @@ public class KllDirectFloatsSketchTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE EMPTY HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     //println(sk.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    sk = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -516,13 +516,13 @@ public class KllDirectFloatsSketchTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE SINGLE HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     sk2.update(1);
     //println(sk.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    sk = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -539,7 +539,7 @@ public class KllDirectFloatsSketchTest {
 
   @Test
   public void checkGetWritableMemory() {
-    final KllDirectFloatsSketch sketch = getDFSketch(200, 200);
+    final KllFloatsSketch sketch = getDFSketch(200, 200);
     assertEquals(sketch.getK(), 200);
     assertEquals(sketch.getN(), 200);
     assertFalse(sketch.isEmpty());
@@ -550,7 +550,7 @@ public class KllDirectFloatsSketchTest {
     assertFalse(sketch.isDoublesSketch());
 
     final WritableMemory wmem = sketch.getWritableMemory();
-    final KllHeapFloatsSketch sk = KllHeapFloatsSketch.heapify(wmem);
+    final KllFloatsSketch sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), 200);
     assertEquals(sk.getN(), 200);
     assertFalse(sk.isEmpty());
@@ -564,7 +564,7 @@ public class KllDirectFloatsSketchTest {
   @Test
   public void checkReset() {
     WritableMemory dstMem = WritableMemory.allocate(3000);
-    KllDirectFloatsSketch sk = KllDirectFloatsSketch.newInstance(20, dstMem, memReqSvr);
+    KllFloatsSketch sk = KllFloatsSketch.newDirectInstance(20, dstMem, memReqSvr);
     for (int i = 1; i <= 100; i++) { sk.update(i); }
     long n1 = sk.getN();
     float min1 = sk.getMinValue();
@@ -582,20 +582,20 @@ public class KllDirectFloatsSketchTest {
   @Test
   public void checkHeapify() {
     WritableMemory dstMem = WritableMemory.allocate(6000);
-    KllDirectFloatsSketch sk = KllDirectFloatsSketch.newInstance(20, dstMem, memReqSvr);
+    KllFloatsSketch sk = KllFloatsSketch.newDirectInstance(20, dstMem, memReqSvr);
     for (int i = 1; i <= 100; i++) { sk.update(i); }
-    KllHeapFloatsSketch sk2 = KllDirectFloatsSketch.heapify(dstMem);
+    KllFloatsSketch sk2 = KllFloatsSketch.heapify(dstMem);
     assertEquals(sk2.getMinValue(), 1.0);
     assertEquals(sk2.getMaxValue(), 100.0);
   }
 
-  private static KllDirectFloatsSketch getDFSketch(final int k, final int n) {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch(k);
+  private static KllFloatsSketch getDFSketch(final int k, final int n) {
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= n; i++) { sk.update(i); }
     byte[] byteArr = sk.toUpdatableByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
 
-    KllDirectFloatsSketch dfsk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    KllFloatsSketch dfsk = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     return dfsk;
   }
 
diff --git a/src/test/java/org/apache/datasketches/kll/KllDoublesSketchIteratorTest.java b/src/test/java/org/apache/datasketches/kll/KllDoublesSketchIteratorTest.java
index d3d23176..7ce77d59 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDoublesSketchIteratorTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDoublesSketchIteratorTest.java
@@ -26,14 +26,14 @@ public class KllDoublesSketchIteratorTest {
 
   @Test
   public void emptySketch() {
-    KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     KllDoublesSketchIterator it = sketch.iterator();
     Assert.assertFalse(it.next());
   }
 
   @Test
   public void oneItemSketch() {
-    KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     sketch.update(0);
     KllDoublesSketchIterator it = sketch.iterator();
     Assert.assertTrue(it.next());
@@ -45,7 +45,7 @@ public class KllDoublesSketchIteratorTest {
   @Test
   public void bigSketches() {
     for (int n = 1000; n < 100000; n += 2000) {
-      KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+      KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
       for (int i = 0; i < n; i++) {
         sketch.update(i);
       }
diff --git a/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
index 113a38a8..3fa66423 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
@@ -39,7 +39,7 @@ public class KllDoublesSketchTest {
 
   @Test
   public void empty() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     sketch.update(Double.NaN); // this must not change anything
     assertTrue(sketch.isEmpty());
     assertEquals(sketch.getN(), 0);
@@ -56,21 +56,21 @@ public class KllDoublesSketchTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void getQuantileInvalidArg() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     sketch.update(1);
     sketch.getQuantile(-1.0);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void getQuantilesInvalidArg() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     sketch.update(1);
     sketch.getQuantiles(new double[] {2.0});
   }
 
   @Test
   public void oneItem() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     sketch.update(1);
     assertFalse(sketch.isEmpty());
     assertEquals(sketch.getN(), 1);
@@ -84,7 +84,7 @@ public class KllDoublesSketchTest {
 
   @Test
   public void manyItemsEstimationMode() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     final int n = 1_000_000;
 
     for (int i = 0; i < n; i++) {
@@ -130,7 +130,7 @@ public class KllDoublesSketchTest {
 
   @Test
   public void getRankGetCdfGetPmfConsistency() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     final int n = 1000;
     final double[] values = new double[n];
     for (int i = 0; i < n; i++) {
@@ -153,8 +153,8 @@ public class KllDoublesSketchTest {
 
   @Test
   public void merge() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch();
-    final KllHeapDoublesSketch sketch2 = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance();
+    final KllDoublesSketch sketch2 = KllDoublesSketch.newHeapInstance();
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i * 1.0);
@@ -178,8 +178,8 @@ public class KllDoublesSketchTest {
 
   @Test
   public void mergeLowerK() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch(256);
-    final KllHeapDoublesSketch sketch2 = new KllHeapDoublesSketch(128);
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance(256);
+    final KllDoublesSketch sketch2 = KllDoublesSketch.newHeapInstance(128);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -209,8 +209,8 @@ public class KllDoublesSketchTest {
 
   @Test
   public void mergeEmptyLowerK() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch(256);
-    final KllHeapDoublesSketch sketch2 = new KllHeapDoublesSketch(128);
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance(256);
+    final KllDoublesSketch sketch2 = KllDoublesSketch.newHeapInstance(128);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -238,8 +238,8 @@ public class KllDoublesSketchTest {
 
   @Test
   public void mergeExactModeLowerK() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch(256);
-    final KllHeapDoublesSketch sketch2 = new KllHeapDoublesSketch(128);
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance(256);
+    final KllDoublesSketch sketch2 = KllDoublesSketch.newHeapInstance(128);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -254,8 +254,8 @@ public class KllDoublesSketchTest {
 
   @Test
   public void mergeMinMinValueFromOther() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch();
-    final KllHeapDoublesSketch sketch2 = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance();
+    final KllDoublesSketch sketch2 = KllDoublesSketch.newHeapInstance();
     sketch1.update(1);
     sketch2.update(2);
     sketch2.merge(sketch1);
@@ -264,11 +264,11 @@ public class KllDoublesSketchTest {
 
   @Test
   public void mergeMinAndMaxFromOther() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance();
     for (int i = 1; i <= 1_000_000; i++) {
       sketch1.update(i);
     }
-    final KllHeapDoublesSketch sketch2 = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch2 = KllDoublesSketch.newHeapInstance();
     sketch2.merge(sketch1);
     assertEquals(sketch2.getMinValue(), 1);
     assertEquals(sketch2.getMaxValue(), 1_000_000);
@@ -277,18 +277,18 @@ public class KllDoublesSketchTest {
   @SuppressWarnings("unused")
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void kTooSmall() {
-    new KllHeapDoublesSketch(KllSketch.DEFAULT_M - 1);
+    KllDoublesSketch.newHeapInstance(KllSketch.DEFAULT_M - 1);
   }
 
   @SuppressWarnings("unused")
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void kTooLarge() {
-    new KllHeapDoublesSketch(KllSketch.MAX_K + 1);
+    KllDoublesSketch.newHeapInstance(KllSketch.MAX_K + 1);
   }
 
   @Test
   public void minK() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch(KllSketch.DEFAULT_M);
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance(KllSketch.DEFAULT_M);
     for (int i = 0; i < 1000; i++) {
       sketch.update(i);
     }
@@ -298,7 +298,7 @@ public class KllDoublesSketchTest {
 
   @Test
   public void maxK() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch(KllSketch.MAX_K);
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance(KllSketch.MAX_K);
     for (int i = 0; i < 1000; i++) {
       sketch.update(i);
     }
@@ -308,9 +308,9 @@ public class KllDoublesSketchTest {
 
   @Test
   public void serializeDeserializeEmpty() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance();
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapDoublesSketch sketch2 = KllHeapDoublesSketch.heapify(Memory.wrap(bytes));
+    final KllDoublesSketch sketch2 = KllDoublesSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertTrue(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -323,10 +323,10 @@ public class KllDoublesSketchTest {
 
   @Test
   public void serializeDeserializeOneItem() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance();
     sketch1.update(1);
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapDoublesSketch sketch2 = KllHeapDoublesSketch.heapify(Memory.wrap(bytes));
+    final KllDoublesSketch sketch2 = KllDoublesSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), 1);
@@ -349,13 +349,13 @@ public class KllDoublesSketchTest {
 
   @Test
   public void serializeDeserialize() {
-    final KllHeapDoublesSketch sketch1 = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch1 = KllDoublesSketch.newHeapInstance();
     final int n = 1000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
     }
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapDoublesSketch sketch2 = KllHeapDoublesSketch.heapify(Memory.wrap(bytes));
+    final KllDoublesSketch sketch2 = KllDoublesSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -368,21 +368,21 @@ public class KllDoublesSketchTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void outOfOrderSplitPoints() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     sketch.update(0);
     sketch.getCDF(new double[] {1, 0});
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void nanSplitPoint() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     sketch.update(0);
     sketch.getCDF(new double[] {Double.NaN});
   }
 
   @Test
   public void getQuantiles() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch();
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance();
     sketch.update(1);
     sketch.update(2);
     sketch.update(3);
@@ -396,7 +396,7 @@ public class KllDoublesSketchTest {
 
   @Test
   public void checkReset() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch(20);
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance(20);
     for (int i = 1; i <= 100; i++) { sk.update(i); }
     long n1 = sk.getN();
     double min1 = sk.getMinValue();
diff --git a/src/test/java/org/apache/datasketches/kll/KllDoublesValidationTest.java b/src/test/java/org/apache/datasketches/kll/KllDoublesValidationTest.java
index e6d1221c..a6fd1f0f 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDoublesValidationTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDoublesValidationTest.java
@@ -211,7 +211,7 @@ public class KllDoublesValidationTest {
       int n = (int) correctResultsWithReset[(7 * testI) + 2];
       int stride = (int) correctResultsWithReset[(7 * testI) + 3];
       int[] inputArray = makeInputArray(n, stride);
-      KllHeapDoublesSketch sketch = new KllHeapDoublesSketch(k);
+      KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance(k);
       for (int i = 0; i < n; i++) {
         sketch.update(inputArray[i]);
       }
diff --git a/src/test/java/org/apache/datasketches/kll/KllFloatsSketchIteratorTest.java b/src/test/java/org/apache/datasketches/kll/KllFloatsSketchIteratorTest.java
index d55af856..4789de86 100644
--- a/src/test/java/org/apache/datasketches/kll/KllFloatsSketchIteratorTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllFloatsSketchIteratorTest.java
@@ -26,14 +26,14 @@ public class KllFloatsSketchIteratorTest {
 
   @Test
   public void emptySketch() {
-    KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     KllFloatsSketchIterator it = sketch.iterator();
     Assert.assertFalse(it.next());
   }
 
   @Test
   public void oneItemSketch() {
-    KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     sketch.update(0);
     KllFloatsSketchIterator it = sketch.iterator();
     Assert.assertTrue(it.next());
@@ -45,7 +45,7 @@ public class KllFloatsSketchIteratorTest {
   @Test
   public void bigSketches() {
     for (int n = 1000; n < 100000; n += 2000) {
-      KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+      KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
       for (int i = 0; i < n; i++) {
         sketch.update(i);
       }
diff --git a/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
index 17c3da60..a3e23a93 100644
--- a/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
@@ -40,7 +40,7 @@ public class KllFloatsSketchTest {
 
   @Test
   public void empty() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     sketch.update(Float.NaN); // this must not change anything
     assertTrue(sketch.isEmpty());
     assertEquals(sketch.getN(), 0);
@@ -57,21 +57,21 @@ public class KllFloatsSketchTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void getQuantileInvalidArg() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     sketch.update(1);
     sketch.getQuantile(-1.0);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void getQuantilesInvalidArg() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     sketch.update(1);
     sketch.getQuantiles(new double[] {2.0});
   }
 
   @Test
   public void oneItem() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     sketch.update(1);
     assertFalse(sketch.isEmpty());
     assertEquals(sketch.getN(), 1);
@@ -85,7 +85,7 @@ public class KllFloatsSketchTest {
 
   @Test
   public void manyItemsEstimationMode() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     final int n = 1_000_000;
 
     for (int i = 0; i < n; i++) {
@@ -131,7 +131,7 @@ public class KllFloatsSketchTest {
 
   @Test
   public void getRankGetCdfGetPmfConsistency() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     final int n = 1000;
     final float[] values = new float[n];
     for (int i = 0; i < n; i++) {
@@ -154,8 +154,8 @@ public class KllFloatsSketchTest {
 
   @Test
   public void merge() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch();
-    final KllHeapFloatsSketch sketch2 = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance();
+    final KllFloatsSketch sketch2 = KllFloatsSketch.newHeapInstance();
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i * 1.0f);
@@ -179,8 +179,8 @@ public class KllFloatsSketchTest {
 
   @Test
   public void mergeLowerK() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch(256);
-    final KllHeapFloatsSketch sketch2 = new KllHeapFloatsSketch(128);
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance(256);
+    final KllFloatsSketch sketch2 = KllFloatsSketch.newHeapInstance(128);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -210,8 +210,8 @@ public class KllFloatsSketchTest {
 
   @Test
   public void mergeEmptyLowerK() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch(256);
-    final KllHeapFloatsSketch sketch2 = new KllHeapFloatsSketch(128);
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance(256);
+    final KllFloatsSketch sketch2 = KllFloatsSketch.newHeapInstance(128);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -239,8 +239,8 @@ public class KllFloatsSketchTest {
 
   @Test
   public void mergeExactModeLowerK() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch(256);
-    final KllHeapFloatsSketch sketch2 = new KllHeapFloatsSketch(128);
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance(256);
+    final KllFloatsSketch sketch2 = KllFloatsSketch.newHeapInstance(128);
     final int n = 10000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
@@ -255,8 +255,8 @@ public class KllFloatsSketchTest {
 
   @Test
   public void mergeMinMinValueFromOther() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch();
-    final KllHeapFloatsSketch sketch2 = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance();
+    final KllFloatsSketch sketch2 = KllFloatsSketch.newHeapInstance();
     sketch1.update(1);
     sketch2.update(2);
     sketch2.merge(sketch1);
@@ -265,11 +265,11 @@ public class KllFloatsSketchTest {
 
   @Test
   public void mergeMinAndMaxFromOther() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance();
     for (int i = 1; i <= 1_000_000; i++) {
       sketch1.update(i);
     }
-    final KllHeapFloatsSketch sketch2 = new KllHeapFloatsSketch(10);
+    final KllFloatsSketch sketch2 = KllFloatsSketch.newHeapInstance(10);
     sketch2.merge(sketch1);
     assertEquals(sketch2.getMinValue(), 1F);
     assertEquals(sketch2.getMaxValue(), 1_000_000F);
@@ -278,18 +278,18 @@ public class KllFloatsSketchTest {
   @SuppressWarnings("unused")
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void kTooSmall() {
-    new KllHeapFloatsSketch(KllSketch.DEFAULT_M - 1);
+    KllFloatsSketch.newHeapInstance(KllSketch.DEFAULT_M - 1);
   }
 
   @SuppressWarnings("unused")
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void kTooLarge() {
-    new KllHeapFloatsSketch(KllSketch.MAX_K + 1);
+    KllFloatsSketch.newHeapInstance(KllSketch.MAX_K + 1);
   }
 
   @Test
   public void minK() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch(KllSketch.DEFAULT_M);
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance(KllSketch.DEFAULT_M);
     for (int i = 0; i < 1000; i++) {
       sketch.update(i);
     }
@@ -299,7 +299,7 @@ public class KllFloatsSketchTest {
 
   @Test
   public void maxK() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch(KllSketch.MAX_K);
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance(KllSketch.MAX_K);
     for (int i = 0; i < 1000; i++) {
       sketch.update(i);
     }
@@ -309,9 +309,9 @@ public class KllFloatsSketchTest {
 
   @Test
   public void serializeDeserializeEmpty() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance();
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapFloatsSketch sketch2 = KllHeapFloatsSketch.heapify(Memory.wrap(bytes));
+    final KllFloatsSketch sketch2 = KllFloatsSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertTrue(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -324,10 +324,10 @@ public class KllFloatsSketchTest {
 
   @Test
   public void serializeDeserializeOneItem() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance();
     sketch1.update(1);
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapFloatsSketch sketch2 = KllHeapFloatsSketch.heapify(Memory.wrap(bytes));
+    final KllFloatsSketch sketch2 = KllFloatsSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), 1);
@@ -341,7 +341,7 @@ public class KllFloatsSketchTest {
   @Test
   public void deserializeOneItemV1() throws Exception {
     final byte[] bytes = getResourceBytes("kll_sketch_float_one_item_v1.sk");
-    final KllHeapFloatsSketch sketch = KllHeapFloatsSketch.heapify(Memory.wrap(bytes));
+    final KllFloatsSketch sketch = KllFloatsSketch.heapify(Memory.wrap(bytes));
     assertFalse(sketch.isEmpty());
     assertFalse(sketch.isEstimationMode());
     assertEquals(sketch.getN(), 1);
@@ -350,13 +350,13 @@ public class KllFloatsSketchTest {
 
   @Test
   public void serializeDeserialize() {
-    final KllHeapFloatsSketch sketch1 = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch1 = KllFloatsSketch.newHeapInstance();
     final int n = 1000;
     for (int i = 0; i < n; i++) {
       sketch1.update(i);
     }
     final byte[] bytes = sketch1.toByteArray();
-    final KllHeapFloatsSketch sketch2 = KllHeapFloatsSketch.heapify(Memory.wrap(bytes));
+    final KllFloatsSketch sketch2 = KllFloatsSketch.heapify(Memory.wrap(bytes));
     assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
     assertFalse(sketch2.isEmpty());
     assertEquals(sketch2.getNumRetained(), sketch1.getNumRetained());
@@ -369,21 +369,21 @@ public class KllFloatsSketchTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void outOfOrderSplitPoints() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     sketch.update(0);
     sketch.getCDF(new float[] {1, 0});
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void nanSplitPoint() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     sketch.update(0);
     sketch.getCDF(new float[] {Float.NaN});
   }
 
   @Test
   public void getQuantiles() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch();
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance();
     sketch.update(1);
     sketch.update(2);
     sketch.update(3);
@@ -402,7 +402,7 @@ public class KllFloatsSketchTest {
     final int n = 200;
     int bytes = KllSketch.getMaxSerializedSizeBytes(k, n); //assumed float before
     assertEquals(bytes, 832);
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch(k);
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= n; i++) { sk.update(i); }
     final byte[] byteArr = sk.toByteArray();
     assertEquals(byteArr.length, 832);
@@ -412,7 +412,7 @@ public class KllFloatsSketchTest {
 
   @Test
   public void checkReset() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch(20);
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance(20);
     for (int i = 1; i <= 100; i++) { sk.update(i); }
     long n1 = sk.getN();
     float min1 = sk.getMinValue();
diff --git a/src/test/java/org/apache/datasketches/kll/KllFloatsValidationTest.java b/src/test/java/org/apache/datasketches/kll/KllFloatsValidationTest.java
index a7cea783..d1e09fc7 100644
--- a/src/test/java/org/apache/datasketches/kll/KllFloatsValidationTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllFloatsValidationTest.java
@@ -212,7 +212,7 @@ public class KllFloatsValidationTest {
       int n = (int) correctResultsWithReset[(7 * testI) + 2];
       int stride = (int) correctResultsWithReset[(7 * testI) + 3];
       int[] inputArray = makeInputArray(n, stride);
-      KllHeapFloatsSketch sketch = new KllHeapFloatsSketch(k);
+      KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance(k);
       for (int i = 0; i < n; i++) {
         sketch.update(inputArray[i]);
       }
diff --git a/src/test/java/org/apache/datasketches/kll/KllHelperTest.java b/src/test/java/org/apache/datasketches/kll/KllHelperTest.java
index e713440d..4d0a6e4a 100644
--- a/src/test/java/org/apache/datasketches/kll/KllHelperTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllHelperTest.java
@@ -86,7 +86,7 @@ public class KllHelperTest {
 
   @Test
   public void checkUpdatableSerDe() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch(200);
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance(200);
     for (int i = 1; i <= 533; i++) { sk.update(i); }
     int retained = sk.getNumRetained();
     int numLevels = ((KllSketch)sk).getNumLevels();
@@ -102,10 +102,10 @@ public class KllHelperTest {
     println("upBytes1: " + upBytes1);
 
     Memory mem;
-    KllHeapDoublesSketch sk2;
+    KllDoublesSketch sk2;
 
     mem = Memory.wrap(compByteArr1);
-    sk2 = KllHeapDoublesSketch.heapify(mem);
+    sk2 = KllDoublesSketch.heapify(mem);
     byte[] compByteArr2 = sk2.toByteArray();
     int compBytes2 = compByteArr2.length;
     println("compBytes2: " + compBytes2);
@@ -113,7 +113,7 @@ public class KllHelperTest {
     assertEquals(sk2.getNumRetained(), retained);
 
     mem = Memory.wrap(compByteArr2);
-    sk2 = KllHeapDoublesSketch.heapify(mem);
+    sk2 = KllDoublesSketch.heapify(mem);
     byte[] upByteArr2 = sk2.toUpdatableByteArray();
     int upBytes2 = upByteArr2.length;
     println("upBytes2: " + upBytes2);
diff --git a/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java b/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
index c26f8779..544a4239 100644
--- a/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
@@ -31,7 +31,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidFamily() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
     setMemoryFamilyID(wmem, Family.KLL.getID() - 1);
@@ -40,7 +40,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidSerVer() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
     setMemorySerVer(wmem, SERIAL_VERSION_EMPTY_FULL - 1);
@@ -49,7 +49,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidEmptyAndSingle() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
     setMemoryFlags(wmem, EMPTY_BIT_MASK | SINGLE_ITEM_BIT_MASK);
@@ -58,7 +58,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidUpdatableAndSerVer() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
     setMemoryFlags(wmem, UPDATABLE_BIT_MASK);
@@ -68,7 +68,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidSingleAndPreInts() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     sk.update(1);
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
@@ -78,7 +78,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidSingleAndSerVer() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     sk.update(1);
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
@@ -88,7 +88,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidEmptyDoublesAndPreIntsFull() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
     setMemoryPreInts(wmem, PREAMBLE_INTS_FULL);
@@ -97,7 +97,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidSingleDoubleCompactAndSerVer() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     sk.update(1);
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
@@ -107,7 +107,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidDoubleUpdatableAndPreInts() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     byte[] byteArr = sk.toUpdatableByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
     setMemoryPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
@@ -116,7 +116,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidFloatFullAndPreInts() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     sk.update(1); sk.update(2);
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
@@ -126,7 +126,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidFloatUpdatableFullAndPreInts() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     sk.update(1); sk.update(2);
     byte[] byteArr = sk.toUpdatableByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
@@ -136,7 +136,7 @@ public class KllMemoryValidateTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkInvalidDoubleCompactSingleAndPreInts() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     sk.update(1);
     byte[] byteArr = sk.toByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java b/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
index e7523deb..5f50d41a 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
@@ -35,7 +35,7 @@ public class MiscDirectDoublesTest {
 
   @Test
   public void checkBounds() {
-    final KllDirectDoublesSketch sk = getDDSketch(200, 0);
+    final KllDoublesSketch sk = getDDSketch(200, 0);
     for (int i = 0; i < 1000; i++) {
       sk.update(i);
     }
@@ -52,7 +52,7 @@ public class MiscDirectDoublesTest {
 
   @Test
   public void checkMisc() {
-    final KllDirectDoublesSketch sk = getDDSketch(8, 0);
+    final KllDoublesSketch sk = getDDSketch(8, 0);
     assertTrue(Objects.isNull(sk.getQuantiles(10)));
     //sk.toString(true, true);
     for (int i = 0; i < 20; i++) { sk.update(i); }
@@ -67,11 +67,11 @@ public class MiscDirectDoublesTest {
 
   //@Test //enable static println(..) for visual checking
   public void visualCheckToString() {
-    final KllDirectDoublesSketch sk = getDDSketch(20, 0);
+    final KllDoublesSketch sk = getDDSketch(20, 0);
     for (int i = 0; i < 10; i++) { sk.update(i + 1); }
     println(sk.toString(true, true));
 
-    final KllDirectDoublesSketch sk2 = getDDSketch(20, 0);
+    final KllDoublesSketch sk2 = getDDSketch(20, 0);
     for (int i = 0; i < 400; i++) { sk2.update(i + 1); }
     println("\n" + sk2.toString(true, true));
 
@@ -82,7 +82,7 @@ public class MiscDirectDoublesTest {
 
   //@Test
   public void viewCompactions() {
-    final KllDirectDoublesSketch sk = getDDSketch(20, 0);
+    final KllDoublesSketch sk = getDDSketch(20, 0);
     show(sk, 20);
     show(sk, 21); //compaction 1
     show(sk, 43);
@@ -98,7 +98,7 @@ public class MiscDirectDoublesTest {
     show(sk, 108);
   }
 
-  private static void show(final KllDirectDoublesSketch sk, int limit) {
+  private static void show(final KllDoublesSketch sk, int limit) {
     int i = (int) sk.getN();
     for ( ; i < limit; i++) { sk.update(i + 1); }
     println(sk.toString(true, true));
@@ -107,7 +107,7 @@ public class MiscDirectDoublesTest {
   @Test
   public void checkSketchInitializeDoubleHeap() {
     int k = 20; //don't change this
-    KllDirectDoublesSketch sk;
+    KllDoublesSketch sk;
 
     //println("#### CASE: DOUBLE FULL HEAP");
     sk = getDDSketch(k, 0);
@@ -163,8 +163,8 @@ public class MiscDirectDoublesTest {
   @Test
   public void checkSketchInitializeDoubleHeapifyCompactMem() {
     int k = 20; //don't change this
-    KllHeapDoublesSketch sk;
-    KllDirectDoublesSketch sk2;
+    KllDoublesSketch sk;
+    KllDoublesSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
@@ -175,7 +175,7 @@ public class MiscDirectDoublesTest {
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -195,7 +195,7 @@ public class MiscDirectDoublesTest {
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -216,7 +216,7 @@ public class MiscDirectDoublesTest {
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -234,8 +234,8 @@ public class MiscDirectDoublesTest {
   @Test
   public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
     int k = 20; //don't change this
-    KllHeapDoublesSketch sk;
-    KllDirectDoublesSketch sk2;
+    KllDoublesSketch sk;
+    KllDoublesSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
@@ -246,7 +246,7 @@ public class MiscDirectDoublesTest {
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -266,7 +266,7 @@ public class MiscDirectDoublesTest {
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -287,7 +287,7 @@ public class MiscDirectDoublesTest {
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -305,8 +305,8 @@ public class MiscDirectDoublesTest {
   @Test
   public void checkMemoryToStringDoubleUpdatable() {
     int k = 20; //don't change this
-    KllDirectDoublesSketch sk;
-    KllDirectDoublesSketch sk2;
+    KllDoublesSketch sk;
+    KllDoublesSketch sk2;
     byte[] upBytes;
     byte[] upBytes2;
     WritableMemory wmem;
@@ -320,7 +320,7 @@ public class MiscDirectDoublesTest {
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    sk2 = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -335,7 +335,7 @@ public class MiscDirectDoublesTest {
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    sk2 = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -351,7 +351,7 @@ public class MiscDirectDoublesTest {
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    sk2 = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -365,8 +365,8 @@ public class MiscDirectDoublesTest {
     int k = 20;
     int n1 = 21;
     int n2 = 21;
-    KllDirectDoublesSketch sk1 = getDDSketch(k, 0);
-    KllDirectDoublesSketch sk2 = getDDSketch(k, 0);
+    KllDoublesSketch sk1 = getDDSketch(k, 0);
+    KllDoublesSketch sk2 = getDDSketch(k, 0);
     for (int i = 1; i <= n1; i++) {
       sk1.update(i);
     }
@@ -383,7 +383,7 @@ public class MiscDirectDoublesTest {
 
   @Test
   public void checkSizes() {
-    KllDirectDoublesSketch sk = getDDSketch(20, 0);
+    KllDoublesSketch sk = getDDSketch(20, 0);
     for (int i = 1; i <= 21; i++) { sk.update(i); }
     //println(sk.toString(true, true));
     byte[] byteArr1 = sk.toUpdatableByteArray();
@@ -398,7 +398,7 @@ public class MiscDirectDoublesTest {
   public void checkNewInstance() {
     int k = 200;
     WritableMemory dstMem = WritableMemory.allocate(6000);
-    KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(k, dstMem, memReqSvr);
+    KllDoublesSketch sk = KllDoublesSketch.newDirectInstance(k, dstMem, memReqSvr);
     for (int i = 1; i <= 10_000; i++) {sk.update(i); }
     assertEquals(sk.getMinValue(), 1.0);
     assertEquals(sk.getMaxValue(), 10000.0);
@@ -410,18 +410,18 @@ public class MiscDirectDoublesTest {
     int k = 20;
     int m = 4;
     WritableMemory dstMem = WritableMemory.allocate(1000);
-    KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(k, m, dstMem, memReqSvr);
+    KllDoublesSketch sk = KllDirectDoublesSketch.newDirectInstance(k, m, dstMem, memReqSvr);
     for (int i = 1; i <= 200; i++) {sk.update(i); }
     assertEquals(sk.getMinValue(), 1.0);
     assertEquals(sk.getMaxValue(), 200.0);
   }
 
-  private static KllDirectDoublesSketch getDDSketch(final int k, final int n) {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch(k);
+  private static KllDoublesSketch getDDSketch(final int k, final int n) {
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= n; i++) { sk.update(i); }
     byte[] byteArr = sk.toUpdatableByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
-    KllDirectDoublesSketch ddsk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
+    KllDoublesSketch ddsk = KllDoublesSketch.writableWrap(wmem, memReqSvr);
     return ddsk;
   }
 
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java b/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
index 809ffe1a..f710a8f6 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
@@ -35,7 +35,7 @@ public class MiscDirectFloatsTest {
 
   @Test
   public void checkBounds() {
-    final KllDirectFloatsSketch sk = getDFSketch(200, 0);
+    final KllFloatsSketch sk = getDFSketch(200, 0);
     for (int i = 0; i < 1000; i++) {
       sk.update(i);
     }
@@ -52,7 +52,7 @@ public class MiscDirectFloatsTest {
 
   @Test
   public void checkMisc() {
-    final KllDirectFloatsSketch sk = getDFSketch(8, 0);
+    final KllFloatsSketch sk = getDFSketch(8, 0);
     assertTrue(Objects.isNull(sk.getQuantiles(10)));
     //sk.toString(true, true);
     for (int i = 0; i < 20; i++) { sk.update(i); }
@@ -67,11 +67,11 @@ public class MiscDirectFloatsTest {
 
   //@Test //enable static println(..) for visual checking
   public void visualCheckToString() {
-    final KllDirectFloatsSketch sk = getDFSketch(20, 0);
+    final KllFloatsSketch sk = getDFSketch(20, 0);
     for (int i = 0; i < 10; i++) { sk.update(i + 1); }
     println(sk.toString(true, true));
 
-    final KllDirectFloatsSketch sk2 = getDFSketch(20, 0);
+    final KllFloatsSketch sk2 = getDFSketch(20, 0);
     for (int i = 0; i < 400; i++) { sk2.update(i + 1); }
     println("\n" + sk2.toString(true, true));
 
@@ -82,7 +82,7 @@ public class MiscDirectFloatsTest {
 
   //@Test
   public void viewCompactions() {
-    final KllDirectFloatsSketch sk = getDFSketch(20, 0);
+    final KllFloatsSketch sk = getDFSketch(20, 0);
     show(sk, 20);
     show(sk, 21); //compaction 1
     show(sk, 43);
@@ -98,7 +98,7 @@ public class MiscDirectFloatsTest {
     show(sk, 108);
   }
 
-  private static void show(final KllDirectFloatsSketch sk, int limit) {
+  private static void show(final KllFloatsSketch sk, int limit) {
     int i = (int) sk.getN();
     for ( ; i < limit; i++) { sk.update(i + 1); }
     println(sk.toString(true, true));
@@ -107,7 +107,7 @@ public class MiscDirectFloatsTest {
   @Test
   public void checkSketchInitializeFloatHeap() {
     int k = 20; //don't change this
-    KllDirectFloatsSketch sk;
+    KllFloatsSketch sk;
 
     //println("#### CASE: FLOAT FULL HEAP");
     sk = getDFSketch(k, 0);
@@ -163,8 +163,8 @@ public class MiscDirectFloatsTest {
   @Test
   public void checkSketchInitializeFloatHeapifyCompactMem() {
     int k = 20; //don't change this
-    KllHeapFloatsSketch sk;
-    KllDirectFloatsSketch sk2;
+    KllFloatsSketch sk;
+    KllFloatsSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
@@ -175,7 +175,7 @@ public class MiscDirectFloatsTest {
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -195,7 +195,7 @@ public class MiscDirectFloatsTest {
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -216,7 +216,7 @@ public class MiscDirectFloatsTest {
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -234,8 +234,8 @@ public class MiscDirectFloatsTest {
   @Test
   public void checkSketchInitializeFloatHeapifyUpdatableMem() {
     int k = 20; //don't change this
-    KllHeapFloatsSketch sk;
-    KllDirectFloatsSketch sk2;
+    KllFloatsSketch sk;
+    KllFloatsSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
@@ -246,7 +246,7 @@ public class MiscDirectFloatsTest {
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -266,7 +266,7 @@ public class MiscDirectFloatsTest {
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -287,7 +287,7 @@ public class MiscDirectFloatsTest {
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     //println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -305,8 +305,8 @@ public class MiscDirectFloatsTest {
   @Test
   public void checkMemoryToStringFloatUpdatable() {
     int k = 20; //don't change this
-    KllDirectFloatsSketch sk;
-    KllDirectFloatsSketch sk2;
+    KllFloatsSketch sk;
+    KllFloatsSketch sk2;
     byte[] upBytes;
     byte[] upBytes2;
     WritableMemory wmem;
@@ -320,7 +320,7 @@ public class MiscDirectFloatsTest {
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    sk2 = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -335,7 +335,7 @@ public class MiscDirectFloatsTest {
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    sk2 = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -351,7 +351,7 @@ public class MiscDirectFloatsTest {
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    sk2 = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -365,8 +365,8 @@ public class MiscDirectFloatsTest {
     int k = 20;
     int n1 = 21;
     int n2 = 21;
-    KllDirectFloatsSketch sk1 = getDFSketch(k, 0);
-    KllDirectFloatsSketch sk2 = getDFSketch(k, 0);
+    KllFloatsSketch sk1 = getDFSketch(k, 0);
+    KllFloatsSketch sk2 = getDFSketch(k, 0);
     for (int i = 1; i <= n1; i++) {
       sk1.update(i);
     }
@@ -383,7 +383,7 @@ public class MiscDirectFloatsTest {
 
   @Test
   public void checkSizes() {
-    KllDirectFloatsSketch sk = getDFSketch(20, 0);
+    KllFloatsSketch sk = getDFSketch(20, 0);
     for (int i = 1; i <= 21; i++) { sk.update(i); }
     //println(sk.toString(true, true));
     byte[] byteArr1 = sk.toUpdatableByteArray();
@@ -398,7 +398,7 @@ public class MiscDirectFloatsTest {
   public void checkNewInstance() {
     int k = 200;
     WritableMemory dstMem = WritableMemory.allocate(3000);
-    KllDirectFloatsSketch sk = KllDirectFloatsSketch.newInstance(k, dstMem, memReqSvr);
+    KllFloatsSketch sk = KllFloatsSketch.newDirectInstance(k, dstMem, memReqSvr);
     for (int i = 1; i <= 10_000; i++) {sk.update(i); }
     assertEquals(sk.getMinValue(), 1.0F);
     assertEquals(sk.getMaxValue(), 10000.0F);
@@ -410,18 +410,18 @@ public class MiscDirectFloatsTest {
     int k = 20;
     int m = 4;
     WritableMemory dstMem = WritableMemory.allocate(1000);
-    KllDirectFloatsSketch sk = KllDirectFloatsSketch.newInstance(k, m, dstMem, memReqSvr);
+    KllFloatsSketch sk = KllDirectFloatsSketch.newDirectInstance(k, m, dstMem, memReqSvr);
     for (int i = 1; i <= 200; i++) {sk.update(i); }
     assertEquals(sk.getMinValue(), 1.0);
     assertEquals(sk.getMaxValue(), 200.0);
   }
 
-  private static KllDirectFloatsSketch getDFSketch(final int k, final int n) {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch(k);
+  private static KllFloatsSketch getDFSketch(final int k, final int n) {
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= n; i++) { sk.update(i); }
     byte[] byteArr = sk.toUpdatableByteArray();
     WritableMemory wmem = WritableMemory.writableWrap(byteArr);
-    KllDirectFloatsSketch dfsk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
+    KllFloatsSketch dfsk = KllFloatsSketch.writableWrap(wmem, memReqSvr);
     return dfsk;
   }
 
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java b/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
index ed43f225..9d4055d1 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
@@ -25,6 +25,8 @@ import static org.testng.Assert.assertTrue;
 
 import java.util.Objects;
 
+import org.apache.datasketches.memory.DefaultMemoryRequestServer;
+import org.apache.datasketches.memory.MemoryRequestServer;
 import org.apache.datasketches.memory.WritableMemory;
 import org.apache.datasketches.SketchesArgumentException;
 import org.testng.annotations.Test;
@@ -38,7 +40,7 @@ public class MiscDoublesTest {
 
   @Test
   public void checkBounds() {
-    final KllHeapDoublesSketch kll = new KllHeapDoublesSketch(); //default k = 200
+    final KllDoublesSketch kll = KllDoublesSketch.newHeapInstance(); //default k = 200
     for (int i = 0; i < 1000; i++) {
       kll.update(i);
     }
@@ -55,49 +57,49 @@ public class MiscDoublesTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions1() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(6, (byte)3); //corrupt with odd M
-    KllHeapDoublesSketch.heapify(wmem);
+    KllDoublesSketch.heapify(wmem);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions2() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(0, (byte)1); //corrupt preamble ints, should be 2
-    KllHeapDoublesSketch.heapify(wmem);
+    KllDoublesSketch.heapify(wmem);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions3() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     sk.update(1.0f);
     sk.update(2.0f);
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(0, (byte)1); //corrupt preamble ints, should be 5
-    KllHeapDoublesSketch.heapify(wmem);
+    KllDoublesSketch.heapify(wmem);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions4() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(1, (byte)0); //corrupt SerVer, should be 1 or 2
-    KllHeapDoublesSketch.heapify(wmem);
+    KllDoublesSketch.heapify(wmem);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions5() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch();
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance();
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(2, (byte)0); //corrupt FamilyID, should be 15
-    KllHeapDoublesSketch.heapify(wmem);
+    KllDoublesSketch.heapify(wmem);
   }
 
   @Test
   public void checkMisc() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch(8);
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance(8);
     assertTrue(Objects.isNull(sk.getQuantiles(10)));
     sk.toString(true, true);
     for (int i = 0; i < 20; i++) { sk.update(i); }
@@ -112,12 +114,12 @@ public class MiscDoublesTest {
 
   //@Test //enable static println(..) for visual checking
   public void visualCheckToString() {
-    final KllHeapDoublesSketch sketch = new KllHeapDoublesSketch(20);
+    final KllDoublesSketch sketch = KllDoublesSketch.newHeapInstance(20);
     for (int i = 0; i < 10; i++) { sketch.update(i + 1); }
     final String s1 = sketch.toString(true, true);
     println(s1);
 
-    final KllHeapDoublesSketch sketch2 = new KllHeapDoublesSketch(20);
+    final KllDoublesSketch sketch2 = KllDoublesSketch.newHeapInstance(20);
     for (int i = 0; i < 400; i++) { sketch2.update(i + 1); }
     println("\n" + sketch2.toString(true, true));
 
@@ -128,7 +130,7 @@ public class MiscDoublesTest {
 
   @Test
   public void viewCompactions() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch(20);
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance(20);
     show(sk, 20);
     show(sk, 21); //compaction 1
     show(sk, 43);
@@ -144,7 +146,7 @@ public class MiscDoublesTest {
     show(sk, 108);
   }
 
-  private static void show(final KllHeapDoublesSketch sk, int limit) {
+  private static void show(final KllDoublesSketch sk, int limit) {
     int i = (int) sk.getN();
     for ( ; i < limit; i++) { sk.update(i + 1); }
     println(sk.toString(true, true));
@@ -152,7 +154,7 @@ public class MiscDoublesTest {
 
   @Test
   public void checkGrowLevels() {
-    KllHeapDoublesSketch sk = new KllHeapDoublesSketch(20);
+    KllDoublesSketch sk = KllDoublesSketch.newHeapInstance(20);
     for (int i = 1; i <= 21; i++) { sk.update(i); }
     assertEquals(sk.getNumLevels(), 2);
     assertEquals(sk.getDoubleItemsArray().length, 33);
@@ -162,10 +164,10 @@ public class MiscDoublesTest {
   @Test
   public void checkSketchInitializeDoubleHeap() {
     int k = 20; //don't change this
-    KllHeapDoublesSketch sk;
+    KllDoublesSketch sk;
 
     println("#### CASE: DOUBLE FULL HEAP");
-    sk = new KllHeapDoublesSketch(k);
+    sk = KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk.update(i); }
     //println(sk.toString(true, true));
     assertEquals(sk.getK(), k);
@@ -182,7 +184,7 @@ public class MiscDoublesTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE HEAP EMPTY");
-    sk = new KllHeapDoublesSketch(k);
+    sk = KllDoublesSketch.newHeapInstance(k);
     //println(sk.toString(true, true));
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
@@ -198,7 +200,7 @@ public class MiscDoublesTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE HEAP SINGLE");
-    sk = new KllHeapDoublesSketch(k);
+    sk = KllDoublesSketch.newHeapInstance(k);
     sk.update(1);
     //println(sk.toString(true, true));
     assertEquals(sk.getK(), k);
@@ -218,19 +220,19 @@ public class MiscDoublesTest {
   @Test
   public void checkSketchInitializeDoubleHeapifyCompactMem() {
     int k = 20; //don't change this
-    KllHeapDoublesSketch sk;
-    KllHeapDoublesSketch sk2;
+    KllDoublesSketch sk;
+    KllDoublesSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
     println("#### CASE: DOUBLE FULL HEAPIFIED FROM COMPACT");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk2.update(i); }
     //println(sk.toString(true, true));
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -245,12 +247,12 @@ public class MiscDoublesTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE EMPTY HEAPIFIED FROM COMPACT");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     //println(sk.toString(true, true));
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -265,13 +267,13 @@ public class MiscDoublesTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE SINGLE HEAPIFIED FROM COMPACT");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     sk2.update(1);
     println(sk2.toString(true, true));
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -289,19 +291,19 @@ public class MiscDoublesTest {
   @Test
   public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
     int k = 20; //don't change this
-    KllHeapDoublesSketch sk;
-    KllHeapDoublesSketch sk2;
+    KllDoublesSketch sk;
+    KllDoublesSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
     println("#### CASE: DOUBLE FULL HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk2.update(i); }
     //println(sk2.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -316,12 +318,12 @@ public class MiscDoublesTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE EMPTY HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     //println(sk.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -336,13 +338,13 @@ public class MiscDoublesTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: DOUBLE SINGLE HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapDoublesSketch(k);
+    sk2 = KllDoublesSketch.newHeapInstance(k);
     sk2.update(1);
     //println(sk.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapDoublesSketch.heapify(wmem);
+    sk = KllDoublesSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -360,22 +362,22 @@ public class MiscDoublesTest {
   @Test
   public void checkMemoryToStringDoubleCompact() {
     int k = 20; // don't change this
-    KllHeapDoublesSketch sk;
-    KllHeapDoublesSketch sk2;
+    KllDoublesSketch sk;
+    KllDoublesSketch sk2;
     byte[] compBytes;
     byte[] compBytes2;
     WritableMemory wmem;
     String s;
 
     println("#### CASE: DOUBLE FULL COMPACT");
-    sk = new KllHeapDoublesSketch(k);
+    sk = KllDoublesSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk.update(i); }
     compBytes = sk.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapDoublesSketch.heapify(wmem);
+    sk2 = KllDoublesSketch.heapify(wmem);
     compBytes2 = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -384,13 +386,13 @@ public class MiscDoublesTest {
     assertEquals(compBytes, compBytes2);
 
     println("#### CASE: DOUBLE EMPTY COMPACT");
-    sk = new KllHeapDoublesSketch(20);
+    sk = KllDoublesSketch.newHeapInstance(20);
     compBytes = sk.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapDoublesSketch.heapify(wmem);
+    sk2 = KllDoublesSketch.heapify(wmem);
     compBytes2 = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -399,14 +401,14 @@ public class MiscDoublesTest {
     assertEquals(compBytes, compBytes2);
 
     println("#### CASE: DOUBLE SINGLE COMPACT");
-    sk = new KllHeapDoublesSketch(20);
+    sk = KllDoublesSketch.newHeapInstance(20);
     sk.update(1);
     compBytes = sk.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapDoublesSketch.heapify(wmem);
+    sk2 = KllDoublesSketch.heapify(wmem);
     compBytes2 = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -418,22 +420,22 @@ public class MiscDoublesTest {
   @Test
   public void checkMemoryToStringDoubleUpdatable() {
     int k = 20; //don't change this
-    KllHeapDoublesSketch sk;
-    KllHeapDoublesSketch sk2;
+    KllDoublesSketch sk;
+    KllDoublesSketch sk2;
     byte[] upBytes;
     byte[] upBytes2;
     WritableMemory wmem;
     String s;
 
     println("#### CASE: DOUBLE FULL UPDATABLE");
-    sk = new KllHeapDoublesSketch(20);
+    sk = KllDoublesSketch.newHeapInstance(20);
     for (int i = 1; i <= k + 1; i++) { sk.update(i); }
     upBytes = sk.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapDoublesSketch.heapify(wmem);
+    sk2 = KllDoublesSketch.heapify(wmem);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -442,13 +444,13 @@ public class MiscDoublesTest {
     assertEquals(upBytes, upBytes2);
 
     println("#### CASE: DOUBLE EMPTY UPDATABLE");
-    sk = new KllHeapDoublesSketch(k);
+    sk = KllDoublesSketch.newHeapInstance(k);
     upBytes = sk.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapDoublesSketch.heapify(wmem);
+    sk2 = KllDoublesSketch.heapify(wmem);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -457,14 +459,14 @@ public class MiscDoublesTest {
     assertEquals(upBytes, upBytes2);
 
     println("#### CASE: DOUBLE SINGLE UPDATABL");
-    sk = new KllHeapDoublesSketch(k);
+    sk = KllDoublesSketch.newHeapInstance(k);
     sk.update(1);
     upBytes = sk.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapDoublesSketch.heapify(wmem);
+    sk2 = KllDoublesSketch.heapify(wmem);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -476,10 +478,14 @@ public class MiscDoublesTest {
   @Test
   public void checkSimpleMerge() {
     int k = 20;
+    int m = 4;
     int n1 = 21;
-    int n2 = 21;
-    KllHeapDoublesSketch sk1 = new KllHeapDoublesSketch(k);
-    KllHeapDoublesSketch sk2 = new KllHeapDoublesSketch(k);
+    int n2 = 43;
+    WritableMemory wmem = WritableMemory.allocate(3000);
+    WritableMemory wmem2 = WritableMemory.allocate(3000);
+    MemoryRequestServer memReqSvr = new DefaultMemoryRequestServer();
+    KllDoublesSketch sk1 = KllDirectDoublesSketch.newDirectInstance(k, m, wmem, memReqSvr);
+    KllDoublesSketch sk2 = KllDirectDoublesSketch.newDirectInstance(k, m, wmem2, memReqSvr);
     for (int i = 1; i <= n1; i++) {
       sk1.update(i);
     }
diff --git a/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java b/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
index 78f0a525..746b885e 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
@@ -26,6 +26,8 @@ import static org.testng.Assert.assertTrue;
 import java.util.Objects;
 
 import org.apache.datasketches.SketchesArgumentException;
+import org.apache.datasketches.memory.DefaultMemoryRequestServer;
+import org.apache.datasketches.memory.MemoryRequestServer;
 import org.apache.datasketches.memory.WritableMemory;
 import org.testng.annotations.Test;
 
@@ -38,7 +40,7 @@ public class MiscFloatsTest {
 
   @Test
   public void checkBounds() {
-    final KllHeapFloatsSketch kll = new KllHeapFloatsSketch(); //default k = 200
+    final KllFloatsSketch kll = KllFloatsSketch.newHeapInstance(); //default k = 200
     for (int i = 0; i < 1000; i++) {
       kll.update(i);
     }
@@ -55,49 +57,49 @@ public class MiscFloatsTest {
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions1() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(6, (byte)3); //corrupt with odd M
-    KllHeapFloatsSketch.heapify(wmem);
+    KllFloatsSketch.heapify(wmem);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions2() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(0, (byte)1); //corrupt preamble ints, should be 2
-    KllHeapFloatsSketch.heapify(wmem);
+    KllFloatsSketch.heapify(wmem);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions3() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     sk.update(1.0f);
     sk.update(2.0f);
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(0, (byte)1); //corrupt preamble ints, should be 5
-    KllHeapFloatsSketch.heapify(wmem);
+    KllFloatsSketch.heapify(wmem);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions4() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(1, (byte)0); //corrupt SerVer, should be 1 or 2
-    KllHeapFloatsSketch.heapify(wmem);
+    KllFloatsSketch.heapify(wmem);
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
   public void checkHeapifyExceptions5() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch();
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance();
     WritableMemory wmem = WritableMemory.writableWrap(sk.toByteArray());
     wmem.putByte(2, (byte)0); //corrupt FamilyID, should be 15
-    KllHeapFloatsSketch.heapify(wmem);
+    KllFloatsSketch.heapify(wmem);
   }
 
   @Test
   public void checkMisc() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch(8);
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance(8);
     assertTrue(Objects.isNull(sk.getQuantiles(10)));
     sk.toString(true, true);
     for (int i = 0; i < 20; i++) { sk.update(i); }
@@ -112,12 +114,12 @@ public class MiscFloatsTest {
 
   //@Test //enable static println(..) for visual checking
   public void visualCheckToString() {
-    final KllHeapFloatsSketch sketch = new KllHeapFloatsSketch(20);
+    final KllFloatsSketch sketch = KllFloatsSketch.newHeapInstance(20);
     for (int i = 0; i < 10; i++) { sketch.update(i + 1); }
     final String s1 = sketch.toString(true, true);
     println(s1);
 
-    final KllHeapFloatsSketch sketch2 = new KllHeapFloatsSketch(20);
+    final KllFloatsSketch sketch2 = KllFloatsSketch.newHeapInstance(20);
     for (int i = 0; i < 400; i++) { sketch2.update(i + 1); }
     println("\n" + sketch2.toString(true, true));
 
@@ -128,7 +130,7 @@ public class MiscFloatsTest {
 
   @Test
   public void viewCompactions() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch(20);
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance(20);
     show(sk, 20);
     show(sk, 21); //compaction 1
     show(sk, 43);
@@ -144,7 +146,7 @@ public class MiscFloatsTest {
     show(sk, 108);
   }
 
-  private static void show(final KllHeapFloatsSketch sk, int limit) {
+  private static void show(final KllFloatsSketch sk, int limit) {
     int i = (int) sk.getN();
     for ( ; i < limit; i++) { sk.update(i + 1); }
     println(sk.toString(true, true));
@@ -152,7 +154,7 @@ public class MiscFloatsTest {
 
   @Test
   public void checkGrowLevels() {
-    KllHeapFloatsSketch sk = new KllHeapFloatsSketch(20);
+    KllFloatsSketch sk = KllFloatsSketch.newHeapInstance(20);
     for (int i = 1; i <= 21; i++) { sk.update(i); }
     assertEquals(sk.getNumLevels(), 2);
     assertEquals(sk.getFloatItemsArray().length, 33);
@@ -162,10 +164,10 @@ public class MiscFloatsTest {
   @Test
   public void checkSketchInitializeFloatHeap() {
     int k = 20; //don't change this
-    KllHeapFloatsSketch sk;
+    KllFloatsSketch sk;
 
     println("#### CASE: FLOAT FULL HEAP");
-    sk = new KllHeapFloatsSketch(k);
+    sk = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk.update(i); }
     //println(sk.toString(true, true));
     assertEquals(sk.getK(), k);
@@ -182,7 +184,7 @@ public class MiscFloatsTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: FLOAT HEAP EMPTY");
-    sk = new KllHeapFloatsSketch(k);
+    sk = KllFloatsSketch.newHeapInstance(k);
     //println(sk.toString(true, true));
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
@@ -198,7 +200,7 @@ public class MiscFloatsTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: FLOAT HEAP SINGLE");
-    sk = new KllHeapFloatsSketch(k);
+    sk = KllFloatsSketch.newHeapInstance(k);
     sk.update(1);
     //println(sk.toString(true, true));
     assertEquals(sk.getK(), k);
@@ -218,19 +220,19 @@ public class MiscFloatsTest {
   @Test
   public void checkSketchInitializeFloatHeapifyCompactMem() {
     int k = 20; //don't change this
-    KllHeapFloatsSketch sk;
-    KllHeapFloatsSketch sk2;
+    KllFloatsSketch sk;
+    KllFloatsSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
     println("#### CASE: FLOAT FULL HEAPIFIED FROM COMPACT");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk2.update(i); }
     println(sk2.toString(true, true));
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -245,12 +247,12 @@ public class MiscFloatsTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: FLOAT EMPTY HEAPIFIED FROM COMPACT");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     //println(sk.toString(true, true));
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -265,13 +267,13 @@ public class MiscFloatsTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: FLOAT SINGLE HEAPIFIED FROM COMPACT");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     sk2.update(1);
     //println(sk2.toString(true, true));
     compBytes = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -289,19 +291,19 @@ public class MiscFloatsTest {
   @Test
   public void checkSketchInitializeFloatHeapifyUpdatableMem() {
     int k = 20; //don't change this
-    KllHeapFloatsSketch sk;
-    KllHeapFloatsSketch sk2;
+    KllFloatsSketch sk;
+    KllFloatsSketch sk2;
     byte[] compBytes;
     WritableMemory wmem;
 
     println("#### CASE: FLOAT FULL HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk2.update(i); }
     //println(sk2.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), k + 1);
     assertEquals(sk.getNumRetained(), 11);
@@ -316,12 +318,12 @@ public class MiscFloatsTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: FLOAT EMPTY HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     //println(sk.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 0);
     assertEquals(sk.getNumRetained(), 0);
@@ -336,13 +338,13 @@ public class MiscFloatsTest {
     assertFalse(sk.isLevelZeroSorted());
 
     println("#### CASE: FLOAT SINGLE HEAPIFIED FROM UPDATABLE");
-    sk2 = new KllHeapFloatsSketch(k);
+    sk2 = KllFloatsSketch.newHeapInstance(k);
     sk2.update(1);
     //println(sk.toString(true, true));
     compBytes = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     println(KllPreambleUtil.toString(wmem));
-    sk = KllHeapFloatsSketch.heapify(wmem);
+    sk = KllFloatsSketch.heapify(wmem);
     assertEquals(sk.getK(), k);
     assertEquals(sk.getN(), 1);
     assertEquals(sk.getNumRetained(), 1);
@@ -360,22 +362,22 @@ public class MiscFloatsTest {
   @Test
   public void checkMemoryToStringFloatCompact() {
     int k = 20; //don't change this
-    KllHeapFloatsSketch sk;
-    KllHeapFloatsSketch sk2;
+    KllFloatsSketch sk;
+    KllFloatsSketch sk2;
     byte[] compBytes;
     byte[] compBytes2;
     WritableMemory wmem;
     String s;
 
     println("#### CASE: FLOAT FULL COMPACT");
-    sk = new KllHeapFloatsSketch(k);
+    sk = KllFloatsSketch.newHeapInstance(k);
     for (int i = 1; i <= k + 1; i++) { sk.update(i); }
     compBytes = sk.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapFloatsSketch.heapify(wmem);
+    sk2 = KllFloatsSketch.heapify(wmem);
     compBytes2 = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -384,13 +386,13 @@ public class MiscFloatsTest {
     assertEquals(compBytes, compBytes2);
 
     println("#### CASE: FLOAT EMPTY COMPACT");
-    sk = new KllHeapFloatsSketch(k);
+    sk = KllFloatsSketch.newHeapInstance(k);
     compBytes = sk.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapFloatsSketch.heapify(wmem);
+    sk2 = KllFloatsSketch.heapify(wmem);
     compBytes2 = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -399,14 +401,14 @@ public class MiscFloatsTest {
     assertEquals(compBytes, compBytes2);
 
     println("#### CASE: FLOAT SINGLE COMPACT");
-    sk = new KllHeapFloatsSketch(k);
+    sk = KllFloatsSketch.newHeapInstance(k);
     sk.update(1);
     compBytes = sk.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapFloatsSketch.heapify(wmem);
+    sk2 = KllFloatsSketch.heapify(wmem);
     compBytes2 = sk2.toByteArray();
     wmem = WritableMemory.writableWrap(compBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -418,22 +420,22 @@ public class MiscFloatsTest {
   @Test
   public void checkMemoryToStringFloatUpdatable() {
     int k = 20; //don't change this
-    KllHeapFloatsSketch sk;
-    KllHeapFloatsSketch sk2;
+    KllFloatsSketch sk;
+    KllFloatsSketch sk2;
     byte[] upBytes;
     byte[] upBytes2;
     WritableMemory wmem;
     String s;
 
     println("#### CASE: FLOAT FULL UPDATABLE");
-    sk = new KllHeapFloatsSketch(20);
+    sk = KllFloatsSketch.newHeapInstance(20);
     for (int i = 1; i <= k + 1; i++) { sk.update(i); }
     upBytes = sk.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapFloatsSketch.heapify(wmem);
+    sk2 = KllFloatsSketch.heapify(wmem);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -442,13 +444,13 @@ public class MiscFloatsTest {
     assertEquals(upBytes, upBytes2);
 
     println("#### CASE: FLOAT EMPTY UPDATABLE");
-    sk = new KllHeapFloatsSketch(k);
+    sk = KllFloatsSketch.newHeapInstance(k);
     upBytes = sk.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapFloatsSketch.heapify(wmem);
+    sk2 = KllFloatsSketch.heapify(wmem);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -457,14 +459,14 @@ public class MiscFloatsTest {
     assertEquals(upBytes, upBytes2);
 
     println("#### CASE: FLOAT SINGLE UPDATABLE");
-    sk = new KllHeapFloatsSketch(k);
+    sk = KllFloatsSketch.newHeapInstance(k);
     sk.update(1);
     upBytes = sk.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes);
     s = KllPreambleUtil.memoryToString(wmem);
     println("step 1: sketch to byte[]/memory & analyze memory");
     println(s);
-    sk2 = KllHeapFloatsSketch.heapify(wmem);
+    sk2 = KllFloatsSketch.heapify(wmem);
     upBytes2 = sk2.toUpdatableByteArray();
     wmem = WritableMemory.writableWrap(upBytes2);
     s = KllPreambleUtil.memoryToString(wmem);
@@ -479,8 +481,11 @@ public class MiscFloatsTest {
     int m = 4;
     int n1 = 21;
     int n2 = 43;
-    KllHeapFloatsSketch sk1 = new KllHeapFloatsSketch(k, m);
-    KllHeapFloatsSketch sk2 = new KllHeapFloatsSketch(k, m);
+    WritableMemory wmem = WritableMemory.allocate(3000);
+    WritableMemory wmem2 = WritableMemory.allocate(3000);
+    MemoryRequestServer memReqSvr = new DefaultMemoryRequestServer();
+    KllFloatsSketch sk1 = KllDirectFloatsSketch.newDirectInstance(k, m, wmem, memReqSvr);
+    KllFloatsSketch sk2 = KllDirectFloatsSketch.newDirectInstance(k, m, wmem2, memReqSvr);
     for (int i = 1; i <= n1; i++) {
       sk1.update(i);
     }
@@ -493,11 +498,6 @@ public class MiscFloatsTest {
     println(sk1.toString(true, true));
   }
 
-  @Test
-  public void checkOtherM() {
-
-  }
-
   @Test
   public void printlnTest() {
     println("PRINTING: " + this.getClass().getName());


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