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

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


The following commit(s) were added to refs/heads/Cleanup_phase1 by this push:
     new 29a9434d0 Cleanup phase 1
29a9434d0 is described below

commit 29a9434d00ef8bda2b4f25886606da51a8b30624
Author: Lee Rhodes <[email protected]>
AuthorDate: Mon Aug 11 18:39:07 2025 -0700

    Cleanup phase 1
---
 .../org/apache/datasketches/common/Family.java     |   2 +-
 .../datasketches/common/MemorySegmentRequest.java  |   8 +-
 ...ion.java => SketchesNotSupportedException.java} |  24 +-
 .../java/org/apache/datasketches/common/Util.java  |   2 +-
 .../apache/datasketches/hll/AbstractCoupons.java   |   6 +-
 .../datasketches/hll/DirectCouponHashSet.java      |   5 +-
 .../apache/datasketches/hll/DirectCouponList.java  |   2 +-
 .../apache/datasketches/hll/DirectHll4Array.java   |   2 +-
 .../apache/datasketches/hll/DirectHll6Array.java   |   2 +-
 .../apache/datasketches/hll/DirectHll8Array.java   |   2 +-
 .../apache/datasketches/hll/DirectHllArray.java    |   2 +-
 .../java/org/apache/datasketches/hll/HllArray.java |   2 +-
 .../java/org/apache/datasketches/hllmap/Map.java   |   6 +-
 .../apache/datasketches/kll/KllDoublesSketch.java  |   2 +-
 .../apache/datasketches/kll/KllFloatsSketch.java   |   2 +-
 .../datasketches/kll/KllHeapDoublesSketch.java     |   2 +-
 .../datasketches/kll/KllHeapFloatsSketch.java      |   2 +-
 .../datasketches/kll/KllHeapLongsSketch.java       |   2 +-
 .../org/apache/datasketches/kll/KllHelper.java     |   4 +-
 .../apache/datasketches/kll/KllItemsHelper.java    |   2 +-
 .../apache/datasketches/kll/KllItemsSketch.java    |   2 +-
 .../apache/datasketches/kll/KllLongsSketch.java    |   2 +-
 .../apache/datasketches/kll/KllPreambleUtil.java   |   2 +-
 .../apache/datasketches/quantiles/ClassicUtil.java |  22 +-
 .../quantiles/CompactDoublesSketch.java            |   5 +
 .../quantiles/DirectCompactDoublesSketch.java      |   8 +-
 .../quantiles/DirectDoublesSketchAccessor.java     |  25 +-
 .../quantiles/DirectUpdateDoublesSketch.java       | 173 +++++++++++--
 .../quantiles/DirectUpdateDoublesSketchR.java      | 268 ---------------------
 .../quantiles/DoublesBufferAccessor.java           |   2 +
 .../datasketches/quantiles/DoublesMergeImpl.java   |   4 +-
 .../datasketches/quantiles/DoublesSketch.java      |  32 ++-
 .../quantiles/DoublesSketchAccessor.java           |  50 +++-
 .../quantiles/DoublesSketchIterator.java           |  10 +-
 .../datasketches/quantiles/DoublesUnion.java       |  10 +-
 .../datasketches/quantiles/DoublesUnionImpl.java   | 131 ++++++++--
 .../datasketches/quantiles/DoublesUnionImplR.java  | 166 -------------
 .../apache/datasketches/quantiles/DoublesUtil.java |  12 +-
 .../quantiles/HeapCompactDoublesSketch.java        |   2 +-
 .../quantiles/HeapDoublesSketchAccessor.java       |   8 +-
 .../quantiles/HeapUpdateDoublesSketch.java         |  13 +-
 .../org/apache/datasketches/req/ReqCompactor.java  |   2 +-
 .../datasketches/sampling/EbppsItemsSketch.java    |   4 +-
 .../theta/ConcurrentDirectQuickSelectSketch.java   |  10 +-
 .../theta/ConcurrentHeapQuickSelectSketch.java     |   4 +-
 .../theta/ConcurrentHeapThetaBuffer.java           |   6 +-
 .../theta/DirectQuickSelectSketch.java             |   2 +-
 .../DirectArrayOfDoublesQuickSelectSketch.java     |   6 +-
 .../quantiles/DirectCompactDoublesSketchTest.java  |   3 +-
 .../quantiles/DirectUpdateDoublesSketchTest.java   |  22 +-
 .../datasketches/quantiles/DoublesSketchTest.java  |   6 +-
 .../quantiles/DoublesUnionBuilderTest.java         |   4 +-
 .../quantiles/DoublesUnionImplTest.java            |   8 +-
 .../datasketches/quantiles/DoublesUtilTest.java    |   2 +-
 .../quantiles/HeapUpdateDoublesSketchTest.java     |  16 +-
 .../QuantilesSketchCrossLanguageTest.java          |   2 +-
 .../datasketches/quantiles/ReadOnlyMemoryTest.java | 124 +++++-----
 57 files changed, 548 insertions(+), 701 deletions(-)

diff --git a/src/main/java/org/apache/datasketches/common/Family.java 
b/src/main/java/org/apache/datasketches/common/Family.java
index 0ca3d7cb8..51ca822e2 100644
--- a/src/main/java/org/apache/datasketches/common/Family.java
+++ b/src/main/java/org/apache/datasketches/common/Family.java
@@ -177,7 +177,7 @@ public enum Family {
       lookupFamName.put(f.getFamilyName().toUpperCase(Locale.US), f);
     }
     if (ByteOrder.nativeOrder() != ByteOrder.LITTLE_ENDIAN) {
-      throw new BigEndianNativeOrderNotSupportedException();
+      throw new SketchesNotSupportedException("Machine Native Endianness must 
be LITTLE_ENDIAN.");
     }
   }
 
diff --git 
a/src/main/java/org/apache/datasketches/common/MemorySegmentRequest.java 
b/src/main/java/org/apache/datasketches/common/MemorySegmentRequest.java
index 859163279..5bf3253cd 100644
--- a/src/main/java/org/apache/datasketches/common/MemorySegmentRequest.java
+++ b/src/main/java/org/apache/datasketches/common/MemorySegmentRequest.java
@@ -50,12 +50,16 @@ public interface MemorySegmentRequest {
    * It is up to the user to override this as appropriate.
    * @param prevSeg the previous MemorySegment to be closed.
    */
-  default void requestClose(final MemorySegment prevSeg) { }
+  default void requestClose(final MemorySegment prevSeg) {
+    //Because the default request goes on the heap, this default is a no-op
+  }
 
   /**
    * This class implements the defaults
    */
-  public static class Default implements MemorySegmentRequest { }
+  public static class Default implements MemorySegmentRequest {
+    //A convenience class that creates the target for the static member 
DEFAULT.
+  }
 
   /**
    * Create Default as static member.
diff --git 
a/src/main/java/org/apache/datasketches/common/BigEndianNativeOrderNotSupportedException.java
 
b/src/main/java/org/apache/datasketches/common/SketchesNotSupportedException.java
similarity index 53%
rename from 
src/main/java/org/apache/datasketches/common/BigEndianNativeOrderNotSupportedException.java
rename to 
src/main/java/org/apache/datasketches/common/SketchesNotSupportedException.java
index 67dcd34d7..e22cc1637 100644
--- 
a/src/main/java/org/apache/datasketches/common/BigEndianNativeOrderNotSupportedException.java
+++ 
b/src/main/java/org/apache/datasketches/common/SketchesNotSupportedException.java
@@ -20,16 +20,28 @@
 package org.apache.datasketches.common;
 
 /**
- * The DataSketches Library is not supported on Big Endian machines.
+ * This operation or mode is not supported.
+ *
+ * @author Lee Rhodes
  */
-public class BigEndianNativeOrderNotSupportedException extends 
SketchesException {
+public class SketchesNotSupportedException extends SketchesException {
   private static final long serialVersionUID = 1L;
+  private static final String baseStr = "This operation or mode is not 
supported: ";
+
+  //other constructors to be added as needed.
 
   /**
-   * Constructs a new runtime exception with the message:
-   * "The DataSketches Library is not supported on Big Endian machines."
+   * Constructs a new runtime exception with the specified detail message. The 
cause is not
+   * initialized, and may subsequently be initialized by a call to
+   * Throwable.initCause(java.lang.Throwable).
+   *
+   * @param message the detail message which is appended to the base 
message:<br>
+   * "This operation or mode is not supported: ".
+   *
+   * <p>The detail message is saved for later retrieval by the 
Throwable.getMessage() method.</p>
    */
-  public BigEndianNativeOrderNotSupportedException() {
-    super("The DataSketches Library is not supported on Big Endian machines.");
+  public SketchesNotSupportedException(final String message) {
+    super(baseStr + message);
   }
+
 }
diff --git a/src/main/java/org/apache/datasketches/common/Util.java 
b/src/main/java/org/apache/datasketches/common/Util.java
index c36e15937..9bed9a804 100644
--- a/src/main/java/org/apache/datasketches/common/Util.java
+++ b/src/main/java/org/apache/datasketches/common/Util.java
@@ -41,7 +41,7 @@ public final class Util {
 
   static {
     if (ByteOrder.nativeOrder() != ByteOrder.LITTLE_ENDIAN) {
-      throw new BigEndianNativeOrderNotSupportedException();
+      throw new SketchesNotSupportedException("Machine Native Endianness must 
be LITTLE_ENDIAN.");
     }
   }
 
diff --git a/src/main/java/org/apache/datasketches/hll/AbstractCoupons.java 
b/src/main/java/org/apache/datasketches/hll/AbstractCoupons.java
index 774f91884..62727ebed 100644
--- a/src/main/java/org/apache/datasketches/hll/AbstractCoupons.java
+++ b/src/main/java/org/apache/datasketches/hll/AbstractCoupons.java
@@ -112,13 +112,13 @@ abstract class AbstractCoupons extends HllSketchImpl {
   }
 
   @Override
-  void putEmptyFlag(final boolean empty) {} //no-op for coupons
+  void putEmptyFlag(final boolean empty) { /*no-op for coupons */ }
 
   @Override
-  void putOutOfOrder(final boolean outOfOrder) {} //no-op for coupons
+  void putOutOfOrder(final boolean outOfOrder) { /*no-op for coupons */ }
 
   @Override
-  void putRebuildCurMinNumKxQFlag(final boolean rebuild) {} //no-op for coupons
+  void putRebuildCurMinNumKxQFlag(final boolean rebuild) { /*no-op for coupons 
*/ }
 
   @Override
   byte[] toCompactByteArray() {
diff --git a/src/main/java/org/apache/datasketches/hll/DirectCouponHashSet.java 
b/src/main/java/org/apache/datasketches/hll/DirectCouponHashSet.java
index 692d68c1e..e00d4a888 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectCouponHashSet.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectCouponHashSet.java
@@ -55,9 +55,8 @@ final class DirectCouponHashSet extends DirectCouponList {
   }
 
   //Constructs this sketch with read-only data, may be compact.
-  DirectCouponHashSet(final int lgConfigK, final TgtHllType tgtHllType, final 
MemorySegment seg,
-      final boolean readOnly) {
-    super(lgConfigK, tgtHllType, CurMode.SET, seg, true);
+  DirectCouponHashSet(final int lgConfigK, final TgtHllType tgtHllType, final 
MemorySegment seg, final boolean readOnly) {
+    super(lgConfigK, tgtHllType, CurMode.SET, seg, readOnly);
     assert seg.get(JAVA_BYTE, LG_K_BYTE) > 7;
   }
 
diff --git a/src/main/java/org/apache/datasketches/hll/DirectCouponList.java 
b/src/main/java/org/apache/datasketches/hll/DirectCouponList.java
index f548d1710..90a19a6f7 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectCouponList.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectCouponList.java
@@ -82,7 +82,7 @@ class DirectCouponList extends AbstractCoupons {
       final boolean readOnly) {
     super(lgConfigK, tgtHllType, curMode);
     wseg = null;
-    this.seg = seg;
+    this.seg = readOnly ? seg.asReadOnly() : seg;
     compact = extractCompactFlag(seg);
   }
 
diff --git a/src/main/java/org/apache/datasketches/hll/DirectHll4Array.java 
b/src/main/java/org/apache/datasketches/hll/DirectHll4Array.java
index bd9425e17..99e9450bb 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectHll4Array.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectHll4Array.java
@@ -53,7 +53,7 @@ final class DirectHll4Array extends DirectHllArray {
 
   //Called by HllSketch.wrap(MemorySegment)
   DirectHll4Array(final int lgConfigK, final MemorySegment seg, final boolean 
readOnly) {
-    super(lgConfigK, TgtHllType.HLL_4, seg, true);
+    super(lgConfigK, TgtHllType.HLL_4, seg, readOnly);
     final int auxCount = extractAuxCount(seg);
     if (auxCount > 0) {
       final boolean compact = extractCompactFlag(seg);
diff --git a/src/main/java/org/apache/datasketches/hll/DirectHll6Array.java 
b/src/main/java/org/apache/datasketches/hll/DirectHll6Array.java
index 91355e162..c9a8eb7c7 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectHll6Array.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectHll6Array.java
@@ -40,7 +40,7 @@ final class DirectHll6Array extends DirectHllArray {
 
   //Called by HllSketch.wrap(MemorySegment)
   DirectHll6Array(final int lgConfigK, final MemorySegment seg, final boolean 
readOnly) {
-    super(lgConfigK, TgtHllType.HLL_6, seg, true);
+    super(lgConfigK, TgtHllType.HLL_6, seg, readOnly);
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/DirectHll8Array.java 
b/src/main/java/org/apache/datasketches/hll/DirectHll8Array.java
index 0cf932a5d..7267d2f57 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectHll8Array.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectHll8Array.java
@@ -42,7 +42,7 @@ final class DirectHll8Array extends DirectHllArray {
 
   //Called by HllSketch.wrap(MemorySegment)
   DirectHll8Array(final int lgConfigK, final MemorySegment seg, final boolean 
readOnly) {
-    super(lgConfigK, TgtHllType.HLL_8, seg, true);
+    super(lgConfigK, TgtHllType.HLL_8, seg, readOnly);
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/hll/DirectHllArray.java 
b/src/main/java/org/apache/datasketches/hll/DirectHllArray.java
index 0b2a2b46a..e0fb7594e 100644
--- a/src/main/java/org/apache/datasketches/hll/DirectHllArray.java
+++ b/src/main/java/org/apache/datasketches/hll/DirectHllArray.java
@@ -82,7 +82,7 @@ abstract class DirectHllArray extends AbstractHllArray {
   DirectHllArray(final int lgConfigK, final TgtHllType tgtHllType, final 
MemorySegment seg, final boolean readOnly) {
     super(lgConfigK, tgtHllType, CurMode.HLL);
     wseg = null;
-    this.seg = seg;
+    this.seg = readOnly ? seg.asReadOnly() : seg;
     segObj = seg.toArray(JAVA_BYTE);
     compact = extractCompactFlag(seg);
   }
diff --git a/src/main/java/org/apache/datasketches/hll/HllArray.java 
b/src/main/java/org/apache/datasketches/hll/HllArray.java
index 20e5df764..ba86cb1bc 100644
--- a/src/main/java/org/apache/datasketches/hll/HllArray.java
+++ b/src/main/java/org/apache/datasketches/hll/HllArray.java
@@ -197,7 +197,7 @@ abstract class HllArray extends AbstractHllArray {
   }
 
   @Override
-  void putEmptyFlag(final boolean empty) { }
+  void putEmptyFlag(final boolean empty) { /* meaningless for HllArray classes 
*/ }
 
   @Override
   void putHipAccum(final double value) {
diff --git a/src/main/java/org/apache/datasketches/hllmap/Map.java 
b/src/main/java/org/apache/datasketches/hllmap/Map.java
index 8ff00f386..df730e3d4 100644
--- a/src/main/java/org/apache/datasketches/hllmap/Map.java
+++ b/src/main/java/org/apache/datasketches/hllmap/Map.java
@@ -84,7 +84,7 @@ abstract class Map {
    * @param index the given index
    * @param estimate the given estimate
    */
-  void updateEstimate(final int index, final double estimate) {}
+  void updateEstimate(final int index, final double estimate) { /* overridden 
by sub-classes */ }
 
   /**
    * Returns the upper bound cardinality with respect to {@link 
#getEstimate(byte[])} associated
@@ -136,7 +136,7 @@ abstract class Map {
    * Delete the key at the given index
    * @param index the given index
    */
-  void deleteKey(final int index) {}
+  void deleteKey(final int index) { /* overridden by sub-classes */ }
 
   /**
    * Returns <code>true</code> if the two specified sub-arrays of bytes are 
<i>equal</i> to one another.
@@ -184,7 +184,7 @@ abstract class Map {
   }
 
   static final int getStride(final long hash, final int tableEntries) {
-    return (int) ((hash >>> 1) % (tableEntries - 2L) + 1L);
+    return (int) (((hash >>> 1) % (tableEntries - 2L)) + 1L);
   }
 
   static boolean isBitSet(final byte[] byteArr, final int bitIndex) {
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java 
b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 874d06cdc..aa7dd5e40 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -321,7 +321,7 @@ public abstract class KllDoublesSketch extends KllSketch 
implements QuantilesDou
       assert seg != null;
       sketch = KllDoublesSketch.heapify(getMemorySegment());
     }
-    return KllHelper.toStringImpl(sketch, withLevels, withLevelsAndItems, 
getSerDe());
+    return KllHelper.toStringImpl(sketch, withLevels, withLevelsAndItems);
   }
 
   //SINGLE UPDATE
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java 
b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 5a4e5edc7..cdfafcbbb 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -321,7 +321,7 @@ public abstract class KllFloatsSketch extends KllSketch 
implements QuantilesFloa
       assert seg != null;
       sketch = KllFloatsSketch.heapify(getMemorySegment());
     }
-    return KllHelper.toStringImpl(sketch, withLevels, withLevelsAndItems, 
getSerDe());
+    return KllHelper.toStringImpl(sketch, withLevels, withLevelsAndItems);
   }
 
   //SINGLE UPDATE
diff --git 
a/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java 
b/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java
index ef4e4ec5a..ab50741c4 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapDoublesSketch.java
@@ -307,7 +307,7 @@ final class KllHeapDoublesSketch extends KllDoublesSketch {
   }
 
   @Override
-  void setMemorySegment(final MemorySegment wseg) { }
+  void setMemorySegment(final MemorySegment wseg) { /* heap does not have 
MemorySegment */ }
 
   @Override
   public boolean hasMemorySegment() {
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java 
b/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java
index 609bf8600..d14864969 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapFloatsSketch.java
@@ -307,7 +307,7 @@ final class KllHeapFloatsSketch extends KllFloatsSketch {
   }
 
   @Override
-  void setMemorySegment(final MemorySegment wseg) { }
+  void setMemorySegment(final MemorySegment wseg) { /* heap does not have 
MemorySegment */ }
 
   @Override
   public boolean hasMemorySegment() {
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapLongsSketch.java 
b/src/main/java/org/apache/datasketches/kll/KllHeapLongsSketch.java
index 5b2a42723..9eebe5e99 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapLongsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapLongsSketch.java
@@ -307,7 +307,7 @@ final class KllHeapLongsSketch extends KllLongsSketch {
   }
 
   @Override
-  void setMemorySegment(final MemorySegment wseg) { }
+  void setMemorySegment(final MemorySegment wseg) { /* heap does not have 
MemorySegment */ }
 
   @Override
   public boolean hasMemorySegment() {
diff --git a/src/main/java/org/apache/datasketches/kll/KllHelper.java 
b/src/main/java/org/apache/datasketches/kll/KllHelper.java
index 70e117f78..3d784972f 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHelper.java
@@ -48,7 +48,6 @@ import static 
org.apache.datasketches.quantilescommon.QuantilesAPI.UNSUPPORTED_M
 import java.lang.foreign.MemorySegment;
 import java.util.Arrays;
 
-import org.apache.datasketches.common.ArrayOfItemsSerDe;
 import org.apache.datasketches.common.MemorySegmentRequest;
 import org.apache.datasketches.common.positional.PositionalSegment;
 import org.apache.datasketches.kll.KllSketch.SketchStructure;
@@ -500,8 +499,7 @@ final class KllHelper {
     return bytesOut;
   }
 
-  static <T> String toStringImpl(final KllSketch sketch, final boolean 
withLevels, final boolean withLevelsAndItems,
-      final ArrayOfItemsSerDe<T> serDe) {
+  static String toStringImpl(final KllSketch sketch, final boolean withLevels, 
final boolean withLevelsAndItems) {
     final StringBuilder sb = new StringBuilder();
     final int k = sketch.getK();
     final int m = sketch.getM();
diff --git a/src/main/java/org/apache/datasketches/kll/KllItemsHelper.java 
b/src/main/java/org/apache/datasketches/kll/KllItemsHelper.java
index cdeff3fab..a066bf536 100644
--- a/src/main/java/org/apache/datasketches/kll/KllItemsHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllItemsHelper.java
@@ -485,7 +485,7 @@ final class KllItemsHelper {
       final int otherPop = KllHelper.currentLevelSizeItems(lvl, 
otherNumLevels, otherLevelsArr);
       worklevels[lvl + 1] = worklevels[lvl] + selfPop + otherPop;
       assert (selfPop >= 0) && (otherPop >= 0);
-      if ((selfPop == 0) && (otherPop == 0)) { }
+      if ((selfPop == 0) && (otherPop == 0)) { /* do nothing for this case */ }
       else if ((selfPop > 0) && (otherPop == 0)) {
         System.arraycopy(myCurItemsArr, myCurLevelsArr[lvl], workbuf, 
worklevels[lvl], selfPop);
       }
diff --git a/src/main/java/org/apache/datasketches/kll/KllItemsSketch.java 
b/src/main/java/org/apache/datasketches/kll/KllItemsSketch.java
index e12240278..305030110 100644
--- a/src/main/java/org/apache/datasketches/kll/KllItemsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllItemsSketch.java
@@ -302,7 +302,7 @@ public abstract class KllItemsSketch<T> extends KllSketch 
implements QuantilesGe
       assert seg != null;
       sketch = KllItemsSketch.heapify(getMemorySegment(), comparator, serDe);
     }
-    return KllHelper.toStringImpl(sketch, withLevels, withLevelsAndItems, 
getSerDe());
+    return KllHelper.toStringImpl(sketch, withLevels, withLevelsAndItems);
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/kll/KllLongsSketch.java 
b/src/main/java/org/apache/datasketches/kll/KllLongsSketch.java
index 4f69ca12d..f0c54d2b2 100644
--- a/src/main/java/org/apache/datasketches/kll/KllLongsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllLongsSketch.java
@@ -321,7 +321,7 @@ public abstract class KllLongsSketch extends KllSketch 
implements QuantilesLongs
       assert seg != null;
       sketch = KllLongsSketch.heapify(getMemorySegment());
     }
-    return KllHelper.toStringImpl(sketch, withLevels, withLevelsAndItems, 
getSerDe());
+    return KllHelper.toStringImpl(sketch, withLevels, withLevelsAndItems);
   }
 
   //SINGLE UPDATE
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java 
b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index 9d39b0fa1..0e22c0195 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -135,7 +135,7 @@ import org.apache.datasketches.kll.KllSketch.SketchType;
  *
  *  @author Lee Rhodes
  */
-final class KllPreambleUtil<T> {
+final class KllPreambleUtil {
 
   private KllPreambleUtil() {}
 
diff --git a/src/main/java/org/apache/datasketches/quantiles/ClassicUtil.java 
b/src/main/java/org/apache/datasketches/quantiles/ClassicUtil.java
index 12bd47948..4e49a7dbb 100644
--- a/src/main/java/org/apache/datasketches/quantiles/ClassicUtil.java
+++ b/src/main/java/org/apache/datasketches/quantiles/ClassicUtil.java
@@ -98,6 +98,21 @@ public final class ClassicUtil {
     return max(MIN_K, min(MAX_K, k));
   }
 
+  /**
+   * Computes the new size of a growing base buffer.
+   * It doubles whatever the current size is until it reaches 2 * k items.
+   * This assumes all items are the same size and the combinedBuffer has no 
levels above the base buffer.
+   * @param k the given k of the sketch
+   * @param curCombinedBufCap the current capacity of the combined buffer in 
items.
+   * @return the new size of the base buffer in items.
+   */
+  static int computeGrowingBaseBufferCap(final int k, final int 
curCombinedBufCap) {
+    if (curCombinedBufCap < (2 * k)) {
+      return 2 * Math.max(Math.min(k, curCombinedBufCap), MIN_K);
+    } 
+    return 2 * k;
+  }
+
   /**
    * Used by Classic Quantiles.
    * Checks the validity of the given k
@@ -167,17 +182,16 @@ public final class ClassicUtil {
 
   /**
    * Used by Classic Quantiles.
-   * Checks just the flags field of an input MemorySegment object. Returns 
true for a compact
+   * Checks just the flags field of an input MemorySegment object. Returns 
true for a compact or readOnly
    * sketch, false for an update sketch. Does not perform additional checks, 
including sketch
    * family.
    * @param srcSeg the source MemorySegment containing a sketch
    * @return true if flags indicate a compact sketch, otherwise false
    */
   static boolean checkIsMemorySegmentCompact(final MemorySegment srcSeg) {
-    // only reading so downcast is ok
     final int flags = extractFlags(srcSeg);
-    final int compactFlags = READ_ONLY_FLAG_MASK | COMPACT_FLAG_MASK;
-    return (flags & compactFlags) > 0;
+    final int compactFlags = COMPACT_FLAG_MASK;
+    return ((flags & compactFlags) > 0);
   }
 
   /**
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/CompactDoublesSketch.java 
b/src/main/java/org/apache/datasketches/quantiles/CompactDoublesSketch.java
index 18e05d315..40d0fc2cd 100644
--- a/src/main/java/org/apache/datasketches/quantiles/CompactDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/quantiles/CompactDoublesSketch.java
@@ -50,4 +50,9 @@ public abstract class CompactDoublesSketch extends 
DoublesSketch {
     throw new SketchesStateException("Cannot update a compact sketch, which is 
read-only.");
   }
 
+  @Override
+  void setReadOnly() {
+    //No-op: A Compact Sketch is already read-only.
+  }
+
 }
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DirectCompactDoublesSketch.java
 
b/src/main/java/org/apache/datasketches/quantiles/DirectCompactDoublesSketch.java
index 9338a0c68..c50b13c00 100644
--- 
a/src/main/java/org/apache/datasketches/quantiles/DirectCompactDoublesSketch.java
+++ 
b/src/main/java/org/apache/datasketches/quantiles/DirectCompactDoublesSketch.java
@@ -95,7 +95,7 @@ final class DirectCompactDoublesSketch extends 
CompactDoublesSketch {
     insertFamilyID(dstSeg, Family.QUANTILES.getID());
     insertK(dstSeg, k);
 
-    final int flags = COMPACT_FLAG_MASK | READ_ONLY_FLAG_MASK; // true for all 
compact sketches
+    final int flags = COMPACT_FLAG_MASK | READ_ONLY_FLAG_MASK; // both true 
for all compact sketches
 
     if (sketch.isEmpty()) {
       insertFlags(dstSeg, flags | EMPTY_FLAG_MASK);
@@ -107,7 +107,7 @@ final class DirectCompactDoublesSketch extends 
CompactDoublesSketch {
 
       final int bbCount = computeBaseBufferItems(k, n);
 
-      final DoublesSketchAccessor inputAccessor = 
DoublesSketchAccessor.wrap(sketch);
+      final DoublesSketchAccessor inputAccessor = 
DoublesSketchAccessor.wrap(sketch, false);
       assert bbCount == inputAccessor.numItems();
 
       long dstSegOffset = COMBINED_BUFFER;
@@ -153,13 +153,13 @@ final class DirectCompactDoublesSketch extends 
CompactDoublesSketch {
     final long n = empty ? 0 : extractN(srcSeg);
 
     //VALIDITY CHECKS
-    DirectUpdateDoublesSketchR.checkPreLongs(preLongs);
+    DirectUpdateDoublesSketch.checkPreLongs(preLongs);
     checkFamilyID(familyID);
     DoublesUtil.checkDoublesSerVer(serVer, MIN_DIRECT_DOUBLES_SER_VER);
     checkCompact(serVer, flags);
     checkK(k);
     checkDirectSegCapacity(k, n, segCap);
-    DirectUpdateDoublesSketchR.checkEmptyAndN(empty, n);
+    DirectUpdateDoublesSketch.checkEmptyAndN(empty, n);
 
     final DirectCompactDoublesSketch dds = new DirectCompactDoublesSketch(k);
     dds.seg_ = srcSeg;
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DirectDoublesSketchAccessor.java
 
b/src/main/java/org/apache/datasketches/quantiles/DirectDoublesSketchAccessor.java
index 86c3aeadb..dd66e6466 100644
--- 
a/src/main/java/org/apache/datasketches/quantiles/DirectDoublesSketchAccessor.java
+++ 
b/src/main/java/org/apache/datasketches/quantiles/DirectDoublesSketchAccessor.java
@@ -46,8 +46,8 @@ final class DirectDoublesSketchAccessor extends 
DoublesSketchAccessor {
     assert (index >= 0) && (index < numItems_);
     assert n_ == ds_.getN();
 
-    final int idxOffset = offset_ + (index << 3);
-    return ds_.getMemorySegment().get(JAVA_DOUBLE_UNALIGNED, idxOffset);
+    final int byteOffset = offset_ + (index << 3);
+    return ds_.getMemorySegment().get(JAVA_DOUBLE_UNALIGNED, byteOffset);
   }
 
   @Override
@@ -56,27 +56,26 @@ final class DirectDoublesSketchAccessor extends 
DoublesSketchAccessor {
     assert n_ == ds_.getN();
     assert !ds_.isCompact(); // can't write to a compact sketch
 
-    final int idxOffset = offset_ + (index << 3);
+    final int byteOffset = offset_ + (index << 3);
     final MemorySegment seg = ds_.getMemorySegment();
-    final double oldVal = seg.get(JAVA_DOUBLE_UNALIGNED, idxOffset);
-    seg.set(JAVA_DOUBLE_UNALIGNED, idxOffset, quantile);
+    final double oldVal = seg.get(JAVA_DOUBLE_UNALIGNED, byteOffset);
+    seg.set(JAVA_DOUBLE_UNALIGNED, byteOffset, quantile);
     return oldVal;
   }
 
   @Override
   double[] getArray(final int fromIdx, final int numItems) {
-    final double[] dstArray = new double[numItems];
-    final int offsetBytes = offset_ + (fromIdx << 3);
-    MemorySegment.copy(ds_.getMemorySegment(), JAVA_DOUBLE_UNALIGNED, 
offsetBytes, dstArray, 0, numItems);
-    return dstArray;
+    final int byteOffset = offset_ + (fromIdx << 3);
+    final MemorySegment seg = ds_.getMemorySegment();
+    return seg.asSlice(byteOffset, numItems << 
3).toArray(JAVA_DOUBLE_UNALIGNED);
   }
 
   @Override
-  void putArray(final double[] srcArray, final int srcIndex,
-                final int dstIndex, final int numItems) {
+  void putArray(final double[] srcArray, final int srcIndex, final int 
dstIndex, final int numItems) {
     assert !ds_.isCompact(); // can't write to compact sketch
-    final int offsetBytes = offset_ + (dstIndex << 3);
-    MemorySegment.copy(srcArray, srcIndex, ds_.getMemorySegment(), 
JAVA_DOUBLE_UNALIGNED, offsetBytes, numItems);
+
+    final int byteOffset = offset_ + (dstIndex << 3);
+    MemorySegment.copy(srcArray, srcIndex, ds_.getMemorySegment(), 
JAVA_DOUBLE_UNALIGNED, byteOffset, numItems);
   }
 
   @Override
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketch.java
 
b/src/main/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketch.java
index 4af183bc3..00117cb37 100644
--- 
a/src/main/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketch.java
+++ 
b/src/main/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketch.java
@@ -26,12 +26,16 @@ import static 
org.apache.datasketches.quantiles.ClassicUtil.DOUBLES_SER_VER;
 import static org.apache.datasketches.quantiles.ClassicUtil.checkFamilyID;
 import static org.apache.datasketches.quantiles.ClassicUtil.checkK;
 import static org.apache.datasketches.quantiles.ClassicUtil.computeBitPattern;
+import static org.apache.datasketches.quantiles.DoublesUtil.checkDoublesSerVer;
 import static org.apache.datasketches.quantiles.PreambleUtil.COMBINED_BUFFER;
+import static org.apache.datasketches.quantiles.PreambleUtil.COMPACT_FLAG_MASK;
 import static org.apache.datasketches.quantiles.PreambleUtil.EMPTY_FLAG_MASK;
 import static org.apache.datasketches.quantiles.PreambleUtil.FLAGS_BYTE;
 import static org.apache.datasketches.quantiles.PreambleUtil.MAX_DOUBLE;
 import static org.apache.datasketches.quantiles.PreambleUtil.MIN_DOUBLE;
 import static org.apache.datasketches.quantiles.PreambleUtil.N_LONG;
+import static org.apache.datasketches.quantiles.PreambleUtil.ORDERED_FLAG_MASK;
+import static 
org.apache.datasketches.quantiles.PreambleUtil.READ_ONLY_FLAG_MASK;
 import static org.apache.datasketches.quantiles.PreambleUtil.extractFamilyID;
 import static org.apache.datasketches.quantiles.PreambleUtil.extractFlags;
 import static org.apache.datasketches.quantiles.PreambleUtil.extractK;
@@ -51,25 +55,31 @@ import java.lang.foreign.MemorySegment;
 
 import org.apache.datasketches.common.Family;
 import org.apache.datasketches.common.MemorySegmentRequest;
+import org.apache.datasketches.common.MemorySegmentStatus;
+import org.apache.datasketches.common.SketchesArgumentException;
+import org.apache.datasketches.common.SketchesReadOnlyException;
+import org.apache.datasketches.quantilescommon.QuantilesAPI;
 
 /**
- * Implements the DoublesSketch off-heap.
+ * Implements the DoublesSketch in a MemorySegment.
  *
  * @author Kevin Lang
  * @author Lee Rhodes
- *
  */
-final class DirectUpdateDoublesSketch extends DirectUpdateDoublesSketchR {
-  private MemorySegmentRequest mSegReq = null;
+final class DirectUpdateDoublesSketch extends UpdateDoublesSketch {
+  private static final int MIN_DIRECT_DOUBLES_SER_VER = 3;
+  private MemorySegmentRequest mSegReq_ = null;
+  private MemorySegment seg_;
 
   //**CONSTRUCTORS**
   private DirectUpdateDoublesSketch(final int k, final MemorySegment seg, 
final MemorySegmentRequest mSegReq) {
-    super(k, seg); //Checks k
-    this.mSegReq = mSegReq;
+    super(k); //Checks k
+    mSegReq_ = mSegReq;
+    seg_ = seg;
   }
 
   /**
-   * Creates a new Direct instance of a DoublesSketch, which may be off-heap.
+   * Creates a new instance of a DoublesSketch in a MemorySegment.
    *
    * @param k Parameter that controls space usage of sketch and accuracy of 
estimates.
    * Must be greater than 1 and less than 65536 and a power of 2.
@@ -106,9 +116,11 @@ final class DirectUpdateDoublesSketch extends 
DirectUpdateDoublesSketchR {
   }
 
   /**
-   * Wrap this sketch around the given non-compact MemorySegment image of a 
DoublesSketch.
+   * Wrap this sketch around the given updatable MemorySegment image of a 
DoublesSketch.
    *
    * @param srcSeg the given non-compact MemorySegment image of a 
DoublesSketch that may have data
+   * @param mSegReq the MemorySegmentRequest used as a callback for more space 
if required.
+   * If it is null, the default MemorySegmentRequest will be used.
    * @return a sketch that wraps the given srcSeg
    */
   static DirectUpdateDoublesSketch wrapInstance(final MemorySegment srcSeg, 
final MemorySegmentRequest mSegReq) {
@@ -126,7 +138,7 @@ final class DirectUpdateDoublesSketch extends 
DirectUpdateDoublesSketchR {
     //VALIDITY CHECKS
     checkPreLongs(preLongs);
     checkFamilyID(familyID);
-    DoublesUtil.checkDoublesSerVer(serVer, MIN_DIRECT_DOUBLES_SER_VER);
+    checkDoublesSerVer(serVer, MIN_DIRECT_DOUBLES_SER_VER);
     checkDirectFlags(flags); //Cannot be compact
     checkK(k);
     checkCompact(serVer, flags);
@@ -138,22 +150,54 @@ final class DirectUpdateDoublesSketch extends 
DirectUpdateDoublesSketchR {
 
   //**END CONSTRUCTORS**
 
+  @Override
+  public double getMaxItem() {
+    if (isEmpty()) { throw new 
IllegalArgumentException(QuantilesAPI.EMPTY_MSG); }
+    return seg_.get(JAVA_DOUBLE_UNALIGNED, MAX_DOUBLE);
+  }
+
+  @Override
+  public double getMinItem() {
+    if (isEmpty()) { throw new 
IllegalArgumentException(QuantilesAPI.EMPTY_MSG); }
+    return seg_.get(JAVA_DOUBLE_UNALIGNED, MIN_DOUBLE);
+  }
+
+  @Override
+  public long getN() {
+    return (seg_.byteSize() < COMBINED_BUFFER) ? 0 : 
seg_.get(JAVA_LONG_UNALIGNED, N_LONG);
+  }
+
+  @Override
+  public boolean hasMemorySegment() {
+    return (seg_ != null);
+  }
+
+  @Override
+  public boolean isOffHeap() {
+    return (seg_ != null) ? seg_.isNative() : false;
+  }
+
   @Override
   public boolean isReadOnly() {
-    return false;
+    return seg_.isReadOnly();
+  }
+
+  @Override
+  public boolean isSameResource(final MemorySegment that) {
+    return MemorySegmentStatus.isSameResource(seg_, that);
   }
 
   @Override
   public void update(final double dataItem) {
     if (Double.isNaN(dataItem)) { return; }
-
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
     final int curBBCount = getBaseBufferCount();
     final int newBBCount = curBBCount + 1; //derived, not stored
 
     //must check MemorySegment capacity before we put anything in it
     final int combBufItemCap = getCombinedBufferItemCapacity();
-    if (newBBCount > combBufItemCap) {
-      //only changes combinedBuffer when it is only a base buffer
+    if (newBBCount > combBufItemCap) { //newBBCount can never exceed 2 * k.
+      //unlike the heap sketch, this will grow the base buffer immediately to 
full size.
       seg_ = growCombinedSegBuffer(2 * getK());
     }
 
@@ -206,6 +250,7 @@ final class DirectUpdateDoublesSketch extends 
DirectUpdateDoublesSketchR {
 
   @Override
   public void reset() {
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
     if (seg_.byteSize() >= COMBINED_BUFFER) {
       seg_.set(JAVA_BYTE, FLAGS_BYTE, (byte) EMPTY_FLAG_MASK); //not compact, 
not ordered
       seg_.set(JAVA_LONG_UNALIGNED, N_LONG, 0L);
@@ -216,6 +261,44 @@ final class DirectUpdateDoublesSketch extends 
DirectUpdateDoublesSketchR {
 
   //Restricted overrides
 
+  @Override
+  int getBaseBufferCount() {
+    return ClassicUtil.computeBaseBufferItems(getK(), getN());
+  }
+
+  @Override
+  long getBitPattern() {
+    final int k = getK();
+    final long n = getN();
+    return ClassicUtil.computeBitPattern(k, n);
+  }
+
+  @Override
+  double[] getCombinedBuffer() {
+    final int k = getK();
+    if (isEmpty()) { return new double[k << 1]; } //2K
+    final long n = getN();
+    final int itemCap = ClassicUtil.computeCombinedBufferItemCapacity(k, n);
+    final double[] combinedBuffer = new double[itemCap];
+    MemorySegment.copy(seg_, JAVA_DOUBLE_UNALIGNED, COMBINED_BUFFER, 
combinedBuffer, 0, itemCap);
+    return combinedBuffer;
+  }
+
+  @Override
+  int getCombinedBufferItemCapacity() {
+    return Math.max(0, (int)seg_.byteSize() - COMBINED_BUFFER) / Double.BYTES;
+  }
+
+  @Override
+  MemorySegment getMemorySegment() {
+    return seg_;
+  }
+
+  @Override
+  void setReadOnly() {
+    seg_ = seg_.asReadOnly();
+  }
+
   @Override
   UpdateDoublesSketch getSketchAndReset() {
     final HeapUpdateDoublesSketch skCopy = heapify(this);
@@ -225,6 +308,7 @@ final class DirectUpdateDoublesSketch extends 
DirectUpdateDoublesSketchR {
 
   @Override
   double[] growCombinedBuffer(final int curCombBufItemCap, final int 
itemSpaceNeeded) {
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
     seg_ = growCombinedSegBuffer(itemSpaceNeeded);
     // copy out any data that was there
     final double[] newCombBuf = new double[itemSpaceNeeded];
@@ -236,35 +320,39 @@ final class DirectUpdateDoublesSketch extends 
DirectUpdateDoublesSketchR {
 
   @Override
   void putMinItem(final double minQuantile) {
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
     assert (seg_.byteSize() >= COMBINED_BUFFER);
     seg_.set(JAVA_DOUBLE_UNALIGNED, MIN_DOUBLE, minQuantile);
   }
 
   @Override
   void putMaxItem(final double maxQuantile) {
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
     assert (seg_.byteSize() >= COMBINED_BUFFER);
     seg_.set(JAVA_DOUBLE_UNALIGNED, MAX_DOUBLE, maxQuantile);
   }
 
   @Override
   void putN(final long n) {
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
     assert (seg_.byteSize() >= COMBINED_BUFFER);
     seg_.set(JAVA_LONG_UNALIGNED, N_LONG, n);
   }
 
   @Override
   void putCombinedBuffer(final double[] combinedBuffer) {
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
     MemorySegment.copy(combinedBuffer, 0, seg_, JAVA_DOUBLE_UNALIGNED, 
COMBINED_BUFFER, combinedBuffer.length);
   }
 
   @Override
   void putBaseBufferCount(final int baseBufferCount) {
-    //intentionally a no-op, not kept on-heap, always derived.
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
   }
 
   @Override
   void putBitPattern(final long bitPattern) {
-    //intentionally a no-op, not kept on-heap, always derived.
+    if (seg_.isReadOnly()) { throw new SketchesReadOnlyException("This sketch 
is read only."); }
   }
 
   //Direct supporting methods
@@ -274,11 +362,60 @@ final class DirectUpdateDoublesSketch extends 
DirectUpdateDoublesSketchR {
     final int needBytes = (itemSpaceNeeded << 3) + COMBINED_BUFFER; //+ 
preamble + min & max
     assert needBytes > segBytes;
 
-    mSegReq = (mSegReq == null) ? MemorySegmentRequest.DEFAULT : mSegReq;
+    mSegReq_ = (mSegReq_ == null) ? MemorySegmentRequest.DEFAULT : mSegReq_;
 
-    final MemorySegment newSeg = mSegReq.request(seg_, needBytes);
+    final MemorySegment newSeg = mSegReq_.request(seg_, needBytes);
     MemorySegment.copy(seg_, 0, newSeg, 0, segBytes);
-    mSegReq.requestClose(seg_);
+    mSegReq_.requestClose(seg_);
     return newSeg;
   }
+
+  //Checks
+
+  /**
+   * Checks the validity of the direct MemorySegment capacity assuming n, k.
+   * @param k the given k
+   * @param n the given n
+   * @param segCapBytes the current MemorySegment capacity in bytes
+   */
+  static void checkDirectSegCapacity(final int k, final long n, final long 
segCapBytes) {
+    final int reqBufBytes = getUpdatableStorageBytes(k, n);
+
+    if (segCapBytes < reqBufBytes) {
+      throw new SketchesArgumentException("Possible corruption: MemorySegment 
capacity too small: "
+          + segCapBytes + " < " + reqBufBytes);
+    }
+  }
+
+  static void checkCompact(final int serVer, final int flags) {
+    final boolean compact = (serVer == 2) || ((flags & COMPACT_FLAG_MASK) > 0);
+    if (compact) {
+      throw new SketchesArgumentException("Compact MemorySegment is not 
supported for Wrap Instance.");
+    }
+  }
+
+  static void checkPreLongs(final int preLongs) {
+    if ((preLongs < 1) || (preLongs > 2)) {
+      throw new SketchesArgumentException(
+          "Possible corruption: PreLongs must be 1 or 2: " + preLongs);
+    }
+  }
+
+  static void checkDirectFlags(final int flags) {
+    final int allowedFlags = //Cannot be compact!
+        READ_ONLY_FLAG_MASK | EMPTY_FLAG_MASK | ORDERED_FLAG_MASK;
+    final int flagsMask = ~allowedFlags;
+    if ((flags & flagsMask) > 0) {
+      throw new SketchesArgumentException(
+         "Possible corruption: Invalid flags field: Cannot be compact! "
+             + Integer.toBinaryString(flags));
+    }
+  }
+
+  static void checkEmptyAndN(final boolean empty, final long n) {
+    if (empty && (n > 0)) {
+      throw new SketchesArgumentException(
+          "Possible corruption: Empty Flag = true and N > 0: " + n);
+    }
+  }
 }
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketchR.java
 
b/src/main/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketchR.java
deleted file mode 100644
index f673d38ab..000000000
--- 
a/src/main/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketchR.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.quantiles;
-
-import static java.lang.foreign.ValueLayout.JAVA_DOUBLE_UNALIGNED;
-import static java.lang.foreign.ValueLayout.JAVA_LONG_UNALIGNED;
-import static org.apache.datasketches.quantiles.PreambleUtil.COMBINED_BUFFER;
-import static org.apache.datasketches.quantiles.PreambleUtil.COMPACT_FLAG_MASK;
-import static org.apache.datasketches.quantiles.PreambleUtil.EMPTY_FLAG_MASK;
-import static org.apache.datasketches.quantiles.PreambleUtil.MAX_DOUBLE;
-import static org.apache.datasketches.quantiles.PreambleUtil.MIN_DOUBLE;
-import static org.apache.datasketches.quantiles.PreambleUtil.N_LONG;
-import static org.apache.datasketches.quantiles.PreambleUtil.ORDERED_FLAG_MASK;
-import static 
org.apache.datasketches.quantiles.PreambleUtil.READ_ONLY_FLAG_MASK;
-import static org.apache.datasketches.quantiles.PreambleUtil.extractFamilyID;
-import static org.apache.datasketches.quantiles.PreambleUtil.extractFlags;
-import static org.apache.datasketches.quantiles.PreambleUtil.extractK;
-import static org.apache.datasketches.quantiles.PreambleUtil.extractN;
-import static org.apache.datasketches.quantiles.PreambleUtil.extractPreLongs;
-import static org.apache.datasketches.quantiles.PreambleUtil.extractSerVer;
-
-import java.lang.foreign.MemorySegment;
-
-import org.apache.datasketches.common.MemorySegmentStatus;
-import org.apache.datasketches.common.SketchesArgumentException;
-import org.apache.datasketches.common.SketchesReadOnlyException;
-import org.apache.datasketches.quantilescommon.QuantilesAPI;
-
-/**
- * Implements the DoublesSketch off-heap.
- *
- * @author Kevin Lang
- * @author Lee Rhodes
- *
- */
-class DirectUpdateDoublesSketchR extends UpdateDoublesSketch {
-  static final int MIN_DIRECT_DOUBLES_SER_VER = 3;
-  MemorySegment seg_;
-
-  //**CONSTRUCTORS**********************************************************
-  DirectUpdateDoublesSketchR(final int k, final MemorySegment seg) {
-    super(k); //Checks k
-    seg_ = seg;
-  }
-
-  /**
-   * Wrap this sketch around the given non-compact MemorySegment image of a 
DoublesSketch.
-   *
-   * @param srcSeg the given non-compact MemorySegment image of a 
DoublesSketch that may have data
-   * @return a sketch that wraps the given srcSeg
-   */
-  static DirectUpdateDoublesSketchR wrapInstance(final MemorySegment srcSeg) {
-    final long segCap = srcSeg.byteSize();
-
-    final int preLongs = extractPreLongs(srcSeg);
-    final int serVer = extractSerVer(srcSeg);
-    final int familyID = extractFamilyID(srcSeg);
-    final int flags = extractFlags(srcSeg);
-    final int k = extractK(srcSeg);
-
-    final boolean empty = (flags & EMPTY_FLAG_MASK) > 0; //Preamble flags 
empty state
-    final long n = empty ? 0 : extractN(srcSeg);
-
-    //VALIDITY CHECKS
-    checkPreLongs(preLongs);
-    ClassicUtil.checkFamilyID(familyID);
-    DoublesUtil.checkDoublesSerVer(serVer, MIN_DIRECT_DOUBLES_SER_VER);
-    checkDirectFlags(flags); //Cannot be compact
-    ClassicUtil.checkK(k);
-    checkCompact(serVer, flags);
-    checkDirectSegCapacity(k, n, segCap);
-    checkEmptyAndN(empty, n);
-
-    return new DirectUpdateDoublesSketchR(k, srcSeg);
-  }
-
-  @Override
-  public double getMaxItem() {
-    if (isEmpty()) { throw new 
IllegalArgumentException(QuantilesAPI.EMPTY_MSG); }
-    return seg_.get(JAVA_DOUBLE_UNALIGNED, MAX_DOUBLE);
-  }
-
-  @Override
-  public double getMinItem() {
-    if (isEmpty()) { throw new 
IllegalArgumentException(QuantilesAPI.EMPTY_MSG); }
-    return seg_.get(JAVA_DOUBLE_UNALIGNED, MIN_DOUBLE);
-  }
-
-  @Override
-  public long getN() {
-    return (seg_.byteSize() < COMBINED_BUFFER) ? 0 : 
seg_.get(JAVA_LONG_UNALIGNED, N_LONG);
-  }
-
-  @Override
-  public boolean hasMemorySegment() {
-    return (seg_ != null);
-  }
-
-  @Override
-  public boolean isOffHeap() {
-    return (seg_ != null) ? seg_.isNative() : false;
-  }
-
-  @Override
-  public boolean isReadOnly() {
-    return true;
-  }
-
-  @Override
-  public boolean isSameResource(final MemorySegment that) {
-    return MemorySegmentStatus.isSameResource(seg_, that);
-  }
-
-  @Override
-  public void reset() {
-    throw new SketchesReadOnlyException("Call to reset() on read-only sketch");
-  }
-
-  @Override
-  public void update(final double dataItem) {
-    throw new SketchesReadOnlyException("Call to update() on read-only 
sketch");
-  }
-
-  //Restricted overrides
-  //Gets
-
-  @Override
-  int getBaseBufferCount() {
-    return ClassicUtil.computeBaseBufferItems(getK(), getN());
-  }
-
-  @Override
-  long getBitPattern() {
-    final int k = getK();
-    final long n = getN();
-    return ClassicUtil.computeBitPattern(k, n);
-  }
-
-  @Override
-  double[] getCombinedBuffer() {
-    final int k = getK();
-    if (isEmpty()) { return new double[k << 1]; } //2K
-    final long n = getN();
-    final int itemCap = ClassicUtil.computeCombinedBufferItemCapacity(k, n);
-    final double[] combinedBuffer = new double[itemCap];
-    MemorySegment.copy(seg_, JAVA_DOUBLE_UNALIGNED, COMBINED_BUFFER, 
combinedBuffer, 0, itemCap);
-    return combinedBuffer;
-  }
-
-  @Override
-  int getCombinedBufferItemCapacity() {
-    return Math.max(0, (int)seg_.byteSize() - COMBINED_BUFFER) / 8;
-  }
-
-  @Override
-  MemorySegment getMemorySegment() {
-    return seg_;
-  }
-
-  @Override
-  UpdateDoublesSketch getSketchAndReset() {
-    throw new SketchesReadOnlyException("Call to getSketchAndReset() on 
read-only sketch");
-  }
-
-  @Override
-  double[] growCombinedBuffer(final int curCombBufItemCap, final int 
itemSpaceNeeded) {
-    throw new SketchesReadOnlyException("Call to growCombinedBuffer() on 
read-only sketch");
-  }
-
-  //Puts
-
-  @Override
-  void putMinItem(final double minQuantile) {
-    throw new SketchesReadOnlyException("Call to putMinItem() on read-only 
sketch");
-  }
-
-  @Override
-  void putMaxItem(final double maxQuantile) {
-    throw new SketchesReadOnlyException("Call to putMaxItem() on read-only 
sketch");
-  }
-
-  @Override
-  void putN(final long n) {
-    throw new SketchesReadOnlyException("Call to putN() on read-only sketch");
-  }
-
-  @Override
-  void putCombinedBuffer(final double[] combinedBuffer) {
-    throw new SketchesReadOnlyException("Call to putCombinedBuffer() on 
read-only sketch");
-  }
-
-  @Override
-  void putBaseBufferCount(final int baseBufferCount) {
-    throw new SketchesReadOnlyException("Call to putBaseBufferCount() on 
read-only sketch");
-  }
-
-  @Override
-  void putBitPattern(final long bitPattern) {
-    throw new SketchesReadOnlyException("Call to putBitPattern() on read-only 
sketch");
-  }
-
-  //Checks
-
-  /**
-   * Checks the validity of the direct MemorySegment capacity assuming n, k.
-   * @param k the given k
-   * @param n the given n
-   * @param segCapBytes the current MemorySegment capacity in bytes
-   */
-  static void checkDirectSegCapacity(final int k, final long n, final long 
segCapBytes) {
-    final int reqBufBytes = getUpdatableStorageBytes(k, n);
-
-    if (segCapBytes < reqBufBytes) {
-      throw new SketchesArgumentException("Possible corruption: MemorySegment 
capacity too small: "
-          + segCapBytes + " < " + reqBufBytes);
-    }
-  }
-
-  static void checkCompact(final int serVer, final int flags) {
-    final boolean compact = (serVer == 2) || ((flags & COMPACT_FLAG_MASK) > 0);
-    if (compact) {
-      throw new SketchesArgumentException("Compact MemorySegment is not 
supported for Wrap Instance.");
-    }
-  }
-
-  static void checkPreLongs(final int preLongs) {
-    if ((preLongs < 1) || (preLongs > 2)) {
-      throw new SketchesArgumentException(
-          "Possible corruption: PreLongs must be 1 or 2: " + preLongs);
-    }
-  }
-
-  static void checkDirectFlags(final int flags) {
-    final int allowedFlags = //Cannot be compact!
-        READ_ONLY_FLAG_MASK | EMPTY_FLAG_MASK | ORDERED_FLAG_MASK;
-    final int flagsMask = ~allowedFlags;
-    if ((flags & flagsMask) > 0) {
-      throw new SketchesArgumentException(
-         "Possible corruption: Invalid flags field: Cannot be compact! "
-             + Integer.toBinaryString(flags));
-    }
-  }
-
-  static void checkEmptyAndN(final boolean empty, final long n) {
-    if (empty && (n > 0)) {
-      throw new SketchesArgumentException(
-          "Possible corruption: Empty Flag = true and N > 0: " + n);
-    }
-  }
-
-}
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DoublesBufferAccessor.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesBufferAccessor.java
index 1014a1045..fecc96d56 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesBufferAccessor.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesBufferAccessor.java
@@ -20,6 +20,8 @@
 package org.apache.datasketches.quantiles;
 
 /**
+ * The hierarchy of Accessors enable easy access to the data structure of the 
Classic Quantiles sketches.
+ *
  * @author Jon Malkin
  */
 abstract class DoublesBufferAccessor {
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DoublesMergeImpl.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesMergeImpl.java
index 30cd6aeca..ab1747472 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesMergeImpl.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesMergeImpl.java
@@ -73,7 +73,7 @@ final class DoublesMergeImpl {
     }
     //The remainder of this code is for the case where the k's are equal
 
-    final DoublesSketchAccessor srcSketchBuf = DoublesSketchAccessor.wrap(src);
+    final DoublesSketchAccessor srcSketchBuf = DoublesSketchAccessor.wrap(src, 
false);
     final long nFinal = tgtN + srcN;
 
     for (int i = 0; i < srcSketchBuf.numItems(); i++) { // update only the 
base buffer
@@ -158,7 +158,7 @@ final class DoublesMergeImpl {
 
     if (src.isEmpty()) { return; }
 
-    final DoublesSketchAccessor srcSketchBuf = DoublesSketchAccessor.wrap(src);
+    final DoublesSketchAccessor srcSketchBuf = DoublesSketchAccessor.wrap(src, 
false);
     final long nFinal = tgtN + src.getN();
 
     for (int i = 0; i < srcSketchBuf.numItems(); i++) { // update only the 
base buffer
diff --git a/src/main/java/org/apache/datasketches/quantiles/DoublesSketch.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesSketch.java
index 8204370b6..05611c49c 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesSketch.java
@@ -36,6 +36,7 @@ import java.lang.foreign.MemorySegment;
 import java.util.Arrays;
 import java.util.Random;
 
+import org.apache.datasketches.common.MemorySegmentRequest;
 import org.apache.datasketches.common.MemorySegmentStatus;
 import org.apache.datasketches.common.SketchesArgumentException;
 import org.apache.datasketches.common.SketchesStateException;
@@ -150,18 +151,18 @@ public abstract class DoublesSketch implements 
QuantilesDoublesAPI, MemorySegmen
   }
 
   /**
-   * Wrap this sketch around the given MemorySegment image of a DoublesSketch, 
compact or updatable.
-   * A DirectUpdateDoublesSketch can only wrap an updatable array, and a
-   * DirectCompactDoublesSketch can only wrap a compact array.
+   * Wrap this sketch around the given updatable MemorySegment image of a 
DoublesSketch, compact or updatable.
    *
-   * @param srcSeg the given MemorySegment image of a DoublesSketch that may 
have data,
-   * @return a sketch that wraps the given srcSeg
+   * @param srcSeg the given MemorySegment image of a DoublesSketch that may 
have data
+   * @param mSegReq the MemorySegmentRequest used if the incoming 
MemorySegment is in updatable form and needs to expand.
+   * Otherwise, it can be null.
+   * @return a sketch that wraps the given srcSeg in read-only mode.
    */
-  public static DoublesSketch wrap(final MemorySegment srcSeg) {
+  public static DoublesSketch wrap(final MemorySegment srcSeg, final 
MemorySegmentRequest mSegReq) {
     if (checkIsMemorySegmentCompact(srcSeg)) {
       return DirectCompactDoublesSketch.wrapInstance(srcSeg);
     }
-    return DirectUpdateDoublesSketchR.wrapInstance(srcSeg);
+    return DirectUpdateDoublesSketch.wrapInstance(srcSeg, mSegReq);
   }
 
   @Override
@@ -466,8 +467,8 @@ public abstract class DoublesSketch implements 
QuantilesDoublesAPI, MemorySegmen
    *
    * @param dstSeg the given MemorySegment.
    */
-  public void putMemorySegment(final MemorySegment dstSeg) {
-    putMemorySegment(dstSeg, true);
+  public void putIntoMemorySegment(final MemorySegment dstSeg) {
+    putIntoMemorySegment(dstSeg, true);
   }
 
   /**
@@ -478,7 +479,7 @@ public abstract class DoublesSketch implements 
QuantilesDoublesAPI, MemorySegmen
    * @param compact if true, compacts and sorts the base buffer, which 
optimizes merge
    *                performance at the cost of slightly increased 
serialization time.
    */
-  public void putMemorySegment(final MemorySegment dstSeg, final boolean 
compact) {
+  public void putIntoMemorySegment(final MemorySegment dstSeg, final boolean 
compact) {
     if (hasMemorySegment() && (isCompact() == compact)) {
       final MemorySegment srcSeg = getMemorySegment();
       MemorySegment.copy(srcSeg, 0, dstSeg, 0, getSerializedSizeBytes());
@@ -546,8 +547,8 @@ public abstract class DoublesSketch implements 
QuantilesDoublesAPI, MemorySegmen
   abstract long getBitPattern();
 
   /**
-   * Returns the capacity for the combined base buffer
-   * @return the capacity for the combined base buffer
+   * Returns the capacity for the combined base buffer + levels
+   * @return the capacity for the combined base buffer + levels
    */
   abstract int getCombinedBufferItemCapacity();
 
@@ -563,6 +564,11 @@ public abstract class DoublesSketch implements 
QuantilesDoublesAPI, MemorySegmen
    */
   abstract MemorySegment getMemorySegment();
 
+  /**
+   * Sets the internal MemorySegment to Read Only.
+   */
+  abstract void setReadOnly();
+
   //************SORTED VIEW****************************
 
   @Override
@@ -580,7 +586,7 @@ public abstract class DoublesSketch implements 
QuantilesDoublesAPI, MemorySegmen
     final int numQuantiles = getNumRetained();
     final double[] svQuantiles = new double[numQuantiles];
     final long[] svCumWeights = new long[numQuantiles];
-    final DoublesSketchAccessor sketchAccessor = 
DoublesSketchAccessor.wrap(this);
+    final DoublesSketchAccessor sketchAccessor = 
DoublesSketchAccessor.wrap(this, false);
 
     // Populate from DoublesSketch:
     //  copy over the "levels" and then the base buffer, all with appropriate 
weights
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DoublesSketchAccessor.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesSketchAccessor.java
index a74bc628e..f4991d658 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesSketchAccessor.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesSketchAccessor.java
@@ -25,7 +25,7 @@ import org.apache.datasketches.common.Family;
 import org.apache.datasketches.common.SketchesArgumentException;
 
 /**
- * This allows access to package-private levels and data in whatever quantiles 
sketch you give
+ * This allows access to package-private levels and data in whatever doubles 
quantiles sketch you give
  * it: on-heap, off-heap; compact and non-compact
  * @author Jon Malkin
  */
@@ -38,7 +38,7 @@ abstract class DoublesSketchAccessor extends 
DoublesBufferAccessor {
   long n_;
   int currLvl_;
   int numItems_;
-  int offset_;
+  int offset_; //bytes for Direct, doubles for heap
 
   DoublesSketchAccessor(
     final DoublesSketch ds,
@@ -50,7 +50,7 @@ abstract class DoublesSketchAccessor extends 
DoublesBufferAccessor {
   }
 
   private DoublesSketchAccessor(
-      final boolean secure, //required part of Finalizer Attack prevention
+      @SuppressWarnings("unused") final boolean secure, //required part of 
Finalizer Attack prevention
       final DoublesSketch ds,
       final boolean forceSize,
       final int level) {
@@ -66,12 +66,15 @@ abstract class DoublesSketchAccessor extends 
DoublesBufferAccessor {
     return true;
   }
 
-  static DoublesSketchAccessor wrap(final DoublesSketch ds) {
-    return wrap(ds, false);
-  }
-
+  /**
+   * Wrap the given DoublesSketch
+   * @param ds the given DoublesSketch
+   * @param forceSize Generally, this must be true if modeling an updatable 
sketch, i.e., not compact.
+   * See {@link #setLevel(int) setLevel(int)} below.
+   *
+   * @return this
+   */
   static DoublesSketchAccessor wrap(final DoublesSketch ds, final boolean 
forceSize) {
-
     if (ds.hasMemorySegment()) {
       return new DirectDoublesSketchAccessor(ds, forceSize, BB_LVL_IDX);
     }
@@ -80,12 +83,35 @@ abstract class DoublesSketchAccessor extends 
DoublesBufferAccessor {
 
   abstract DoublesSketchAccessor copyAndSetLevel(final int level);
 
+  /*
+   * This initializes the following internal member variables:
+   * <ul>
+   * <li><i>n_</i> The local copy of DoublesSketch.getN().</li>
+   * <li><i>currLvl_</i> The current level being processed.</li>
+   * <li><i>numItems_</i> The number of items in this level.</li>
+   * <li><i>offset_</i> If accessing a MemorySegment sketch, this is bytes 
offset from the start of the segment.
+   * If the sketch is on-heap, this is the item offset within the given level 
in item units.</li>
+   * </ul>
+   *
+   * <p>If the constructor parameter <i>forceSize</i> is true and accessing 
the BaseBuffer,
+   * it forces the <i>numItems_</i> to be 2K independent of the actual 
getBaseBufferCount().</p>
+   *
+   * <p>If <i>forceSize</i> is false and accessing the BaseBuffer, 
<i>numItems_</i> is set to <i>getBaseBufferCount()</i>.
+   *
+   * <p>If <i>forceSize</i> is true and accessing a higher level, the 
<i>numItems_</i> is always <i>K</i>.</p>
+   *
+   * <p>If <i>forceSize</i> is false and accessing a higher level, 
<i>numItems_</i> is <i>K</i>
+   * only if the level is valid (i.e., a corresponding bit in 
<i>bitPattern</i> is one), otherwise it is zero.</p>
+   *
+   * @param lvl the given level to process.
+   */
   DoublesSketchAccessor setLevel(final int lvl) {
     currLvl_ = lvl;
     if (lvl == BB_LVL_IDX) {
       numItems_ = (forceSize_ ? ds_.getK() * 2 : ds_.getBaseBufferCount());
       offset_ = (ds_.hasMemorySegment() ? COMBINED_BUFFER : 0);
     } else {
+      //compact only keeps valid levels, updatable retains all levels even if 
not valid.
       if (((ds_.getBitPattern() & (1L << lvl)) > 0) || forceSize_) {
         numItems_ = ds_.getK();
       } else {
@@ -94,7 +120,7 @@ abstract class DoublesSketchAccessor extends 
DoublesBufferAccessor {
 
       // determine offset in two parts
       // 1. index into combined buffer (compact vs update)
-      // 2. adjust if byte offset (direct) instead of array index (heap)
+      // 2. adjust if byte offset (direct) instead of doubles array index 
(heap)
       final int levelStart;
       if (ds_.isCompact()) {
         levelStart = ds_.getBaseBufferCount() + (countValidLevelsBelow(lvl) * 
ds_.getK());
@@ -103,10 +129,10 @@ abstract class DoublesSketchAccessor extends 
DoublesBufferAccessor {
       }
 
       if (ds_.hasMemorySegment()) {
-        final int preLongsAndExtra = Family.QUANTILES.getMaxPreLongs() + 2; // 
+2 for min, max vals
-        offset_ = (preLongsAndExtra + levelStart) << 3;
+        final int preLongsAndExtra = Family.QUANTILES.getMaxPreLongs() + 2; // 
+2 for min, max
+        offset_ = (preLongsAndExtra + levelStart) << 3; //bytes relative to 
MemorySegment start
       } else {
-        offset_ = levelStart;
+        offset_ = levelStart; //double array index
       }
     }
 
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DoublesSketchIterator.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesSketchIterator.java
index 649211fe7..1d08c6377 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesSketchIterator.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesSketchIterator.java
@@ -28,7 +28,7 @@ import 
org.apache.datasketches.quantilescommon.QuantilesDoublesSketchIterator;
  * Iterator over DoublesSketch. The order is not defined.
  */
 public final class DoublesSketchIterator implements 
QuantilesDoublesSketchIterator {
-  private DoublesSketchAccessor sketchAccessor;
+  private final DoublesSketchAccessor sketchAccessor;
   private long bitPattern;
   private int level;
   private long weight;
@@ -36,11 +36,11 @@ public final class DoublesSketchIterator implements 
QuantilesDoublesSketchIterat
 
   DoublesSketchIterator(final DoublesSketch sketch, final long bitPattern) {
     Objects.requireNonNull(sketch, "sketch must not be null");
-    sketchAccessor = DoublesSketchAccessor.wrap(sketch);
+    sketchAccessor = DoublesSketchAccessor.wrap(sketch, false);
     this.bitPattern = bitPattern;
-    this.level = -1;
-    this.weight = 1;
-    this.index = -1;
+    level = -1;
+    weight = 1;
+    index = -1;
   }
 
   @Override
diff --git a/src/main/java/org/apache/datasketches/quantiles/DoublesUnion.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesUnion.java
index 6a5c56d57..371a96dfe 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesUnion.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesUnion.java
@@ -48,7 +48,7 @@ public abstract class DoublesUnion implements 
MemorySegmentStatus {
   }
 
   /**
-   * Returns a Heap Union object that has been initialized with the data from 
the given MemorySegment
+   * Returns a Heap Union object that has been initialized with the data from 
the given MemorySegment that contains an
    * image of a sketch.
    *
    * @param srcSeg A MemorySegment image of a DoublesSketch to be used as a 
source of data and will not be modified.
@@ -59,13 +59,13 @@ public abstract class DoublesUnion implements 
MemorySegmentStatus {
   }
 
   /**
-   * Returns an updatable Union object that wraps off-heap data of the given 
MemorySegment image of
-   * a sketch. The data structures of the Union remain off-heap.
+   * Returns an updatable Union object that wraps the given MemorySegment that 
contains an image of a sketch.
+   * The data structures of the Union remain in the MemorySegment.
    *
-   * @param seg A MemorySegment region to be used as the data structure for 
the sketch and will be modified.
+   * @param seg A MemorySegment to be used as the data structure for the 
sketch and will be modified.
    * @return a Union object
    */
-  public static DoublesUnion wrap(final MemorySegment seg) {
+  public static DoublesUnion writableWrap(final MemorySegment seg) {
     return DoublesUnionImpl.wrapInstance(seg);
   }
 
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DoublesUnionImpl.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesUnionImpl.java
index c3530e0b2..2a65c48c7 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesUnionImpl.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesUnionImpl.java
@@ -19,25 +19,31 @@
 
 package org.apache.datasketches.quantiles;
 
+import static org.apache.datasketches.common.Util.LS;
 import static org.apache.datasketches.quantiles.DoublesUtil.copyToHeap;
 
 import java.lang.foreign.MemorySegment;
 import java.util.Objects;
 
+import org.apache.datasketches.common.SketchesArgumentException;
+import org.apache.datasketches.common.SketchesReadOnlyException;
+
 /**
- * Union operation for on-heap.
+ * Union operation.
  *
  * @author Lee Rhodes
  * @author Kevin Lang
  */
-final class DoublesUnionImpl extends DoublesUnionImplR {
+final class DoublesUnionImpl extends DoublesUnion {
+  int maxK_;
+  UpdateDoublesSketch gadget_ = null;
 
   private DoublesUnionImpl(final int maxK) {
-    super(maxK);
+   maxK_ = maxK;
   }
 
   /**
-   * Returns a empty Heap DoublesUnion object.
+   * Returns a empty DoublesUnion object on the heap.
    * @param maxK determines the accuracy and size of the union and is a 
maximum.
    * The effective <i>k</i> can be smaller due to unions with smaller <i>k</i> 
sketches.
    * It is recommended that <i>maxK</i> be a power of 2 to enable unioning of 
sketches with
@@ -49,7 +55,7 @@ final class DoublesUnionImpl extends DoublesUnionImplR {
   }
 
   /**
-   * Returns a empty DoublesUnion object that refers to the given direct, 
off-heap MemorySegment,
+   * Returns a empty DoublesUnion object that refers to the given 
MemorySegment,
    * which will be initialized to the empty state.
    *
    * @param maxK determines the accuracy and size of the union and is a 
maximum.
@@ -90,7 +96,7 @@ final class DoublesUnionImpl extends DoublesUnionImplR {
    * it is not retained. The <i>maxK</i> of the resulting union will be that 
obtained from
    * the sketch MemorySegment image.
    *
-   * @param srcSeg a MemorySegment image of a quantiles DoublesSketch
+   * @param srcSeg an optionally read-only MemorySegment image of a 
DoublesSketch
    * @return a DoublesUnion object
    */
   static DoublesUnionImpl heapifyInstance(final MemorySegment srcSeg) {
@@ -102,16 +108,16 @@ final class DoublesUnionImpl extends DoublesUnionImplR {
   }
 
   /**
-   * Returns an updatable Union object that wraps off-heap data structure of 
the given MemorySegment
-   * image of a non-compact DoublesSketch. The data structures of the Union 
remain off-heap.
+   * Returns an updatable Union object that wraps the data of the given 
MemorySegment
+   * image of a updatable DoublesSketch. The data of the Union will remain in 
the MemorySegment.
    *
-   * @param seg A MemorySegment image of a non-compact DoublesSketch to be 
used as the data
-   * structure for the union and will be modified.
+   * @param srcSeg A writable MemorySegment image of a updatable DoublesSketch 
to be used as data for the union.
    * @return a Union object
    */
-  static DoublesUnionImpl wrapInstance(final MemorySegment seg) {
-    Objects.requireNonNull(seg);
-    final DirectUpdateDoublesSketch sketch = 
DirectUpdateDoublesSketch.wrapInstance(seg, null);
+  static DoublesUnionImpl wrapInstance(final MemorySegment srcSeg) {
+    Objects.requireNonNull(srcSeg);
+    if (srcSeg.isReadOnly()) { throw new SketchesReadOnlyException("Cannot 
create a Union with a Read Only MemorySegment."); }
+    final DirectUpdateDoublesSketch sketch = 
DirectUpdateDoublesSketch.wrapInstance(srcSeg, null);
     final DoublesUnionImpl union = new DoublesUnionImpl(sketch.getK());
     union.gadget_ = sketch;
     return union;
@@ -127,19 +133,49 @@ final class DoublesUnionImpl extends DoublesUnionImplR {
   @Override
   public void union(final MemorySegment seg) {
     Objects.requireNonNull(seg);
-    gadget_ = updateLogic(maxK_, gadget_, DoublesSketch.wrap(seg));
+    gadget_ = updateLogic(maxK_, gadget_, DoublesSketch.wrap(seg, null));
     gadget_.doublesSV = null;
   }
 
   @Override
-  public void update(final double quantile) {
+  public void update(final double dataItem) {
     if (gadget_ == null) {
       gadget_ = HeapUpdateDoublesSketch.newInstance(maxK_);
     }
-    gadget_.update(quantile);
+    gadget_.update(dataItem);
     gadget_.doublesSV = null;
   }
 
+  @Override
+  public byte[] toByteArray() {
+    if (gadget_ == null) {
+      return DoublesSketch.builder().setK(maxK_).build().toByteArray();
+    }
+    return gadget_.toByteArray();
+  }
+
+  @Override
+  public UpdateDoublesSketch getResult() {
+    if (gadget_ == null) {
+      return HeapUpdateDoublesSketch.newInstance(maxK_);
+    }
+    return DoublesUtil.copyToHeap(gadget_); //can't have any externally owned 
handles.
+  }
+
+  @Override
+  public UpdateDoublesSketch getResult(final MemorySegment dstSeg) {
+    final long segCapBytes = dstSeg.byteSize();
+    if (gadget_ == null) {
+      if (segCapBytes < DoublesSketch.getUpdatableStorageBytes(0, 0)) {
+        throw new SketchesArgumentException("Insufficient capacity for result: 
" + segCapBytes);
+      }
+      return DirectUpdateDoublesSketch.newInstance(maxK_, dstSeg, null);
+    }
+
+    gadget_.putIntoMemorySegment(dstSeg, false);
+    return DirectUpdateDoublesSketch.wrapInstance(dstSeg, null);
+  }
+
   @Override
   public UpdateDoublesSketch getResultAndReset() {
     if (gadget_ == null) { return null; } //Intentionally return null here for 
speed.
@@ -153,9 +189,59 @@ final class DoublesUnionImpl extends DoublesUnionImplR {
     gadget_.reset();
   }
 
+  @Override
+  public boolean hasMemorySegment() {
+    return (gadget_ != null) && gadget_.hasMemorySegment();
+  }
+
+  @Override
+  public boolean isOffHeap() {
+    return (gadget_ != null) && gadget_.isOffHeap();
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return (gadget_ == null) || gadget_.isEmpty();
+  }
+
+  @Override
+  public boolean isSameResource(final MemorySegment that) {
+    return (gadget_ == null) ? false : gadget_.isSameResource(that);
+  }
+
+  @Override
+  public int getMaxK() {
+    return maxK_;
+  }
+
+  @Override
+  public int getEffectiveK() {
+    return (gadget_ != null) ? gadget_.getK() : maxK_;
+  }
+
+  @Override
+  public String toString() {
+    return toString(true, false);
+  }
+
+  @Override
+  public String toString(final boolean sketchSummary, final boolean 
dataDetail) {
+    final StringBuilder sb = new StringBuilder();
+    final String thisSimpleName = this.getClass().getSimpleName();
+    final int maxK = getMaxK();
+    final String kStr = String.format("%,d", maxK);
+    sb.append(LS).append("### Quantiles ").append(thisSimpleName).append(LS);
+    sb.append("   maxK                         : ").append(kStr);
+    if (gadget_ == null) {
+      sb.append(HeapUpdateDoublesSketch.newInstance(maxK_).toString());
+      return sb.toString();
+    }
+    sb.append(gadget_.toString(sketchSummary, dataDetail));
+    return sb.toString();
+  }
+
   //@formatter:off
-  static UpdateDoublesSketch updateLogic(final int myMaxK, final 
UpdateDoublesSketch myQS,
-                                         final DoublesSketch other) {
+  static UpdateDoublesSketch updateLogic(final int myMaxK, final 
UpdateDoublesSketch myQS, final DoublesSketch other) {
     int sw1 = ((myQS  == null) ? 0 :  myQS.isEmpty() ? 4 : 8);
     sw1 |=    ((other == null) ? 0 : other.isEmpty() ? 1 : 2);
     int outCase = 0; //0=null, 1=NOOP, 2=copy, 3=merge
@@ -182,7 +268,7 @@ final class DoublesUnionImpl extends DoublesUnionImplR {
         if (!other.isEstimationMode()) { //other is exact, stream items in
           ret = HeapUpdateDoublesSketch.newInstance(myMaxK);
           // exact mode, only need copy base buffer
-          final DoublesSketchAccessor otherAccessor = 
DoublesSketchAccessor.wrap(other);
+          final DoublesSketchAccessor otherAccessor = 
DoublesSketchAccessor.wrap(other, false); // T/F doesn't matter
           for (int i = 0; i < otherAccessor.numItems(); ++i) {
             ret.update(otherAccessor.get(i));
           }
@@ -200,7 +286,7 @@ final class DoublesUnionImpl extends DoublesUnionImplR {
         if (!other.isEstimationMode()) { //other is exact, stream items in
           ret = myQS;
           // exact mode, only need copy base buffer
-          final DoublesSketchAccessor otherAccessor = 
DoublesSketchAccessor.wrap(other);
+          final DoublesSketchAccessor otherAccessor = 
DoublesSketchAccessor.wrap(other, false); // T/F doesn't matter
           for (int i = 0; i < otherAccessor.numItems(); ++i) {
             ret.update(otherAccessor.get(i));
           }
@@ -210,13 +296,12 @@ final class DoublesUnionImpl extends DoublesUnionImplR {
         } else if (myQS.isEmpty()) {
           if (myQS.hasMemorySegment()) {
             final MemorySegment seg = myQS.getMemorySegment(); //myQS is 
empty, ok to reconfigure
-            other.putMemorySegment(seg, false); // not compact, but BB ordered
+            other.putIntoMemorySegment(seg, false); // not compact, but 
BaseBuf ordered
             ret = DirectUpdateDoublesSketch.wrapInstance(seg, null);
           } else { //myQS is empty and on heap
             ret = DoublesUtil.copyToHeap(other);
           }
-        }
-        else { //Not Empty: myQS has data, downsample to tmp
+        } else { //Not Empty: myQS has data, downsample to tmp
           final UpdateDoublesSketch tmp = 
DoublesSketch.builder().setK(other.getK()).build();
 
           DoublesMergeImpl.downSamplingMergeInto(myQS, tmp); //myData -> tmp
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/DoublesUnionImplR.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesUnionImplR.java
deleted file mode 100644
index 9b34b2b81..000000000
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesUnionImplR.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.quantiles;
-
-import static org.apache.datasketches.common.Util.LS;
-
-import java.lang.foreign.MemorySegment;
-
-import org.apache.datasketches.common.SketchesArgumentException;
-import org.apache.datasketches.common.SketchesReadOnlyException;
-
-/**
- * Union operation for on-heap.
- *
- * @author Lee Rhodes
- * @author Kevin Lang
- */
-class DoublesUnionImplR extends DoublesUnion {
-  int maxK_;
-  UpdateDoublesSketch gadget_ = null;
-
-  DoublesUnionImplR(final int maxK) {
-    maxK_ = maxK;
-  }
-
-  /**
-   * Returns a read-only Union object that wraps off-heap data structure of 
the given MemorySegment
-   * image of a non-compact DoublesSketch. The data structures of the Union 
remain off-heap.
-   *
-   * @param seg A MemorySegment image of a non-compact DoublesSketch to be 
used as the data
-   * structure for the union and will be modified.
-   * @return a Union object
-   */
-  static DoublesUnionImplR wrapInstance(final MemorySegment seg) {
-    final DirectUpdateDoublesSketchR sketch = 
DirectUpdateDoublesSketchR.wrapInstance(seg);
-    final int k = sketch.getK();
-    final DoublesUnionImplR union = new DoublesUnionImplR(k);
-    union.maxK_ = k;
-    union.gadget_ = sketch;
-    return union;
-  }
-
-  @Override
-  public void union(final DoublesSketch sketchIn) {
-    throw new SketchesReadOnlyException("Call to update() on read-only Union");
-  }
-
-  @Override
-  public void union(final MemorySegment seg) {
-    throw new SketchesReadOnlyException("Call to update() on read-only Union");
-  }
-
-  @Override
-  public void update(final double dataItem) {
-    throw new SketchesReadOnlyException("Call to update() on read-only Union");
-  }
-
-  @Override
-  public byte[] toByteArray() {
-    if (gadget_ == null) {
-      return DoublesSketch.builder().setK(maxK_).build().toByteArray();
-    }
-    return gadget_.toByteArray();
-  }
-
-  @Override
-  public UpdateDoublesSketch getResult() {
-    if (gadget_ == null) {
-      return HeapUpdateDoublesSketch.newInstance(maxK_);
-    }
-    return DoublesUtil.copyToHeap(gadget_); //can't have any externally owned 
handles.
-  }
-
-  @Override
-  public UpdateDoublesSketch getResult(final MemorySegment dstSeg) {
-    final long segCapBytes = dstSeg.byteSize();
-    if (gadget_ == null) {
-      if (segCapBytes < DoublesSketch.getUpdatableStorageBytes(0, 0)) {
-        throw new SketchesArgumentException("Insufficient capacity for result: 
" + segCapBytes);
-      }
-      return DirectUpdateDoublesSketch.newInstance(maxK_, dstSeg, null);
-    }
-
-    gadget_.putMemorySegment(dstSeg, false);
-    return DirectUpdateDoublesSketch.wrapInstance(dstSeg, null);
-  }
-
-  @Override
-  public UpdateDoublesSketch getResultAndReset() {
-    throw new SketchesReadOnlyException("Call to getResultAndReset() on 
read-only Union");
-  }
-
-  @Override
-  public void reset() {
-    throw new SketchesReadOnlyException("Call to reset() on read-only Union");
-  }
-
-  @Override
-  public boolean hasMemorySegment() {
-    return (gadget_ != null) && gadget_.hasMemorySegment();
-  }
-
-  @Override
-  public boolean isOffHeap() {
-    return (gadget_ != null) && gadget_.isOffHeap();
-  }
-
-  @Override
-  public boolean isEmpty() {
-    return (gadget_ == null) || gadget_.isEmpty();
-  }
-
-  @Override
-  public boolean isSameResource(final MemorySegment that) {
-    return (gadget_ == null) ? false : gadget_.isSameResource(that);
-  }
-
-  @Override
-  public int getMaxK() {
-    return maxK_;
-  }
-
-  @Override
-  public int getEffectiveK() {
-    return (gadget_ != null) ? gadget_.getK() : maxK_;
-  }
-
-  @Override
-  public String toString() {
-    return toString(true, false);
-  }
-
-  @Override
-  public String toString(final boolean sketchSummary, final boolean 
dataDetail) {
-    final StringBuilder sb = new StringBuilder();
-    final String thisSimpleName = this.getClass().getSimpleName();
-    final int maxK = getMaxK();
-    final String kStr = String.format("%,d", maxK);
-    sb.append(LS).append("### Quantiles ").append(thisSimpleName).append(LS);
-    sb.append("   maxK                         : ").append(kStr);
-    if (gadget_ == null) {
-      sb.append(HeapUpdateDoublesSketch.newInstance(maxK_).toString());
-      return sb.toString();
-    }
-    sb.append(gadget_.toString(sketchSummary, dataDetail));
-    return sb.toString();
-  }
-
-}
diff --git a/src/main/java/org/apache/datasketches/quantiles/DoublesUtil.java 
b/src/main/java/org/apache/datasketches/quantiles/DoublesUtil.java
index cbab287f4..3d99eeaf0 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesUtil.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesUtil.java
@@ -62,8 +62,8 @@ final class DoublesUtil {
       final int combBufItems = 
computeCombinedBufferItemCapacity(sketch.getK(), sketch.getN());
       final double[] combBuf = new double[combBufItems];
       qsCopy.putCombinedBuffer(combBuf);
-      final DoublesSketchAccessor sketchAccessor = 
DoublesSketchAccessor.wrap(sketch);
-      final DoublesSketchAccessor copyAccessor = 
DoublesSketchAccessor.wrap(qsCopy);
+      final DoublesSketchAccessor sketchAccessor = 
DoublesSketchAccessor.wrap(sketch, false);
+      final DoublesSketchAccessor copyAccessor = 
DoublesSketchAccessor.wrap(qsCopy, false);
       // start with BB
       copyAccessor.putArray(sketchAccessor.getArray(0, 
sketchAccessor.numItems()),
               0, 0, sketchAccessor.numItems());
@@ -137,6 +137,7 @@ final class DoublesUtil {
     sb.append(LS).append("### Classic Quantiles 
").append(thisSimpleName).append(" SUMMARY: ").append(LS);
     sb.append("    Empty                        : 
").append(sk.isEmpty()).append(LS);
     sb.append("    Segment, Capacity bytes      : 
").append(sk.hasMemorySegment()).append(", ").append(segCap).append(LS);
+    sb.append("    Segment, ReadOnly            : 
").append(sk.hasMemorySegment() ? sk.getMemorySegment().isReadOnly() : 
false).append(LS);
     sb.append("    Estimation Mode              : 
").append(sk.isEstimationMode()).append(LS);
     sb.append("    K                            : ").append(kStr).append(LS);
     sb.append("    N                            : ").append(nStr).append(LS);
@@ -159,7 +160,7 @@ final class DoublesUtil {
     return sb.toString();
   }
 
-  private static <T> String outputLevels(final DoublesSketch sk) {
+  private static String outputLevels(final DoublesSketch sk) {
     final String name = sk.getClass().getSimpleName();
     final int k = sk.getK();
     final long n = sk.getN();
@@ -182,7 +183,7 @@ final class DoublesUtil {
     return sb.toString();
   }
 
-  private static <T> String outputDataDetail(final DoublesSketch sk) {
+  private static String outputDataDetail(final DoublesSketch sk) {
     final String name = sk.getClass().getSimpleName();
     final int k = sk.getK();
     final long n = sk.getN();
@@ -210,8 +211,7 @@ final class DoublesUtil {
     return sb.toString();
   }
 
-  private static boolean getValidFromIndex(final int levelNum, final long 
bitPattern, final int index,
-      final int bbCount) {
+  private static boolean getValidFromIndex(final int levelNum, final long 
bitPattern, final int index, final int bbCount) {
     return ((levelNum == -1) && (index < bbCount)) || 
getValidFromLevel(levelNum, bitPattern);
   }
 
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/HeapCompactDoublesSketch.java 
b/src/main/java/org/apache/datasketches/quantiles/HeapCompactDoublesSketch.java
index 43ce103ae..1ab9d2e32 100644
--- 
a/src/main/java/org/apache/datasketches/quantiles/HeapCompactDoublesSketch.java
+++ 
b/src/main/java/org/apache/datasketches/quantiles/HeapCompactDoublesSketch.java
@@ -124,7 +124,7 @@ final class HeapCompactDoublesSketch extends 
CompactDoublesSketch {
     final int retainedItems = computeRetainedItems(k, n);
     final double[] combinedBuffer = new double[retainedItems];
 
-    final DoublesSketchAccessor accessor = DoublesSketchAccessor.wrap(sketch);
+    final DoublesSketchAccessor accessor = DoublesSketchAccessor.wrap(sketch, 
false);
     assert hcds.baseBufferCount_ == accessor.numItems();
 
     // copy and sort base buffer
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/HeapDoublesSketchAccessor.java
 
b/src/main/java/org/apache/datasketches/quantiles/HeapDoublesSketchAccessor.java
index ccf6aa6a5..fac541e55 100644
--- 
a/src/main/java/org/apache/datasketches/quantiles/HeapDoublesSketchAccessor.java
+++ 
b/src/main/java/org/apache/datasketches/quantiles/HeapDoublesSketchAccessor.java
@@ -25,6 +25,7 @@ import java.util.Arrays;
  * @author Jon Malkin
  */
 final class HeapDoublesSketchAccessor extends DoublesSketchAccessor {
+
   HeapDoublesSketchAccessor(final DoublesSketch ds,
                             final boolean forceSize,
                             final int level) {
@@ -59,13 +60,12 @@ final class HeapDoublesSketchAccessor extends 
DoublesSketchAccessor {
 
   @Override
   double[] getArray(final int fromIdx, final int numItems) {
-    final int stIdx = offset_ + fromIdx;
-    return Arrays.copyOfRange(ds_.getCombinedBuffer(), stIdx, stIdx + 
numItems);
+    final int srcIdx = offset_ + fromIdx;
+    return Arrays.copyOfRange(ds_.getCombinedBuffer(), srcIdx, srcIdx + 
numItems);
   }
 
   @Override
-  void putArray(final double[] srcArray, final int srcIndex,
-                final int dstIndex, final int numItems) {
+  void putArray(final double[] srcArray, final int srcIndex, final int 
dstIndex, final int numItems) {
     final int tgtIdx = offset_ + dstIndex;
     System.arraycopy(srcArray, srcIndex, ds_.getCombinedBuffer(), tgtIdx, 
numItems);
   }
diff --git 
a/src/main/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketch.java 
b/src/main/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketch.java
index 350f8cb3f..7dd0c8c8a 100644
--- 
a/src/main/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketch.java
+++ 
b/src/main/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketch.java
@@ -26,6 +26,7 @@ import static 
org.apache.datasketches.quantiles.ClassicUtil.checkHeapFlags;
 import static 
org.apache.datasketches.quantiles.ClassicUtil.computeBaseBufferItems;
 import static org.apache.datasketches.quantiles.ClassicUtil.computeBitPattern;
 import static 
org.apache.datasketches.quantiles.ClassicUtil.computeCombinedBufferItemCapacity;
+import static 
org.apache.datasketches.quantiles.ClassicUtil.computeGrowingBaseBufferCap;
 import static 
org.apache.datasketches.quantiles.ClassicUtil.computeNumLevelsNeeded;
 import static 
org.apache.datasketches.quantiles.ClassicUtil.computeRetainedItems;
 import static org.apache.datasketches.quantiles.PreambleUtil.COMPACT_FLAG_MASK;
@@ -44,6 +45,7 @@ import java.util.Arrays;
 
 import org.apache.datasketches.common.Family;
 import org.apache.datasketches.common.SketchesArgumentException;
+import org.apache.datasketches.common.SketchesNotSupportedException;
 import org.apache.datasketches.quantilescommon.QuantilesAPI;
 
 /**
@@ -252,8 +254,8 @@ final class HeapUpdateDoublesSketch extends 
UpdateDoublesSketch {
     final long newN = n_ + 1;
 
     final int combBufItemCap = combinedBuffer_.length;
-    if (newBBCount > combBufItemCap) {
-      growBaseBuffer(); //only changes combinedBuffer when it is only a base 
buffer
+    if (newBBCount > combBufItemCap) { //newBBCount can never be > 2 * k
+      growBaseBuffer(); //this only changes combinedBuffer when it is only a 
base buffer
     }
 
     //put the new item in the base buffer
@@ -373,6 +375,11 @@ final class HeapUpdateDoublesSketch extends 
UpdateDoublesSketch {
     return null;
   }
 
+  @Override
+  void setReadOnly() {
+    throw new SketchesNotSupportedException("Not Supported on a heap sketch. 
Convert to CompactSketch instead.");
+  }
+
   @Override
   HeapUpdateDoublesSketch getSketchAndReset() {
     final HeapUpdateDoublesSketch skCopy = HeapUpdateDoublesSketch.copy(this);
@@ -428,7 +435,7 @@ final class HeapUpdateDoublesSketch extends 
UpdateDoublesSketch {
     final int oldSize = combinedBuffer_.length;
     assert oldSize < (2 * k_);
     final double[] baseBuffer = combinedBuffer_;
-    final int newSize = 2 * Math.max(Math.min(k_, oldSize), MIN_K);
+    final int newSize = computeGrowingBaseBufferCap(k_, oldSize);
     combinedBuffer_ = Arrays.copyOf(baseBuffer, newSize);
   }
 
diff --git a/src/main/java/org/apache/datasketches/req/ReqCompactor.java 
b/src/main/java/org/apache/datasketches/req/ReqCompactor.java
index e25c0cb6a..151cd8ff3 100644
--- a/src/main/java/org/apache/datasketches/req/ReqCompactor.java
+++ b/src/main/java/org/apache/datasketches/req/ReqCompactor.java
@@ -207,7 +207,7 @@ class ReqCompactor {
   ReqCompactor merge(final ReqCompactor other) {
     assert lgWeight == other.lgWeight;
     state |= other.state;
-    while (ensureEnoughSections()) {}
+    while (ensureEnoughSections()) { /* do nothing */ }
     buf.sort();
     final FloatBuffer otherBuf = new FloatBuffer(other.buf);
     otherBuf.sort();
diff --git 
a/src/main/java/org/apache/datasketches/sampling/EbppsItemsSketch.java 
b/src/main/java/org/apache/datasketches/sampling/EbppsItemsSketch.java
index 32dba2cb1..d1d147021 100644
--- a/src/main/java/org/apache/datasketches/sampling/EbppsItemsSketch.java
+++ b/src/main/java/org/apache/datasketches/sampling/EbppsItemsSketch.java
@@ -269,8 +269,8 @@ public final class EbppsItemsSketch<T> {
    * @param other the sketch to merge into the current object
    */
   public void merge(final EbppsItemsSketch<T> other) {
-    if (other.getCumulativeWeight() == 0.0) {
-    } else if (other.getCumulativeWeight() > cumulativeWt_) {
+    if (other.getCumulativeWeight() == 0.0) { /* do nothing */ }
+    else if (other.getCumulativeWeight() > cumulativeWt_) {
       // need to swap this with other
       // make a copy of other, merge into it, and take the result
       final EbppsItemsSketch<T> copy = new EbppsItemsSketch<>(other);
diff --git 
a/src/main/java/org/apache/datasketches/theta/ConcurrentDirectQuickSelectSketch.java
 
b/src/main/java/org/apache/datasketches/theta/ConcurrentDirectQuickSelectSketch.java
index 9230f3456..6e7cad3c5 100644
--- 
a/src/main/java/org/apache/datasketches/theta/ConcurrentDirectQuickSelectSketch.java
+++ 
b/src/main/java/org/apache/datasketches/theta/ConcurrentDirectQuickSelectSketch.java
@@ -120,7 +120,7 @@ final class ConcurrentDirectQuickSelectSketch extends 
DirectQuickSelectSketch
 
   @Override
   public byte[] toByteArray() {
-    while (!sharedPropagationInProgress_.compareAndSet(false, true)) { } 
//busy wait till free
+    while (!sharedPropagationInProgress_.compareAndSet(false, true)) { /* busy 
wait till free */ }
     final byte[] res = super.toByteArray();
     sharedPropagationInProgress_.set(false);
     return res;
@@ -163,7 +163,7 @@ final class ConcurrentDirectQuickSelectSketch extends 
DirectQuickSelectSketch
 
   @Override
   public boolean startEagerPropagation() {
-    while (!sharedPropagationInProgress_.compareAndSet(false, true)) { } 
//busy wait till free
+    while (!sharedPropagationInProgress_.compareAndSet(false, true)) { /* busy 
wait till free */ }
     return (!isEstimationMode());// no eager propagation is allowed in 
estimation mode
   }
 
@@ -198,7 +198,7 @@ final class ConcurrentDirectQuickSelectSketch extends 
DirectQuickSelectSketch
   }
 
   @Override
-  public final void initBgPropagationService() {
+  public void initBgPropagationService() {
     executorService_ = 
ConcurrentPropagationService.getExecutorService(Thread.currentThread().threadId());
   }
 
@@ -252,11 +252,11 @@ final class ConcurrentDirectQuickSelectSketch extends 
DirectQuickSelectSketch
   /**
    * Advances the epoch while there is no background propagation
    * This ensures a propagation invoked before the reset cannot affect the 
sketch after the reset
-   * is completed. Ignore AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE and 
AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE 
+   * is completed. Ignore AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE and 
AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE
    * SpotBugs warnings, they are False Positive.
    */
 
-  @SuppressFBWarnings(value = {"AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE", 
"VO_VOLATILE_INCREMENT"}, 
+  @SuppressFBWarnings(value = {"AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE", 
"VO_VOLATILE_INCREMENT"},
       justification = "Likely False Positive, Fix Later")
   private void advanceEpoch() {
     awaitBgPropagationTermination();
diff --git 
a/src/main/java/org/apache/datasketches/theta/ConcurrentHeapQuickSelectSketch.java
 
b/src/main/java/org/apache/datasketches/theta/ConcurrentHeapQuickSelectSketch.java
index e01e01761..c061bde1d 100644
--- 
a/src/main/java/org/apache/datasketches/theta/ConcurrentHeapQuickSelectSketch.java
+++ 
b/src/main/java/org/apache/datasketches/theta/ConcurrentHeapQuickSelectSketch.java
@@ -115,7 +115,7 @@ final class ConcurrentHeapQuickSelectSketch extends 
HeapQuickSelectSketch
 
   @Override
   public byte[] toByteArray() {
-    while (!sharedPropagationInProgress_.compareAndSet(false, true)) { } 
//busy wait till free
+    while (!sharedPropagationInProgress_.compareAndSet(false, true)) { /* busy 
wait till free */ }
     final byte[] res = super.toByteArray();
     sharedPropagationInProgress_.set(false);
     return res;
@@ -158,7 +158,7 @@ final class ConcurrentHeapQuickSelectSketch extends 
HeapQuickSelectSketch
 
   @Override
   public boolean startEagerPropagation() {
-    while (!sharedPropagationInProgress_.compareAndSet(false, true)) { } 
//busy wait till free
+    while (!sharedPropagationInProgress_.compareAndSet(false, true)) { /* busy 
wait till free */ }
     return (!isEstimationMode());// no eager propagation is allowed in 
estimation mode
   }
 
diff --git 
a/src/main/java/org/apache/datasketches/theta/ConcurrentHeapThetaBuffer.java 
b/src/main/java/org/apache/datasketches/theta/ConcurrentHeapThetaBuffer.java
index 184b34ebe..2071b74ce 100644
--- a/src/main/java/org/apache/datasketches/theta/ConcurrentHeapThetaBuffer.java
+++ b/src/main/java/org/apache/datasketches/theta/ConcurrentHeapThetaBuffer.java
@@ -96,8 +96,7 @@ final class ConcurrentHeapThetaBuffer extends 
HeapQuickSelectSketch {
    */
   private boolean propagateToSharedSketch(final long hash) {
     //no inspection StatementWithEmptyBody
-    while (localPropagationInProgress.get()) {
-    } //busy wait until previous propagation completed
+    while (localPropagationInProgress.get()) { /* busy wait until previous 
propagation completed */ }
     localPropagationInProgress.set(true);
     final boolean res = shared.propagate(localPropagationInProgress, null, 
hash);
     //in this case the parent empty_ and curCount_ were not touched
@@ -110,8 +109,7 @@ final class ConcurrentHeapThetaBuffer extends 
HeapQuickSelectSketch {
    */
   private void propagateToSharedSketch() {
     //no inspection StatementWithEmptyBody
-    while (localPropagationInProgress.get()) {
-    } //busy wait until previous propagation completed
+    while (localPropagationInProgress.get()) { /* busy wait until previous 
propagation completed */ }
 
     final CompactSketch compactSketch = compact(propagateOrderedCompact, null);
     localPropagationInProgress.set(true);
diff --git 
a/src/main/java/org/apache/datasketches/theta/DirectQuickSelectSketch.java 
b/src/main/java/org/apache/datasketches/theta/DirectQuickSelectSketch.java
index 22e37ca6f..45b01edba 100644
--- a/src/main/java/org/apache/datasketches/theta/DirectQuickSelectSketch.java
+++ b/src/main/java/org/apache/datasketches/theta/DirectQuickSelectSketch.java
@@ -119,7 +119,7 @@ class DirectQuickSelectSketch extends 
DirectQuickSelectSketchR {
   }
 
   private DirectQuickSelectSketch(
-      final boolean secure, //required part of Finalizer Attack prevention
+      @SuppressWarnings("unused") final boolean secure, //required part of 
Finalizer Attack prevention
       final int lgNomLongs,
       final long seed,
       final float p,
diff --git 
a/src/main/java/org/apache/datasketches/tuple/arrayofdoubles/DirectArrayOfDoublesQuickSelectSketch.java
 
b/src/main/java/org/apache/datasketches/tuple/arrayofdoubles/DirectArrayOfDoublesQuickSelectSketch.java
index b34f08f5c..344df137c 100644
--- 
a/src/main/java/org/apache/datasketches/tuple/arrayofdoubles/DirectArrayOfDoublesQuickSelectSketch.java
+++ 
b/src/main/java/org/apache/datasketches/tuple/arrayofdoubles/DirectArrayOfDoublesQuickSelectSketch.java
@@ -51,7 +51,7 @@ import org.apache.datasketches.tuple.Util;
 class DirectArrayOfDoublesQuickSelectSketch extends 
ArrayOfDoublesQuickSelectSketch {
 
   // these values exist only on heap, never serialized
-  private MemorySegment seg_;
+  private final MemorySegment seg_;
   // these can be derived from the seg_ contents, but are kept here for 
performance
   private int keysOffset_;
   private int valuesOffset_;
@@ -91,7 +91,7 @@ class DirectArrayOfDoublesQuickSelectSketch extends 
ArrayOfDoublesQuickSelectSke
   }
 
   private DirectArrayOfDoublesQuickSelectSketch(
-      final boolean secure, //required part of Finalizer Attack prevention
+      @SuppressWarnings("unused") final boolean secure, //required part of 
Finalizer Attack prevention
       final int nomEntries,
       final int lgResizeFactor,
       final float samplingProbability,
@@ -150,7 +150,7 @@ class DirectArrayOfDoublesQuickSelectSketch extends 
ArrayOfDoublesQuickSelectSke
   }
 
   private DirectArrayOfDoublesQuickSelectSketch(
-      final boolean secure, //required part of Finalizer Attack prevention
+      @SuppressWarnings("unused") final boolean secure, //required part of 
Finalizer Attack prevention
       final MemorySegment seg,
       final long seed) {
     super(seg.get(JAVA_BYTE, NUM_VALUES_BYTE), seed);
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/DirectCompactDoublesSketchTest.java
 
b/src/test/java/org/apache/datasketches/quantiles/DirectCompactDoublesSketchTest.java
index aa1ded0b1..946eca5ca 100644
--- 
a/src/test/java/org/apache/datasketches/quantiles/DirectCompactDoublesSketchTest.java
+++ 
b/src/test/java/org/apache/datasketches/quantiles/DirectCompactDoublesSketchTest.java
@@ -29,6 +29,7 @@ import java.lang.foreign.MemorySegment;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
+import org.apache.datasketches.common.MemorySegmentRequest;
 import org.apache.datasketches.common.SketchesArgumentException;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -96,7 +97,7 @@ public class DirectCompactDoublesSketchTest {
     final CompactDoublesSketch s1 = DoublesSketch.builder().build().compact();
     final MemorySegment seg
             = 
MemorySegment.ofBuffer(ByteBuffer.wrap(s1.toByteArray()).order(ByteOrder.nativeOrder()));
-    final DoublesSketch s2 = DoublesSketch.wrap(seg);
+    final DoublesSketch s2 = DoublesSketch.wrap(seg, 
MemorySegmentRequest.DEFAULT);
     assertTrue(s2.isEmpty());
     assertEquals(s2.getN(), 0);
     assertTrue(Double.isNaN(s2.isEmpty() ? Double.NaN : s2.getMinItem()));
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketchTest.java
 
b/src/test/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketchTest.java
index 8eff2a795..d8aca558b 100644
--- 
a/src/test/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketchTest.java
+++ 
b/src/test/java/org/apache/datasketches/quantiles/DirectUpdateDoublesSketchTest.java
@@ -170,28 +170,28 @@ public class DirectUpdateDoublesSketchTest {
     final MemorySegment seg = MemorySegment.ofArray(new byte[8]);
     try {
       final int flags = PreambleUtil.COMPACT_FLAG_MASK;
-      DirectUpdateDoublesSketchR.checkCompact(2, 0);
+      DirectUpdateDoublesSketch.checkCompact(2, 0);
       fail();
     } catch (final SketchesArgumentException e) {} //OK
     try {
       final int flags = PreambleUtil.COMPACT_FLAG_MASK;
-      DirectUpdateDoublesSketchR.checkCompact(3, flags);
+      DirectUpdateDoublesSketch.checkCompact(3, flags);
       fail();
     } catch (final SketchesArgumentException e) {} //OK
     try {
-      DirectUpdateDoublesSketchR.checkPreLongs(3);
+      DirectUpdateDoublesSketch.checkPreLongs(3);
       fail();
     } catch (final SketchesArgumentException e) {} //OK
     try {
-      DirectUpdateDoublesSketchR.checkPreLongs(0);
+      DirectUpdateDoublesSketch.checkPreLongs(0);
       fail();
     } catch (final SketchesArgumentException e) {} //OK
     try {
-      
DirectUpdateDoublesSketchR.checkDirectFlags(PreambleUtil.COMPACT_FLAG_MASK);
+      
DirectUpdateDoublesSketch.checkDirectFlags(PreambleUtil.COMPACT_FLAG_MASK);
       fail();
     } catch (final SketchesArgumentException e) {} //OK
     try {
-      DirectUpdateDoublesSketchR.checkEmptyAndN(true, 1);
+      DirectUpdateDoublesSketch.checkEmptyAndN(true, 1);
       fail();
     } catch (final SketchesArgumentException e) {} //OK
   }
@@ -199,12 +199,12 @@ public class DirectUpdateDoublesSketchTest {
   @Test
   public void checkCheckDirectSegCapacity() {
     final int k = 128;
-    DirectUpdateDoublesSketchR.checkDirectSegCapacity(k, (2 * k) - 1, (4 + (2 
* k)) * 8);
-    DirectUpdateDoublesSketchR.checkDirectSegCapacity(k, (2 * k) + 1, (4 + (3 
* k)) * 8);
-    DirectUpdateDoublesSketchR.checkDirectSegCapacity(k, 0, 8);
+    DirectUpdateDoublesSketch.checkDirectSegCapacity(k, (2 * k) - 1, (4 + (2 * 
k)) * 8);
+    DirectUpdateDoublesSketch.checkDirectSegCapacity(k, (2 * k) + 1, (4 + (3 * 
k)) * 8);
+    DirectUpdateDoublesSketch.checkDirectSegCapacity(k, 0, 8);
 
     try {
-      DirectUpdateDoublesSketchR.checkDirectSegCapacity(k, 10000, 64);
+      DirectUpdateDoublesSketch.checkDirectSegCapacity(k, 10000, 64);
       fail();
     } catch (final SketchesArgumentException e) {
       // expected
@@ -230,7 +230,7 @@ public class DirectUpdateDoublesSketchTest {
 
     final byte[] arr2 = sketch2.toByteArray(false);
     assertEquals(arr2.length, sketch2.getSerializedSizeBytes());
-    final DoublesSketch sketch3 = 
DoublesSketch.wrap(MemorySegment.ofArray(arr2));
+    final DoublesSketch sketch3 = 
DoublesSketch.wrap(MemorySegment.ofArray(arr2), null);
     assertEquals(sketch3.getMinItem(), 0.0);
     assertEquals(sketch3.getMaxItem(), 1999.0);
     assertEquals(sketch3.getQuantile(0.5), 1000.0, 10.0);
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/DoublesSketchTest.java 
b/src/test/java/org/apache/datasketches/quantiles/DoublesSketchTest.java
index 14557a1b6..8d64c6bec 100644
--- a/src/test/java/org/apache/datasketches/quantiles/DoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/quantiles/DoublesSketchTest.java
@@ -43,7 +43,7 @@ public class DoublesSketchTest {
     for (int i = 0; i < 1000; i++) {
       heapSketch.update(i);
     }
-    final DoublesSketch directSketch = 
DoublesSketch.wrap(MemorySegment.ofArray(heapSketch.toByteArray(false)));
+    final DoublesSketch directSketch = 
DoublesSketch.wrap(MemorySegment.ofArray(heapSketch.toByteArray(false)), null);
 
     assertEquals(directSketch.getMinItem(), 0.0);
     assertEquals(directSketch.getMaxItem(), 999.0);
@@ -91,8 +91,8 @@ public class DoublesSketchTest {
     assertEquals(sketch1.getMinItem(), sketch2.getMinItem());
     assertEquals(sketch1.getMaxItem(), sketch2.getMaxItem());
 
-    final DoublesSketchAccessor accessor1 = 
DoublesSketchAccessor.wrap(sketch1);
-    final DoublesSketchAccessor accessor2 = 
DoublesSketchAccessor.wrap(sketch2);
+    final DoublesSketchAccessor accessor1 = 
DoublesSketchAccessor.wrap(sketch1, false);
+    final DoublesSketchAccessor accessor2 = 
DoublesSketchAccessor.wrap(sketch2, false);
 
     // Compare base buffers. Already confirmed n and k match.
     for (int i = 0; i < accessor1.numItems(); ++i) {
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/DoublesUnionBuilderTest.java 
b/src/test/java/org/apache/datasketches/quantiles/DoublesUnionBuilderTest.java
index 5d4677ef6..d2f1d6e9f 100644
--- 
a/src/test/java/org/apache/datasketches/quantiles/DoublesUnionBuilderTest.java
+++ 
b/src/test/java/org/apache/datasketches/quantiles/DoublesUnionBuilderTest.java
@@ -35,7 +35,7 @@ public class DoublesUnionBuilderTest {
 
     final int bytes = qs1.getCurrentCompactSerializedSizeBytes();
     final MemorySegment dstSeg = MemorySegment.ofArray(new byte[bytes]);
-    qs1.putMemorySegment(dstSeg);
+    qs1.putIntoMemorySegment(dstSeg);
     final MemorySegment srcSeg = dstSeg;
 
     final DoublesUnionBuilder bldr = new DoublesUnionBuilder();
@@ -62,7 +62,7 @@ public void checkDeprecated1() {
 
   final int bytes = qs1.getCurrentCompactSerializedSizeBytes();
   final MemorySegment dstSeg = MemorySegment.ofArray(new byte[bytes]);
-  qs1.putMemorySegment(dstSeg);
+  qs1.putIntoMemorySegment(dstSeg);
   final MemorySegment srcSeg = dstSeg;
 
   final DoublesUnionBuilder bldr = new DoublesUnionBuilder();
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/DoublesUnionImplTest.java 
b/src/test/java/org/apache/datasketches/quantiles/DoublesUnionImplTest.java
index 0a44c501b..f122108df 100644
--- a/src/test/java/org/apache/datasketches/quantiles/DoublesUnionImplTest.java
+++ b/src/test/java/org/apache/datasketches/quantiles/DoublesUnionImplTest.java
@@ -371,7 +371,7 @@ public class DoublesUnionImplTest {
     union.union(sketch2);
     union.union(sketch1);
     final MemorySegment seg = 
MemorySegment.ofArray(union.getResult().toByteArray(true));
-    final DoublesSketch result = DoublesSketch.wrap(seg);
+    final DoublesSketch result = DoublesSketch.wrap(seg, null);
     assertEquals(result.getN(), n1 + n2);
     assertEquals(result.getK(), k);
 
@@ -397,7 +397,7 @@ public class DoublesUnionImplTest {
     final DoublesSketch qs1 = buildAndLoadQS(256, 1000);
     final int bytes = qs1.getCurrentCompactSerializedSizeBytes();
     final MemorySegment dstSeg = MemorySegment.ofArray(new byte[bytes]);
-    qs1.putMemorySegment(dstSeg);
+    qs1.putIntoMemorySegment(dstSeg);
     final MemorySegment srcSeg = dstSeg;
 
     final DoublesUnion union = DoublesUnion.builder().build(); //virgin
@@ -415,7 +415,7 @@ public class DoublesUnionImplTest {
     final DoublesSketch qs1 = buildAndLoadDQS(256, 1000);
     final int bytes = qs1.getCurrentCompactSerializedSizeBytes();
     final MemorySegment dstSeg = MemorySegment.ofArray(new byte[bytes]);
-    qs1.putMemorySegment(dstSeg);
+    qs1.putIntoMemorySegment(dstSeg);
     final MemorySegment srcSeg = dstSeg;
 
     final DoublesUnion union = DoublesUnion.builder().build(); //virgin
@@ -685,7 +685,7 @@ public class DoublesUnionImplTest {
 
     final byte[] byteArr = sketch.toByteArray(false);
     final MemorySegment seg = MemorySegment.ofArray(byteArr);
-    final DoublesUnion union = DoublesUnion.wrap(seg);
+    final DoublesUnion union = DoublesUnion.writableWrap(seg);
     Assert.assertFalse(union.isEmpty());
     assertTrue(union.hasMemorySegment());
     assertFalse(union.isOffHeap());
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/DoublesUtilTest.java 
b/src/test/java/org/apache/datasketches/quantiles/DoublesUtilTest.java
index 00e3782a3..d1993e143 100644
--- a/src/test/java/org/apache/datasketches/quantiles/DoublesUtilTest.java
+++ b/src/test/java/org/apache/datasketches/quantiles/DoublesUtilTest.java
@@ -85,7 +85,7 @@ public class DoublesUtilTest {
 
     // DirectCompactDoublesSketch
     final MemorySegment seg2 = MemorySegment.ofArray(hcds.toByteArray());
-    final DirectCompactDoublesSketch dcds = (DirectCompactDoublesSketch) 
DoublesSketch.wrap(seg2);
+    final DirectCompactDoublesSketch dcds = (DirectCompactDoublesSketch) 
DoublesSketch.wrap(seg2, null);
     final HeapUpdateDoublesSketch target4 = DoublesUtil.copyToHeap(dcds);
     DoublesSketchTest.testSketchEquality(huds, dcds);
     DoublesSketchTest.testSketchEquality(dcds, target4);
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketchTest.java
 
b/src/test/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketchTest.java
index 3fa387aec..9d4ff0e2b 100644
--- 
a/src/test/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketchTest.java
+++ 
b/src/test/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketchTest.java
@@ -411,7 +411,7 @@ public class HeapUpdateDoublesSketchTest {
     byteArr = qs.toByteArray(false);
     seg = MemorySegment.ofArray(byteArr);
     qs2 = DoublesSketch.heapify(seg);
-    final DoublesSketchAccessor dsa = DoublesSketchAccessor.wrap(qs2);
+    final DoublesSketchAccessor dsa = DoublesSketchAccessor.wrap(qs2, false);
     dsa.sort();
     for (double f = 0.1; f < 0.95; f += 0.1) {
       assertEquals(qs.getQuantile(f), qs2.getQuantile(f), 0.0);
@@ -747,7 +747,7 @@ public class HeapUpdateDoublesSketchTest {
     }
     final int bytes = qs1.getCurrentUpdatableSerializedSizeBytes();
     final MemorySegment dstSeg = MemorySegment.ofArray(new byte[bytes]);
-    qs1.putMemorySegment(dstSeg, false);
+    qs1.putIntoMemorySegment(dstSeg, false);
     final MemorySegment srcSeg = dstSeg;
     final DoublesSketch qs2 = DoublesSketch.heapify(srcSeg);
     assertEquals(qs1.getMinItem(), qs2.getMinItem(), 0.0);
@@ -762,7 +762,7 @@ public class HeapUpdateDoublesSketchTest {
     }
     final int bytes = qs1.getCurrentCompactSerializedSizeBytes();
     final MemorySegment dstSeg = MemorySegment.ofArray(new byte[bytes-1]); 
//too small
-    qs1.putMemorySegment(dstSeg);
+    qs1.putIntoMemorySegment(dstSeg);
   }
 
   //Himanshu's case
@@ -774,7 +774,7 @@ public class HeapUpdateDoublesSketchTest {
     final int k = 1024;
     final DoublesSketch qsk = new DoublesSketchBuilder().setK(k).build();
     final DoublesUnion u1 = DoublesUnion.heapify(qsk);
-    u1.getResult().putMemorySegment(seg);
+    u1.getResult().putIntoMemorySegment(seg);
     final DoublesUnion u2 = DoublesUnion.heapify(seg);
     final DoublesSketch qsk2 = u2.getResult();
     assertTrue(qsk2.isEmpty());
@@ -1039,15 +1039,15 @@ public class HeapUpdateDoublesSketchTest {
   /**
    * @param s value to print
    */
-  static void println(final String s) {
-    print(s+LS);
+  static void println(final Object o) {
+    print(o.toString() + LS);
   }
 
   /**
    * @param s value to print
    */
-  static void print(final String s) {
-    //System.err.print(s); //disable here
+  static void print(final Object o) {
+    //System.out.print(o.toString()); //disable here
   }
 
 }
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/QuantilesSketchCrossLanguageTest.java
 
b/src/test/java/org/apache/datasketches/quantiles/QuantilesSketchCrossLanguageTest.java
index 20ceab5ca..0a4ed3c15 100644
--- 
a/src/test/java/org/apache/datasketches/quantiles/QuantilesSketchCrossLanguageTest.java
+++ 
b/src/test/java/org/apache/datasketches/quantiles/QuantilesSketchCrossLanguageTest.java
@@ -92,7 +92,7 @@ public class QuantilesSketchCrossLanguageTest {
     final int[] nArr = {0, 1, 10, 100, 1000, 10000, 100000, 1000000};
     for (final int n: nArr) {
       final byte[] byteArr = 
Files.readAllBytes(cppPath.resolve("quantiles_double_n" + n + "_cpp.sk"));
-      final DoublesSketch sk = 
DoublesSketch.wrap(MemorySegment.ofArray(byteArr));
+      final DoublesSketch sk = 
DoublesSketch.wrap(MemorySegment.ofArray(byteArr), null);
       assertTrue(n == 0 ? sk.isEmpty() : !sk.isEmpty());
       assertTrue(n > 128 ? sk.isEstimationMode() : !sk.isEstimationMode());
       assertEquals(sk.getN(), n);
diff --git 
a/src/test/java/org/apache/datasketches/quantiles/ReadOnlyMemoryTest.java 
b/src/test/java/org/apache/datasketches/quantiles/ReadOnlyMemoryTest.java
index 42d9a0357..4407ebdc5 100644
--- a/src/test/java/org/apache/datasketches/quantiles/ReadOnlyMemoryTest.java
+++ b/src/test/java/org/apache/datasketches/quantiles/ReadOnlyMemoryTest.java
@@ -19,33 +19,47 @@
 
 package org.apache.datasketches.quantiles;
 
+import static 
org.apache.datasketches.common.MemorySegmentStatus.isSameResource;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
 import java.lang.foreign.MemorySegment;
 
 import org.apache.datasketches.common.SketchesArgumentException;
 import org.apache.datasketches.common.SketchesReadOnlyException;
+import org.apache.datasketches.common.SketchesStateException;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 public class ReadOnlyMemoryTest {
 
   @Test
-  public void wrapAndTryUpdatingSparseSketch() {
-    final UpdateDoublesSketch s1 = DoublesSketch.builder().build();
-    s1.update(1);
-    s1.update(2);
-    final byte[] bytes = s1.toByteArray(false);
-    Assert.assertEquals(bytes.length, 64); // 32 + MIN_K(=2) * 2 * 8 = 64
-    //final MemorySegment seg = MemorySegment.ofArray(ByteBuffer.wrap(bytes)
-    // .asReadOnlyBuffer().order(ByteOrder.nativeOrder()));
+  public void wrapAndTryUpdatingReadOnlySketch() {
+    final UpdateDoublesSketch sk1 = DoublesSketch.builder().build();
+    sk1.update(1);
+    sk1.update(2);
+    final byte[] bytes = sk1.toByteArray(false);
+    final int curBytes = sk1.getCurrentUpdatableSerializedSizeBytes();
+    Assert.assertEquals(bytes.length, curBytes);
+    //convert to MemorySegment
     final MemorySegment seg = MemorySegment.ofArray(bytes);
-    final UpdateDoublesSketch s2 = (UpdateDoublesSketch) 
DoublesSketch.wrap(seg);
-    Assert.assertEquals(s2.getMinItem(), 1.0);
-    Assert.assertEquals(s2.getMaxItem(), 2.0);
-
+    final UpdateDoublesSketch sk2 = (UpdateDoublesSketch) 
DoublesSketch.wrap(seg, null);
+    assertEquals(seg.byteSize(), curBytes);
+    sk2.update(3);
+    sk2.update(4);
+    assertEquals(sk2.getMinItem(), 1.0);
+    assertEquals(sk2.getMaxItem(), 4.0);
+    //check the size for just 4 elements
+    final MemorySegment seg2 = sk2.getMemorySegment();
+    assertEquals(seg2.byteSize(), 
DoublesSketch.getUpdatableStorageBytes(sk2.getK(), sk2.getN()));
+
+    //Now set to read only
+    sk2.setReadOnly();
     try {
-      s2.update(3);
+      //println(sk2.toString(true, true));
+      sk2.update(5);
+      //println(sk2.toString(true, true));
       fail();
     } catch (final SketchesReadOnlyException e) {
       // expected
@@ -60,10 +74,10 @@ public class ReadOnlyMemoryTest {
     //MemorySegment seg = 
MemorySegment.ofArray(ByteBuffer.wrap(s1.compact().toByteArray())
     // .asReadOnlyBuffer().order(ByteOrder.nativeOrder())););
     final MemorySegment seg = 
MemorySegment.ofArray(s1.compact().toByteArray());
-    final DoublesSketch s2 = DoublesSketch.wrap(seg); // compact, so this is ok
-    Assert.assertEquals(s2.getMinItem(), 1.0);
-    Assert.assertEquals(s2.getMaxItem(), 2.0);
-    Assert.assertEquals(s2.getN(), 2);
+    final DoublesSketch s2 = DoublesSketch.wrap(seg, null); // compact, so 
this is ok
+    assertEquals(s2.getMinItem(), 1.0);
+    assertEquals(s2.getMaxItem(), 2.0);
+    assertEquals(s2.getN(), 2);
   }
 
   @Test
@@ -73,8 +87,8 @@ public class ReadOnlyMemoryTest {
     s1.update(2);
     final MemorySegment seg = MemorySegment.ofArray(s1.toByteArray(false));
     final DoublesSketch s2 = DoublesSketch.heapify(seg);
-    Assert.assertEquals(s2.getMinItem(), 1.0);
-    Assert.assertEquals(s2.getMaxItem(), 2.0);
+    assertEquals(s2.getMinItem(), 1.0);
+    assertEquals(s2.getMaxItem(), 2.0);
   }
 
   @Test
@@ -85,8 +99,8 @@ public class ReadOnlyMemoryTest {
     final MemorySegment seg = MemorySegment.ofArray(s1.toByteArray(false));
     final UpdateDoublesSketch s2 = (UpdateDoublesSketch) 
DoublesSketch.heapify(seg);
     s2.update(3);
-    Assert.assertEquals(s2.getMinItem(), 1.0);
-    Assert.assertEquals(s2.getMaxItem(), 3.0);
+    assertEquals(s2.getMinItem(), 1.0);
+    assertEquals(s2.getMaxItem(), 3.0);
   }
 
   @Test
@@ -96,8 +110,8 @@ public class ReadOnlyMemoryTest {
     s1.update(2);
     final MemorySegment seg = MemorySegment.ofArray(s1.toByteArray(true));
     final DoublesSketch s2 = DoublesSketch.heapify(seg);
-    Assert.assertEquals(s2.getMinItem(), 1.0);
-    Assert.assertEquals(s2.getMaxItem(), 2.0);
+    assertEquals(s2.getMinItem(), 1.0);
+    assertEquals(s2.getMaxItem(), 2.0);
   }
 
   @Test
@@ -105,7 +119,7 @@ public class ReadOnlyMemoryTest {
     final UpdateDoublesSketch s1 = DoublesSketch.builder().build();
     final MemorySegment seg = MemorySegment.ofArray(s1.toByteArray());
     final DoublesSketch s2 = DoublesSketch.heapify(seg);
-    Assert.assertTrue(s2.isEmpty());
+    assertTrue(s2.isEmpty());
   }
 
   @Test
@@ -113,15 +127,15 @@ public class ReadOnlyMemoryTest {
     final CompactDoublesSketch s1 = DoublesSketch.builder().build().compact();
     final MemorySegment seg = MemorySegment.ofArray(s1.toByteArray());
     final DoublesSketch s2 = DoublesSketch.heapify(seg);
-    Assert.assertTrue(s2.isEmpty());
+    assertTrue(s2.isEmpty());
   }
 
   @Test
   public void wrapEmptyUpdateSketch() {
     final UpdateDoublesSketch s1 = DoublesSketch.builder().build();
-    final MemorySegment seg = MemorySegment.ofArray(s1.toByteArray());
-    final UpdateDoublesSketch s2 = (UpdateDoublesSketch) 
DoublesSketch.wrap(seg);
-    Assert.assertTrue(s2.isEmpty());
+    final MemorySegment seg = 
MemorySegment.ofArray(s1.toByteArray()).asReadOnly();
+    final UpdateDoublesSketch s2 = (UpdateDoublesSketch) 
DoublesSketch.wrap(seg, null);
+    assertTrue(s2.isEmpty());
 
     // ensure the various put calls fail
     try {
@@ -186,7 +200,7 @@ public class ReadOnlyMemoryTest {
   public void wrapEmptyCompactSketch() {
     final UpdateDoublesSketch s1 = DoublesSketch.builder().build();
     final MemorySegment seg = 
MemorySegment.ofArray(s1.compact().toByteArray());
-    final DoublesSketch s2 = DoublesSketch.wrap(seg); // compact, so this is ok
+    final DoublesSketch s2 = DoublesSketch.wrap(seg, null); // compact, so 
this is ok
     Assert.assertTrue(s2.isEmpty());
   }
 
@@ -217,51 +231,17 @@ public class ReadOnlyMemoryTest {
   }
 
   @Test
-  public void wrapUnionFromSparse() {
+  public void wrapUnionFromHeap() {
     final UpdateDoublesSketch s1 = DoublesSketch.builder().build();
     s1.update(1);
     s1.update(2);
     final MemorySegment seg = 
MemorySegment.ofArray(s1.toByteArray(false)).asReadOnly();
-    final DoublesUnion u = DoublesUnion.wrap(seg);
-    final DoublesSketch s2 = u.getResult();
-    Assert.assertEquals(s2.getMinItem(), 1.0);
-    Assert.assertEquals(s2.getMaxItem(), 2.0);
-
-    // ensure update and reset methods fail
     try {
-      u.update(3);
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
-    }
-
-    try {
-      u.union(s2);
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
-    }
-
-    try {
-      u.union(seg);
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
-    }
-
-    try {
-      u.reset();
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
+      final DoublesUnion u = DoublesUnion.writableWrap(seg);
+    } catch (final SketchesReadOnlyException e) {
+      //expected
     }
 
-    try {
-      u.getResultAndReset();
-      fail();
-    } catch (final IllegalArgumentException e) { //null
-      // expected
-    }
   }
 
   @Test(expectedExceptions = SketchesArgumentException.class)
@@ -270,8 +250,16 @@ public class ReadOnlyMemoryTest {
     s1.update(1);
     s1.update(2);
     final MemorySegment seg = MemorySegment.ofArray(s1.toByteArray(true));
-    DoublesUnion.wrap(seg);
+    DoublesUnion.writableWrap(seg); //not from compact
     fail();
   }
 
+  /**
+   * println
+   * @param o object to print
+   */
+  private static void println(final Object o) {
+    System.out.println(o.toString());
+  }
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to