Date: Tue, 29 Mar 2022 21:05:46 -0700
Subject: [PATCH 19/31] Fix issues reported in PR Review, branch "Direct kll
double" #360
---
.../kll/KllDirectDoublesSketch.java | 20 ++---
.../kll/KllDirectFloatsSketch.java | 20 ++---
.../datasketches/kll/KllDirectSketch.java | 31 ++++----
.../datasketches/kll/KllDoublesSketch.java | 33 +++++----
.../datasketches/kll/KllFloatsSketch.java | 33 +++++----
.../datasketches/kll/KllHeapSketch.java | 2 +-
.../apache/datasketches/kll/KllHelper.java | 12 ++-
...ryValidate.java => KllMemoryValidate.java} | 74 ++++++++++---------
.../datasketches/kll/KllPreambleUtil.java | 2 +-
.../apache/datasketches/kll/KllSketch.java | 63 ++++++++++------
.../apache/datasketches/kll/package-info.java | 2 +-
.../kll/KllDirectDoublesSketchTest.java | 18 ++---
.../kll/KllDirectFloatsSketchTest.java | 18 ++---
.../datasketches/kll/MemoryValidateTest.java | 26 +++----
.../kll/MiscDirectDoublesTest.java | 41 +++++-----
.../kll/MiscDirectFloatsTest.java | 68 +++++++++--------
.../datasketches/kll/MiscDoublesTest.java | 45 +++--------
.../datasketches/kll/MiscFloatsTest.java | 45 +++--------
18 files changed, 272 insertions(+), 281 deletions(-)
rename src/main/java/org/apache/datasketches/kll/{MemoryValidate.java => KllMemoryValidate.java} (86%)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 547aff0bb..be377a005 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -36,6 +36,8 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR32;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR33;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -58,7 +60,7 @@ public final class KllDirectDoublesSketch extends KllDirectSketch {
* @param memVal the MemoryValadate object
*/
private KllDirectDoublesSketch(final WritableMemory wmem, final MemoryRequestServer memReqSvr,
- final MemoryValidate memVal) {
+ final KllMemoryValidate memVal) {
super(SketchType.DOUBLES_SKETCH, wmem, memReqSvr, memVal);
}
@@ -70,12 +72,12 @@ private KllDirectDoublesSketch(final WritableMemory wmem, final MemoryRequestSer
* @return instance of this sketch
*/
public static KllDirectDoublesSketch writableWrap(final WritableMemory srcMem, final MemoryRequestServer memReqSvr) {
- final MemoryValidate memVal = new MemoryValidate(srcMem);
+ final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
return new KllDirectDoublesSketch(srcMem, memReqSvr, memVal);
}
/**
- * Create a new instance of this sketch using default M.
+ * Create a new instance of this sketch using the default m of 8.
* @param k parameter that controls size of the sketch and accuracy of estimates
* @param dstMem the given destination WritableMemory object for use by the sketch
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
@@ -94,7 +96,7 @@ public static KllDirectDoublesSketch newInstance(final int k, final WritableMemo
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
* @return a new instance of this sketch
*/
- public static KllDirectDoublesSketch newInstance(final int k, final int m, final WritableMemory dstMem,
+ static KllDirectDoublesSketch newInstance(final int k, final int m, final WritableMemory dstMem,
final MemoryRequestServer memReqSvr) {
insertPreInts(dstMem, PREAMBLE_INTS_DOUBLE);
insertSerVer(dstMem, SERIAL_VERSION_UPDATABLE);
@@ -111,7 +113,7 @@ public static KllDirectDoublesSketch newInstance(final int k, final int m, final
dstMem.putDoubleArray(offset, new double[] {Double.NaN, Double.NaN}, 0, 2);
offset += 2 * Double.BYTES;
dstMem.putDoubleArray(offset, new double[k], 0, k);
- final MemoryValidate memVal = new MemoryValidate(dstMem);
+ final KllMemoryValidate memVal = new KllMemoryValidate(dstMem);
return new KllDirectDoublesSketch(dstMem, memReqSvr, memVal);
}
@@ -216,7 +218,7 @@ public double getQuantile(final double fraction) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public double getQuantileLowerBound(final double fraction) {
- return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDyMinK(), false)));
+ return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
}
/**
@@ -268,7 +270,7 @@ public double[] getQuantiles(final int numEvenlySpaced) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public double getQuantileUpperBound(final double fraction) {
- return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDyMinK(), false)));
+ return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
}
/**
@@ -299,8 +301,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(32); }
- if (!other.isDoublesSketch()) { kllSketchThrow(33); }
+ if (!other.isDirect()) { kllSketchThrow(ERR32); }
+ if (!other.isDoublesSketch()) { kllSketchThrow(ERR33); }
mergeDoubleImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index 97c214a01..92447f62e 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -35,6 +35,8 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR32;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR34;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -58,7 +60,7 @@ public final class KllDirectFloatsSketch extends KllDirectSketch {
* @param memVal the MemoryValadate object
*/
private KllDirectFloatsSketch(final WritableMemory wmem, final MemoryRequestServer memReqSvr,
- final MemoryValidate memVal) {
+ final KllMemoryValidate memVal) {
super(SketchType.FLOATS_SKETCH, wmem, memReqSvr, memVal);
}
@@ -70,12 +72,12 @@ private KllDirectFloatsSketch(final WritableMemory wmem, final MemoryRequestServ
* @return instance of this sketch
*/
public static KllDirectFloatsSketch writableWrap(final WritableMemory srcMem, final MemoryRequestServer memReqSvr) {
- final MemoryValidate memVal = new MemoryValidate(srcMem);
+ final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
return new KllDirectFloatsSketch(srcMem, memReqSvr, memVal);
}
/**
- * Create a new instance of this sketch using default M.
+ * Create a new instance of this sketch using the default m of 8.
* @param k parameter that controls size of the sketch and accuracy of estimates
* @param dstMem the given destination WritableMemory object for use by the sketch
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
@@ -94,7 +96,7 @@ public static KllDirectFloatsSketch newInstance(final int k, final WritableMemor
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
* @return a new instance of this sketch
*/
- public static KllDirectFloatsSketch newInstance(final int k, final int m, final WritableMemory dstMem,
+ static KllDirectFloatsSketch newInstance(final int k, final int m, final WritableMemory dstMem,
final MemoryRequestServer memReqSvr) {
insertPreInts(dstMem, PREAMBLE_INTS_FLOAT);
insertSerVer(dstMem, SERIAL_VERSION_UPDATABLE);
@@ -111,7 +113,7 @@ public static KllDirectFloatsSketch newInstance(final int k, final int m, final
dstMem.putFloatArray(offset, new float[] {Float.NaN, Float.NaN}, 0, 2);
offset += 2 * Float.BYTES;
dstMem.putFloatArray(offset, new float[k], 0, k);
- final MemoryValidate memVal = new MemoryValidate(dstMem);
+ final KllMemoryValidate memVal = new KllMemoryValidate(dstMem);
return new KllDirectFloatsSketch(dstMem, memReqSvr, memVal);
}
@@ -216,7 +218,7 @@ public float getQuantile(final double fraction) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public float getQuantileLowerBound(final double fraction) {
- return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDyMinK(), false)));
+ return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
}
/**
@@ -268,7 +270,7 @@ public float[] getQuantiles(final int numEvenlySpaced) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public float getQuantileUpperBound(final double fraction) {
- return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDyMinK(), false)));
+ return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
}
/**
@@ -299,8 +301,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(32); }
- if (!other.isFloatsSketch()) { kllSketchThrow(34); }
+ if (!other.isDirect()) { kllSketchThrow(ERR32); }
+ if (!other.isFloatsSketch()) { kllSketchThrow(ERR34); }
mergeFloatImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index ef1009819..8cdde3eea 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -31,6 +31,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
import static org.apache.datasketches.kll.KllSketch.SketchType.FLOATS_SKETCH;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR30;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
@@ -55,7 +56,7 @@ abstract class KllDirectSketch extends KllSketch {
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
*/
KllDirectSketch(final SketchType sketchType, final WritableMemory wmem, final MemoryRequestServer memReqSvr,
- final MemoryValidate memVal) {
+ final KllMemoryValidate memVal) {
super(sketchType, wmem, memReqSvr);
levelsArrUpdatable = memVal.levelsArrUpdatable;
minMaxArrUpdatable = memVal.minMaxArrUpdatable;
@@ -101,7 +102,7 @@ public byte[] toUpdatableByteArray() {
}
@Override
- int getDyMinK() {
+ int getDynamicMinK() {
return extractDyMinK(wmem);
}
@@ -164,14 +165,14 @@ int getNumLevels() {
@Override
void incN() {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
long n = extractN(wmem);
insertN(wmem, ++n);
}
@Override
void incNumLevels() {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
int numLevels = extractNumLevels(wmem);
insertNumLevels(wmem, ++numLevels);
}
@@ -183,7 +184,7 @@ boolean isLevelZeroSorted() {
@Override
void setDoubleItemsArray(final double[] doubleItems) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
itemsArrUpdatable.putDoubleArray(0, doubleItems, 0, doubleItems.length);
}
@@ -194,13 +195,13 @@ void setDoubleItemsArrayAt(final int index, final double value) {
@Override
void setDyMinK(final int dyMinK) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
insertDyMinK(wmem, dyMinK);
}
@Override
void setFloatItemsArray(final float[] floatItems) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
itemsArrUpdatable.putFloatArray(0, floatItems, 0, floatItems.length);
}
@@ -216,7 +217,7 @@ void setItemsArrayUpdatable(final WritableMemory itemsMem) {
@Override
void setLevelsArray(final int[] levelsArr) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
levelsArrUpdatable.putIntArray(0, levelsArr, 0, levelsArr.length);
}
@@ -246,31 +247,31 @@ void setLevelsArrayUpdatable(final WritableMemory levelsMem) {
@Override
void setLevelZeroSorted(final boolean sorted) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
insertLevelZeroSortedFlag(wmem, sorted);
}
@Override
void setMaxDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
minMaxArrUpdatable.putDouble(Double.BYTES, value);
}
@Override
void setMaxFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
minMaxArrUpdatable.putFloat(Float.BYTES, value);
}
@Override
void setMinDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
minMaxArrUpdatable.putDouble(0, value);
}
@Override
void setMinFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
minMaxArrUpdatable.putFloat(0, value);
}
@@ -281,13 +282,13 @@ void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) {
@Override
void setN(final long n) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
insertN(wmem, n);
}
@Override
void setNumLevels(final int numLevels) {
- if (!updatable) { kllSketchThrow(30); }
+ if (!updatable) { kllSketchThrow(ERR30); }
insertNumLevels(wmem, numLevels);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 952d258ed..b9e97577f 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -23,6 +23,9 @@
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR33;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR35;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR50;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
@@ -84,7 +87,7 @@ public KllDoublesSketch(final int k, final int m) {
* @param mem Memory object that contains data serialized by this sketch.
* @param memVal the MemoryCheck object
*/
- private KllDoublesSketch(final Memory mem, final MemoryValidate memVal) {
+ private KllDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
super(memVal.k, memVal.m, SketchType.DOUBLES_SKETCH);
buildHeapKllSketchFromMemory(memVal);
}
@@ -99,7 +102,7 @@ private KllDoublesSketch(final Memory mem, final MemoryValidate memVal) {
//To simplify the code, the MemoryValidate class does nearly all the validity checking.
//The validated Memory is then passed to the actual private heapify constructor.
public static KllDoublesSketch heapify(final Memory mem) {
- final MemoryValidate memChk = new MemoryValidate(mem);
+ final KllMemoryValidate memChk = new KllMemoryValidate(mem);
if (!memChk.doublesSketch) {
throw new SketchesArgumentException("Memory object is not a KllDoublesSketch.");
}
@@ -203,7 +206,7 @@ public double getQuantile(final double fraction) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public double getQuantileLowerBound(final double fraction) {
- return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDyMinK(), false)));
+ return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
}
/**
@@ -255,7 +258,7 @@ public double[] getQuantiles(final int numEvenlySpaced) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public double getQuantileUpperBound(final double fraction) {
- return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDyMinK(), false)));
+ return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
}
/**
@@ -286,8 +289,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (other.isDirect()) { kllSketchThrow(35); }
- if (!other.isDoublesSketch()) { kllSketchThrow(33); }
+ if (other.isDirect()) { kllSketchThrow(ERR35); }
+ if (!other.isDoublesSketch()) { kllSketchThrow(ERR33); }
mergeDoubleImpl(other);
}
@@ -296,7 +299,7 @@ public void merge(final KllSketch other) {
*
* @param value an item from a stream of items. NaNs are ignored.
*/
- public void update(final double value) { //possibly move proxy
+ public void update(final double value) {
updateDouble(value);
}
@@ -307,22 +310,22 @@ public void update(final double value) { //possibly move proxy
double getDoubleItemsArrayAt(final int index) { return doubleItems_[index]; }
@Override //Dummy
- float[] getFloatItemsArray() { return null; }
+ float[] getFloatItemsArray() { kllSketchThrow(ERR50); return null; }
@Override //Dummy
- float getFloatItemsArrayAt(final int index) { return Float.NaN; }
+ float getFloatItemsArrayAt(final int index) { kllSketchThrow(ERR50); return Float.NaN; }
@Override //Used internally
double getMaxDoubleValue() { return maxDoubleValue_; }
@Override //Dummy
- float getMaxFloatValue() { return (float) maxDoubleValue_; }
+ float getMaxFloatValue() { kllSketchThrow(ERR50); return (float) maxDoubleValue_; }
@Override //Used internally
double getMinDoubleValue() { return minDoubleValue_; }
@Override //Dummy
- float getMinFloatValue() { return (float) minDoubleValue_; }
+ float getMinFloatValue() { kllSketchThrow(ERR50); return (float) minDoubleValue_; }
@Override //Used internally
void setDoubleItemsArray(final double[] doubleItems) { doubleItems_ = doubleItems; }
@@ -331,21 +334,21 @@ public void update(final double value) { //possibly move proxy
void setDoubleItemsArrayAt(final int index, final double value) { doubleItems_[index] = value; }
@Override //Dummy
- void setFloatItemsArray(final float[] floatItems) { }
+ void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(ERR50); }
@Override //Dummy
- void setFloatItemsArrayAt(final int index, final float value) { }
+ void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(ERR50); }
@Override //Used internally
void setMaxDoubleValue(final double value) { maxDoubleValue_ = value; }
@Override //Dummy
- void setMaxFloatValue(final float value) { }
+ void setMaxFloatValue(final float value) { kllSketchThrow(ERR50); }
@Override //Used internally
void setMinDoubleValue(final double value) { minDoubleValue_ = value; }
@Override //Dummy
- void setMinFloatValue(final float value) { }
+ void setMinFloatValue(final float value) { kllSketchThrow(ERR50); }
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 6faec6acf..5921f556a 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -23,6 +23,9 @@
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR34;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR35;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR50;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
@@ -84,7 +87,7 @@ public KllFloatsSketch(final int k, final int m) {
* @param mem Memory object that contains data serialized by this sketch.
* @param memVal the MemoryCheck object
*/
- private KllFloatsSketch(final Memory mem, final MemoryValidate memVal) {
+ private KllFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
super(memVal.k, memVal.m, SketchType.FLOATS_SKETCH);
buildHeapKllSketchFromMemory(memVal);
}
@@ -99,7 +102,7 @@ private KllFloatsSketch(final Memory mem, final MemoryValidate memVal) {
//To simplify the code, the MemoryValidate class does nearly all the validity checking.
//The validated Memory is then passed to the actual private heapify constructor.
public static KllFloatsSketch heapify(final Memory mem) {
- final MemoryValidate memVal = new MemoryValidate(mem);
+ final KllMemoryValidate memVal = new KllMemoryValidate(mem);
if (memVal.doublesSketch) {
throw new SketchesArgumentException("Memory object is not a KllFloatsSketch.");
}
@@ -203,7 +206,7 @@ public float getQuantile(final double fraction) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public float getQuantileLowerBound(final double fraction) {
- return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDyMinK(), false)));
+ return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
}
/**
@@ -255,7 +258,7 @@ public float[] getQuantiles(final int numEvenlySpaced) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public float getQuantileUpperBound(final double fraction) {
- return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDyMinK(), false)));
+ return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
}
/**
@@ -286,8 +289,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllFloatsSketch other) {
- if (other.isDirect()) { kllSketchThrow(35); }
- if (!other.isFloatsSketch()) { kllSketchThrow(34); }
+ if (other.isDirect()) { kllSketchThrow(ERR35); }
+ if (!other.isFloatsSketch()) { kllSketchThrow(ERR34); }
mergeFloatImpl(other);
}
@@ -301,10 +304,10 @@ public void update(final float value) {
}
@Override //Dummy
- double[] getDoubleItemsArray() { return null; }
+ double[] getDoubleItemsArray() { kllSketchThrow(ERR50); return null; }
@Override //Dummy
- double getDoubleItemsArrayAt(final int index) { return Double.NaN; }
+ double getDoubleItemsArrayAt(final int index) { kllSketchThrow(ERR50); return Double.NaN; }
@Override //Used internally
float[] getFloatItemsArray() { return floatItems_; }
@@ -313,37 +316,37 @@ public void update(final float value) {
float getFloatItemsArrayAt(final int index) { return floatItems_[index]; }
@Override //Dummy
- double getMaxDoubleValue() { return maxFloatValue_; }
+ double getMaxDoubleValue() { kllSketchThrow(ERR50); return maxFloatValue_; }
@Override //Used internally
float getMaxFloatValue() { return maxFloatValue_; }
@Override //Dummy
- double getMinDoubleValue() { return minFloatValue_; }
+ double getMinDoubleValue() { kllSketchThrow(ERR50); return minFloatValue_; }
@Override //Used internally
float getMinFloatValue() { return minFloatValue_; }
@Override //Dummy
- void setDoubleItemsArray(final double[] doubleItems) { }
+ void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(ERR50); }
@Override //Dummy
- void setDoubleItemsArrayAt(final int index, final double value) { }
+ void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(ERR50); }
@Override //Used internally
void setFloatItemsArray(final float[] floatItems) { floatItems_ = floatItems; }
- @Override
+ @Override //Used internally
void setFloatItemsArrayAt(final int index, final float value) { floatItems_[index] = value; }
@Override //Dummy
- void setMaxDoubleValue(final double value) { }
+ void setMaxDoubleValue(final double value) { kllSketchThrow(ERR50); }
@Override //Used internally
void setMaxFloatValue(final float value) { maxFloatValue_ = value; }
@Override //Dummy
- void setMinDoubleValue(final double value) { }
+ void setMinDoubleValue(final double value) { kllSketchThrow(ERR50); }
@Override //Used internally
void setMinFloatValue(final float value) { minFloatValue_ = value; }
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java b/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
index 94c295af0..81c56aa71 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
@@ -71,7 +71,7 @@ public long getN() {
}
@Override
- int getDyMinK() {
+ int getDynamicMinK() {
return dyMinK_;
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllHelper.java b/src/main/java/org/apache/datasketches/kll/KllHelper.java
index ba06282e8..09d8fde47 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHelper.java
@@ -24,6 +24,12 @@
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
+import static org.apache.datasketches.kll.KllSketch.CDF_COEF;
+import static org.apache.datasketches.kll.KllSketch.CDF_EXP;
+import static org.apache.datasketches.kll.KllSketch.MAX_M;
+import static org.apache.datasketches.kll.KllSketch.MIN_M;
+import static org.apache.datasketches.kll.KllSketch.PMF_COEF;
+import static org.apache.datasketches.kll.KllSketch.PMF_EXP;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
import org.apache.datasketches.SketchesArgumentException;
@@ -195,7 +201,7 @@ static void checkK(final int k, final int m) {
}
static void checkM(final int m) {
- if (m < 2 || m > 8 || ((m & 1) == 1)) {
+ if (m < MIN_M || m > MAX_M || ((m & 1) == 1)) {
throw new SketchesArgumentException(
"M must be >= 2, <= 8 and even: " + m);
}
@@ -257,8 +263,8 @@ static int findLevelToCompact(final int k, final int m, final int numLevels, fin
// thousands of trials
static double getNormalizedRankError(final int k, final boolean pmf) {
return pmf
- ? 2.446 / pow(k, 0.9433)
- : 2.296 / pow(k, 0.9723);
+ ? PMF_COEF / pow(k, PMF_EXP)
+ : CDF_COEF / pow(k, CDF_EXP);
}
static int getNumRetainedAboveLevelZero(final int numLevels, final int[] levels) {
diff --git a/src/main/java/org/apache/datasketches/kll/MemoryValidate.java b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
similarity index 86%
rename from src/main/java/org/apache/datasketches/kll/MemoryValidate.java
rename to src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
index f7a9ce881..9015081ba 100644
--- a/src/main/java/org/apache/datasketches/kll/MemoryValidate.java
+++ b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
@@ -20,6 +20,14 @@
package org.apache.datasketches.kll;
import static org.apache.datasketches.Family.idToFamily;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR0;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR1;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR10;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR2;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR20;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR4;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR5;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR6;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
@@ -57,7 +65,7 @@
* @author lrhodes
*
*/
-final class MemoryValidate {
+final class KllMemoryValidate {
// first 8 bytes
final int preInts; // = extractPreInts(srcMem);
final int serVer;
@@ -92,13 +100,13 @@ final class MemoryValidate {
WritableMemory minMaxArrUpdatable;
WritableMemory itemsArrUpdatable;
- MemoryValidate(final Memory srcMem) {
+ KllMemoryValidate(final Memory srcMem) {
memCapacity = (int) srcMem.getCapacity();
preInts = extractPreInts(srcMem);
serVer = extractSerVer(srcMem);
familyID = extractFamilyID(srcMem);
- if (familyID != Family.KLL.getID()) { memoryValidateThrow(0, familyID); }
+ if (familyID != Family.KLL.getID()) { memoryValidateThrow(MERR0, familyID); }
famName = idToFamily(familyID).toString();
flags = extractFlags(srcMem);
empty = extractEmptyFlag(srcMem);
@@ -110,19 +118,19 @@ final class MemoryValidate {
m = extractM(srcMem);
KllHelper.checkM(m);
KllHelper.checkK(k, m);
- if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(10, 0); }
+ if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(MERR10, 0); }
if (updatable) { updatableMemoryValidate((WritableMemory) srcMem); }
else { compactMemoryValidate(srcMem); }
}
void compactMemoryValidate(final Memory srcMem) {
- if (empty && singleItem) { memoryValidateThrow(20, 0); }
+ if (empty && singleItem) { memoryValidateThrow(MERR20, 0); }
final int sw = (empty ? 1 : 0) | (singleItem ? 4 : 0) | (doublesSketch ? 8 : 0);
switch (sw) {
case 0: { //FLOAT_FULL_COMPACT
- if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(6, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(2, serVer); }
+ if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(MERR6, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(MERR2, serVer); }
layout = Layout.FLOAT_FULL_COMPACT;
n = extractN(srcMem);
dyMinK = extractDyMinK(srcMem);
@@ -148,8 +156,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 1: { //FLOAT_EMPTY_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(1, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(2, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(MERR1, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(MERR2, serVer); }
layout = Layout.FLOAT_EMPTY_COMPACT;
n = 0; //assumed
dyMinK = k; //assumed
@@ -167,8 +175,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 4: { //FLOAT_SINGLE_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(1, preInts); }
- if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(4, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(MERR1, preInts); }
+ if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(MERR4, serVer); }
layout = Layout.FLOAT_SINGLE_COMPACT;
n = 1;
dyMinK = k;
@@ -189,8 +197,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 8: { //DOUBLE_FULL_COMPACT
- if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(5, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(2, serVer); }
+ if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(MERR5, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(MERR2, serVer); }
layout = Layout.DOUBLE_FULL_COMPACT;
n = extractN(srcMem);
dyMinK = extractDyMinK(srcMem);
@@ -216,8 +224,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 9: { //DOUBLE_EMPTY_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(1, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(2, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(MERR1, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(MERR2, serVer); }
layout = Layout.DOUBLE_EMPTY_COMPACT;
n = 0;
dyMinK = k;
@@ -236,8 +244,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 12: { //DOUBLE_SINGLE_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(1, preInts); }
- if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(4, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(MERR1, preInts); }
+ if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(MERR4, serVer); }
layout = Layout.DOUBLE_SINGLE_COMPACT;
n = 1;
dyMinK = k;
@@ -264,7 +272,7 @@ void compactMemoryValidate(final Memory srcMem) {
void updatableMemoryValidate(final WritableMemory wSrcMem) {
if (doublesSketch) { //DOUBLE_UPDATABLE
- if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(5, preInts); }
+ if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(MERR5, preInts); }
layout = Layout.DOUBLE_UPDATABLE;
n = extractN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
@@ -287,7 +295,7 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
sketchBytes = offset + itemsArrBytes;
}
else { //FLOAT_UPDATABLE
- if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(6, preInts); }
+ if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(MERR6, preInts); }
layout = Layout.FLOAT_UPDATABLE;
n = extractN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
@@ -310,25 +318,19 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
}
}
- private static void memoryValidateThrow(final int errNo, final int value) {
+ enum MERRNO { MERR0, MERR1, MERR2, MERR4, MERR5, MERR6, MERR10, MERR20 }
+
+ private static void memoryValidateThrow(final MERRNO errNo, final int value) {
String msg = "";
switch (errNo) {
- case 0: msg = "FamilyID Field must be: " + Family.KLL.getID() + ", NOT: " + value; break;
- case 1: msg = "Empty Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: " + value; break;
- case 2: msg = "Empty Bit: 1 -> SerVer: " + SERIAL_VERSION_EMPTY_FULL + ", NOT: " + value; break;
- //case 3: msg = "Single Item Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: " + value; break;
- case 4: msg = "Single Item Bit: 1 -> SerVer: " + SERIAL_VERSION_SINGLE + ", NOT: " + value; break;
- case 5: msg = "Double Sketch Bit: 1 -> PreInts: " + PREAMBLE_INTS_DOUBLE + ", NOT: " + value; break;
- case 6: msg = "Double Sketch Bit: 0 -> PreInts: " + PREAMBLE_INTS_FLOAT + ", NOT: " + value; break;
- //case 7: msg = "The M field must be set to " + DEFAULT_M + ", NOT: " + value; break;
- //case 8: msg = "The dynamic MinK must be equal to K, NOT: " + value; break;
- //case 9: msg = "numLevels must be one, NOT: " + value; break;
- case 10: msg = "((SerVer == 3) ^ (Updatable Bit)) must = 0."; break;
- case 20: msg = "Empty flag bit and SingleItem flag bit cannot both be set. Flags: " + value; break;
- //case 21: msg = "N != 0 and empty bit is set. N: " + value; break;
- //case 22: msg = "N != 1 and single item bit is set. N: " + value; break;
- //case 23: msg = "Family name is not KLL"; break;
- //case 24: msg = "Given Memory has insufficient capacity. Need " + value + " bytes."; break;
+ case MERR0: msg = "FamilyID Field must be: " + Family.KLL.getID() + ", NOT: " + value; break;
+ case MERR1: msg = "Empty Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: " + value; break;
+ case MERR2: msg = "Empty Bit: 1 -> SerVer: " + SERIAL_VERSION_EMPTY_FULL + ", NOT: " + value; break;
+ case MERR4: msg = "Single Item Bit: 1 -> SerVer: " + SERIAL_VERSION_SINGLE + ", NOT: " + value; break;
+ case MERR5: msg = "Double Sketch Bit: 1 -> PreInts: " + PREAMBLE_INTS_DOUBLE + ", NOT: " + value; break;
+ case MERR6: msg = "Double Sketch Bit: 0 -> PreInts: " + PREAMBLE_INTS_FLOAT + ", NOT: " + value; break;
+ case MERR10: msg = "((SerVer == 3) ^ (Updatable Bit)) must = 0."; break;
+ case MERR20: msg = "Empty flag bit and SingleItem flag bit cannot both be set. Flags: " + value; break;
default: msg = "Unknown error: errNo: " + errNo; break;
}
throw new SketchesArgumentException(msg);
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index 61d1f37fd..3fb4a4242 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -199,7 +199,7 @@ static String toString(final Memory mem) {
}
static String memoryToString(final Memory mem) {
- final MemoryValidate memChk = new MemoryValidate(mem);
+ final KllMemoryValidate memChk = new KllMemoryValidate(mem);
final int flags = memChk.flags & 0XFF;
final String flagsStr = (flags) + ", 0x" + (Integer.toHexString(flags)) + ", "
+ zeroPad(Integer.toBinaryString(flags), 8);
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index 97c98fd3d..d50cb2f12 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -27,10 +27,10 @@
import static java.lang.Math.min;
import static java.lang.Math.round;
import static org.apache.datasketches.Util.isOdd;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
+import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
import static org.apache.datasketches.kll.KllPreambleUtil.N_LONG_ADR;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_DOUBLE;
@@ -96,9 +96,16 @@
* @author Lee Rhodes, Kevin Lang
*/
public abstract class KllSketch {
+ static final int MIN_M = 2;
+ static final int MAX_M = 8;
+ static final double EPS_DELTA_THRESHOLD = 1E-6;
+ static final double MIN_EPS = 4.7634E-5;
+ static final double PMF_COEF = 2.446;
+ static final double PMF_EXP = 0.9433;
+ static final double CDF_COEF = 2.296;
+ static final double CDF_EXP = 0.9723;
static final Random random = new Random();
static final boolean compatible = true; //rank 0.0 and 1.0. compatible with classic Quantiles Sketch
- //final int M = DEFAULT_M; // configured minimum buffer "width", default is 8.
SketchType sketchType;
WritableMemory wmem;
MemoryRequestServer memReqSvr;
@@ -142,14 +149,14 @@ public enum SketchType { FLOATS_SKETCH, DOUBLES_SKETCH }
// thousands of trials
public static int getKFromEpsilon(final double epsilon, final boolean pmf) {
//Ensure that eps is >= than the lowest possible eps given MAX_K and pmf=false.
- final double eps = max(epsilon, 4.7634E-5);
+ final double eps = max(epsilon, MIN_EPS);
final double kdbl = pmf
- ? exp(log(2.446 / eps) / 0.9433)
- : exp(log(2.296 / eps) / 0.9723);
+ ? exp(log(PMF_COEF / eps) / PMF_EXP)
+ : exp(log(CDF_COEF / eps) / CDF_EXP);
final double krnd = round(kdbl);
final double del = abs(krnd - kdbl);
- final int k = (int) (del < 1E-6 ? krnd : ceil(kdbl));
- return max(2, min(MAX_K, k));
+ final int k = (int) (del < EPS_DELTA_THRESHOLD ? krnd : ceil(kdbl));
+ return max(MIN_M, min(MAX_K, k));
}
/**
@@ -230,15 +237,18 @@ final static boolean isCompatible() {
return compatible;
}
- final static void kllSketchThrow(final int errNo) {
+ enum ERRNO { ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR50 }
+
+ final static void kllSketchThrow(final ERRNO errNo) {
String msg = "";
switch (errNo) {
- case 30: msg = "Given sketch Memory is immutable, cannot write."; break;
- case 31: msg = "Given sketch Memory is immutable and incompatible."; break;
- case 32: msg = "Given sketch must be of type Direct."; break;
- case 33: msg = "Given sketch must be of type Double."; break;
- case 34: msg = "Given sketch must be of type Float."; break;
- case 35: msg = "Given sketch must not be of type Direct."; break;
+ case ERR30: msg = "Given sketch Memory is immutable, cannot write."; break;
+ case ERR31: msg = "Given sketch Memory is immutable and incompatible."; break;
+ case ERR32: msg = "Given sketch must be of type Direct."; break;
+ case ERR33: msg = "Given sketch must be of type Double."; break;
+ case ERR34: msg = "Given sketch must be of type Float."; break;
+ case ERR35: msg = "Given sketch must not be of type Direct."; break;
+ case ERR50: msg = "This is an artifact of inheritance and should never be called."; break;
default: msg = "Unknown error: errNo: " + errNo; break;
}
throw new SketchesArgumentException(msg);
@@ -294,7 +304,7 @@ public final int getCurrentUpdatableSerializedSizeBytes() {
* {@link org.apache.datasketches.kll}
*/
public final double getNormalizedRankError(final boolean pmf) {
- return getNormalizedRankError(getDyMinK(), pmf);
+ return getNormalizedRankError(getDynamicMinK(), pmf);
}
/**
@@ -367,7 +377,7 @@ public byte[] toUpdatableByteArray() {
//package-private non-static methods
- final void buildHeapKllSketchFromMemory(final MemoryValidate memVal) {
+ final void buildHeapKllSketchFromMemory(final KllMemoryValidate memVal) {
final boolean doubleType = (sketchType == DOUBLES_SKETCH);
final boolean updatable = memVal.updatable;
setLevelZeroSorted(memVal.level0Sorted);
@@ -511,7 +521,12 @@ final double[] getDoublesQuantiles(final double[] fractions) {
return quantiles;
}
- abstract int getDyMinK();
+ /**
+ * Dynamic MinK is the value of K that results from a merge with a sketch configured with a value of K lower than
+ * the k of this sketch. This value is then used in computing the estimated upper and lower bounds of error.
+ * @return The dynamic minimum K as a result of merging with lower values of k.
+ */
+ abstract int getDynamicMinK();
/**
* @return full size of internal items array including garbage; for a doubles sketch this will be null.
@@ -711,7 +726,7 @@ final void mergeDoubleImpl(final KllSketch other) {
// after the level 0 update, we capture the key mutable variables
final double myMin = getMinDoubleValue();
final double myMax = getMaxDoubleValue();
- final int myDyMinK = getDyMinK();
+ final int myDyMinK = getDynamicMinK();
final int myCurNumLevels = getNumLevels();
final int[] myCurLevelsArr = getLevelsArray();
@@ -779,7 +794,7 @@ final void mergeDoubleImpl(final KllSketch other) {
//Update Preamble:
setN(finalN);
if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
- setDyMinK(min(myDyMinK, other.getDyMinK()));
+ setDyMinK(min(myDyMinK, other.getDynamicMinK()));
}
//Update min, max values
@@ -821,7 +836,7 @@ final void mergeFloatImpl(final KllSketch other) {
// after the level 0 update, we capture the key mutable variables
final float myMin = getMinFloatValue();
final float myMax = getMaxFloatValue();
- final int myDyMinK = getDyMinK();
+ final int myDyMinK = getDynamicMinK();
final int myCurNumLevels = getNumLevels();
final int[] myCurLevelsArr = getLevelsArray();
@@ -889,7 +904,7 @@ final void mergeFloatImpl(final KllSketch other) {
//Update Preamble:
setN(finalN);
if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
- setDyMinK(min(myDyMinK, other.getDyMinK()));
+ setDyMinK(min(myDyMinK, other.getDynamicMinK()));
}
//Update min, max values
@@ -976,7 +991,7 @@ final byte[] toCompactByteArrayImpl() {
} else { // n > 1
//remainder of preamble after first 8 bytes
insertN(wmem, getN());
- insertDyMinK(wmem, getDyMinK());
+ insertDyMinK(wmem, getDynamicMinK());
insertNumLevels(wmem, getNumLevels());
offset = (doubleType) ? DATA_START_ADR_DOUBLE : DATA_START_ADR_FLOAT;
@@ -1041,7 +1056,7 @@ final String toStringImpl(final boolean withLevels, final boolean withData) {
final String skType = (direct ? "Direct" : "") + (doubleType ? "Doubles" : "Floats");
sb.append(Util.LS).append("### Kll").append(skType).append("Sketch Summary:").append(Util.LS);
sb.append(" K : ").append(k).append(Util.LS);
- sb.append(" Dynamic min K : ").append(getDyMinK()).append(Util.LS);
+ sb.append(" Dynamic min K : ").append(getDynamicMinK()).append(Util.LS);
sb.append(" M : ").append(m).append(Util.LS);
sb.append(" N : ").append(getN()).append(Util.LS);
sb.append(" Epsilon : ").append(epsPct).append(Util.LS);
@@ -1162,7 +1177,7 @@ final byte[] toUpdatableByteArrayImpl() {
loadFirst8Bytes(this, wmem, true);
//remainder of preamble after first 8 bytes
insertN(wmem, getN());
- insertDyMinK(wmem, getDyMinK());
+ insertDyMinK(wmem, getDynamicMinK());
insertNumLevels(wmem, getNumLevels());
//load data
diff --git a/src/main/java/org/apache/datasketches/kll/package-info.java b/src/main/java/org/apache/datasketches/kll/package-info.java
index 6dcc6c20d..3071c9766 100644
--- a/src/main/java/org/apache/datasketches/kll/package-info.java
+++ b/src/main/java/org/apache/datasketches/kll/package-info.java
@@ -35,7 +35,7 @@
*
* The normalized rank (rank) of any specific value is defined as its
* absolute rank divided by N.
- * Thus, the normalized rank is a value in the interval [0.0, 1.0), exclusive.
+ * Thus, the normalized rank is a value in the interval [0.0, 1.0).
* In the documentation and Javadocs for this sketch absolute rank is never used so any
* reference to just rank should be interpreted to mean normalized rank.
*
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
index c1b45b0ba..77c1e7814 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
@@ -314,7 +314,7 @@ public void maxK() {
}
@Test
- public void serializeDeserializeEmpty() { //compact serialize then heapify using KllDoublesSketch
+ public void serializeDeserializeEmptyViaCompactHeapify() {
final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
final byte[] bytes = sketch1.toByteArray();
final KllDoublesSketch sketch2 = KllDoublesSketch.heapify(Memory.wrap(bytes));
@@ -329,7 +329,7 @@ public void serializeDeserializeEmpty() { //compact serialize then heapify using
}
@Test
- public void serializeDeserializeEmpty2() { //updatable serialize then new (loaded) KllDirectDoublesSketch
+ public void serializeDeserializeEmptyViaUpdatableWritableWrap() {
final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
final byte[] bytes = sketch1.toUpdatableByteArray();
final KllDirectDoublesSketch sketch2 =
@@ -345,7 +345,7 @@ public void serializeDeserializeEmpty2() { //updatable serialize then new (loade
}
@Test
- public void serializeDeserializeOneItem() { //compact serialize then heapify using KllDoublesSketch
+ public void serializeDeserializeOneItemViaCompactHeapify() {
final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
sketch1.update(1);
final byte[] bytes = sketch1.toByteArray();
@@ -361,7 +361,7 @@ public void serializeDeserializeOneItem() { //compact serialize then heapify usi
}
@Test
- public void serializeDeserializeOneItem2() { //updatable serialize then new (loaded) KllDirectDoublesSketch
+ public void serializeDeserializeOneItemViaUpdatableWritableWrap() {
final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
sketch1.update(1);
final byte[] bytes = sketch1.toUpdatableByteArray();
@@ -378,7 +378,7 @@ public void serializeDeserializeOneItem2() { //updatable serialize then new (loa
}
@Test
- public void serializeDeserialize() { //compact serialize then heapify using KllDoublesSketch
+ public void serializeDeserializeFullViaCompactHeapify() {
final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
final int n = 1000;
for (int i = 0; i < n; i++) {
@@ -397,7 +397,7 @@ public void serializeDeserialize() { //compact serialize then heapify using KllD
}
@Test
- public void serializeDeserialize2() { //updatable serialize then new (loaded) KllDirectDoublesSketch
+ public void serializeDeserializeFullViaUpdatableWritableWrap() {
final KllDirectDoublesSketch sketch1 = getDDSketch(200, 0);
final int n = 1000;
for (int i = 0; i < n; i++) {
@@ -493,7 +493,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -513,7 +513,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -534,7 +534,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
index c5f40b546..d23979d67 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
@@ -313,7 +313,7 @@ public void maxK() {
}
@Test
- public void serializeDeserializeEmpty() { //compact serialize then heapify using KllDoublesSketch
+ public void serializeDeserializeEmptyViaCompactHeapify() {
final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
final byte[] bytes = sketch1.toByteArray();
final KllFloatsSketch sketch2 = KllFloatsSketch.heapify(Memory.wrap(bytes));
@@ -328,7 +328,7 @@ public void serializeDeserializeEmpty() { //compact serialize then heapify using
}
@Test
- public void serializeDeserializeEmpty2() { //updatable serialize then new (loaded) KllDirectDoublesSketch
+ public void serializeDeserializeEmptyViaUpdatableWritableWrap() {
final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
final byte[] bytes = sketch1.toUpdatableByteArray();
final KllDirectFloatsSketch sketch2 =
@@ -344,7 +344,7 @@ public void serializeDeserializeEmpty2() { //updatable serialize then new (loade
}
@Test
- public void serializeDeserializeOneItem() { //compact serialize then heapify using KllDoublesSketch
+ public void serializeDeserializeOneItemViaCompactHeapify() {
final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
sketch1.update(1);
final byte[] bytes = sketch1.toByteArray();
@@ -360,7 +360,7 @@ public void serializeDeserializeOneItem() { //compact serialize then heapify usi
}
@Test
- public void serializeDeserializeOneItem2() { //updatable serialize then new (loaded) KllDirectDoublesSketch
+ public void serializeDeserializeOneItemViaUpdatableWritableWrap() {
final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
sketch1.update(1);
final byte[] bytes = sketch1.toUpdatableByteArray();
@@ -377,7 +377,7 @@ public void serializeDeserializeOneItem2() { //updatable serialize then new (loa
}
@Test
- public void serializeDeserialize() { //compact serialize then heapify using KllDoublesSketch
+ public void serializeDeserializeFullViaCompactHeapify() {
final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
final int n = 1000;
for (int i = 0; i < n; i++) {
@@ -396,7 +396,7 @@ public void serializeDeserialize() { //compact serialize then heapify using KllD
}
@Test
- public void serializeDeserialize2() { //updatable serialize then new (loaded) KllDirectDoublesSketch
+ public void serializeDeserializeFullViaUpdatableWritableWrap() {
final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
final int n = 1000;
for (int i = 0; i < n; i++) {
@@ -492,7 +492,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0);
@@ -512,7 +512,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Double.NaN);
@@ -533,7 +533,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0);
diff --git a/src/test/java/org/apache/datasketches/kll/MemoryValidateTest.java b/src/test/java/org/apache/datasketches/kll/MemoryValidateTest.java
index 057a8bd8f..9ce967ea4 100644
--- a/src/test/java/org/apache/datasketches/kll/MemoryValidateTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MemoryValidateTest.java
@@ -35,7 +35,7 @@ public void checkInvalidFamily() {
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
insertFamilyID(wmem, Family.KLL.getID() - 1);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -44,7 +44,7 @@ public void checkInvalidSerVer() {
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL - 1);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -53,7 +53,7 @@ public void checkInvalidEmptyAndSingle() {
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
insertFlags(wmem, EMPTY_BIT_MASK | SINGLE_ITEM_BIT_MASK);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -63,7 +63,7 @@ public void checkInvalidUpdatableAndSerVer() {
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
insertFlags(wmem, UPDATABLE_BIT_MASK);
insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -73,7 +73,7 @@ public void checkInvalidPreIntsAndSingle() {
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
insertFlags(wmem, UPDATABLE_BIT_MASK);
insertSerVer(wmem, SERIAL_VERSION_SINGLE);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -83,7 +83,7 @@ public void checkInvalidSerVerAndSingle2() {
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
insertFlags(wmem, SINGLE_ITEM_BIT_MASK);
insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -93,7 +93,7 @@ public void checkInvalidPreIntsAndSingle2() {
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
insertFlags(wmem, SINGLE_ITEM_BIT_MASK);
insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -104,7 +104,7 @@ public void checkInvalidPreIntsAndDouble() {
insertFlags(wmem, DOUBLES_SKETCH_BIT_MASK);
insertPreInts(wmem, PREAMBLE_INTS_DOUBLE);
insertSerVer(wmem, SERIAL_VERSION_SINGLE);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -115,7 +115,7 @@ public void checkInvalidDoubleCompactAndSingle() {
insertFlags(wmem, SINGLE_ITEM_BIT_MASK | DOUBLES_SKETCH_BIT_MASK);
insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -126,7 +126,7 @@ public void checkInvalidDoubleUpdatableAndSerVer() {
insertSerVer(wmem, SERIAL_VERSION_UPDATABLE);
insertFlags(wmem, DOUBLES_SKETCH_BIT_MASK | UPDATABLE_BIT_MASK);
insertPreInts(wmem, PREAMBLE_INTS_DOUBLE - 1);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -137,7 +137,7 @@ public void checkInvalidFloatFullAndPreInts() {
insertFlags(wmem, 0); //float full
insertSerVer(wmem, SERIAL_VERSION_SINGLE); //should be 1
insertPreInts(wmem, PREAMBLE_INTS_FLOAT);
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -148,7 +148,7 @@ public void checkInvalidFloatUpdatableFullAndPreInts() {
insertFlags(wmem, UPDATABLE_BIT_MASK); //float updatable full
insertSerVer(wmem, SERIAL_VERSION_UPDATABLE);
insertPreInts(wmem, 0);//should be 5
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
@@ -159,7 +159,7 @@ public void checkInvalidDoubleCompactSingleAndPreInts() {
insertFlags(wmem, DOUBLES_SKETCH_BIT_MASK | SINGLE_ITEM_BIT_MASK);
insertPreInts(wmem, 5);//should be 2
insertSerVer(wmem, SERIAL_VERSION_SINGLE); //should be 2
- MemoryValidate memVal = new MemoryValidate(wmem);
+ KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
}
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java b/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
index d312056ca..c407b4e37 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
@@ -118,7 +118,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertTrue(Objects.isNull(sk.getFloatItemsArray()));
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
@@ -135,7 +135,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertTrue(Objects.isNull(sk.getFloatItemsArray()));
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
@@ -153,7 +153,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
+ assertEquals(sk.getDynamicMinK(), k);
assertTrue(Objects.isNull(sk.getFloatItemsArray()));
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
@@ -184,8 +184,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -205,8 +204,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -227,8 +225,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
@@ -258,8 +255,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -279,8 +275,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -301,8 +296,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
@@ -409,7 +403,20 @@ public void checkNewInstance() {
WritableMemory dstMem = WritableMemory.allocate(6000);
KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(k, dstMem, memReqSvr);
for (int i = 1; i <= 10_000; i++) {sk.update(i); }
- println(sk.toString(true, true));
+ assertEquals(sk.getMinValue(), 1.0);
+ assertEquals(sk.getMaxValue(), 10000.0);
+ //println(sk.toString(true, true));
+ }
+
+ @Test
+ public void checkDifferentM() {
+ int k = 20;
+ int m = 4;
+ WritableMemory dstMem = WritableMemory.allocate(1000);
+ KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(k, m, dstMem, memReqSvr);
+ for (int i = 1; i <= 200; i++) {sk.update(i); }
+ assertEquals(sk.getMinValue(), 1.0);
+ assertEquals(sk.getMaxValue(), 200.0);
}
private static KllDirectDoublesSketch getDDSketch(final int k, final int n) {
@@ -430,7 +437,7 @@ public void printlnTest() {
* @param s value to print
*/
static void println(final String s) {
- System.out.println(s); //disable here
+ //System.out.println(s); //disable here
}
}
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java b/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
index 4dfa54448..3bd1ce1d4 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
@@ -109,7 +109,7 @@ public void checkSketchInitializeFloatHeap() {
int k = 20; //don't change this
KllDirectFloatsSketch sk;
- //println("#### CASE: DOUBLE FULL HEAP");
+ //println("#### CASE: FLOAT FULL HEAP");
sk = getDFSketch(k, 0);
for (int i = 1; i <= k + 1; i++) { sk.update(i); }
//println(sk.toString(true, true));
@@ -118,8 +118,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -127,7 +126,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
- //println("#### CASE: DOUBLE HEAP EMPTY");
+ //println("#### CASE: FLOAT HEAP EMPTY");
sk = getDFSketch(k, 0);
//println(sk.toString(true, true));
assertEquals(sk.getK(), k);
@@ -135,8 +134,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -144,7 +142,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
- //println("#### CASE: DOUBLE HEAP SINGLE");
+ //println("#### CASE: FLOAT HEAP SINGLE");
sk = getDFSketch(k, 0);
sk.update(1);
//println(sk.toString(true, true));
@@ -153,8 +151,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
@@ -171,7 +168,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
byte[] compBytes;
WritableMemory wmem;
- //println("#### CASE: DOUBLE FULL HEAPIFIED FROM COMPACT");
+ //println("#### CASE: FLOAT FULL HEAPIFIED FROM COMPACT");
sk2 = getDFSketch(k, 0);
for (int i = 1; i <= k + 1; i++) { sk2.update(i); }
//println(sk.toString(true, true));
@@ -184,8 +181,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -193,7 +189,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
- //println("#### CASE: DOUBLE EMPTY HEAPIFIED FROM COMPACT");
+ //println("#### CASE: FLOAT EMPTY HEAPIFIED FROM COMPACT");
sk2 = getDFSketch(k, 0);
//println(sk.toString(true, true));
compBytes = sk2.toByteArray();
@@ -205,8 +201,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -214,7 +209,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
- //println("#### CASE: DOUBLE SINGLE HEAPIFIED FROM COMPACT");
+ //println("#### CASE: FLOAT SINGLE HEAPIFIED FROM COMPACT");
sk2 = getDFSketch(k, 0);
sk2.update(1);
//println(sk2.toString(true, true));
@@ -227,8 +222,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
@@ -245,7 +239,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
byte[] compBytes;
WritableMemory wmem;
- //println("#### CASE: DOUBLE FULL HEAPIFIED FROM UPDATABLE");
+ //println("#### CASE: FLOAT FULL HEAPIFIED FROM UPDATABLE");
sk2 = getDFSketch(k, 0);
for (int i = 1; i <= k + 1; i++) { sk2.update(i); }
//println(sk2.toString(true, true));
@@ -258,8 +252,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -267,7 +260,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
- // println("#### CASE: DOUBLE EMPTY HEAPIFIED FROM UPDATABLE");
+ // println("#### CASE: FLOAT EMPTY HEAPIFIED FROM UPDATABLE");
sk2 = getDFSketch(k, 0);
//println(sk.toString(true, true));
compBytes = sk2.toUpdatableByteArray();
@@ -279,8 +272,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -288,7 +280,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
- //println("#### CASE: DOUBLE SINGLE HEAPIFIED FROM UPDATABLE");
+ //println("#### CASE: FLOAT SINGLE HEAPIFIED FROM UPDATABLE");
sk2 = getDFSketch(k, 0);
sk2.update(1);
//println(sk.toString(true, true));
@@ -301,8 +293,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
@@ -321,7 +312,7 @@ public void checkMemoryToStringFloatUpdatable() {
WritableMemory wmem;
String s;
- println("#### CASE: DOUBLE FULL UPDATABLE");
+ println("#### CASE: FLOAT FULL UPDATABLE");
sk = getDFSketch(k, 0);
for (int i = 1; i <= k + 1; i++) { sk.update(i); }
upBytes = sk.toUpdatableByteArray();
@@ -337,7 +328,7 @@ public void checkMemoryToStringFloatUpdatable() {
println(s);
assertEquals(upBytes, upBytes2);
- println("#### CASE: DOUBLE EMPTY UPDATABLE");
+ println("#### CASE: FLOAT EMPTY UPDATABLE");
sk = getDFSketch(k, 0);
upBytes = sk.toUpdatableByteArray();
wmem = WritableMemory.writableWrap(upBytes);
@@ -352,7 +343,7 @@ public void checkMemoryToStringFloatUpdatable() {
println(s);
assertEquals(upBytes, upBytes2);
- println("#### CASE: DOUBLE SINGLE UPDATABL");
+ println("#### CASE: FLOAT SINGLE UPDATABL");
sk = getDFSketch(k, 0);
sk.update(1);
upBytes = sk.toUpdatableByteArray();
@@ -409,7 +400,20 @@ public void checkNewInstance() {
WritableMemory dstMem = WritableMemory.allocate(3000);
KllDirectFloatsSketch sk = KllDirectFloatsSketch.newInstance(k, dstMem, memReqSvr);
for (int i = 1; i <= 10_000; i++) {sk.update(i); }
- println(sk.toString(true, true));
+ assertEquals(sk.getMinValue(), 1.0F);
+ assertEquals(sk.getMaxValue(), 10000.0F);
+ //println(sk.toString(true, true));
+ }
+
+ @Test
+ public void checkDifferentM() {
+ int k = 20;
+ int m = 4;
+ WritableMemory dstMem = WritableMemory.allocate(1000);
+ KllDirectFloatsSketch sk = KllDirectFloatsSketch.newInstance(k, m, dstMem, memReqSvr);
+ for (int i = 1; i <= 200; i++) {sk.update(i); }
+ assertEquals(sk.getMinValue(), 1.0);
+ assertEquals(sk.getMaxValue(), 200.0);
}
private static KllDirectFloatsSketch getDFSketch(final int k, final int n) {
@@ -430,7 +434,7 @@ public void printlnTest() {
* @param s value to print
*/
static void println(final String s) {
- System.out.println(s); //disable here
+ //System.out.println(s); //disable here
}
}
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java b/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
index 1c14720e3..ba28c6034 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
@@ -173,14 +173,11 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
- assertEquals(sk.getMaxFloatValue(), 21.0F);
assertEquals(sk.getMinDoubleValue(), 1.0);
- assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
@@ -192,14 +189,11 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
- assertEquals(sk.getMaxFloatValue(), Float.NaN);
assertEquals(sk.getMinDoubleValue(), Double.NaN);
- assertEquals(sk.getMinFloatValue(), Float.NaN);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
@@ -212,14 +206,11 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
- assertEquals(sk.getMaxFloatValue(), 1.0F);
assertEquals(sk.getMinDoubleValue(), 1.0);
- assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
}
@@ -245,14 +236,11 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
- assertEquals(sk.getMaxFloatValue(), 21.0F);
assertEquals(sk.getMinDoubleValue(), 1.0);
- assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
@@ -268,14 +256,11 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
- assertEquals(sk.getMaxFloatValue(), Float.NaN);
assertEquals(sk.getMinDoubleValue(), Double.NaN);
- assertEquals(sk.getMinFloatValue(), Float.NaN);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
@@ -292,14 +277,11 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
- assertEquals(sk.getMaxFloatValue(), 1.0F);
assertEquals(sk.getMinDoubleValue(), 1.0);
- assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
}
@@ -325,14 +307,11 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
- assertEquals(sk.getMaxFloatValue(), 21.0F);
assertEquals(sk.getMinDoubleValue(), 1.0);
- assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
@@ -348,14 +327,11 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
- assertEquals(sk.getMaxFloatValue(), Float.NaN);
assertEquals(sk.getMinDoubleValue(), Double.NaN);
- assertEquals(sk.getMinFloatValue(), Float.NaN);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
@@ -372,14 +348,11 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
- assertEquals(sk.getMaxFloatValue(), 1.0F);
assertEquals(sk.getMinDoubleValue(), 1.0);
- assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
}
diff --git a/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java b/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
index 5e66aea89..c42e58557 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
@@ -173,13 +173,10 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
- assertEquals(sk.getMaxDoubleValue(), 21.0);
assertEquals(sk.getMaxFloatValue(), 21.0F);
- assertEquals(sk.getMinDoubleValue(), 1.0);
assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
@@ -192,13 +189,10 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
- assertEquals(sk.getMaxDoubleValue(), Double.NaN);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
- assertEquals(sk.getMinDoubleValue(), Double.NaN);
assertEquals(sk.getMinFloatValue(), Float.NaN);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
@@ -212,13 +206,10 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
- assertEquals(sk.getMaxDoubleValue(), 1.0);
assertEquals(sk.getMaxFloatValue(), 1.0F);
- assertEquals(sk.getMinDoubleValue(), 1.0);
assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
@@ -245,13 +236,10 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
- assertEquals(sk.getMaxDoubleValue(), 21.0);
assertEquals(sk.getMaxFloatValue(), 21.0F);
- assertEquals(sk.getMinDoubleValue(), 1.0);
assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
@@ -268,13 +256,10 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
- assertEquals(sk.getMaxDoubleValue(), Double.NaN);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
- assertEquals(sk.getMinDoubleValue(), Double.NaN);
assertEquals(sk.getMinFloatValue(), Float.NaN);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
@@ -292,13 +277,10 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
- assertEquals(sk.getMaxDoubleValue(), 1.0);
assertEquals(sk.getMaxFloatValue(), 1.0F);
- assertEquals(sk.getMinDoubleValue(), 1.0);
assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
@@ -325,13 +307,10 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
- assertEquals(sk.getMaxDoubleValue(), 21.0);
assertEquals(sk.getMaxFloatValue(), 21.0F);
- assertEquals(sk.getMinDoubleValue(), 1.0);
assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 2);
assertFalse(sk.isLevelZeroSorted());
@@ -348,13 +327,10 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
- assertEquals(sk.getMaxDoubleValue(), Double.NaN);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
- assertEquals(sk.getMinDoubleValue(), Double.NaN);
assertEquals(sk.getMinFloatValue(), Float.NaN);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
@@ -372,13 +348,10 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDyMinK(), k);
- assertTrue(Objects.isNull(sk.getDoubleItemsArray()));
+ assertEquals(sk.getDynamicMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
- assertEquals(sk.getMaxDoubleValue(), 1.0);
assertEquals(sk.getMaxFloatValue(), 1.0F);
- assertEquals(sk.getMinDoubleValue(), 1.0);
assertEquals(sk.getMinFloatValue(), 1.0F);
assertEquals(sk.getNumLevels(), 1);
assertFalse(sk.isLevelZeroSorted());
From 71af0d94f36e370e4a0eff8ced3ae89121070743 Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Wed, 30 Mar 2022 11:10:59 -0700
Subject: [PATCH 20/31] Fixed issues from latest comments.
---
.../kll/KllDirectDoublesSketch.java | 8 +-
.../kll/KllDirectFloatsSketch.java | 8 +-
.../datasketches/kll/KllDirectSketch.java | 28 +++----
.../datasketches/kll/KllDoublesSketch.java | 26 +++---
.../datasketches/kll/KllFloatsSketch.java | 26 +++---
.../datasketches/kll/KllMemoryValidate.java | 83 ++++++++++---------
.../apache/datasketches/kll/KllSketch.java | 22 ++---
7 files changed, 105 insertions(+), 96 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index be377a005..50cbae3ff 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -36,8 +36,8 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR32;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR33;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_DOUBLE;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -301,8 +301,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(ERR32); }
- if (!other.isDoublesSketch()) { kllSketchThrow(ERR33); }
+ if (!other.isDirect()) { kllSketchThrow(ERR_SRC_IS_NOT_DIRECT); }
+ if (!other.isDoublesSketch()) { kllSketchThrow(ERR_SRC_IS_NOT_DOUBLE); }
mergeDoubleImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index 92447f62e..c802a2495 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -35,8 +35,8 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR32;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR34;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_FLOAT;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -301,8 +301,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(ERR32); }
- if (!other.isFloatsSketch()) { kllSketchThrow(ERR34); }
+ if (!other.isDirect()) { kllSketchThrow(ERR_SRC_IS_NOT_DIRECT); }
+ if (!other.isFloatsSketch()) { kllSketchThrow(ERR_SRC_IS_NOT_FLOAT); }
mergeFloatImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index 8cdde3eea..6a559aee3 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -31,7 +31,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
import static org.apache.datasketches.kll.KllSketch.SketchType.FLOATS_SKETCH;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR30;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_TGT_IS_IMMUTABLE;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
@@ -165,14 +165,14 @@ int getNumLevels() {
@Override
void incN() {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
long n = extractN(wmem);
insertN(wmem, ++n);
}
@Override
void incNumLevels() {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
int numLevels = extractNumLevels(wmem);
insertNumLevels(wmem, ++numLevels);
}
@@ -184,7 +184,7 @@ boolean isLevelZeroSorted() {
@Override
void setDoubleItemsArray(final double[] doubleItems) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putDoubleArray(0, doubleItems, 0, doubleItems.length);
}
@@ -195,13 +195,13 @@ void setDoubleItemsArrayAt(final int index, final double value) {
@Override
void setDyMinK(final int dyMinK) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
insertDyMinK(wmem, dyMinK);
}
@Override
void setFloatItemsArray(final float[] floatItems) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putFloatArray(0, floatItems, 0, floatItems.length);
}
@@ -217,7 +217,7 @@ void setItemsArrayUpdatable(final WritableMemory itemsMem) {
@Override
void setLevelsArray(final int[] levelsArr) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
levelsArrUpdatable.putIntArray(0, levelsArr, 0, levelsArr.length);
}
@@ -247,31 +247,31 @@ void setLevelsArrayUpdatable(final WritableMemory levelsMem) {
@Override
void setLevelZeroSorted(final boolean sorted) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
insertLevelZeroSortedFlag(wmem, sorted);
}
@Override
void setMaxDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putDouble(Double.BYTES, value);
}
@Override
void setMaxFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putFloat(Float.BYTES, value);
}
@Override
void setMinDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putDouble(0, value);
}
@Override
void setMinFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putFloat(0, value);
}
@@ -282,13 +282,13 @@ void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) {
@Override
void setN(final long n) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
insertN(wmem, n);
}
@Override
void setNumLevels(final int numLevels) {
- if (!updatable) { kllSketchThrow(ERR30); }
+ if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
insertNumLevels(wmem, numLevels);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index b9e97577f..eb05d4688 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -23,9 +23,9 @@
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR33;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR35;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR50;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_DOUBLE;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_CANNOT_BE_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_MUST_NOT_CALL;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
@@ -289,8 +289,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (other.isDirect()) { kllSketchThrow(ERR35); }
- if (!other.isDoublesSketch()) { kllSketchThrow(ERR33); }
+ if (other.isDirect()) { kllSketchThrow(ERR_SRC_CANNOT_BE_DIRECT); }
+ if (!other.isDoublesSketch()) { kllSketchThrow(ERR_SRC_IS_NOT_DOUBLE); }
mergeDoubleImpl(other);
}
@@ -310,22 +310,22 @@ public void update(final double value) {
double getDoubleItemsArrayAt(final int index) { return doubleItems_[index]; }
@Override //Dummy
- float[] getFloatItemsArray() { kllSketchThrow(ERR50); return null; }
+ float[] getFloatItemsArray() { kllSketchThrow(ERR_MUST_NOT_CALL); return null; }
@Override //Dummy
- float getFloatItemsArrayAt(final int index) { kllSketchThrow(ERR50); return Float.NaN; }
+ float getFloatItemsArrayAt(final int index) { kllSketchThrow(ERR_MUST_NOT_CALL); return Float.NaN; }
@Override //Used internally
double getMaxDoubleValue() { return maxDoubleValue_; }
@Override //Dummy
- float getMaxFloatValue() { kllSketchThrow(ERR50); return (float) maxDoubleValue_; }
+ float getMaxFloatValue() { kllSketchThrow(ERR_MUST_NOT_CALL); return (float) maxDoubleValue_; }
@Override //Used internally
double getMinDoubleValue() { return minDoubleValue_; }
@Override //Dummy
- float getMinFloatValue() { kllSketchThrow(ERR50); return (float) minDoubleValue_; }
+ float getMinFloatValue() { kllSketchThrow(ERR_MUST_NOT_CALL); return (float) minDoubleValue_; }
@Override //Used internally
void setDoubleItemsArray(final double[] doubleItems) { doubleItems_ = doubleItems; }
@@ -334,21 +334,21 @@ public void update(final double value) {
void setDoubleItemsArrayAt(final int index, final double value) { doubleItems_[index] = value; }
@Override //Dummy
- void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(ERR50); }
+ void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(ERR_MUST_NOT_CALL); }
@Override //Dummy
- void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(ERR50); }
+ void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
@Override //Used internally
void setMaxDoubleValue(final double value) { maxDoubleValue_ = value; }
@Override //Dummy
- void setMaxFloatValue(final float value) { kllSketchThrow(ERR50); }
+ void setMaxFloatValue(final float value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
@Override //Used internally
void setMinDoubleValue(final double value) { minDoubleValue_ = value; }
@Override //Dummy
- void setMinFloatValue(final float value) { kllSketchThrow(ERR50); }
+ void setMinFloatValue(final float value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 5921f556a..2408b865f 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -23,9 +23,9 @@
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR34;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR35;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR50;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_FLOAT;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_CANNOT_BE_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_MUST_NOT_CALL;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
@@ -289,8 +289,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllFloatsSketch other) {
- if (other.isDirect()) { kllSketchThrow(ERR35); }
- if (!other.isFloatsSketch()) { kllSketchThrow(ERR34); }
+ if (other.isDirect()) { kllSketchThrow(ERR_SRC_CANNOT_BE_DIRECT); }
+ if (!other.isFloatsSketch()) { kllSketchThrow(ERR_SRC_IS_NOT_FLOAT); }
mergeFloatImpl(other);
}
@@ -304,10 +304,10 @@ public void update(final float value) {
}
@Override //Dummy
- double[] getDoubleItemsArray() { kllSketchThrow(ERR50); return null; }
+ double[] getDoubleItemsArray() { kllSketchThrow(ERR_MUST_NOT_CALL); return null; }
@Override //Dummy
- double getDoubleItemsArrayAt(final int index) { kllSketchThrow(ERR50); return Double.NaN; }
+ double getDoubleItemsArrayAt(final int index) { kllSketchThrow(ERR_MUST_NOT_CALL); return Double.NaN; }
@Override //Used internally
float[] getFloatItemsArray() { return floatItems_; }
@@ -316,22 +316,22 @@ public void update(final float value) {
float getFloatItemsArrayAt(final int index) { return floatItems_[index]; }
@Override //Dummy
- double getMaxDoubleValue() { kllSketchThrow(ERR50); return maxFloatValue_; }
+ double getMaxDoubleValue() { kllSketchThrow(ERR_MUST_NOT_CALL); return maxFloatValue_; }
@Override //Used internally
float getMaxFloatValue() { return maxFloatValue_; }
@Override //Dummy
- double getMinDoubleValue() { kllSketchThrow(ERR50); return minFloatValue_; }
+ double getMinDoubleValue() { kllSketchThrow(ERR_MUST_NOT_CALL); return minFloatValue_; }
@Override //Used internally
float getMinFloatValue() { return minFloatValue_; }
@Override //Dummy
- void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(ERR50); }
+ void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(ERR_MUST_NOT_CALL); }
@Override //Dummy
- void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(ERR50); }
+ void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
@Override //Used internally
void setFloatItemsArray(final float[] floatItems) { floatItems_ = floatItems; }
@@ -340,13 +340,13 @@ public void update(final float value) {
void setFloatItemsArrayAt(final int index, final float value) { floatItems_[index] = value; }
@Override //Dummy
- void setMaxDoubleValue(final double value) { kllSketchThrow(ERR50); }
+ void setMaxDoubleValue(final double value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
@Override //Used internally
void setMaxFloatValue(final float value) { maxFloatValue_ = value; }
@Override //Dummy
- void setMinDoubleValue(final double value) { kllSketchThrow(ERR50); }
+ void setMinDoubleValue(final double value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
@Override //Used internally
void setMinFloatValue(final float value) { minFloatValue_ = value; }
diff --git a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
index 9015081ba..1b9470ee3 100644
--- a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
+++ b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
@@ -20,14 +20,14 @@
package org.apache.datasketches.kll;
import static org.apache.datasketches.Family.idToFamily;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR0;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR1;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR10;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR2;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR20;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR4;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR5;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.MERR6;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_SRC_NOT_KLL;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_EMPTYBIT_AND_PREINTS;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_UPDATABLEBIT_AND_SER_VER;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_EMPTYBIT_AND_SER_VER;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_EMPTYBIT_AND_SINGLEBIT;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_SINGLEBIT_AND_SER_VER;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_DOUBLEBIT_AND_PREINTS;
+import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_FLOATBIT_AND_PREINTS;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
@@ -106,7 +106,7 @@ final class KllMemoryValidate {
serVer = extractSerVer(srcMem);
familyID = extractFamilyID(srcMem);
- if (familyID != Family.KLL.getID()) { memoryValidateThrow(MERR0, familyID); }
+ if (familyID != Family.KLL.getID()) { memoryValidateThrow(ERR_SRC_NOT_KLL, familyID); }
famName = idToFamily(familyID).toString();
flags = extractFlags(srcMem);
empty = extractEmptyFlag(srcMem);
@@ -118,19 +118,19 @@ final class KllMemoryValidate {
m = extractM(srcMem);
KllHelper.checkM(m);
KllHelper.checkK(k, m);
- if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(MERR10, 0); }
+ if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(ERR_UPDATABLEBIT_AND_SER_VER, 0); }
if (updatable) { updatableMemoryValidate((WritableMemory) srcMem); }
else { compactMemoryValidate(srcMem); }
}
void compactMemoryValidate(final Memory srcMem) {
- if (empty && singleItem) { memoryValidateThrow(MERR20, 0); }
+ if (empty && singleItem) { memoryValidateThrow(ERR_EMPTYBIT_AND_SINGLEBIT, 0); }
final int sw = (empty ? 1 : 0) | (singleItem ? 4 : 0) | (doublesSketch ? 8 : 0);
switch (sw) {
case 0: { //FLOAT_FULL_COMPACT
- if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(MERR6, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(MERR2, serVer); }
+ if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(ERR_FLOATBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(ERR_EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.FLOAT_FULL_COMPACT;
n = extractN(srcMem);
dyMinK = extractDyMinK(srcMem);
@@ -156,8 +156,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 1: { //FLOAT_EMPTY_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(MERR1, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(MERR2, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(ERR_EMPTYBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(ERR_EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.FLOAT_EMPTY_COMPACT;
n = 0; //assumed
dyMinK = k; //assumed
@@ -175,8 +175,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 4: { //FLOAT_SINGLE_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(MERR1, preInts); }
- if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(MERR4, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(ERR_EMPTYBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(ERR_SINGLEBIT_AND_SER_VER, serVer); }
layout = Layout.FLOAT_SINGLE_COMPACT;
n = 1;
dyMinK = k;
@@ -197,8 +197,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 8: { //DOUBLE_FULL_COMPACT
- if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(MERR5, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(MERR2, serVer); }
+ if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(ERR_DOUBLEBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(ERR_EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.DOUBLE_FULL_COMPACT;
n = extractN(srcMem);
dyMinK = extractDyMinK(srcMem);
@@ -224,8 +224,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 9: { //DOUBLE_EMPTY_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(MERR1, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(MERR2, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(ERR_EMPTYBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(ERR_EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.DOUBLE_EMPTY_COMPACT;
n = 0;
dyMinK = k;
@@ -244,8 +244,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 12: { //DOUBLE_SINGLE_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(MERR1, preInts); }
- if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(MERR4, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(ERR_EMPTYBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(ERR_SINGLEBIT_AND_SER_VER, serVer); }
layout = Layout.DOUBLE_SINGLE_COMPACT;
n = 1;
dyMinK = k;
@@ -272,7 +272,7 @@ void compactMemoryValidate(final Memory srcMem) {
void updatableMemoryValidate(final WritableMemory wSrcMem) {
if (doublesSketch) { //DOUBLE_UPDATABLE
- if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(MERR5, preInts); }
+ if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(ERR_DOUBLEBIT_AND_PREINTS, preInts); }
layout = Layout.DOUBLE_UPDATABLE;
n = extractN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
@@ -295,7 +295,7 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
sketchBytes = offset + itemsArrBytes;
}
else { //FLOAT_UPDATABLE
- if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(MERR6, preInts); }
+ if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(ERR_FLOATBIT_AND_PREINTS, preInts); }
layout = Layout.FLOAT_UPDATABLE;
n = extractN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
@@ -318,20 +318,29 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
}
}
- enum MERRNO { MERR0, MERR1, MERR2, MERR4, MERR5, MERR6, MERR10, MERR20 }
+ enum MERRNO { ERR_SRC_NOT_KLL, ERR_EMPTYBIT_AND_PREINTS, ERR_EMPTYBIT_AND_SER_VER,
+ ERR_SINGLEBIT_AND_SER_VER, ERR_DOUBLEBIT_AND_PREINTS, ERR_FLOATBIT_AND_PREINTS, ERR_UPDATABLEBIT_AND_SER_VER,
+ ERR_EMPTYBIT_AND_SINGLEBIT }
- private static void memoryValidateThrow(final MERRNO errNo, final int value) {
+ private static void memoryValidateThrow(final MERRNO errType, final int value) {
String msg = "";
- switch (errNo) {
- case MERR0: msg = "FamilyID Field must be: " + Family.KLL.getID() + ", NOT: " + value; break;
- case MERR1: msg = "Empty Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: " + value; break;
- case MERR2: msg = "Empty Bit: 1 -> SerVer: " + SERIAL_VERSION_EMPTY_FULL + ", NOT: " + value; break;
- case MERR4: msg = "Single Item Bit: 1 -> SerVer: " + SERIAL_VERSION_SINGLE + ", NOT: " + value; break;
- case MERR5: msg = "Double Sketch Bit: 1 -> PreInts: " + PREAMBLE_INTS_DOUBLE + ", NOT: " + value; break;
- case MERR6: msg = "Double Sketch Bit: 0 -> PreInts: " + PREAMBLE_INTS_FLOAT + ", NOT: " + value; break;
- case MERR10: msg = "((SerVer == 3) ^ (Updatable Bit)) must = 0."; break;
- case MERR20: msg = "Empty flag bit and SingleItem flag bit cannot both be set. Flags: " + value; break;
- default: msg = "Unknown error: errNo: " + errNo; break;
+ switch (errType) {
+ case ERR_SRC_NOT_KLL: msg = "FamilyID Field must be: " + Family.KLL.getID() + ", NOT: " + value; break;
+ case ERR_EMPTYBIT_AND_PREINTS: msg =
+ "Empty Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: " + value; break;
+ case ERR_EMPTYBIT_AND_SER_VER: msg =
+ "Empty Bit: 1 -> SerVer: " + SERIAL_VERSION_EMPTY_FULL + ", NOT: " + value; break;
+ case ERR_SINGLEBIT_AND_SER_VER: msg =
+ "Single Item Bit: 1 -> SerVer: " + SERIAL_VERSION_SINGLE + ", NOT: " + value; break;
+ case ERR_DOUBLEBIT_AND_PREINTS: msg =
+ "Double Sketch Bit: 1 -> PreInts: " + PREAMBLE_INTS_DOUBLE + ", NOT: " + value; break;
+ case ERR_FLOATBIT_AND_PREINTS: msg =
+ "Double Sketch Bit: 0 -> PreInts: " + PREAMBLE_INTS_FLOAT + ", NOT: " + value; break;
+ case ERR_UPDATABLEBIT_AND_SER_VER: msg =
+ "((SerVer == 3) ^ (Updatable Bit)) must = 0."; break;
+ case ERR_EMPTYBIT_AND_SINGLEBIT: msg =
+ "Empty flag bit and SingleItem flag bit cannot both be set. Flags: " + value; break;
+ default: msg = "Unknown error"; break;
}
throw new SketchesArgumentException(msg);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index d50cb2f12..b15faba3a 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -237,19 +237,19 @@ final static boolean isCompatible() {
return compatible;
}
- enum ERRNO { ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR50 }
+ enum ERRNO { ERR_TGT_IS_IMMUTABLE, ERR_SRC_IS_NOT_DIRECT, ERR_SRC_IS_NOT_DOUBLE,
+ ERR_SRC_IS_NOT_FLOAT, ERR_SRC_CANNOT_BE_DIRECT, ERR_MUST_NOT_CALL }
- final static void kllSketchThrow(final ERRNO errNo) {
+ final static void kllSketchThrow(final ERRNO errType) {
String msg = "";
- switch (errNo) {
- case ERR30: msg = "Given sketch Memory is immutable, cannot write."; break;
- case ERR31: msg = "Given sketch Memory is immutable and incompatible."; break;
- case ERR32: msg = "Given sketch must be of type Direct."; break;
- case ERR33: msg = "Given sketch must be of type Double."; break;
- case ERR34: msg = "Given sketch must be of type Float."; break;
- case ERR35: msg = "Given sketch must not be of type Direct."; break;
- case ERR50: msg = "This is an artifact of inheritance and should never be called."; break;
- default: msg = "Unknown error: errNo: " + errNo; break;
+ switch (errType) {
+ case ERR_TGT_IS_IMMUTABLE: msg = "Given sketch Memory is immutable, cannot write."; break;
+ case ERR_SRC_IS_NOT_DIRECT: msg = "Given sketch must be of type Direct."; break;
+ case ERR_SRC_IS_NOT_DOUBLE: msg = "Given sketch must be of type Double."; break;
+ case ERR_SRC_IS_NOT_FLOAT: msg = "Given sketch must be of type Float."; break;
+ case ERR_SRC_CANNOT_BE_DIRECT: msg = "Given sketch must not be of type Direct."; break;
+ case ERR_MUST_NOT_CALL: msg = "This is an artifact of inheritance and should never be called."; break;
+ default: msg = "Unknown error."; break;
}
throw new SketchesArgumentException(msg);
}
From 532a4e8a447ddb1ae175245ddd811caf16dcf9ea Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Wed, 30 Mar 2022 11:56:36 -0700
Subject: [PATCH 21/31] Found a few more miscellaneous items.
---
.../datasketches/kll/KllDoublesSketch.java | 28 ++++++++-----------
.../datasketches/kll/KllFloatsSketch.java | 28 ++++++++-----------
.../apache/datasketches/kll/KllHelper.java | 4 +--
.../datasketches/kll/KllPreambleUtil.java | 6 ++--
.../apache/datasketches/kll/KllSketch.java | 3 +-
5 files changed, 31 insertions(+), 38 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index eb05d4688..93bfc2f44 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -39,12 +39,20 @@
* @author Lee Rhodes, Kevin Lang
*/
public final class KllDoublesSketch extends KllHeapSketch {
-
- // Specific to the doubles sketch
- private double[] doubleItems_; // the continuous array of double items
+ private double[] doubleItems_;
private double minDoubleValue_;
private double maxDoubleValue_;
+ /**
+ * Private heapify constructor.
+ * @param mem Memory object that contains data serialized by this sketch.
+ * @param memVal the MemoryCheck object
+ */
+ private KllDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
+ super(memVal.k, memVal.m, SketchType.DOUBLES_SKETCH);
+ buildHeapKllSketchFromMemory(memVal);
+ }
+
/**
* Heap constructor with the default k = 200, and DEFAULT_M of 8.
* This will have a rank error of about 1.65%.
@@ -75,23 +83,13 @@ public KllDoublesSketch(final int k) {
* @param k parameter that controls size of the sketch and accuracy of estimates
* @param m parameter that controls the minimum level width.
*/
- public KllDoublesSketch(final int k, final int m) {
+ KllDoublesSketch(final int k, final int m) {
super(k, m, SketchType.DOUBLES_SKETCH);
doubleItems_ = new double[k];
minDoubleValue_ = Double.NaN;
maxDoubleValue_ = Double.NaN;
}
- /**
- * Private heapify constructor.
- * @param mem Memory object that contains data serialized by this sketch.
- * @param memVal the MemoryCheck object
- */
- private KllDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
- super(memVal.k, memVal.m, SketchType.DOUBLES_SKETCH);
- buildHeapKllSketchFromMemory(memVal);
- }
-
/**
* Factory heapify takes the sketch image in Memory and instantiates an on-heap sketch.
* The resulting sketch will not retain any link to the source Memory.
@@ -99,8 +97,6 @@ private KllDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
* See Memory
* @return a heap-based sketch based on the given Memory.
*/
- //To simplify the code, the MemoryValidate class does nearly all the validity checking.
- //The validated Memory is then passed to the actual private heapify constructor.
public static KllDoublesSketch heapify(final Memory mem) {
final KllMemoryValidate memChk = new KllMemoryValidate(mem);
if (!memChk.doublesSketch) {
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 2408b865f..57627e76f 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -39,12 +39,20 @@
* @author Lee Rhodes, Kevin Lang
*/
public final class KllFloatsSketch extends KllHeapSketch {
-
- // Specific to the floats sketch
- private float[] floatItems_; // the continuous array of float items
+ private float[] floatItems_;
private float minFloatValue_;
private float maxFloatValue_;
+ /**
+ * Private heapify constructor.
+ * @param mem Memory object that contains data serialized by this sketch.
+ * @param memVal the MemoryCheck object
+ */
+ private KllFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
+ super(memVal.k, memVal.m, SketchType.FLOATS_SKETCH);
+ buildHeapKllSketchFromMemory(memVal);
+ }
+
/**
* Heap constructor with the default k = 200, and DEFAULT_M of 8.
* This will have a rank error of about 1.65%.
@@ -75,23 +83,13 @@ public KllFloatsSketch(final int k) {
* @param k parameter that controls size of the sketch and accuracy of estimates
* @param m parameter that controls the minimum level width.
*/
- public KllFloatsSketch(final int k, final int m) {
+ KllFloatsSketch(final int k, final int m) {
super(k, m, SketchType.FLOATS_SKETCH);
floatItems_ = new float[k];
minFloatValue_ = Float.NaN;
maxFloatValue_ = Float.NaN;
}
- /**
- * Private heapify constructor.
- * @param mem Memory object that contains data serialized by this sketch.
- * @param memVal the MemoryCheck object
- */
- private KllFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
- super(memVal.k, memVal.m, SketchType.FLOATS_SKETCH);
- buildHeapKllSketchFromMemory(memVal);
- }
-
/**
* Factory heapify takes the sketch image in Memory and instantiates an on-heap sketch.
* The resulting sketch will not retain any link to the source Memory.
@@ -99,8 +97,6 @@ private KllFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
* See Memory
* @return a heap-based sketch based on the given Memory.
*/
- //To simplify the code, the MemoryValidate class does nearly all the validity checking.
- //The validated Memory is then passed to the actual private heapify constructor.
public static KllFloatsSketch heapify(final Memory mem) {
final KllMemoryValidate memVal = new KllMemoryValidate(mem);
if (memVal.doublesSketch) {
diff --git a/src/main/java/org/apache/datasketches/kll/KllHelper.java b/src/main/java/org/apache/datasketches/kll/KllHelper.java
index 09d8fde47..83e2bf45c 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHelper.java
@@ -24,10 +24,10 @@
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
+import static org.apache.datasketches.kll.KllPreambleUtil.MAX_M;
+import static org.apache.datasketches.kll.KllPreambleUtil.MIN_M;
import static org.apache.datasketches.kll.KllSketch.CDF_COEF;
import static org.apache.datasketches.kll.KllSketch.CDF_EXP;
-import static org.apache.datasketches.kll.KllSketch.MAX_M;
-import static org.apache.datasketches.kll.KllSketch.MIN_M;
import static org.apache.datasketches.kll.KllSketch.PMF_COEF;
import static org.apache.datasketches.kll.KllSketch.PMF_EXP;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index 3fb4a4242..2d006d48f 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -131,7 +131,9 @@ private KllPreambleUtil() {}
*/
public static final int DEFAULT_K = 200;
public static final int DEFAULT_M = 8;
- static final int MAX_K = (1 << 16) - 1; // serialized as an unsigned short
+ public static final int MAX_K = (1 << 16) - 1; // serialized as an unsigned short
+ public static final int MAX_M = 8;
+ public static final int MIN_M = 2;
// Preamble byte addresses
static final int PREAMBLE_INTS_BYTE_ADR = 0;
@@ -153,7 +155,7 @@ private KllPreambleUtil() {}
static final int DATA_START_ADR_FLOAT = 20; // float sketch, not single item
// DOUBLE SKETCH 19 to 23 is reserved for future use in double sketch
- static final int DATA_START_ADR_DOUBLE = 20; // double sketch, not single item //TODO??
+ static final int DATA_START_ADR_DOUBLE = 20; // double sketch, not single item
// Other static values
static final byte SERIAL_VERSION_EMPTY_FULL = 1; // Empty or full preamble, NOT single item format
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index b15faba3a..b93691a3c 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -32,6 +32,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
+import static org.apache.datasketches.kll.KllPreambleUtil.MIN_M;
import static org.apache.datasketches.kll.KllPreambleUtil.N_LONG_ADR;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_EMPTY_SINGLE;
@@ -96,8 +97,6 @@
* @author Lee Rhodes, Kevin Lang
*/
public abstract class KllSketch {
- static final int MIN_M = 2;
- static final int MAX_M = 8;
static final double EPS_DELTA_THRESHOLD = 1E-6;
static final double MIN_EPS = 4.7634E-5;
static final double PMF_COEF = 2.446;
From d446ae5c91a228a7ec35fa59c7cd6b0617e6ab27 Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Wed, 30 Mar 2022 13:35:11 -0700
Subject: [PATCH 22/31] Fixing feedback from Review.
---
.../kll/KllDirectDoublesSketch.java | 8 +-
.../kll/KllDirectFloatsSketch.java | 8 +-
.../datasketches/kll/KllDirectSketch.java | 28 +++----
.../datasketches/kll/KllDoublesSketch.java | 26 +++----
.../datasketches/kll/KllFloatsSketch.java | 26 +++----
.../datasketches/kll/KllMemoryValidate.java | 74 +++++++++----------
.../apache/datasketches/kll/KllSketch.java | 18 ++---
7 files changed, 94 insertions(+), 94 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 50cbae3ff..74ce437ea 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -36,8 +36,8 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_DIRECT;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_DOUBLE;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -301,8 +301,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(ERR_SRC_IS_NOT_DIRECT); }
- if (!other.isDoublesSketch()) { kllSketchThrow(ERR_SRC_IS_NOT_DOUBLE); }
+ if (!other.isDirect()) { kllSketchThrow(SRC_IS_NOT_DIRECT); }
+ if (!other.isDoublesSketch()) { kllSketchThrow(SRC_IS_NOT_DOUBLE); }
mergeDoubleImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index c802a2495..4198abbc8 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -35,8 +35,8 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_DIRECT;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_FLOAT;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -301,8 +301,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(ERR_SRC_IS_NOT_DIRECT); }
- if (!other.isFloatsSketch()) { kllSketchThrow(ERR_SRC_IS_NOT_FLOAT); }
+ if (!other.isDirect()) { kllSketchThrow(SRC_IS_NOT_DIRECT); }
+ if (!other.isFloatsSketch()) { kllSketchThrow(SRC_IS_NOT_FLOAT); }
mergeFloatImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index 6a559aee3..691106e63 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -31,7 +31,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
import static org.apache.datasketches.kll.KllSketch.SketchType.FLOATS_SKETCH;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_TGT_IS_IMMUTABLE;
+import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
@@ -165,14 +165,14 @@ int getNumLevels() {
@Override
void incN() {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
long n = extractN(wmem);
insertN(wmem, ++n);
}
@Override
void incNumLevels() {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
int numLevels = extractNumLevels(wmem);
insertNumLevels(wmem, ++numLevels);
}
@@ -184,7 +184,7 @@ boolean isLevelZeroSorted() {
@Override
void setDoubleItemsArray(final double[] doubleItems) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putDoubleArray(0, doubleItems, 0, doubleItems.length);
}
@@ -195,13 +195,13 @@ void setDoubleItemsArrayAt(final int index, final double value) {
@Override
void setDyMinK(final int dyMinK) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
insertDyMinK(wmem, dyMinK);
}
@Override
void setFloatItemsArray(final float[] floatItems) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putFloatArray(0, floatItems, 0, floatItems.length);
}
@@ -217,7 +217,7 @@ void setItemsArrayUpdatable(final WritableMemory itemsMem) {
@Override
void setLevelsArray(final int[] levelsArr) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
levelsArrUpdatable.putIntArray(0, levelsArr, 0, levelsArr.length);
}
@@ -247,31 +247,31 @@ void setLevelsArrayUpdatable(final WritableMemory levelsMem) {
@Override
void setLevelZeroSorted(final boolean sorted) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
insertLevelZeroSortedFlag(wmem, sorted);
}
@Override
void setMaxDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putDouble(Double.BYTES, value);
}
@Override
void setMaxFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putFloat(Float.BYTES, value);
}
@Override
void setMinDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putDouble(0, value);
}
@Override
void setMinFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putFloat(0, value);
}
@@ -282,13 +282,13 @@ void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) {
@Override
void setN(final long n) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
insertN(wmem, n);
}
@Override
void setNumLevels(final int numLevels) {
- if (!updatable) { kllSketchThrow(ERR_TGT_IS_IMMUTABLE); }
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
insertNumLevels(wmem, numLevels);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 93bfc2f44..8d249f908 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -23,9 +23,9 @@
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_DOUBLE;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_CANNOT_BE_DIRECT;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_MUST_NOT_CALL;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
@@ -285,8 +285,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (other.isDirect()) { kllSketchThrow(ERR_SRC_CANNOT_BE_DIRECT); }
- if (!other.isDoublesSketch()) { kllSketchThrow(ERR_SRC_IS_NOT_DOUBLE); }
+ if (other.isDirect()) { kllSketchThrow(SRC_CANNOT_BE_DIRECT); }
+ if (!other.isDoublesSketch()) { kllSketchThrow(SRC_IS_NOT_DOUBLE); }
mergeDoubleImpl(other);
}
@@ -306,22 +306,22 @@ public void update(final double value) {
double getDoubleItemsArrayAt(final int index) { return doubleItems_[index]; }
@Override //Dummy
- float[] getFloatItemsArray() { kllSketchThrow(ERR_MUST_NOT_CALL); return null; }
+ float[] getFloatItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
@Override //Dummy
- float getFloatItemsArrayAt(final int index) { kllSketchThrow(ERR_MUST_NOT_CALL); return Float.NaN; }
+ float getFloatItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
@Override //Used internally
double getMaxDoubleValue() { return maxDoubleValue_; }
@Override //Dummy
- float getMaxFloatValue() { kllSketchThrow(ERR_MUST_NOT_CALL); return (float) maxDoubleValue_; }
+ float getMaxFloatValue() { kllSketchThrow(MUST_NOT_CALL); return (float) maxDoubleValue_; }
@Override //Used internally
double getMinDoubleValue() { return minDoubleValue_; }
@Override //Dummy
- float getMinFloatValue() { kllSketchThrow(ERR_MUST_NOT_CALL); return (float) minDoubleValue_; }
+ float getMinFloatValue() { kllSketchThrow(MUST_NOT_CALL); return (float) minDoubleValue_; }
@Override //Used internally
void setDoubleItemsArray(final double[] doubleItems) { doubleItems_ = doubleItems; }
@@ -330,21 +330,21 @@ public void update(final double value) {
void setDoubleItemsArrayAt(final int index, final double value) { doubleItems_[index] = value; }
@Override //Dummy
- void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(ERR_MUST_NOT_CALL); }
+ void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(MUST_NOT_CALL); }
@Override //Dummy
- void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
+ void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(MUST_NOT_CALL); }
@Override //Used internally
void setMaxDoubleValue(final double value) { maxDoubleValue_ = value; }
@Override //Dummy
- void setMaxFloatValue(final float value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
+ void setMaxFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
@Override //Used internally
void setMinDoubleValue(final double value) { minDoubleValue_ = value; }
@Override //Dummy
- void setMinFloatValue(final float value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
+ void setMinFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 57627e76f..4ae3aa81c 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -23,9 +23,9 @@
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_IS_NOT_FLOAT;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_SRC_CANNOT_BE_DIRECT;
-import static org.apache.datasketches.kll.KllSketch.ERRNO.ERR_MUST_NOT_CALL;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
@@ -285,8 +285,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllFloatsSketch other) {
- if (other.isDirect()) { kllSketchThrow(ERR_SRC_CANNOT_BE_DIRECT); }
- if (!other.isFloatsSketch()) { kllSketchThrow(ERR_SRC_IS_NOT_FLOAT); }
+ if (other.isDirect()) { kllSketchThrow(SRC_CANNOT_BE_DIRECT); }
+ if (!other.isFloatsSketch()) { kllSketchThrow(SRC_IS_NOT_FLOAT); }
mergeFloatImpl(other);
}
@@ -300,10 +300,10 @@ public void update(final float value) {
}
@Override //Dummy
- double[] getDoubleItemsArray() { kllSketchThrow(ERR_MUST_NOT_CALL); return null; }
+ double[] getDoubleItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
@Override //Dummy
- double getDoubleItemsArrayAt(final int index) { kllSketchThrow(ERR_MUST_NOT_CALL); return Double.NaN; }
+ double getDoubleItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
@Override //Used internally
float[] getFloatItemsArray() { return floatItems_; }
@@ -312,22 +312,22 @@ public void update(final float value) {
float getFloatItemsArrayAt(final int index) { return floatItems_[index]; }
@Override //Dummy
- double getMaxDoubleValue() { kllSketchThrow(ERR_MUST_NOT_CALL); return maxFloatValue_; }
+ double getMaxDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return maxFloatValue_; }
@Override //Used internally
float getMaxFloatValue() { return maxFloatValue_; }
@Override //Dummy
- double getMinDoubleValue() { kllSketchThrow(ERR_MUST_NOT_CALL); return minFloatValue_; }
+ double getMinDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return minFloatValue_; }
@Override //Used internally
float getMinFloatValue() { return minFloatValue_; }
@Override //Dummy
- void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(ERR_MUST_NOT_CALL); }
+ void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(MUST_NOT_CALL); }
@Override //Dummy
- void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
+ void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(MUST_NOT_CALL); }
@Override //Used internally
void setFloatItemsArray(final float[] floatItems) { floatItems_ = floatItems; }
@@ -336,13 +336,13 @@ public void update(final float value) {
void setFloatItemsArrayAt(final int index, final float value) { floatItems_[index] = value; }
@Override //Dummy
- void setMaxDoubleValue(final double value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
+ void setMaxDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
@Override //Used internally
void setMaxFloatValue(final float value) { maxFloatValue_ = value; }
@Override //Dummy
- void setMinDoubleValue(final double value) { kllSketchThrow(ERR_MUST_NOT_CALL); }
+ void setMinDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
@Override //Used internally
void setMinFloatValue(final float value) { minFloatValue_ = value; }
diff --git a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
index 1b9470ee3..4a469be94 100644
--- a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
+++ b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
@@ -20,14 +20,14 @@
package org.apache.datasketches.kll;
import static org.apache.datasketches.Family.idToFamily;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_SRC_NOT_KLL;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_EMPTYBIT_AND_PREINTS;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_UPDATABLEBIT_AND_SER_VER;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_EMPTYBIT_AND_SER_VER;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_EMPTYBIT_AND_SINGLEBIT;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_SINGLEBIT_AND_SER_VER;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_DOUBLEBIT_AND_PREINTS;
-import static org.apache.datasketches.kll.KllMemoryValidate.MERRNO.ERR_FLOATBIT_AND_PREINTS;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.SRC_NOT_KLL;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.EMPTYBIT_AND_PREINTS;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.UPDATABLEBIT_AND_SER_VER;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.EMPTYBIT_AND_SER_VER;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.EMPTYBIT_AND_SINGLEBIT;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.SINGLEBIT_AND_SER_VER;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.DOUBLEBIT_AND_PREINTS;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.FLOATBIT_AND_PREINTS;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
@@ -106,7 +106,7 @@ final class KllMemoryValidate {
serVer = extractSerVer(srcMem);
familyID = extractFamilyID(srcMem);
- if (familyID != Family.KLL.getID()) { memoryValidateThrow(ERR_SRC_NOT_KLL, familyID); }
+ if (familyID != Family.KLL.getID()) { memoryValidateThrow(SRC_NOT_KLL, familyID); }
famName = idToFamily(familyID).toString();
flags = extractFlags(srcMem);
empty = extractEmptyFlag(srcMem);
@@ -118,19 +118,19 @@ final class KllMemoryValidate {
m = extractM(srcMem);
KllHelper.checkM(m);
KllHelper.checkK(k, m);
- if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(ERR_UPDATABLEBIT_AND_SER_VER, 0); }
+ if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(UPDATABLEBIT_AND_SER_VER, 0); }
if (updatable) { updatableMemoryValidate((WritableMemory) srcMem); }
else { compactMemoryValidate(srcMem); }
}
void compactMemoryValidate(final Memory srcMem) {
- if (empty && singleItem) { memoryValidateThrow(ERR_EMPTYBIT_AND_SINGLEBIT, 0); }
+ if (empty && singleItem) { memoryValidateThrow(EMPTYBIT_AND_SINGLEBIT, 0); }
final int sw = (empty ? 1 : 0) | (singleItem ? 4 : 0) | (doublesSketch ? 8 : 0);
switch (sw) {
case 0: { //FLOAT_FULL_COMPACT
- if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(ERR_FLOATBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(ERR_EMPTYBIT_AND_SER_VER, serVer); }
+ if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(FLOATBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.FLOAT_FULL_COMPACT;
n = extractN(srcMem);
dyMinK = extractDyMinK(srcMem);
@@ -156,8 +156,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 1: { //FLOAT_EMPTY_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(ERR_EMPTYBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(ERR_EMPTYBIT_AND_SER_VER, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(EMPTYBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.FLOAT_EMPTY_COMPACT;
n = 0; //assumed
dyMinK = k; //assumed
@@ -175,8 +175,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 4: { //FLOAT_SINGLE_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(ERR_EMPTYBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(ERR_SINGLEBIT_AND_SER_VER, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(EMPTYBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(SINGLEBIT_AND_SER_VER, serVer); }
layout = Layout.FLOAT_SINGLE_COMPACT;
n = 1;
dyMinK = k;
@@ -197,8 +197,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 8: { //DOUBLE_FULL_COMPACT
- if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(ERR_DOUBLEBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(ERR_EMPTYBIT_AND_SER_VER, serVer); }
+ if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(DOUBLEBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.DOUBLE_FULL_COMPACT;
n = extractN(srcMem);
dyMinK = extractDyMinK(srcMem);
@@ -224,8 +224,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 9: { //DOUBLE_EMPTY_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(ERR_EMPTYBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(ERR_EMPTYBIT_AND_SER_VER, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(EMPTYBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.DOUBLE_EMPTY_COMPACT;
n = 0;
dyMinK = k;
@@ -244,8 +244,8 @@ void compactMemoryValidate(final Memory srcMem) {
break;
}
case 12: { //DOUBLE_SINGLE_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(ERR_EMPTYBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(ERR_SINGLEBIT_AND_SER_VER, serVer); }
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(EMPTYBIT_AND_PREINTS, preInts); }
+ if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(SINGLEBIT_AND_SER_VER, serVer); }
layout = Layout.DOUBLE_SINGLE_COMPACT;
n = 1;
dyMinK = k;
@@ -272,7 +272,7 @@ void compactMemoryValidate(final Memory srcMem) {
void updatableMemoryValidate(final WritableMemory wSrcMem) {
if (doublesSketch) { //DOUBLE_UPDATABLE
- if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(ERR_DOUBLEBIT_AND_PREINTS, preInts); }
+ if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(DOUBLEBIT_AND_PREINTS, preInts); }
layout = Layout.DOUBLE_UPDATABLE;
n = extractN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
@@ -295,7 +295,7 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
sketchBytes = offset + itemsArrBytes;
}
else { //FLOAT_UPDATABLE
- if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(ERR_FLOATBIT_AND_PREINTS, preInts); }
+ if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(FLOATBIT_AND_PREINTS, preInts); }
layout = Layout.FLOAT_UPDATABLE;
n = extractN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
@@ -318,27 +318,27 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
}
}
- enum MERRNO { ERR_SRC_NOT_KLL, ERR_EMPTYBIT_AND_PREINTS, ERR_EMPTYBIT_AND_SER_VER,
- ERR_SINGLEBIT_AND_SER_VER, ERR_DOUBLEBIT_AND_PREINTS, ERR_FLOATBIT_AND_PREINTS, ERR_UPDATABLEBIT_AND_SER_VER,
- ERR_EMPTYBIT_AND_SINGLEBIT }
+ enum MemoryInputError { SRC_NOT_KLL, EMPTYBIT_AND_PREINTS, EMPTYBIT_AND_SER_VER,
+ SINGLEBIT_AND_SER_VER, DOUBLEBIT_AND_PREINTS, FLOATBIT_AND_PREINTS, UPDATABLEBIT_AND_SER_VER,
+ EMPTYBIT_AND_SINGLEBIT }
- private static void memoryValidateThrow(final MERRNO errType, final int value) {
+ private static void memoryValidateThrow(final MemoryInputError errType, final int value) {
String msg = "";
switch (errType) {
- case ERR_SRC_NOT_KLL: msg = "FamilyID Field must be: " + Family.KLL.getID() + ", NOT: " + value; break;
- case ERR_EMPTYBIT_AND_PREINTS: msg =
+ case SRC_NOT_KLL: msg = "FamilyID Field must be: " + Family.KLL.getID() + ", NOT: " + value; break;
+ case EMPTYBIT_AND_PREINTS: msg =
"Empty Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: " + value; break;
- case ERR_EMPTYBIT_AND_SER_VER: msg =
+ case EMPTYBIT_AND_SER_VER: msg =
"Empty Bit: 1 -> SerVer: " + SERIAL_VERSION_EMPTY_FULL + ", NOT: " + value; break;
- case ERR_SINGLEBIT_AND_SER_VER: msg =
+ case SINGLEBIT_AND_SER_VER: msg =
"Single Item Bit: 1 -> SerVer: " + SERIAL_VERSION_SINGLE + ", NOT: " + value; break;
- case ERR_DOUBLEBIT_AND_PREINTS: msg =
+ case DOUBLEBIT_AND_PREINTS: msg =
"Double Sketch Bit: 1 -> PreInts: " + PREAMBLE_INTS_DOUBLE + ", NOT: " + value; break;
- case ERR_FLOATBIT_AND_PREINTS: msg =
+ case FLOATBIT_AND_PREINTS: msg =
"Double Sketch Bit: 0 -> PreInts: " + PREAMBLE_INTS_FLOAT + ", NOT: " + value; break;
- case ERR_UPDATABLEBIT_AND_SER_VER: msg =
+ case UPDATABLEBIT_AND_SER_VER: msg =
"((SerVer == 3) ^ (Updatable Bit)) must = 0."; break;
- case ERR_EMPTYBIT_AND_SINGLEBIT: msg =
+ case EMPTYBIT_AND_SINGLEBIT: msg =
"Empty flag bit and SingleItem flag bit cannot both be set. Flags: " + value; break;
default: msg = "Unknown error"; break;
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index b93691a3c..800d986f3 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -236,18 +236,18 @@ final static boolean isCompatible() {
return compatible;
}
- enum ERRNO { ERR_TGT_IS_IMMUTABLE, ERR_SRC_IS_NOT_DIRECT, ERR_SRC_IS_NOT_DOUBLE,
- ERR_SRC_IS_NOT_FLOAT, ERR_SRC_CANNOT_BE_DIRECT, ERR_MUST_NOT_CALL }
+ enum Error { TGT_IS_IMMUTABLE, SRC_IS_NOT_DIRECT, SRC_IS_NOT_DOUBLE,
+ SRC_IS_NOT_FLOAT, SRC_CANNOT_BE_DIRECT, MUST_NOT_CALL }
- final static void kllSketchThrow(final ERRNO errType) {
+ final static void kllSketchThrow(final Error errType) {
String msg = "";
switch (errType) {
- case ERR_TGT_IS_IMMUTABLE: msg = "Given sketch Memory is immutable, cannot write."; break;
- case ERR_SRC_IS_NOT_DIRECT: msg = "Given sketch must be of type Direct."; break;
- case ERR_SRC_IS_NOT_DOUBLE: msg = "Given sketch must be of type Double."; break;
- case ERR_SRC_IS_NOT_FLOAT: msg = "Given sketch must be of type Float."; break;
- case ERR_SRC_CANNOT_BE_DIRECT: msg = "Given sketch must not be of type Direct."; break;
- case ERR_MUST_NOT_CALL: msg = "This is an artifact of inheritance and should never be called."; break;
+ case TGT_IS_IMMUTABLE: msg = "Given sketch Memory is immutable, cannot write."; break;
+ case SRC_IS_NOT_DIRECT: msg = "Given sketch must be of type Direct."; break;
+ case SRC_IS_NOT_DOUBLE: msg = "Given sketch must be of type Double."; break;
+ case SRC_IS_NOT_FLOAT: msg = "Given sketch must be of type Float."; break;
+ case SRC_CANNOT_BE_DIRECT: msg = "Given sketch must not be of type Direct."; break;
+ case MUST_NOT_CALL: msg = "This is an artifact of inheritance and should never be called."; break;
default: msg = "Unknown error."; break;
}
throw new SketchesArgumentException(msg);
From 0843950a7bebd62460c6e96398d12ef2a782b13e Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Wed, 30 Mar 2022 20:28:25 -0700
Subject: [PATCH 23/31] Fixed issues raised during review.
---
.../kll/KllDirectDoublesSketch.java | 80 ++++++++++++-
.../kll/KllDirectFloatsSketch.java | 82 ++++++++++++-
.../datasketches/kll/KllDirectSketch.java | 112 +-----------------
.../datasketches/kll/KllDoublesSketch.java | 4 +-
.../datasketches/kll/KllFloatsSketch.java | 4 +-
.../datasketches/kll/KllHeapSketch.java | 12 +-
.../datasketches/kll/KllMemoryValidate.java | 10 +-
.../datasketches/kll/KllPreambleUtil.java | 14 +--
.../apache/datasketches/kll/KllSketch.java | 28 ++---
.../kll/KllDirectDoublesSketchTest.java | 9 +-
.../kll/KllDirectFloatsSketchTest.java | 8 +-
.../kll/KllDoublesSketchTest.java | 1 -
.../kll/MiscDirectDoublesTest.java | 21 ++--
.../kll/MiscDirectFloatsTest.java | 18 +--
.../datasketches/kll/MiscDoublesTest.java | 18 +--
.../datasketches/kll/MiscFloatsTest.java | 18 +--
16 files changed, 237 insertions(+), 202 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 74ce437ea..93fcbb147 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -27,7 +27,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.UPDATABLE_BIT_MASK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertDyMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
import static org.apache.datasketches.kll.KllPreambleUtil.insertFamilyID;
import static org.apache.datasketches.kll.KllPreambleUtil.insertFlags;
import static org.apache.datasketches.kll.KllPreambleUtil.insertK;
@@ -36,8 +36,10 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
+import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
+import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -105,7 +107,7 @@ static KllDirectDoublesSketch newInstance(final int k, final int m, final Writab
insertK(dstMem, k);
insertM(dstMem, m);
insertN(dstMem, 0);
- insertDyMinK(dstMem, k);
+ insertMinK(dstMem, k);
insertNumLevels(dstMem, 1);
int offset = DATA_START_ADR_DOUBLE;
dstMem.putIntArray(offset, new int[] {k, k}, 0, 2);
@@ -218,7 +220,7 @@ public double getQuantile(final double fraction) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public double getQuantileLowerBound(final double fraction) {
- return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
+ return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getMinK(), false)));
}
/**
@@ -270,7 +272,7 @@ public double[] getQuantiles(final int numEvenlySpaced) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public double getQuantileUpperBound(final double fraction) {
- return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
+ return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getMinK(), false)));
}
/**
@@ -325,4 +327,74 @@ public void update(final double value) {
updateDouble(value);
}
+ @Override
+ double[] getDoubleItemsArray() {
+ final int items = getItemsArrLengthItems();
+ final double[] itemsArr = new double[items];
+ itemsArrUpdatable.getDoubleArray(0, itemsArr, 0, items);
+ return itemsArr;
+ }
+
+ @Override
+ double getDoubleItemsArrayAt(final int index) {
+ return itemsArrUpdatable.getDouble((long)index * Double.BYTES);
+ }
+
+ @Override
+ float[] getFloatItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
+
+ @Override
+ float getFloatItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
+
+ @Override
+ double getMaxDoubleValue() {
+ return minMaxArrUpdatable.getDouble(Double.BYTES);
+ }
+
+ @Override
+ float getMaxFloatValue() { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
+
+ @Override
+ double getMinDoubleValue() {
+ return minMaxArrUpdatable.getDouble(0);
+ }
+
+ @Override
+ float getMinFloatValue() { kllSketchThrow(MUST_NOT_CALL); return Float.NaN; }
+
+ @Override
+ void setDoubleItemsArray(final double[] doubleItems) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ itemsArrUpdatable.putDoubleArray(0, doubleItems, 0, doubleItems.length);
+ }
+
+ @Override
+ void setDoubleItemsArrayAt(final int index, final double value) {
+ itemsArrUpdatable.putDouble((long)index * Double.BYTES, value);
+ }
+
+ @Override
+ void setFloatItemsArray(final float[] floatItems) { kllSketchThrow(MUST_NOT_CALL); }
+
+ @Override
+ void setFloatItemsArrayAt(final int index, final float value) { kllSketchThrow(MUST_NOT_CALL); }
+
+ @Override
+ void setMaxDoubleValue(final double value) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ minMaxArrUpdatable.putDouble(Double.BYTES, value);
+ }
+
+ @Override
+ void setMaxFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
+
+ @Override
+ void setMinDoubleValue(final double value) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ minMaxArrUpdatable.putDouble(0, value);
+ }
+
+ @Override
+ void setMinFloatValue(final float value) { kllSketchThrow(MUST_NOT_CALL); }
+
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index 4198abbc8..36173e773 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -26,7 +26,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.UPDATABLE_BIT_MASK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertDyMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
import static org.apache.datasketches.kll.KllPreambleUtil.insertFamilyID;
import static org.apache.datasketches.kll.KllPreambleUtil.insertFlags;
import static org.apache.datasketches.kll.KllPreambleUtil.insertK;
@@ -35,14 +35,16 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
+import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
+import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
-//Intentional
+//Intentional extra blank line so the code lines up with KllDirectDoublesSketch
/**
* This class implements an off-heap floats KllSketch via a WritableMemory instance of the sketch.
*
@@ -105,7 +107,7 @@ static KllDirectFloatsSketch newInstance(final int k, final int m, final Writabl
insertK(dstMem, k);
insertM(dstMem, m);
insertN(dstMem, 0);
- insertDyMinK(dstMem, k);
+ insertMinK(dstMem, k);
insertNumLevels(dstMem, 1);
int offset = DATA_START_ADR_FLOAT;
dstMem.putIntArray(offset, new int[] {k, k}, 0, 2);
@@ -218,7 +220,7 @@ public float getQuantile(final double fraction) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public float getQuantileLowerBound(final double fraction) {
- return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
+ return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getMinK(), false)));
}
/**
@@ -270,7 +272,7 @@ public float[] getQuantiles(final int numEvenlySpaced) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public float getQuantileUpperBound(final double fraction) {
- return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
+ return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getMinK(), false)));
}
/**
@@ -325,4 +327,74 @@ public void update(final float value) {
updateFloat(value);
}
+ @Override
+ double[] getDoubleItemsArray() { kllSketchThrow(MUST_NOT_CALL); return null; }
+
+ @Override
+ double getDoubleItemsArrayAt(final int index) { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
+
+ @Override
+ float[] getFloatItemsArray() {
+ final int items = getItemsArrLengthItems();
+ final float[] itemsArr = new float[items];
+ itemsArrUpdatable.getFloatArray(0, itemsArr, 0, items);
+ return itemsArr;
+ }
+
+ @Override
+ float getFloatItemsArrayAt(final int index) {
+ return itemsArrUpdatable.getFloat((long)index * Float.BYTES);
+ }
+
+ @Override
+ double getMaxDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
+
+ @Override
+ float getMaxFloatValue() {
+ return minMaxArrUpdatable.getFloat(Float.BYTES);
+ }
+
+ @Override
+ double getMinDoubleValue() { kllSketchThrow(MUST_NOT_CALL); return Double.NaN; }
+
+ @Override
+ float getMinFloatValue() {
+ return minMaxArrUpdatable.getFloat(0);
+ }
+
+ @Override
+ void setDoubleItemsArray(final double[] doubleItems) { kllSketchThrow(MUST_NOT_CALL); }
+
+ @Override
+ void setDoubleItemsArrayAt(final int index, final double value) { kllSketchThrow(MUST_NOT_CALL); }
+
+ @Override
+ void setFloatItemsArray(final float[] floatItems) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ itemsArrUpdatable.putFloatArray(0, floatItems, 0, floatItems.length);
+ }
+
+ @Override
+ void setFloatItemsArrayAt(final int index, final float value) {
+ itemsArrUpdatable.putFloat((long)index * Float.BYTES, value);
+ }
+
+ @Override
+ void setMaxDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
+
+ @Override
+ void setMaxFloatValue(final float value) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ minMaxArrUpdatable.putFloat(Float.BYTES, value);
+ }
+
+ @Override
+ void setMinDoubleValue(final double value) { kllSketchThrow(MUST_NOT_CALL); }
+
+ @Override
+ void setMinFloatValue(final float value) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ minMaxArrUpdatable.putFloat(0, value);
+ }
+
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index 691106e63..400caef4b 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -19,18 +19,16 @@
package org.apache.datasketches.kll;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractDyMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.extractMinK;
import static org.apache.datasketches.kll.KllPreambleUtil.extractK;
import static org.apache.datasketches.kll.KllPreambleUtil.extractLevelZeroSortedFlag;
import static org.apache.datasketches.kll.KllPreambleUtil.extractM;
import static org.apache.datasketches.kll.KllPreambleUtil.extractN;
import static org.apache.datasketches.kll.KllPreambleUtil.extractNumLevels;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertDyMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
import static org.apache.datasketches.kll.KllPreambleUtil.insertLevelZeroSortedFlag;
import static org.apache.datasketches.kll.KllPreambleUtil.insertN;
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
-import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
-import static org.apache.datasketches.kll.KllSketch.SketchType.FLOATS_SKETCH;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -41,8 +39,6 @@
* of the sketch type (float or double).
*/
abstract class KllDirectSketch extends KllSketch {
- //All these members are constant for the life of this object. If the WritableMemory changes,
- // it may require rebuilding this class
final boolean updatable = true;
WritableMemory levelsArrUpdatable;
WritableMemory minMaxArrUpdatable;
@@ -87,38 +83,8 @@ public byte[] toUpdatableByteArray() {
}
@Override
- double[] getDoubleItemsArray() {
- if (sketchType == FLOATS_SKETCH) { return null; }
- final int items = getItemsArrLengthItems();
- final double[] itemsArr = new double[items];
- itemsArrUpdatable.getDoubleArray(0, itemsArr, 0, items);
- return itemsArr;
- }
-
- @Override
- double getDoubleItemsArrayAt(final int index) {
- if (sketchType == FLOATS_SKETCH) { return Double.NaN; }
- return itemsArrUpdatable.getDouble((long)index * Double.BYTES);
- }
-
- @Override
- int getDynamicMinK() {
- return extractDyMinK(wmem);
- }
-
- @Override
- float[] getFloatItemsArray() {
- if (sketchType == DOUBLES_SKETCH) { return null; }
- final int items = getItemsArrLengthItems();
- final float[] itemsArr = new float[items];
- itemsArrUpdatable.getFloatArray(0, itemsArr, 0, items);
- return itemsArr;
- }
-
- @Override
- float getFloatItemsArrayAt(final int index) {
- if (sketchType == DOUBLES_SKETCH) { return Float.NaN; }
- return itemsArrUpdatable.getFloat((long)index * Float.BYTES);
+ int getMinK() {
+ return extractMinK(wmem);
}
int getItemsArrLengthItems() {
@@ -138,26 +104,6 @@ int getLevelsArrayAt(final int index) {
return levelsArrUpdatable.getInt((long)index * Integer.BYTES);
}
- @Override
- double getMaxDoubleValue() {
- return minMaxArrUpdatable.getDouble(Double.BYTES);
- }
-
- @Override
- float getMaxFloatValue() {
- return minMaxArrUpdatable.getFloat(Float.BYTES);
- }
-
- @Override
- double getMinDoubleValue() {
- return minMaxArrUpdatable.getDouble(0);
- }
-
- @Override
- float getMinFloatValue() {
- return minMaxArrUpdatable.getFloat(0);
- }
-
@Override
int getNumLevels() {
return extractNumLevels(wmem);
@@ -183,31 +129,9 @@ boolean isLevelZeroSorted() {
}
@Override
- void setDoubleItemsArray(final double[] doubleItems) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- itemsArrUpdatable.putDoubleArray(0, doubleItems, 0, doubleItems.length);
- }
-
- @Override
- void setDoubleItemsArrayAt(final int index, final double value) {
- itemsArrUpdatable.putDouble((long)index * Double.BYTES, value);
- }
-
- @Override
- void setDyMinK(final int dyMinK) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- insertDyMinK(wmem, dyMinK);
- }
-
- @Override
- void setFloatItemsArray(final float[] floatItems) {
+ void setMinK(final int minK) {
if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- itemsArrUpdatable.putFloatArray(0, floatItems, 0, floatItems.length);
- }
-
- @Override
- void setFloatItemsArrayAt(final int index, final float value) {
- itemsArrUpdatable.putFloat((long)index * Float.BYTES, value);
+ insertMinK(wmem, minK);
}
@Override
@@ -251,30 +175,6 @@ void setLevelZeroSorted(final boolean sorted) {
insertLevelZeroSortedFlag(wmem, sorted);
}
- @Override
- void setMaxDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- minMaxArrUpdatable.putDouble(Double.BYTES, value);
- }
-
- @Override
- void setMaxFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- minMaxArrUpdatable.putFloat(Float.BYTES, value);
- }
-
- @Override
- void setMinDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- minMaxArrUpdatable.putDouble(0, value);
- }
-
- @Override
- void setMinFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- minMaxArrUpdatable.putFloat(0, value);
- }
-
@Override
void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) {
minMaxArrUpdatable = minMaxMem;
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 8d249f908..3db062ce0 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -202,7 +202,7 @@ public double getQuantile(final double fraction) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public double getQuantileLowerBound(final double fraction) {
- return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
+ return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getMinK(), false)));
}
/**
@@ -254,7 +254,7 @@ public double[] getQuantiles(final int numEvenlySpaced) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public double getQuantileUpperBound(final double fraction) {
- return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
+ return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getMinK(), false)));
}
/**
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 4ae3aa81c..c8dd4f7a8 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -202,7 +202,7 @@ public float getQuantile(final double fraction) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public float getQuantileLowerBound(final double fraction) {
- return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
+ return getQuantile(max(0, fraction - KllHelper.getNormalizedRankError(getMinK(), false)));
}
/**
@@ -254,7 +254,7 @@ public float[] getQuantiles(final int numEvenlySpaced) {
* exists with a confidence of at least 99%. Returns NaN if the sketch is empty.
*/
public float getQuantileUpperBound(final double fraction) {
- return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getDynamicMinK(), false)));
+ return getQuantile(min(1.0, fraction + KllHelper.getNormalizedRankError(getMinK(), false)));
}
/**
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java b/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
index 81c56aa71..ab050f66c 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
@@ -31,7 +31,7 @@ abstract class KllHeapSketch extends KllSketch {
private final int k; // configured value of K.
private final int m; // configured value of M.
private long n_; // number of items input into this sketch.
- private int dyMinK_; // dynamic minK for error estimation after merging with different k.
+ private int minK_; // dynamic minK for error estimation after merging with different k.
private int numLevels_; // one-based number of current levels.
private int[] levels_; // array of index offsets into the items[]. Size = numLevels + 1.
private boolean isLevelZeroSorted_;
@@ -49,7 +49,7 @@ abstract class KllHeapSketch extends KllSketch {
this.k = k;
this.m = m;
n_ = 0;
- dyMinK_ = k;
+ minK_ = k;
numLevels_ = 1;
levels_ = new int[] {k, k};
isLevelZeroSorted_ = false;
@@ -71,8 +71,8 @@ public long getN() {
}
@Override
- int getDynamicMinK() {
- return dyMinK_;
+ int getMinK() {
+ return minK_;
}
@Override
@@ -104,8 +104,8 @@ boolean isLevelZeroSorted() {
}
@Override
- void setDyMinK(final int dyMinK) {
- dyMinK_ = dyMinK;
+ void setMinK(final int minK) {
+ minK_ = minK;
}
@Override
diff --git a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
index 4a469be94..3b8dbc3a0 100644
--- a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
+++ b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
@@ -38,7 +38,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_SINGLE;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.extractDoubleSketchFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractDyMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.extractMinK;
import static org.apache.datasketches.kll.KllPreambleUtil.extractEmptyFlag;
import static org.apache.datasketches.kll.KllPreambleUtil.extractFamilyID;
import static org.apache.datasketches.kll.KllPreambleUtil.extractFlags;
@@ -133,7 +133,7 @@ void compactMemoryValidate(final Memory srcMem) {
if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.FLOAT_FULL_COMPACT;
n = extractN(srcMem);
- dyMinK = extractDyMinK(srcMem);
+ dyMinK = extractMinK(srcMem);
numLevels = extractNumLevels(srcMem);
int offset = DATA_START_ADR_FLOAT;
// LEVELS MEM
@@ -201,7 +201,7 @@ void compactMemoryValidate(final Memory srcMem) {
if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
layout = Layout.DOUBLE_FULL_COMPACT;
n = extractN(srcMem);
- dyMinK = extractDyMinK(srcMem);
+ dyMinK = extractMinK(srcMem);
numLevels = extractNumLevels(srcMem);
int offset = DATA_START_ADR_DOUBLE;
// LEVELS MEM
@@ -277,7 +277,7 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
n = extractN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
singleItem = n == 1; // there is no error checking on these bits
- dyMinK = extractDyMinK(wSrcMem);
+ dyMinK = extractMinK(wSrcMem);
numLevels = extractNumLevels(wSrcMem);
int offset = DATA_START_ADR_DOUBLE;
@@ -300,7 +300,7 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
n = extractN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
singleItem = n == 1; // there is no error checking on these bits
- dyMinK = extractDyMinK(wSrcMem);
+ dyMinK = extractMinK(wSrcMem);
numLevels = extractNumLevels(wSrcMem);
int offset = DATA_START_ADR_FLOAT;
//LEVELS
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index 2d006d48f..eafb80c81 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -52,7 +52,7 @@
* || 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
* 1 ||---------------------------------N_LONG---------------------------------------|
* || | | | 20 | 19 | 18 | 17 | 16 |
- * 2 ||<-------Levels Arr Start----------]| unused |NumLevels|--Dynamic-Min K--------|
+ * 2 ||<-------Levels Arr Start----------]| unused |NumLevels|------Min K------------|
* || | | | | | | | |
* ? ||<-------Min/Max Arr Start---------]|[<----------Levels Arr End----------------|
* || | | | | | | | |
@@ -76,7 +76,7 @@
* || 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
* 1 ||---------------------------------N_LONG---------------------------------------|
* || 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
- * 2 ||<-------Levels Arr Start----------]| unused |NumLevels|--Dynamic-Min K--------|
+ * 2 ||<-------Levels Arr Start----------]| unused |NumLevels|------Min K------------|
* || | | | | | | | |
* ? ||<-------Min/Max Arr Start---------]|[<----------Levels Arr End----------------|
* || | | | | | | | |
@@ -148,7 +148,7 @@ private KllPreambleUtil() {}
// MULTI-ITEM
static final int N_LONG_ADR = 8; // to 15
- static final int DY_MIN_K_SHORT_ADR = 16; // to 17
+ static final int MIN_K_SHORT_ADR = 16; // to 17
static final int NUM_LEVELS_BYTE_ADR = 18;
// FLOAT SKETCH 19 is reserved for future use in float sketch
@@ -301,8 +301,8 @@ static long extractN(final Memory mem) {
return mem.getLong(N_LONG_ADR);
}
- static int extractDyMinK(final Memory mem) {
- return mem.getShort(DY_MIN_K_SHORT_ADR) & 0XFFFF;
+ static int extractMinK(final Memory mem) {
+ return mem.getShort(MIN_K_SHORT_ADR) & 0XFFFF;
}
static int extractNumLevels(final Memory mem) {
@@ -362,8 +362,8 @@ static void insertN(final WritableMemory wmem, final long value) {
wmem.putLong(N_LONG_ADR, value);
}
- static void insertDyMinK(final WritableMemory wmem, final int value) {
- wmem.putShort(DY_MIN_K_SHORT_ADR, (short) value);
+ static void insertMinK(final WritableMemory wmem, final int value) {
+ wmem.putShort(MIN_K_SHORT_ADR, (short) value);
}
static void insertNumLevels(final WritableMemory wmem, final int value) {
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index 800d986f3..583883d68 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -41,7 +41,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_SINGLE;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.insertDoubleSketchFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertDyMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
import static org.apache.datasketches.kll.KllPreambleUtil.insertEmptyFlag;
import static org.apache.datasketches.kll.KllPreambleUtil.insertFamilyID;
import static org.apache.datasketches.kll.KllPreambleUtil.insertK;
@@ -303,7 +303,7 @@ public final int getCurrentUpdatableSerializedSizeBytes() {
* {@link org.apache.datasketches.kll}
*/
public final double getNormalizedRankError(final boolean pmf) {
- return getNormalizedRankError(getDynamicMinK(), pmf);
+ return getNormalizedRankError(getMinK(), pmf);
}
/**
@@ -381,7 +381,7 @@ final void buildHeapKllSketchFromMemory(final KllMemoryValidate memVal) {
final boolean updatable = memVal.updatable;
setLevelZeroSorted(memVal.level0Sorted);
setN(memVal.n);
- setDyMinK(memVal.dyMinK);
+ setMinK(memVal.dyMinK);
setNumLevels(memVal.numLevels);
final int[] myLevelsArr = new int[getNumLevels() + 1];
@@ -521,11 +521,11 @@ final double[] getDoublesQuantiles(final double[] fractions) {
}
/**
- * Dynamic MinK is the value of K that results from a merge with a sketch configured with a value of K lower than
+ * MinK is the value of K that results from a merge with a sketch configured with a value of K lower than
* the k of this sketch. This value is then used in computing the estimated upper and lower bounds of error.
- * @return The dynamic minimum K as a result of merging with lower values of k.
+ * @return The minimum K as a result of merging with lower values of k.
*/
- abstract int getDynamicMinK();
+ abstract int getMinK();
/**
* @return full size of internal items array including garbage; for a doubles sketch this will be null.
@@ -725,7 +725,7 @@ final void mergeDoubleImpl(final KllSketch other) {
// after the level 0 update, we capture the key mutable variables
final double myMin = getMinDoubleValue();
final double myMax = getMaxDoubleValue();
- final int myDyMinK = getDynamicMinK();
+ final int myDyMinK = getMinK();
final int myCurNumLevels = getNumLevels();
final int[] myCurLevelsArr = getLevelsArray();
@@ -793,7 +793,7 @@ final void mergeDoubleImpl(final KllSketch other) {
//Update Preamble:
setN(finalN);
if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
- setDyMinK(min(myDyMinK, other.getDynamicMinK()));
+ setMinK(min(myDyMinK, other.getMinK()));
}
//Update min, max values
@@ -835,7 +835,7 @@ final void mergeFloatImpl(final KllSketch other) {
// after the level 0 update, we capture the key mutable variables
final float myMin = getMinFloatValue();
final float myMax = getMaxFloatValue();
- final int myDyMinK = getDynamicMinK();
+ final int myDyMinK = getMinK();
final int myCurNumLevels = getNumLevels();
final int[] myCurLevelsArr = getLevelsArray();
@@ -903,7 +903,7 @@ final void mergeFloatImpl(final KllSketch other) {
//Update Preamble:
setN(finalN);
if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
- setDyMinK(min(myDyMinK, other.getDynamicMinK()));
+ setMinK(min(myDyMinK, other.getMinK()));
}
//Update min, max values
@@ -937,7 +937,7 @@ private static float resolveFloatMaxValue(final float myMax, final float otherMa
abstract void setDoubleItemsArrayAt(int index, double value);
- abstract void setDyMinK(int dyMinK);
+ abstract void setMinK(int minK);
abstract void setFloatItemsArray(float[] floatItems);
@@ -990,7 +990,7 @@ final byte[] toCompactByteArrayImpl() {
} else { // n > 1
//remainder of preamble after first 8 bytes
insertN(wmem, getN());
- insertDyMinK(wmem, getDynamicMinK());
+ insertMinK(wmem, getMinK());
insertNumLevels(wmem, getNumLevels());
offset = (doubleType) ? DATA_START_ADR_DOUBLE : DATA_START_ADR_FLOAT;
@@ -1055,7 +1055,7 @@ final String toStringImpl(final boolean withLevels, final boolean withData) {
final String skType = (direct ? "Direct" : "") + (doubleType ? "Doubles" : "Floats");
sb.append(Util.LS).append("### Kll").append(skType).append("Sketch Summary:").append(Util.LS);
sb.append(" K : ").append(k).append(Util.LS);
- sb.append(" Dynamic min K : ").append(getDynamicMinK()).append(Util.LS);
+ sb.append(" Dynamic min K : ").append(getMinK()).append(Util.LS);
sb.append(" M : ").append(m).append(Util.LS);
sb.append(" N : ").append(getN()).append(Util.LS);
sb.append(" Epsilon : ").append(epsPct).append(Util.LS);
@@ -1176,7 +1176,7 @@ final byte[] toUpdatableByteArrayImpl() {
loadFirst8Bytes(this, wmem, true);
//remainder of preamble after first 8 bytes
insertN(wmem, getN());
- insertDyMinK(wmem, getDynamicMinK());
+ insertMinK(wmem, getMinK());
insertNumLevels(wmem, getNumLevels());
//load data
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
index 77c1e7814..f3ae36e05 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
@@ -19,7 +19,6 @@
package org.apache.datasketches.kll;
-//import static org.apache.datasketches.Util.getResourceBytes; //don't have matching numbers from C++
import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.testng.Assert.assertEquals;
@@ -34,7 +33,6 @@
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
-
@SuppressWarnings("javadoc")
public class KllDirectDoublesSketchTest {
@@ -493,7 +491,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -513,7 +511,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -534,7 +532,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
@@ -592,4 +590,3 @@ static void println(final String s) {
}
}
-
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
index d23979d67..b7f88b72b 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
@@ -19,7 +19,6 @@
package org.apache.datasketches.kll;
-//import static org.apache.datasketches.Util.getResourceBytes; //don't have matching numbers from C++
import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.testng.Assert.assertEquals;
@@ -492,7 +491,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0);
@@ -512,7 +511,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Double.NaN);
@@ -533,7 +532,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0);
@@ -591,4 +590,3 @@ static void println(final String s) {
}
}
-
diff --git a/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
index 323814c0a..0172068f4 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
@@ -19,7 +19,6 @@
package org.apache.datasketches.kll;
-//import static org.apache.datasketches.Util.getResourceBytes; //don't have matching numbers from C++
import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.testng.Assert.assertEquals;
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java b/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
index c407b4e37..eedf5e44e 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDirectDoublesTest.java
@@ -118,8 +118,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -135,8 +134,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -153,8 +151,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
- assertTrue(Objects.isNull(sk.getFloatItemsArray()));
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
@@ -184,7 +181,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -204,7 +201,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -225,7 +222,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
@@ -255,7 +252,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -275,7 +272,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -296,7 +293,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java b/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
index 3bd1ce1d4..597ebe5dc 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDirectFloatsTest.java
@@ -118,7 +118,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -134,7 +134,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -151,7 +151,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
@@ -181,7 +181,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -201,7 +201,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -222,7 +222,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
@@ -252,7 +252,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -272,7 +272,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -293,7 +293,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
diff --git a/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java b/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
index ba28c6034..276f52776 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscDoublesTest.java
@@ -173,7 +173,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -189,7 +189,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -206,7 +206,7 @@ public void checkSketchInitializeDoubleHeap() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
@@ -236,7 +236,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -256,7 +256,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -277,7 +277,7 @@ public void checkSketchInitializeDoubleHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
@@ -307,7 +307,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxDoubleValue(), 21.0);
@@ -327,7 +327,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), Double.NaN);
@@ -348,7 +348,7 @@ public void checkSketchInitializeDoubleHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getDoubleItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxDoubleValue(), 1.0);
diff --git a/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java b/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
index c42e58557..a53199a20 100644
--- a/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
+++ b/src/test/java/org/apache/datasketches/kll/MiscFloatsTest.java
@@ -173,7 +173,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -189,7 +189,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -206,7 +206,7 @@ public void checkSketchInitializeFloatHeap() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
@@ -236,7 +236,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -256,7 +256,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -277,7 +277,7 @@ public void checkSketchInitializeFloatHeapifyCompactMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
@@ -307,7 +307,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 11);
assertFalse(sk.isEmpty());
assertTrue(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 33);
assertEquals(sk.getLevelsArray().length, 3);
assertEquals(sk.getMaxFloatValue(), 21.0F);
@@ -327,7 +327,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 0);
assertTrue(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), Float.NaN);
@@ -348,7 +348,7 @@ public void checkSketchInitializeFloatHeapifyUpdatableMem() {
assertEquals(sk.getNumRetained(), 1);
assertFalse(sk.isEmpty());
assertFalse(sk.isEstimationMode());
- assertEquals(sk.getDynamicMinK(), k);
+ assertEquals(sk.getMinK(), k);
assertEquals(sk.getFloatItemsArray().length, 20);
assertEquals(sk.getLevelsArray().length, 2);
assertEquals(sk.getMaxFloatValue(), 1.0F);
From 06af8baad7954b65010c4926efd834162da150eb Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Thu, 31 Mar 2022 11:44:09 -0700
Subject: [PATCH 24/31] Removed redundant "exclusive"
---
.../apache/datasketches/QuantilesHelper.java | 23 +++++++++++++++----
.../kll/KllDirectDoublesSketch.java | 4 ++--
.../kll/KllDirectFloatsSketch.java | 4 ++--
.../kll/KllDoublesQuantileCalculator.java | 4 ++--
.../datasketches/kll/KllDoublesSketch.java | 4 ++--
.../kll/KllFloatsQuantileCalculator.java | 4 ++--
.../datasketches/kll/KllFloatsSketch.java | 4 ++--
.../quantiles/DoublesAuxiliary.java | 8 +++----
.../quantiles/ItemsAuxiliary.java | 8 +++----
.../HeapUpdateDoublesSketchTest.java | 4 ++--
10 files changed, 40 insertions(+), 27 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/QuantilesHelper.java b/src/main/java/org/apache/datasketches/QuantilesHelper.java
index c7546569c..f128a0d2c 100644
--- a/src/main/java/org/apache/datasketches/QuantilesHelper.java
+++ b/src/main/java/org/apache/datasketches/QuantilesHelper.java
@@ -29,7 +29,7 @@ public class QuantilesHelper {
* An array of {1,1,1,0} becomes {0,1,2,3}
* @param array of weights where first element is zero
* @return total weight
- */ //also used by KLL
+ */ //used by classic Quantiles and KLL
public static long convertToPrecedingCummulative(final long[] array) {
long subtotal = 0;
for (int i = 0; i < array.length; i++) {
@@ -43,15 +43,28 @@ public static long convertToPrecedingCummulative(final long[] array) {
/**
* Returns the linear zero-based index (position) of a value in the hypothetical sorted stream of
* values of size n.
- * @param phi the fractional position where: 0 ≤ φ ≤ 1.0.
+ * @param rank the fractional position where: 0 ≤ φ ≤ 1.0.
* @param n the size of the stream
* @return the index, a value between 0 and n-1.
- */ //also used by KLL
- public static long posOfPhi(final double phi, final long n) {
- final long pos = (long) Math.floor(phi * n);
+ */ //used by classic Quantiles and KLL
+ public static long posOfRank(final double rank, final long n) {
+ final long pos = (long) Math.floor(rank * n);
return pos == n ? n - 1 : pos; //avoids ArrayIndexOutOfBoundException
}
+ /**
+ * Returns the linear zero-based index (position) of a value in the hypothetical sorted stream of
+ * values of size n.
+ * @param rank the fractional position where: 0 ≤ φ ≤ 1.0.
+ * @param n the size of the stream
+ * @return the index, a value between 0 and n-1.
+ * @deprecated use {@link #posOfRank(double, long)} instead. Version 3.2.0.
+ */ //used by classic Quantiles and KLL
+ @Deprecated
+ public static long posOfPhi(final double rank, final long n) {
+ return posOfRank(rank, n);
+ }
+
/**
* This is written in terms of a plain array to facilitate testing.
* @param wtArr the cumulative weights array consisting of chunks
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 93fcbb147..5dc0b347f 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -135,7 +135,7 @@ static KllDirectDoublesSketch newInstance(final int k, final int m, final Writab
* the maximum value.
* It is not necessary to include either the min or max values in these split points.
*
- * @return an array of m+1 double values on the interval [0.0, 1.0) exclusive,
+ * @return an array of m+1 double values on the interval [0.0, 1.0),
* which are a consecutive approximation to the CDF of the input stream given the splitPoints.
* The value at array position j of the returned CDF array is the sum of the returned values
* in positions 0 through j of the returned PMF array.
@@ -180,7 +180,7 @@ public double getMinValue() {
* the maximum value.
* It is not necessary to include either the min or max values in these split points.
*
- * @return an array of m+1 doubles on the interval [0.0, 1.0) exclusive,
+ * @return an array of m+1 doubles on the interval [0.0, 1.0),
* each of which is an approximation to the fraction of the total input stream values
* (the mass) that fall into one of those intervals.
* The definition of an "interval" is inclusive of the left splitPoint and exclusive of the right
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index 36173e773..15c4de1d7 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -135,7 +135,7 @@ static KllDirectFloatsSketch newInstance(final int k, final int m, final Writabl
* the maximum value.
* It is not necessary to include either the min or max values in these split points.
*
- * @return an array of m+1 double values on the interval [0.0, 1.0) exclusive,
+ * @return an array of m+1 double values on the interval [0.0, 1.0),
* which are a consecutive approximation to the CDF of the input stream given the splitPoints.
* The value at array position j of the returned CDF array is the sum of the returned values
* in positions 0 through j of the returned PMF array.
@@ -180,7 +180,7 @@ public float getMinValue() {
* the maximum value.
* It is not necessary to include either the min or max values in these split points.
*
- * @return an array of m+1 doubles on the interval [0.0, 1.0) exclusive,
+ * @return an array of m+1 doubles on the interval [0.0, 1.0),
* each of which is an approximation to the fraction of the total input stream values
* (the mass) that fall into one of those intervals.
* The definition of an "interval" is inclusive of the left splitPoint and exclusive of the right
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesQuantileCalculator.java b/src/main/java/org/apache/datasketches/kll/KllDoublesQuantileCalculator.java
index 91453549a..7870002f1 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesQuantileCalculator.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesQuantileCalculator.java
@@ -132,8 +132,8 @@ private static void tandemMerge(
}
}
- double getQuantile(final double phi) { //phi is normalized rank [0,1].
- final long pos = QuantilesHelper.posOfPhi(phi, n_);
+ double getQuantile(final double rank) {
+ final long pos = QuantilesHelper.posOfRank(rank, n_);
return approximatelyAnswerPositonalQuery(pos);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 3db062ce0..39982b809 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -121,7 +121,7 @@ public static KllDoublesSketch heapify(final Memory mem) {
* the maximum value.
* It is not necessary to include either the min or max values in these split points.
*
- * @return an array of m+1 double values on the interval [0.0, 1.0) exclusive,
+ * @return an array of m+1 double values on the interval [0.0, 1.0),
* which are a consecutive approximation to the CDF of the input stream given the splitPoints.
* The value at array position j of the returned CDF array is the sum of the returned values
* in positions 0 through j of the returned PMF array.
@@ -162,7 +162,7 @@ public double[] getCDF(final double[] splitPoints) {
* the maximum value.
* It is not necessary to include either the min or max values in these split points.
*
- * @return an array of m+1 doubles on the interval [0.0, 1.0) exclusive,
+ * @return an array of m+1 doubles on the interval [0.0, 1.0),
* each of which is an approximation to the fraction of the total input stream values
* (the mass) that fall into one of those intervals.
* The definition of an "interval" is inclusive of the left splitPoint and exclusive of the right
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsQuantileCalculator.java b/src/main/java/org/apache/datasketches/kll/KllFloatsQuantileCalculator.java
index 0fee4046e..87539fc0c 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsQuantileCalculator.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsQuantileCalculator.java
@@ -132,8 +132,8 @@ private static void tandemMerge(
}
}
- float getQuantile(final double phi) { //phi is normalized rank [0,1].
- final long pos = QuantilesHelper.posOfPhi(phi, n_);
+ float getQuantile(final double rank) {
+ final long pos = QuantilesHelper.posOfRank(rank, n_);
return approximatelyAnswerPositonalQuery(pos);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index c8dd4f7a8..7993ccced 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -121,7 +121,7 @@ public static KllFloatsSketch heapify(final Memory mem) {
* the maximum value.
* It is not necessary to include either the min or max values in these split points.
*
- * @return an array of m+1 double values on the interval [0.0, 1.0) exclusive,
+ * @return an array of m+1 double values on the interval [0.0, 1.0),
* which are a consecutive approximation to the CDF of the input stream given the splitPoints.
* The value at array position j of the returned CDF array is the sum of the returned values
* in positions 0 through j of the returned PMF array.
@@ -162,7 +162,7 @@ public double[] getCDF(final float[] splitPoints) {
* the maximum value.
* It is not necessary to include either the min or max values in these split points.
*
- * @return an array of m+1 doubles on the interval [0.0, 1.0) exclusive,
+ * @return an array of m+1 doubles on the interval [0.0, 1.0),
* each of which is an approximation to the fraction of the total input stream values
* (the mass) that fall into one of those intervals.
* The definition of an "interval" is inclusive of the left splitPoint and exclusive of the right
diff --git a/src/main/java/org/apache/datasketches/quantiles/DoublesAuxiliary.java b/src/main/java/org/apache/datasketches/quantiles/DoublesAuxiliary.java
index 40d4d3501..307917d12 100644
--- a/src/main/java/org/apache/datasketches/quantiles/DoublesAuxiliary.java
+++ b/src/main/java/org/apache/datasketches/quantiles/DoublesAuxiliary.java
@@ -70,12 +70,12 @@ final class DoublesAuxiliary {
/**
* Get the estimated quantile given a fractional rank.
- * @param fRank the fractional rank where: 0 ≤ fRank ≤ 1.0.
+ * @param rank the normalized rank where: 0 ≤ rank ≤ 1.0.
* @return the estimated quantile
*/
- double getQuantile(final double fRank) {
- checkFractionalRankBounds(fRank);
- final long pos = QuantilesHelper.posOfPhi(fRank, auxN_);
+ double getQuantile(final double rank) {
+ checkFractionalRankBounds(rank);
+ final long pos = QuantilesHelper.posOfRank(rank, auxN_);
return approximatelyAnswerPositionalQuery(pos);
}
diff --git a/src/main/java/org/apache/datasketches/quantiles/ItemsAuxiliary.java b/src/main/java/org/apache/datasketches/quantiles/ItemsAuxiliary.java
index 9a617d431..4905fc221 100644
--- a/src/main/java/org/apache/datasketches/quantiles/ItemsAuxiliary.java
+++ b/src/main/java/org/apache/datasketches/quantiles/ItemsAuxiliary.java
@@ -79,13 +79,13 @@ final class ItemsAuxiliary {
/**
* Get the estimated quantile given a fractional rank.
- * @param fRank the fractional rank where: 0 ≤ fRank ≤ 1.0.
+ * @param rank the normalized rank where: 0 ≤ rank ≤ 1.0.
* @return the estimated quantile
*/
- T getQuantile(final double fRank) {
- checkFractionalRankBounds(fRank);
+ T getQuantile(final double rank) {
+ checkFractionalRankBounds(rank);
if (auxN_ <= 0) { return null; }
- final long pos = QuantilesHelper.posOfPhi(fRank, auxN_);
+ final long pos = QuantilesHelper.posOfRank(rank, auxN_);
return approximatelyAnswerPositionalQuery(pos);
}
diff --git a/src/test/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketchTest.java b/src/test/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketchTest.java
index 7c017edfb..5513f7d6a 100644
--- a/src/test/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/quantiles/HeapUpdateDoublesSketchTest.java
@@ -855,9 +855,9 @@ public void checkPutMemoryTooSmall() {
}
@Test
- public void checkAuxPosOfPhi() throws Exception {
+ public void checkAuxPosOfRank() throws Exception {
long n = 10;
- long returnValue = QuantilesHelper.posOfPhi(1.0, 10);
+ long returnValue = QuantilesHelper.posOfRank(1.0, 10);
//println("" + returnValue);
assertEquals(returnValue, n-1);
}
From 0e5dde14f336f3970ec38a356f48461b4435a2e8 Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Thu, 31 Mar 2022 16:29:12 -0700
Subject: [PATCH 25/31] Moved public statics from KllPreambleUtil to KllSketch,
added reset() method.
---
.../kll/KllDirectDoublesSketch.java | 13 +----
.../kll/KllDirectFloatsSketch.java | 13 +----
.../datasketches/kll/KllDirectSketch.java | 21 ++++++++
.../datasketches/kll/KllDoublesSketch.java | 19 +++++--
.../datasketches/kll/KllFloatsSketch.java | 19 +++++--
.../apache/datasketches/kll/KllHelper.java | 9 ++--
.../datasketches/kll/KllPreambleUtil.java | 9 ----
.../apache/datasketches/kll/KllSketch.java | 52 +++++++++++++++----
.../kll/KllDirectDoublesSketchTest.java | 41 ++++++++++-----
.../kll/KllDirectFloatsSketchTest.java | 41 ++++++++++-----
.../kll/KllDoublesSketchTest.java | 31 ++++++++---
.../datasketches/kll/KllFloatsSketchTest.java | 31 ++++++++---
.../datasketches/kll/KllHelperTest.java | 16 +++---
13 files changed, 206 insertions(+), 109 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 5dc0b347f..c6720a172 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -22,7 +22,6 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.kll.KllPreambleUtil.DOUBLES_SKETCH_BIT_MASK;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
@@ -87,7 +86,7 @@ public static KllDirectDoublesSketch writableWrap(final WritableMemory srcMem, f
*/
public static KllDirectDoublesSketch newInstance(final int k, final WritableMemory dstMem,
final MemoryRequestServer memReqSvr) {
- return newInstance(k, DEFAULT_M, dstMem, memReqSvr);
+ return newInstance(k, KllSketch.DEFAULT_M, dstMem, memReqSvr);
}
/**
@@ -308,16 +307,6 @@ public void merge(final KllSketch other) {
mergeDoubleImpl(other);
}
- @Override
- public byte[] toByteArray() {
- return toCompactByteArrayImpl();
- }
-
- @Override
- public String toString(final boolean withLevels, final boolean withData) {
- return toStringImpl(withLevels, withData);
- }
-
/**
* Updates this sketch with the given data item.
*
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index 15c4de1d7..11a5298d5 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -22,7 +22,6 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.UPDATABLE_BIT_MASK;
@@ -87,7 +86,7 @@ public static KllDirectFloatsSketch writableWrap(final WritableMemory srcMem, fi
*/
public static KllDirectFloatsSketch newInstance(final int k, final WritableMemory dstMem,
final MemoryRequestServer memReqSvr) {
- return newInstance(k, DEFAULT_M, dstMem, memReqSvr);
+ return newInstance(k, KllSketch.DEFAULT_M, dstMem, memReqSvr);
}
/**
@@ -308,16 +307,6 @@ public void merge(final KllSketch other) {
mergeFloatImpl(other);
}
- @Override
- public byte[] toByteArray() {
- return toCompactByteArrayImpl();
- }
-
- @Override
- public String toString(final boolean withLevels, final boolean withData) {
- return toStringImpl(withLevels, withData);
- }
-
/**
* Updates this sketch with the given data item.
*
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index 400caef4b..13725a518 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -74,6 +74,27 @@ public long getN() {
return extractN(wmem);
}
+ @Override
+ public void reset() {
+ final int k = getK();
+ setN(0);
+ setMinK(k);
+ setNumLevels(1);
+ setLevelsArray(new int[] {k, k});
+ setLevelZeroSorted(false);
+ final int newLevelsArrLen = 2 * Integer.BYTES;
+ final int newItemsArrLen = k;
+ KllSketch.memorySpaceMgmt(this, newLevelsArrLen, newItemsArrLen);
+ levelsArrUpdatable.putIntArray(0L, new int[] {k, k}, 0, 2);
+ if (sketchType == SketchType.DOUBLES_SKETCH) {
+ minMaxArrUpdatable.putDoubleArray(0L, new double[] {Double.NaN, Double.NaN}, 0, 2);
+ itemsArrUpdatable.putDoubleArray(0L, new double[k], 0, k);
+ } else {
+ minMaxArrUpdatable.putFloatArray(0L, new float[] {Float.NaN, Float.NaN}, 0, 2);
+ itemsArrUpdatable.putFloatArray(0L, new float[k], 0, k);
+ }
+ }
+
@Override
public byte[] toUpdatableByteArray() {
final int bytes = (int) wmem.getCapacity();
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 39982b809..08f7c5706 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -21,8 +21,6 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
@@ -58,7 +56,7 @@ private KllDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
* This will have a rank error of about 1.65%.
*/
public KllDoublesSketch() {
- this(DEFAULT_K);
+ this(KllSketch.DEFAULT_K);
}
/**
@@ -69,7 +67,7 @@ public KllDoublesSketch() {
* @param k parameter that controls size of the sketch and accuracy of estimates
*/
public KllDoublesSketch(final int k) {
- this(k, DEFAULT_M);
+ this(k, KllSketch.DEFAULT_M);
}
/**
@@ -290,6 +288,19 @@ public void merge(final KllSketch other) {
mergeDoubleImpl(other);
}
+ @Override
+ public void reset() {
+ final int k = getK();
+ setN(0);
+ setMinK(k);
+ setNumLevels(1);
+ setLevelsArray(new int[] {k, k});
+ setLevelZeroSorted(false);
+ doubleItems_ = new double[k];
+ minDoubleValue_ = Double.NaN;
+ maxDoubleValue_ = Double.NaN;
+ }
+
/**
* Updates this sketch with the given data item.
*
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 7993ccced..4c53675f8 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -21,8 +21,6 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
@@ -58,7 +56,7 @@ private KllFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
* This will have a rank error of about 1.65%.
*/
public KllFloatsSketch() {
- this(DEFAULT_K);
+ this(KllSketch.DEFAULT_K);
}
/**
@@ -69,7 +67,7 @@ public KllFloatsSketch() {
* @param k parameter that controls size of the sketch and accuracy of estimates
*/
public KllFloatsSketch(final int k) {
- this(k, DEFAULT_M);
+ this(k, KllSketch.DEFAULT_M);
}
/**
@@ -290,6 +288,19 @@ public void merge(final KllFloatsSketch other) {
mergeFloatImpl(other);
}
+ @Override
+ public void reset() {
+ final int k = getK();
+ setN(0);
+ setMinK(k);
+ setNumLevels(1);
+ setLevelsArray(new int[] {k, k});
+ setLevelZeroSorted(false);
+ floatItems_ = new float[k];
+ minFloatValue_ = Float.NaN;
+ maxFloatValue_ = Float.NaN;
+ }
+
/**
* Updates this sketch with the given data item.
*
diff --git a/src/main/java/org/apache/datasketches/kll/KllHelper.java b/src/main/java/org/apache/datasketches/kll/KllHelper.java
index 83e2bf45c..f089f8da3 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHelper.java
@@ -23,9 +23,6 @@
import static org.apache.datasketches.Util.floorPowerOf2;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
-import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.MAX_M;
-import static org.apache.datasketches.kll.KllPreambleUtil.MIN_M;
import static org.apache.datasketches.kll.KllSketch.CDF_COEF;
import static org.apache.datasketches.kll.KllSketch.CDF_EXP;
import static org.apache.datasketches.kll.KllSketch.PMF_COEF;
@@ -194,14 +191,14 @@ public static LevelStats getLevelCapacityItems(
* @param k must be greater than 7 and less than 65536.
*/
static void checkK(final int k, final int m) {
- if (k < m || k > MAX_K) {
+ if (k < m || k > KllSketch.MAX_K) {
throw new SketchesArgumentException(
- "K must be >= " + m + " and <= " + MAX_K + ": " + k);
+ "K must be >= " + m + " and <= " + KllSketch.MAX_K + ": " + k);
}
}
static void checkM(final int m) {
- if (m < MIN_M || m > MAX_M || ((m & 1) == 1)) {
+ if (m < KllSketch.MIN_M || m > KllSketch.MAX_M || ((m & 1) == 1)) {
throw new SketchesArgumentException(
"M must be >= 2, <= 8 and even: " + m);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index eafb80c81..45b6e48de 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -126,15 +126,6 @@ private KllPreambleUtil() {}
static final String LS = System.getProperty("line.separator");
- /**
- * The default value of K
- */
- public static final int DEFAULT_K = 200;
- public static final int DEFAULT_M = 8;
- public static final int MAX_K = (1 << 16) - 1; // serialized as an unsigned short
- public static final int MAX_M = 8;
- public static final int MIN_M = 2;
-
// Preamble byte addresses
static final int PREAMBLE_INTS_BYTE_ADR = 0;
static final int SER_VER_BYTE_ADR = 1;
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index 583883d68..64bb19606 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -30,9 +30,6 @@
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
-import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.MIN_M;
import static org.apache.datasketches.kll.KllPreambleUtil.N_LONG_ADR;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_EMPTY_SINGLE;
@@ -110,6 +107,31 @@ public abstract class KllSketch {
MemoryRequestServer memReqSvr;
boolean direct;
+ /**
+ * The default value of K
+ */
+ public static final int DEFAULT_K = 200;
+
+ /**
+ * The default value of M
+ */
+ static final int DEFAULT_M = 8;
+
+ /**
+ * The maximum value of K
+ */
+ public static final int MAX_K = (1 << 16) - 1; // serialized as an unsigned short
+
+ /**
+ * The maximum value of M
+ */
+ static final int MAX_M = 8;
+
+ /**
+ * The minimum value of M
+ */
+ static final int MIN_M = 2;
+
/**
*
* @param sketchType either DOUBLE_SKETCH or FLOAT_SKETCH
@@ -155,7 +177,7 @@ public static int getKFromEpsilon(final double epsilon, final boolean pmf) {
final double krnd = round(kdbl);
final double del = abs(krnd - kdbl);
final int k = (int) (del < EPS_DELTA_THRESHOLD ? krnd : ceil(kdbl));
- return max(MIN_M, min(MAX_K, k));
+ return max(KllSketch.MIN_M, min(KllSketch.MAX_K, k));
}
/**
@@ -166,27 +188,28 @@ public static int getKFromEpsilon(final double epsilon, final boolean pmf) {
* @param k parameter that controls size of the sketch and accuracy of estimates
* @param n stream length
* @return upper bound on the compact serialized size
- * @deprecated use {@link #getMaxSerializedSizeBytes(int, int, long, SketchType, boolean)} instead.
+ * @deprecated use {@link #getMaxSerializedSizeBytes(int, long, SketchType, boolean)} instead.
*/
@Deprecated
public static int getMaxSerializedSizeBytes(final int k, final long n) {
- final KllHelper.GrowthStats gStats = KllHelper.getGrowthSchemeForGivenN(k, DEFAULT_M, n, FLOATS_SKETCH, false);
+ final KllHelper.GrowthStats gStats =
+ KllHelper.getGrowthSchemeForGivenN(k, KllSketch.DEFAULT_M, n, FLOATS_SKETCH, false);
return gStats.compactBytes;
}
/**
* Returns upper bound on the serialized size of a KllSketch given the following parameters.
+ * It assumes the default value of m, which is 8.
* @param k parameter that controls size of the sketch and accuracy of estimates
- * @param m parameter that controls the smallest value of k, and the smallest level width.
- * If in doubt, use the default value of 8.
* @param n stream length
* @param sketchType either DOUBLES_SKETCH or FLOATS_SKETCH
* @param updatable true if updatable form, otherwise the standard compact form.
* @return upper bound on the serialized size of a KllSketch.
*/
- public static int getMaxSerializedSizeBytes(final int k, final int m, final long n,
+ public static int getMaxSerializedSizeBytes(final int k, final long n,
final SketchType sketchType, final boolean updatable) {
- final KllHelper.GrowthStats gStats = KllHelper.getGrowthSchemeForGivenN(k, m, n, sketchType, false);
+ final KllHelper.GrowthStats gStats =
+ KllHelper.getGrowthSchemeForGivenN(k, KllSketch.DEFAULT_M, n, sketchType, false);
return updatable ? gStats.updatableBytes : gStats.compactBytes;
}
@@ -343,6 +366,13 @@ public final boolean isEstimationMode() {
return getNumLevels() > 1;
}
+ /**
+ * This resets the current sketch back to zero entries.
+ * It retains key parameters such as k, m, and
+ * SketchType (double or float).
+ */
+ public abstract void reset();
+
/**
* Returns serialized sketch in a compact byte array form.
* @return serialized sketch in a compact byte array form.
@@ -693,7 +723,7 @@ static WritableMemory memorySpaceMgmt(
newWmem = sketch.memReqSvr.request(oldWmem, requiredSketchBytes);
oldWmem.copyTo(0, newWmem, 0, startAdr); //copy preamble
}
- else { //Expand in current memory
+ else { //Expand or contract in current memory
newWmem = oldWmem;
}
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
index f3ae36e05..4fcaa1bf7 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
@@ -19,8 +19,6 @@
package org.apache.datasketches.kll;
-import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
@@ -282,32 +280,32 @@ public void mergeMinAndMaxFromOther() {
@SuppressWarnings("unused")
@Test(expectedExceptions = SketchesArgumentException.class)
public void kTooSmall() {
- final KllDirectDoublesSketch sketch1 = getDDSketch(DEFAULT_M - 1, 0);
+ final KllDirectDoublesSketch sketch1 = getDDSketch(KllSketch.DEFAULT_M - 1, 0);
}
@SuppressWarnings("unused")
@Test(expectedExceptions = SketchesArgumentException.class)
public void kTooLarge() {
- final KllDirectDoublesSketch sketch1 = getDDSketch(MAX_K + 1, 0);
+ final KllDirectDoublesSketch sketch1 = getDDSketch(KllSketch.MAX_K + 1, 0);
}
@Test
public void minK() {
- final KllDirectDoublesSketch sketch = getDDSketch(DEFAULT_M, 0);
+ final KllDirectDoublesSketch sketch = getDDSketch(KllSketch.DEFAULT_M, 0);
for (int i = 0; i < 1000; i++) {
sketch.update(i);
}
- assertEquals(sketch.getK(), DEFAULT_M);
+ assertEquals(sketch.getK(), KllSketch.DEFAULT_M);
assertEquals(sketch.getQuantile(0.5), 500, 500 * PMF_EPS_FOR_K_8);
}
@Test
public void maxK() {
- final KllDirectDoublesSketch sketch = getDDSketch(MAX_K, 0);
+ final KllDirectDoublesSketch sketch = getDDSketch(KllSketch.MAX_K, 0);
for (int i = 0; i < 1000; i++) {
sketch.update(i);
}
- assertEquals(sketch.getK(), MAX_K);
+ assertEquals(sketch.getK(), KllSketch.MAX_K);
assertEquals(sketch.getQuantile(0.5), 500, 500 * PMF_EPS_FOR_K_256);
}
@@ -461,8 +459,8 @@ public void checkSimpleMergeDirect() { //used for troubleshooting
println(sk2.toString(true, true));
WritableMemory wmem1 = WritableMemory.writableWrap(sk1.toUpdatableByteArray());
WritableMemory wmem2 = WritableMemory.writableWrap(sk2.toUpdatableByteArray());
- KllDirectDoublesSketch dsk1 = KllDirectDoublesSketch.writableWrap(wmem1, new DefaultMemoryRequestServer());
- KllDirectDoublesSketch dsk2 = KllDirectDoublesSketch.writableWrap(wmem2, new DefaultMemoryRequestServer());
+ KllDirectDoublesSketch dsk1 = KllDirectDoublesSketch.writableWrap(wmem1, memReqSvr);
+ KllDirectDoublesSketch dsk2 = KllDirectDoublesSketch.writableWrap(wmem2, memReqSvr);
println("BEFORE MERGE");
println(dsk1.toString(true, true));
dsk1.merge(dsk2);
@@ -485,7 +483,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
compBytes = sk2.toUpdatableByteArray();
wmem = WritableMemory.writableWrap(compBytes);
println(KllPreambleUtil.toString(wmem));
- sk = KllDirectDoublesSketch.writableWrap(wmem, new DefaultMemoryRequestServer());
+ sk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
assertEquals(sk.getK(), k);
assertEquals(sk.getN(), k + 1);
assertEquals(sk.getNumRetained(), 11);
@@ -505,7 +503,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
compBytes = sk2.toUpdatableByteArray();
wmem = WritableMemory.writableWrap(compBytes);
println(KllPreambleUtil.toString(wmem));
- sk = KllDirectDoublesSketch.writableWrap(wmem, new DefaultMemoryRequestServer());
+ sk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
assertEquals(sk.getK(), k);
assertEquals(sk.getN(), 0);
assertEquals(sk.getNumRetained(), 0);
@@ -526,7 +524,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
compBytes = sk2.toUpdatableByteArray();
wmem = WritableMemory.writableWrap(compBytes);
println(KllPreambleUtil.toString(wmem));
- sk = KllDirectDoublesSketch.writableWrap(wmem, new DefaultMemoryRequestServer());
+ sk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
assertEquals(sk.getK(), k);
assertEquals(sk.getN(), 1);
assertEquals(sk.getNumRetained(), 1);
@@ -566,6 +564,23 @@ public void checkGetWritableMemory() {
assertTrue(KllSketch.isCompatible());
}
+ @Test
+ public void checkReset() {
+ WritableMemory dstMem = WritableMemory.allocate(6000);
+ KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(20, dstMem, memReqSvr);
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ long n1 = sk.getN();
+ double min1 = sk.getMinValue();
+ double max1 = sk.getMaxValue();
+ sk.reset();
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ long n2 = sk.getN();
+ double min2 = sk.getMinValue();
+ double max2 = sk.getMaxValue();
+ assertEquals(n2, n1);
+ assertEquals(min2, min1);
+ assertEquals(max2, max1);
+ }
private static KllDirectDoublesSketch getDDSketch(final int k, final int n) {
KllDoublesSketch sk = new KllDoublesSketch(k);
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
index b7f88b72b..4ff004254 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
@@ -19,8 +19,6 @@
package org.apache.datasketches.kll;
-import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
@@ -282,32 +280,32 @@ public void mergeMinAndMaxFromOther() {
@SuppressWarnings("unused")
@Test(expectedExceptions = SketchesArgumentException.class)
public void kTooSmall() {
- final KllDirectFloatsSketch sketch1 = getDFSketch(DEFAULT_M - 1, 0);
+ final KllDirectFloatsSketch sketch1 = getDFSketch(KllSketch.DEFAULT_M - 1, 0);
}
@SuppressWarnings("unused")
@Test(expectedExceptions = SketchesArgumentException.class)
public void kTooLarge() {
- final KllDirectFloatsSketch sketch1 = getDFSketch(MAX_K + 1, 0);
+ final KllDirectFloatsSketch sketch1 = getDFSketch(KllSketch.MAX_K + 1, 0);
}
@Test
public void minK() {
- final KllDirectFloatsSketch sketch = getDFSketch(DEFAULT_M, 0);
+ final KllDirectFloatsSketch sketch = getDFSketch(KllSketch.DEFAULT_M, 0);
for (int i = 0; i < 1000; i++) {
sketch.update(i);
}
- assertEquals(sketch.getK(), DEFAULT_M);
+ assertEquals(sketch.getK(), KllSketch.DEFAULT_M);
assertEquals(sketch.getQuantile(0.5), 500, 500 * PMF_EPS_FOR_K_8);
}
@Test
public void maxK() {
- final KllDirectFloatsSketch sketch = getDFSketch(MAX_K, 0);
+ final KllDirectFloatsSketch sketch = getDFSketch(KllSketch.MAX_K, 0);
for (int i = 0; i < 1000; i++) {
sketch.update(i);
}
- assertEquals(sketch.getK(), MAX_K);
+ assertEquals(sketch.getK(), KllSketch.MAX_K);
assertEquals(sketch.getQuantile(0.5), 500, 500 * PMF_EPS_FOR_K_256);
}
@@ -461,8 +459,8 @@ public void checkSimpleMergeDirect() { //used for troubleshooting
println(sk2.toString(true, true));
WritableMemory wmem1 = WritableMemory.writableWrap(sk1.toUpdatableByteArray());
WritableMemory wmem2 = WritableMemory.writableWrap(sk2.toUpdatableByteArray());
- KllDirectFloatsSketch dsk1 = KllDirectFloatsSketch.writableWrap(wmem1, new DefaultMemoryRequestServer());
- KllDirectFloatsSketch dsk2 = KllDirectFloatsSketch.writableWrap(wmem2, new DefaultMemoryRequestServer());
+ KllDirectFloatsSketch dsk1 = KllDirectFloatsSketch.writableWrap(wmem1, memReqSvr);
+ KllDirectFloatsSketch dsk2 = KllDirectFloatsSketch.writableWrap(wmem2, memReqSvr);
println("BEFORE MERGE");
println(dsk1.toString(true, true));
dsk1.merge(dsk2);
@@ -485,7 +483,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
compBytes = sk2.toUpdatableByteArray();
wmem = WritableMemory.writableWrap(compBytes);
println(KllPreambleUtil.toString(wmem));
- sk = KllDirectFloatsSketch.writableWrap(wmem, new DefaultMemoryRequestServer());
+ sk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
assertEquals(sk.getK(), k);
assertEquals(sk.getN(), k + 1);
assertEquals(sk.getNumRetained(), 11);
@@ -505,7 +503,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
compBytes = sk2.toUpdatableByteArray();
wmem = WritableMemory.writableWrap(compBytes);
println(KllPreambleUtil.toString(wmem));
- sk = KllDirectFloatsSketch.writableWrap(wmem, new DefaultMemoryRequestServer());
+ sk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
assertEquals(sk.getK(), k);
assertEquals(sk.getN(), 0);
assertEquals(sk.getNumRetained(), 0);
@@ -526,7 +524,7 @@ public void checkSketchInitializeDirectDoubleUpdatableMem() {
compBytes = sk2.toUpdatableByteArray();
wmem = WritableMemory.writableWrap(compBytes);
println(KllPreambleUtil.toString(wmem));
- sk = KllDirectFloatsSketch.writableWrap(wmem, new DefaultMemoryRequestServer());
+ sk = KllDirectFloatsSketch.writableWrap(wmem, memReqSvr);
assertEquals(sk.getK(), k);
assertEquals(sk.getN(), 1);
assertEquals(sk.getNumRetained(), 1);
@@ -566,6 +564,23 @@ public void checkGetWritableMemory() {
assertTrue(KllSketch.isCompatible());
}
+ @Test
+ public void checkReset() {
+ WritableMemory dstMem = WritableMemory.allocate(3000);
+ KllDirectFloatsSketch sk = KllDirectFloatsSketch.newInstance(20, dstMem, memReqSvr);
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ long n1 = sk.getN();
+ float min1 = sk.getMinValue();
+ float max1 = sk.getMaxValue();
+ sk.reset();
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ long n2 = sk.getN();
+ float min2 = sk.getMinValue();
+ float max2 = sk.getMaxValue();
+ assertEquals(n2, n1);
+ assertEquals(min2, min1);
+ assertEquals(max2, max1);
+ }
private static KllDirectFloatsSketch getDFSketch(final int k, final int n) {
KllFloatsSketch sk = new KllFloatsSketch(k);
diff --git a/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
index 0172068f4..b149d3c1c 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDoublesSketchTest.java
@@ -19,8 +19,6 @@
package org.apache.datasketches.kll;
-import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
@@ -279,32 +277,32 @@ public void mergeMinAndMaxFromOther() {
@SuppressWarnings("unused")
@Test(expectedExceptions = SketchesArgumentException.class)
public void kTooSmall() {
- new KllDoublesSketch(DEFAULT_M - 1);
+ new KllDoublesSketch(KllSketch.DEFAULT_M - 1);
}
@SuppressWarnings("unused")
@Test(expectedExceptions = SketchesArgumentException.class)
public void kTooLarge() {
- new KllDoublesSketch(MAX_K + 1);
+ new KllDoublesSketch(KllSketch.MAX_K + 1);
}
@Test
public void minK() {
- final KllDoublesSketch sketch = new KllDoublesSketch(DEFAULT_M);
+ final KllDoublesSketch sketch = new KllDoublesSketch(KllSketch.DEFAULT_M);
for (int i = 0; i < 1000; i++) {
sketch.update(i);
}
- assertEquals(sketch.getK(), DEFAULT_M);
+ assertEquals(sketch.getK(), KllSketch.DEFAULT_M);
assertEquals(sketch.getQuantile(0.5), 500, 500 * PMF_EPS_FOR_K_8);
}
@Test
public void maxK() {
- final KllDoublesSketch sketch = new KllDoublesSketch(MAX_K);
+ final KllDoublesSketch sketch = new KllDoublesSketch(KllSketch.MAX_K);
for (int i = 0; i < 1000; i++) {
sketch.update(i);
}
- assertEquals(sketch.getK(), MAX_K);
+ assertEquals(sketch.getK(), KllSketch.MAX_K);
assertEquals(sketch.getQuantile(0.5), 500, 500 * PMF_EPS_FOR_K_256);
}
@@ -396,4 +394,21 @@ public void getQuantiles() {
assertEquals(quantiles1[2], 3.0);
}
+ @Test
+ public void checkReset() {
+ KllDoublesSketch sk = new KllDoublesSketch(20);
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ long n1 = sk.getN();
+ double min1 = sk.getMinValue();
+ double max1 = sk.getMaxValue();
+ sk.reset();
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ long n2 = sk.getN();
+ double min2 = sk.getMinValue();
+ double max2 = sk.getMaxValue();
+ assertEquals(n2, n1);
+ assertEquals(min2, min1);
+ assertEquals(max2, max1);
+ }
+
}
diff --git a/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
index ee74063d7..466bdf2a3 100644
--- a/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
@@ -19,8 +19,6 @@
package org.apache.datasketches.kll;
-import static org.apache.datasketches.kll.KllPreambleUtil.MAX_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.Util.getResourceBytes;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
@@ -280,32 +278,32 @@ public void mergeMinAndMaxFromOther() {
@SuppressWarnings("unused")
@Test(expectedExceptions = SketchesArgumentException.class)
public void kTooSmall() {
- new KllFloatsSketch(DEFAULT_M - 1);
+ new KllFloatsSketch(KllSketch.DEFAULT_M - 1);
}
@SuppressWarnings("unused")
@Test(expectedExceptions = SketchesArgumentException.class)
public void kTooLarge() {
- new KllFloatsSketch(MAX_K + 1);
+ new KllFloatsSketch(KllSketch.MAX_K + 1);
}
@Test
public void minK() {
- final KllFloatsSketch sketch = new KllFloatsSketch(DEFAULT_M);
+ final KllFloatsSketch sketch = new KllFloatsSketch(KllSketch.DEFAULT_M);
for (int i = 0; i < 1000; i++) {
sketch.update(i);
}
- assertEquals(sketch.getK(), DEFAULT_M);
+ assertEquals(sketch.getK(), KllSketch.DEFAULT_M);
assertEquals(sketch.getQuantile(0.5), 500, 500 * PMF_EPS_FOR_K_8);
}
@Test
public void maxK() {
- final KllFloatsSketch sketch = new KllFloatsSketch(MAX_K);
+ final KllFloatsSketch sketch = new KllFloatsSketch(KllSketch.MAX_K);
for (int i = 0; i < 1000; i++) {
sketch.update(i);
}
- assertEquals(sketch.getK(), MAX_K);
+ assertEquals(sketch.getK(), KllSketch.MAX_K);
assertEquals(sketch.getQuantile(0.5), 500, 500 * PMF_EPS_FOR_K_256);
}
@@ -412,4 +410,21 @@ public void checkDeprecatedMethods() {
assertEquals(bytes, 832);
}
+ @Test
+ public void checkReset() {
+ KllFloatsSketch sk = new KllFloatsSketch(20);
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ long n1 = sk.getN();
+ float min1 = sk.getMinValue();
+ float max1 = sk.getMaxValue();
+ sk.reset();
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ long n2 = sk.getN();
+ float min2 = sk.getMinValue();
+ float max2 = sk.getMaxValue();
+ assertEquals(n2, n1);
+ assertEquals(min2, min1);
+ assertEquals(max2, max1);
+ }
+
}
diff --git a/src/test/java/org/apache/datasketches/kll/KllHelperTest.java b/src/test/java/org/apache/datasketches/kll/KllHelperTest.java
index b50a6d0a4..791bdd5c5 100644
--- a/src/test/java/org/apache/datasketches/kll/KllHelperTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllHelperTest.java
@@ -20,8 +20,6 @@
package org.apache.datasketches.kll;
import static org.apache.datasketches.kll.KllHelper.checkM;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_K;
-import static org.apache.datasketches.kll.KllPreambleUtil.DEFAULT_M;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
import static org.apache.datasketches.kll.KllSketch.SketchType.FLOATS_SKETCH;
import static org.testng.Assert.assertEquals;
@@ -57,7 +55,7 @@ public void checkCheckM() {
@Test
public void checkGetKFromEps() {
- final int k = DEFAULT_K;
+ final int k = KllSketch.DEFAULT_K;
final double eps = KllHelper.getNormalizedRankError(k, false);
final double epsPmf = KllHelper.getNormalizedRankError(k, true);
final int kEps = KllSketch.getKFromEpsilon(eps, false);
@@ -126,25 +124,25 @@ public void checkUpdatableSerDe() {
@Test
public void getMaxCompactDoublesSerializedSizeBytes() {
- final int sizeBytes = KllSketch.getMaxSerializedSizeBytes(DEFAULT_K, DEFAULT_M, 1L << 30, DOUBLES_SKETCH, false);
+ final int sizeBytes = KllSketch.getMaxSerializedSizeBytes(KllSketch.DEFAULT_K, 1L << 30, DOUBLES_SKETCH, false);
assertEquals(sizeBytes, 5704);
}
@Test
public void getMaxCompactFloatsSerializedSizeBytes() {
- final int sizeBytes = KllSketch.getMaxSerializedSizeBytes(DEFAULT_K, DEFAULT_M, 1L << 30, FLOATS_SKETCH, false);
+ final int sizeBytes = KllSketch.getMaxSerializedSizeBytes(KllSketch.DEFAULT_K, 1L << 30, FLOATS_SKETCH, false);
assertEquals(sizeBytes, 2908);
}
@Test
public void getMaxUpdatableDoubleSerializedSizeBytes() {
- final int sizeBytes = KllSketch.getMaxSerializedSizeBytes(DEFAULT_K, DEFAULT_M, 1L << 30, DOUBLES_SKETCH, true);
+ final int sizeBytes = KllSketch.getMaxSerializedSizeBytes(KllSketch.DEFAULT_K, 1L << 30, DOUBLES_SKETCH, true);
assertEquals(sizeBytes, 5708);
}
@Test
public void getMaxUpdatableFloatsSerializedSizeBytes() {
- final int sizeBytes = KllSketch.getMaxSerializedSizeBytes(DEFAULT_K, DEFAULT_M, 1L << 30, FLOATS_SKETCH, true);
+ final int sizeBytes = KllSketch.getMaxSerializedSizeBytes(KllSketch.DEFAULT_K, 1L << 30, FLOATS_SKETCH, true);
assertEquals(sizeBytes, 2912);
}
@@ -163,7 +161,7 @@ public void getStatsAtNumLevels2() {
int k = 20;
int m = 8;
int numLevels = 2;
- KllHelper.LevelStats lvlStats = KllHelper.getFinalSketchStatsAtNumLevels(k, DEFAULT_M, numLevels, false);
+ KllHelper.LevelStats lvlStats = KllHelper.getFinalSketchStatsAtNumLevels(k, KllSketch.DEFAULT_M, numLevels, false);
assertEquals(lvlStats.numLevels, 2);
assertEquals(lvlStats.items, 33);
}
@@ -182,7 +180,7 @@ public void testGetAllLevelStats2() {
long n = 533;
int k = 200;
int m = 8;
- KllHelper.GrowthStats gStats = KllHelper.getGrowthSchemeForGivenN(k, DEFAULT_M, n, DOUBLES_SKETCH, false);
+ KllHelper.GrowthStats gStats = KllHelper.getGrowthSchemeForGivenN(k, KllSketch.DEFAULT_M, n, DOUBLES_SKETCH, false);
assertEquals(gStats.numLevels, 2);
assertEquals(gStats.maxItems, 333);
From d29627dfc3774e31addaa0d04ca2eb78493ff7bb Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Thu, 31 Mar 2022 17:31:39 -0700
Subject: [PATCH 26/31] Removed mentions of m.
---
.../org/apache/datasketches/kll/KllDirectSketch.java | 2 +-
.../apache/datasketches/kll/KllDoublesSketch.java | 3 +--
.../org/apache/datasketches/kll/KllFloatsSketch.java | 3 +--
.../org/apache/datasketches/kll/KllHeapSketch.java | 2 +-
.../java/org/apache/datasketches/kll/KllSketch.java | 12 +++++-------
5 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index 13725a518..e4c000b10 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -65,7 +65,7 @@ public int getK() {
}
@Override
- public int getM() {
+ int getM() {
return extractM(wmem);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 08f7c5706..067a570f5 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -52,7 +52,7 @@ private KllDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
}
/**
- * Heap constructor with the default k = 200, and DEFAULT_M of 8.
+ * Heap constructor with the default k = 200.
* This will have a rank error of about 1.65%.
*/
public KllDoublesSketch() {
@@ -63,7 +63,6 @@ public KllDoublesSketch() {
* Heap constructor with a given parameter k. k can be any value between DEFAULT_M and
* 65535, inclusive. The default k = 200 results in a normalized rank error of about
* 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
- * This constructor assumes the DEFAULT_M, which is 8.
* @param k parameter that controls size of the sketch and accuracy of estimates
*/
public KllDoublesSketch(final int k) {
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 4c53675f8..427fea83e 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -52,7 +52,7 @@ private KllFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
}
/**
- * Heap constructor with the default k = 200, and DEFAULT_M of 8.
+ * Heap constructor with the default k = 200.
* This will have a rank error of about 1.65%.
*/
public KllFloatsSketch() {
@@ -63,7 +63,6 @@ public KllFloatsSketch() {
* Heap constructor with a given parameter k. k can be any value between DEFAULT_M and
* 65535, inclusive. The default k = 200 results in a normalized rank error of about
* 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
- * This constructor assumes the DEFAULT_M, which is 8.
* @param k parameter that controls size of the sketch and accuracy of estimates
*/
public KllFloatsSketch(final int k) {
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java b/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
index ab050f66c..fcfcda642 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
@@ -61,7 +61,7 @@ public int getK() {
}
@Override
- public int getM() {
+ int getM() {
return m;
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index 64bb19606..df4b85db6 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -183,8 +183,7 @@ public static int getKFromEpsilon(final double epsilon, final boolean pmf) {
/**
* Returns upper bound on the compact serialized size of a FloatsSketch given a parameter
* k and stream length. This method can be used if allocation of storage
- * is necessary beforehand. This assumes the DEFAULT_M = 8 used in older sketches, it will not
- * work with other values of m.
+ * is necessary beforehand.
* @param k parameter that controls size of the sketch and accuracy of estimates
* @param n stream length
* @return upper bound on the compact serialized size
@@ -199,7 +198,6 @@ public static int getMaxSerializedSizeBytes(final int k, final long n) {
/**
* Returns upper bound on the serialized size of a KllSketch given the following parameters.
- * It assumes the default value of m, which is 8.
* @param k parameter that controls size of the sketch and accuracy of estimates
* @param n stream length
* @param sketchType either DOUBLES_SKETCH or FLOATS_SKETCH
@@ -302,10 +300,10 @@ public final int getCurrentUpdatableSerializedSizeBytes() {
public abstract int getK();
/**
- * Returns the user configured parameter m
- * @return the user configured parameter m
+ * Returns the configured parameter m
+ * @return the configured parameter m
*/
- public abstract int getM();
+ abstract int getM();
/**
* Returns the length of the input stream in items.
@@ -368,7 +366,7 @@ public final boolean isEstimationMode() {
/**
* This resets the current sketch back to zero entries.
- * It retains key parameters such as k, m, and
+ * It retains key parameters such as k and
* SketchType (double or float).
*/
public abstract void reset();
From 091635be25188068eced3ccbaf030c254c447710 Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Mon, 4 Apr 2022 18:04:28 -0700
Subject: [PATCH 27/31] This post fixes all the issues in the last set of
reviews except two: 1) I haven't renamed the memory dedicated "insert*" and
"extract*" methods, and 2) I haven't done the hierarchy refactoring along the
lines we discussed. I want check this in so that we can at least resolve all
the other conversations.
---
.../kll/KllDirectDoublesSketch.java | 14 +-
.../kll/KllDirectFloatsSketch.java | 12 +-
.../datasketches/kll/KllDirectSketch.java | 1 +
.../datasketches/kll/KllDoublesSketch.java | 3 +-
.../datasketches/kll/KllFloatsSketch.java | 3 +-
.../apache/datasketches/kll/KllHelper.java | 13 +-
.../datasketches/kll/KllMemoryValidate.java | 289 +++++++-----------
.../datasketches/kll/KllPreambleUtil.java | 16 +-
.../apache/datasketches/kll/KllSketch.java | 133 ++++----
.../kll/KllDirectDoublesSketchTest.java | 3 +-
.../kll/KllDirectFloatsSketchTest.java | 5 +-
.../datasketches/kll/KllFloatsSketchTest.java | 2 +-
...teTest.java => KllMemoryValidateTest.java} | 66 ++--
13 files changed, 225 insertions(+), 335 deletions(-)
rename src/test/java/org/apache/datasketches/kll/{MemoryValidateTest.java => KllMemoryValidateTest.java} (72%)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index c6720a172..82ac35344 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -21,16 +21,16 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
+import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
import static org.apache.datasketches.kll.KllPreambleUtil.DOUBLES_SKETCH_BIT_MASK;
-import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_DOUBLE;
+import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.UPDATABLE_BIT_MASK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
import static org.apache.datasketches.kll.KllPreambleUtil.insertFamilyID;
import static org.apache.datasketches.kll.KllPreambleUtil.insertFlags;
import static org.apache.datasketches.kll.KllPreambleUtil.insertK;
import static org.apache.datasketches.kll.KllPreambleUtil.insertM;
+import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
import static org.apache.datasketches.kll.KllPreambleUtil.insertN;
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
@@ -39,6 +39,7 @@
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
+import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -92,14 +93,14 @@ public static KllDirectDoublesSketch newInstance(final int k, final WritableMemo
/**
* Create a new instance of this sketch.
* @param k parameter that controls size of the sketch and accuracy of estimates
- * @param m parameter that controls the minimum level width.
+ * @param m parameter that controls the minimum level width in items.
* @param dstMem the given destination WritableMemory object for use by the sketch
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
* @return a new instance of this sketch
*/
static KllDirectDoublesSketch newInstance(final int k, final int m, final WritableMemory dstMem,
final MemoryRequestServer memReqSvr) {
- insertPreInts(dstMem, PREAMBLE_INTS_DOUBLE);
+ insertPreInts(dstMem, PREAMBLE_INTS_FULL);
insertSerVer(dstMem, SERIAL_VERSION_UPDATABLE);
insertFamilyID(dstMem, Family.KLL.getID());
insertFlags(dstMem, DOUBLES_SKETCH_BIT_MASK | UPDATABLE_BIT_MASK);
@@ -108,7 +109,7 @@ static KllDirectDoublesSketch newInstance(final int k, final int m, final Writab
insertN(dstMem, 0);
insertMinK(dstMem, k);
insertNumLevels(dstMem, 1);
- int offset = DATA_START_ADR_DOUBLE;
+ int offset = DATA_START_ADR;
dstMem.putIntArray(offset, new int[] {k, k}, 0, 2);
offset += 2 * Integer.BYTES;
dstMem.putDoubleArray(offset, new double[] {Double.NaN, Double.NaN}, 0, 2);
@@ -359,6 +360,7 @@ void setDoubleItemsArray(final double[] doubleItems) {
@Override
void setDoubleItemsArrayAt(final int index, final double value) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putDouble((long)index * Double.BYTES, value);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index 11a5298d5..bd3091452 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -21,8 +21,8 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
-import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FLOAT;
+import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
+import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.UPDATABLE_BIT_MASK;
import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
@@ -38,6 +38,7 @@
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
+import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.MemoryRequestServer;
@@ -92,14 +93,14 @@ public static KllDirectFloatsSketch newInstance(final int k, final WritableMemor
/**
* Create a new instance of this sketch.
* @param k parameter that controls size of the sketch and accuracy of estimates
- * @param m parameter that controls the minimum level width.
+ * @param m parameter that controls the minimum level width in items.
* @param dstMem the given destination WritableMemory object for use by the sketch
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
* @return a new instance of this sketch
*/
static KllDirectFloatsSketch newInstance(final int k, final int m, final WritableMemory dstMem,
final MemoryRequestServer memReqSvr) {
- insertPreInts(dstMem, PREAMBLE_INTS_FLOAT);
+ insertPreInts(dstMem, PREAMBLE_INTS_FULL);
insertSerVer(dstMem, SERIAL_VERSION_UPDATABLE);
insertFamilyID(dstMem, Family.KLL.getID());
insertFlags(dstMem, UPDATABLE_BIT_MASK);
@@ -108,7 +109,7 @@ static KllDirectFloatsSketch newInstance(final int k, final int m, final Writabl
insertN(dstMem, 0);
insertMinK(dstMem, k);
insertNumLevels(dstMem, 1);
- int offset = DATA_START_ADR_FLOAT;
+ int offset = DATA_START_ADR;
dstMem.putIntArray(offset, new int[] {k, k}, 0, 2);
offset += 2 * Integer.BYTES;
dstMem.putFloatArray(offset, new float[] {Float.NaN, Float.NaN}, 0, 2);
@@ -365,6 +366,7 @@ void setFloatItemsArray(final float[] floatItems) {
@Override
void setFloatItemsArrayAt(final int index, final float value) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putFloat((long)index * Float.BYTES, value);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index e4c000b10..5a4b6e8e7 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -30,6 +30,7 @@
import static org.apache.datasketches.kll.KllPreambleUtil.insertN;
import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
+import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 067a570f5..dc7ad92b5 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -24,6 +24,7 @@
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
+import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
@@ -78,7 +79,7 @@ public KllDoublesSketch(final int k) {
* Other values of m should be considered experimental as they have not been
* as well characterized.
* @param k parameter that controls size of the sketch and accuracy of estimates
- * @param m parameter that controls the minimum level width.
+ * @param m parameter that controls the minimum level width in items.
*/
KllDoublesSketch(final int k, final int m) {
super(k, m, SketchType.DOUBLES_SKETCH);
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 427fea83e..0fbabb909 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -24,6 +24,7 @@
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
+import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
@@ -78,7 +79,7 @@ public KllFloatsSketch(final int k) {
* Other values of m should be considered experimental as they have not been
* as well characterized.
* @param k parameter that controls size of the sketch and accuracy of estimates
- * @param m parameter that controls the minimum level width.
+ * @param m parameter that controls the minimum level width in items.
*/
KllFloatsSketch(final int k, final int m) {
super(k, m, SketchType.FLOATS_SKETCH);
diff --git a/src/main/java/org/apache/datasketches/kll/KllHelper.java b/src/main/java/org/apache/datasketches/kll/KllHelper.java
index f089f8da3..0b24fffc6 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHelper.java
@@ -21,8 +21,7 @@
import static java.lang.Math.pow;
import static org.apache.datasketches.Util.floorPowerOf2;
-import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
+import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
import static org.apache.datasketches.kll.KllSketch.CDF_COEF;
import static org.apache.datasketches.kll.KllSketch.CDF_EXP;
import static org.apache.datasketches.kll.KllSketch.PMF_COEF;
@@ -144,18 +143,14 @@ public static GrowthStats getGrowthSchemeForGivenN(
}
int compactBytes;
int updatableBytes;
+ final int typeBytes = (sketchType == DOUBLES_SKETCH) ? Double.BYTES : Float.BYTES;
do {
numLevels++;
lvlStats = getFinalSketchStatsAtNumLevels(k, m, numLevels, false);
final int maxItems = lvlStats.items;
final long maxN = lvlStats.n;
- if (sketchType == DOUBLES_SKETCH) {
- compactBytes = maxItems * Double.BYTES + numLevels * Integer.BYTES + 2 * Double.BYTES + DATA_START_ADR_DOUBLE;
- updatableBytes = compactBytes + Integer.BYTES;
- } else {
- compactBytes = maxItems * Float.BYTES + numLevels * Integer.BYTES + 2 * Float.BYTES + DATA_START_ADR_FLOAT;
- updatableBytes = compactBytes + Integer.BYTES;
- }
+ compactBytes = maxItems * typeBytes + numLevels * Integer.BYTES + 2 * typeBytes + DATA_START_ADR;
+ updatableBytes = compactBytes + Integer.BYTES;
if (printGrowthScheme) {
printf("%10d %,10d %,20d %,13d %,15d\n", numLevels, maxItems, maxN, compactBytes, updatableBytes);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
index 3b8dbc3a0..214bbc675 100644
--- a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
+++ b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
@@ -26,14 +26,13 @@
import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.EMPTYBIT_AND_SER_VER;
import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.EMPTYBIT_AND_SINGLEBIT;
import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.SINGLEBIT_AND_SER_VER;
-import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.DOUBLEBIT_AND_PREINTS;
-import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.FLOATBIT_AND_PREINTS;
-import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.SINGLEBIT_AND_PREINTS;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.INVALID_PREINTS;
+import static org.apache.datasketches.kll.KllMemoryValidate.MemoryInputError.memoryValidateThrow;
+import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
-import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_EMPTY_SINGLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FLOAT;
+import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_EMPTY_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_SINGLE;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
@@ -86,7 +85,7 @@ final class KllMemoryValidate {
// For example, if the layout is compact & empty, n = 0, if compact and single, n = 1, etc.
long n;
// next 4 bytes
- int dyMinK;
+ int minK;
int numLevels;
// derived
int capacityItems; //capacity of Items array for exporting and for Updatable form
@@ -118,232 +117,156 @@ final class KllMemoryValidate {
m = extractM(srcMem);
KllHelper.checkM(m);
KllHelper.checkK(k, m);
- if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(UPDATABLEBIT_AND_SER_VER, 0); }
+ if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(UPDATABLEBIT_AND_SER_VER, 1); }
if (updatable) { updatableMemoryValidate((WritableMemory) srcMem); }
else { compactMemoryValidate(srcMem); }
}
void compactMemoryValidate(final Memory srcMem) {
- if (empty && singleItem) { memoryValidateThrow(EMPTYBIT_AND_SINGLEBIT, 0); }
- final int sw = (empty ? 1 : 0) | (singleItem ? 4 : 0) | (doublesSketch ? 8 : 0);
+ if (empty && singleItem) { memoryValidateThrow(EMPTYBIT_AND_SINGLEBIT, flags); }
+ final int typeBytes = doublesSketch ? Double.BYTES : Float.BYTES;
+ final int sw = (empty ? 1 : 0) | (singleItem ? 4 : 0);
switch (sw) {
- case 0: { //FLOAT_FULL_COMPACT
- if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(FLOATBIT_AND_PREINTS, preInts); }
+ case 0: { //FULL_COMPACT
+ if (preInts != PREAMBLE_INTS_FULL) { memoryValidateThrow(INVALID_PREINTS, preInts); }
if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
- layout = Layout.FLOAT_FULL_COMPACT;
+ layout = doublesSketch ? Layout.DOUBLE_FULL_COMPACT : Layout.FLOAT_FULL_COMPACT;
n = extractN(srcMem);
- dyMinK = extractMinK(srcMem);
+ minK = extractMinK(srcMem);
numLevels = extractNumLevels(srcMem);
- int offset = DATA_START_ADR_FLOAT;
+ int offset = DATA_START_ADR;
+
// LEVELS MEM
final int[] myLevelsArr = new int[numLevels + 1];
srcMem.getIntArray(offset, myLevelsArr, 0, numLevels); //copies all except the last one
myLevelsArr[numLevels] = KllHelper.computeTotalItemCapacity(k, m, numLevels); //load the last one
levelsArrCompact = Memory.wrap(myLevelsArr); //separate from srcMem,
offset += (int)levelsArrCompact.getCapacity() - Integer.BYTES; // but one larger than srcMem
- // MIN/MAX MEM
- minMaxArrCompact = srcMem.region(offset, 2L * Float.BYTES);
+
+ minMaxArrCompact = srcMem.region(offset, 2L * typeBytes); // MIN/MAX MEM
offset += (int)minMaxArrCompact.getCapacity();
+
// ITEMS MEM
itemsArrStart = offset;
capacityItems = myLevelsArr[numLevels];
itemsRetained = capacityItems - myLevelsArr[0];
- final float[] myItemsArr = new float[capacityItems];
- srcMem.getFloatArray(offset, myItemsArr, myLevelsArr[0], itemsRetained);
- itemsArrCompact = Memory.wrap(myItemsArr);
- sketchBytes = offset + itemsRetained * Float.BYTES;
+ if (doublesSketch) {
+ final double[] myItemsArr = new double[capacityItems];
+ srcMem.getDoubleArray(offset, myItemsArr, myLevelsArr[0], itemsRetained);
+ itemsArrCompact = Memory.wrap(myItemsArr);
+ } else {
+ final float[] myItemsArr = new float[capacityItems];
+ srcMem.getFloatArray(offset, myItemsArr, myLevelsArr[0], itemsRetained);
+ itemsArrCompact = Memory.wrap(myItemsArr);
+ }
+ sketchBytes = offset + itemsRetained * typeBytes;
break;
}
- case 1: { //FLOAT_EMPTY_COMPACT
+ case 1: { //EMPTY_COMPACT
if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(EMPTYBIT_AND_PREINTS, preInts); }
if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
- layout = Layout.FLOAT_EMPTY_COMPACT;
+ layout = doublesSketch ? Layout.DOUBLE_EMPTY_COMPACT : Layout.FLOAT_EMPTY_COMPACT;
n = 0; //assumed
- dyMinK = k; //assumed
+ minK = k; //assumed
numLevels = 1; //assumed
- // LEVELS MEM
- levelsArrCompact = Memory.wrap(new int[] {k, k});
- // MIN/MAX MEM
- minMaxArrCompact = Memory.wrap(new float[] {Float.NaN, Float.NaN});
- // ITEMS MEM
capacityItems = k;
itemsRetained = 0;
- itemsArrCompact = Memory.wrap(new float[k]);
- sketchBytes = DATA_START_ADR_SINGLE_ITEM; //also used for empty
- itemsArrStart = DATA_START_ADR_SINGLE_ITEM;
- break;
- }
- case 4: { //FLOAT_SINGLE_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(EMPTYBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(SINGLEBIT_AND_SER_VER, serVer); }
- layout = Layout.FLOAT_SINGLE_COMPACT;
- n = 1;
- dyMinK = k;
- numLevels = 1;
- // LEVELS MEM
- levelsArrCompact = Memory.wrap(new int[] {k - 1, k});
- final float minMax = srcMem.getFloat(DATA_START_ADR_SINGLE_ITEM);
- // MIN/MAX MEM
- minMaxArrCompact = Memory.wrap(new float[] {minMax, minMax});
- // ITEMS MEM
- capacityItems = k;
- itemsRetained = 1;
- final float[] myFloatItems = new float[k];
- myFloatItems[k - 1] = minMax;
- itemsArrCompact = Memory.wrap(myFloatItems);
- sketchBytes = DATA_START_ADR_SINGLE_ITEM + Float.BYTES;
- itemsArrStart = DATA_START_ADR_SINGLE_ITEM;
- break;
- }
- case 8: { //DOUBLE_FULL_COMPACT
- if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(DOUBLEBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
- layout = Layout.DOUBLE_FULL_COMPACT;
- n = extractN(srcMem);
- dyMinK = extractMinK(srcMem);
- numLevels = extractNumLevels(srcMem);
- int offset = DATA_START_ADR_DOUBLE;
- // LEVELS MEM
- final int[] myLevelsArr = new int[numLevels + 1];
- srcMem.getIntArray(offset, myLevelsArr, 0, numLevels); //all except the last one
- myLevelsArr[numLevels] = KllHelper.computeTotalItemCapacity(k, m, numLevels); //load the last one
- levelsArrCompact = Memory.wrap(myLevelsArr); //separate from srcMem
- offset += (int)levelsArrCompact.getCapacity() - Integer.BYTES;
- // MIN/MAX MEM
- minMaxArrCompact = srcMem.region(offset, 2L * Double.BYTES);
- offset += (int)minMaxArrCompact.getCapacity();
- // ITEMS MEM
- itemsArrStart = offset;
- capacityItems = myLevelsArr[numLevels];
- itemsRetained = capacityItems - myLevelsArr[0];
- final double[] myItemsArr = new double[capacityItems];
- srcMem.getDoubleArray(offset, myItemsArr, myLevelsArr[0], itemsRetained);
- itemsArrCompact = Memory.wrap(myItemsArr);
- sketchBytes = offset + itemsRetained * Double.BYTES;
- break;
- }
- case 9: { //DOUBLE_EMPTY_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(EMPTYBIT_AND_PREINTS, preInts); }
- if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
- layout = Layout.DOUBLE_EMPTY_COMPACT;
- n = 0;
- dyMinK = k;
- numLevels = 1;
- // LEVELS MEM
- levelsArrCompact = Memory.wrap(new int[] {k, k});
- // MIN/MAX MEM
- minMaxArrCompact = Memory.wrap(new double[] {Double.NaN, Double.NaN});
- // ITEMS MEM
- capacityItems = k;
- itemsRetained = 0;
- itemsArrCompact = Memory.wrap(new double[k]);
- sketchBytes = DATA_START_ADR_SINGLE_ITEM; //also used for empty
+ levelsArrCompact = Memory.wrap(new int[] {k, k}); // LEVELS MEM
+ if (doublesSketch) {
+ minMaxArrCompact = Memory.wrap(new double[] {Double.NaN, Double.NaN}); // MIN/MAX MEM
+ itemsArrCompact = Memory.wrap(new double[k]); // ITEMS MEM
+ } else { //Floats Sketch
+ minMaxArrCompact = Memory.wrap(new float[] {Float.NaN, Float.NaN}); // MIN/MAX MEM
+ itemsArrCompact = Memory.wrap(new float[k]); // ITEMS MEM
+ }
+ sketchBytes = DATA_START_ADR_SINGLE_ITEM; //used for empty and single item
itemsArrStart = DATA_START_ADR_SINGLE_ITEM;
break;
}
- case 12: { //DOUBLE_SINGLE_COMPACT
- if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(EMPTYBIT_AND_PREINTS, preInts); }
+ case 4: { //SINGLE_COMPACT
+ if (preInts != PREAMBLE_INTS_EMPTY_SINGLE) { memoryValidateThrow(SINGLEBIT_AND_PREINTS, preInts); }
if (serVer != SERIAL_VERSION_SINGLE) { memoryValidateThrow(SINGLEBIT_AND_SER_VER, serVer); }
- layout = Layout.DOUBLE_SINGLE_COMPACT;
+ layout = doublesSketch ? Layout.DOUBLE_SINGLE_COMPACT : Layout.FLOAT_SINGLE_COMPACT;
n = 1;
- dyMinK = k;
+ minK = k;
numLevels = 1;
-
- // LEVELS MEM
- levelsArrCompact = Memory.wrap(new int[] {k - 1, k});
- final double minMax = srcMem.getDouble(DATA_START_ADR_SINGLE_ITEM);
- // MIN/MAX MEM
- minMaxArrCompact = Memory.wrap(new double[] {minMax, minMax});
- // ITEMS MEM
capacityItems = k;
itemsRetained = 1;
- final double[] myDoubleItems = new double[k];
- myDoubleItems[k - 1] = minMax;
- itemsArrCompact = Memory.wrap(myDoubleItems);
- sketchBytes = DATA_START_ADR_SINGLE_ITEM + Double.BYTES;
+
+ levelsArrCompact = Memory.wrap(new int[] {k - 1, k}); // LEVELS MEM
+ if (doublesSketch) {
+ final double minMax = srcMem.getDouble(DATA_START_ADR_SINGLE_ITEM);
+ minMaxArrCompact = Memory.wrap(new double[] {minMax, minMax}); // MIN/MAX MEM
+ final double[] myDoubleItems = new double[k]; // ITEMS MEM
+ myDoubleItems[k - 1] = minMax;
+ itemsArrCompact = Memory.wrap(myDoubleItems);
+ } else {
+ final float minMax = srcMem.getFloat(DATA_START_ADR_SINGLE_ITEM);
+ minMaxArrCompact = Memory.wrap(new float[] {minMax, minMax}); // MIN/MAX MEM
+ final float[] myFloatItems = new float[k]; // ITEMS MEM
+ myFloatItems[k - 1] = minMax;
+ itemsArrCompact = Memory.wrap(myFloatItems);
+ }
+ sketchBytes = DATA_START_ADR_SINGLE_ITEM + typeBytes;
itemsArrStart = DATA_START_ADR_SINGLE_ITEM;
break;
}
- default: break; //can't happen
+ default: //can not happen
}
}
void updatableMemoryValidate(final WritableMemory wSrcMem) {
- if (doublesSketch) { //DOUBLE_UPDATABLE
- if (preInts != PREAMBLE_INTS_DOUBLE) { memoryValidateThrow(DOUBLEBIT_AND_PREINTS, preInts); }
- layout = Layout.DOUBLE_UPDATABLE;
- n = extractN(wSrcMem);
- empty = n == 0; //empty & singleItem are set for convenience
- singleItem = n == 1; // there is no error checking on these bits
- dyMinK = extractMinK(wSrcMem);
- numLevels = extractNumLevels(wSrcMem);
+ final int typeBytes = doublesSketch ? Double.BYTES : Float.BYTES;
+ if (preInts != PREAMBLE_INTS_FULL) { memoryValidateThrow(INVALID_PREINTS, preInts); }
+ layout = doublesSketch ? Layout.DOUBLE_UPDATABLE : Layout.FLOAT_UPDATABLE;
- int offset = DATA_START_ADR_DOUBLE;
- //LEVELS
- levelsArrUpdatable = wSrcMem.writableRegion(offset, (numLevels + 1L) * Integer.BYTES);
- offset += (int)levelsArrUpdatable.getCapacity();
- //MIN/MAX
- minMaxArrUpdatable = wSrcMem.writableRegion(offset, 2L * Double.BYTES);
- offset += (int)minMaxArrUpdatable.getCapacity();
- //ITEMS
- capacityItems = levelsArrUpdatable.getInt((long)numLevels * Integer.BYTES);
- final int itemsArrBytes = capacityItems * Double.BYTES;
- itemsArrStart = offset;
- itemsArrUpdatable = wSrcMem.writableRegion(offset, itemsArrBytes);
- sketchBytes = offset + itemsArrBytes;
- }
- else { //FLOAT_UPDATABLE
- if (preInts != PREAMBLE_INTS_FLOAT) { memoryValidateThrow(FLOATBIT_AND_PREINTS, preInts); }
- layout = Layout.FLOAT_UPDATABLE;
- n = extractN(wSrcMem);
- empty = n == 0; //empty & singleItem are set for convenience
- singleItem = n == 1; // there is no error checking on these bits
- dyMinK = extractMinK(wSrcMem);
- numLevels = extractNumLevels(wSrcMem);
- int offset = DATA_START_ADR_FLOAT;
- //LEVELS
- levelsArrUpdatable = wSrcMem.writableRegion(offset, (numLevels + 1L) * Integer.BYTES);
- offset += (int)levelsArrUpdatable.getCapacity();
- //MIN/MAX
- minMaxArrUpdatable = wSrcMem.writableRegion(offset, 2L * Float.BYTES);
- offset += (int)minMaxArrUpdatable.getCapacity();
- //ITEMS
- capacityItems = levelsArrUpdatable.getInt((long)numLevels * Integer.BYTES);
- final int itemsArrBytes = capacityItems * Float.BYTES;
- itemsArrStart = offset;
- itemsArrUpdatable = wSrcMem.writableRegion(offset, itemsArrBytes);
- sketchBytes = itemsArrStart + itemsArrBytes;
- }
+ n = extractN(wSrcMem);
+ empty = n == 0; //empty & singleItem are set for convenience
+ singleItem = n == 1; // there is no error checking on these bits
+ minK = extractMinK(wSrcMem);
+ numLevels = extractNumLevels(wSrcMem);
+
+ int offset = DATA_START_ADR;
+
+ levelsArrUpdatable = wSrcMem.writableRegion(offset, (numLevels + 1L) * Integer.BYTES); //LEVELS
+ offset += (int)levelsArrUpdatable.getCapacity();
+
+ minMaxArrUpdatable = wSrcMem.writableRegion(offset, 2L * typeBytes); //MIN/MAX
+ offset += (int)minMaxArrUpdatable.getCapacity();
+
+ capacityItems = levelsArrUpdatable.getInt((long)numLevels * Integer.BYTES); //ITEMS
+ final int itemsArrBytes = capacityItems * typeBytes;
+ itemsArrStart = offset;
+ itemsArrUpdatable = wSrcMem.writableRegion(offset, itemsArrBytes);
+ sketchBytes = offset + itemsArrBytes;
}
- enum MemoryInputError { SRC_NOT_KLL, EMPTYBIT_AND_PREINTS, EMPTYBIT_AND_SER_VER,
- SINGLEBIT_AND_SER_VER, DOUBLEBIT_AND_PREINTS, FLOATBIT_AND_PREINTS, UPDATABLEBIT_AND_SER_VER,
- EMPTYBIT_AND_SINGLEBIT }
+ enum MemoryInputError {
+ SRC_NOT_KLL("FamilyID Field must be: " + Family.KLL.getID() + ", NOT: "),
+ EMPTYBIT_AND_PREINTS("Empty Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: "),
+ EMPTYBIT_AND_SER_VER("Empty Bit: 1 -> SerVer: " + SERIAL_VERSION_EMPTY_FULL + ", NOT: "),
+ SINGLEBIT_AND_SER_VER("Single Item Bit: 1 -> SerVer: " + SERIAL_VERSION_SINGLE + ", NOT: "),
+ SINGLEBIT_AND_PREINTS("Single Item Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: "),
+ INVALID_PREINTS("PreInts Must Be: " + PREAMBLE_INTS_FULL + ", NOT: "),
+ UPDATABLEBIT_AND_SER_VER("((SerVer == 3) ^ (Updatable Bit)) must = 0, NOT: "),
+ EMPTYBIT_AND_SINGLEBIT("Empty flag bit and SingleItem flag bit cannot both be set. Flags: ");
- private static void memoryValidateThrow(final MemoryInputError errType, final int value) {
- String msg = "";
- switch (errType) {
- case SRC_NOT_KLL: msg = "FamilyID Field must be: " + Family.KLL.getID() + ", NOT: " + value; break;
- case EMPTYBIT_AND_PREINTS: msg =
- "Empty Bit: 1 -> PreInts: " + PREAMBLE_INTS_EMPTY_SINGLE + ", NOT: " + value; break;
- case EMPTYBIT_AND_SER_VER: msg =
- "Empty Bit: 1 -> SerVer: " + SERIAL_VERSION_EMPTY_FULL + ", NOT: " + value; break;
- case SINGLEBIT_AND_SER_VER: msg =
- "Single Item Bit: 1 -> SerVer: " + SERIAL_VERSION_SINGLE + ", NOT: " + value; break;
- case DOUBLEBIT_AND_PREINTS: msg =
- "Double Sketch Bit: 1 -> PreInts: " + PREAMBLE_INTS_DOUBLE + ", NOT: " + value; break;
- case FLOATBIT_AND_PREINTS: msg =
- "Double Sketch Bit: 0 -> PreInts: " + PREAMBLE_INTS_FLOAT + ", NOT: " + value; break;
- case UPDATABLEBIT_AND_SER_VER: msg =
- "((SerVer == 3) ^ (Updatable Bit)) must = 0."; break;
- case EMPTYBIT_AND_SINGLEBIT: msg =
- "Empty flag bit and SingleItem flag bit cannot both be set. Flags: " + value; break;
- default: msg = "Unknown error"; break;
+ private String msg;
+
+ private MemoryInputError(final String msg) {
+ this.msg = msg;
+ }
+
+ private String getMessage() {
+ return msg;
}
- throw new SketchesArgumentException(msg);
+
+ final static void memoryValidateThrow(final MemoryInputError errType, final int value) {
+ throw new SketchesArgumentException(errType.getMessage() + value);
+ }
+
}
}
-
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index 45b6e48de..bd64b5ca7 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -139,22 +139,18 @@ private KllPreambleUtil() {}
// MULTI-ITEM
static final int N_LONG_ADR = 8; // to 15
- static final int MIN_K_SHORT_ADR = 16; // to 17
+ static final int MIN_K_SHORT_ADR = 16; // to 17
static final int NUM_LEVELS_BYTE_ADR = 18;
- // FLOAT SKETCH 19 is reserved for future use in float sketch
- static final int DATA_START_ADR_FLOAT = 20; // float sketch, not single item
-
- // DOUBLE SKETCH 19 to 23 is reserved for future use in double sketch
- static final int DATA_START_ADR_DOUBLE = 20; // double sketch, not single item
+ // 19 is reserved for future use
+ static final int DATA_START_ADR = 20; // Full Sketch, not single item
// Other static values
static final byte SERIAL_VERSION_EMPTY_FULL = 1; // Empty or full preamble, NOT single item format
static final byte SERIAL_VERSION_SINGLE = 2; // only single-item format
static final byte SERIAL_VERSION_UPDATABLE = 3; //
static final int PREAMBLE_INTS_EMPTY_SINGLE = 2; // for empty or single item
- static final int PREAMBLE_INTS_FLOAT = 5; // not empty nor single item, full preamble float
- static final int PREAMBLE_INTS_DOUBLE = 5; // not empty nor single item, full preamble double
+ static final int PREAMBLE_INTS_FULL = 5; // Full preamble, not empty nor single item
// Flag bit masks
static final int EMPTY_BIT_MASK = 1;
@@ -221,7 +217,7 @@ static String memoryToString(final Memory mem) {
case DOUBLE_UPDATABLE:
{
sb.append("Bytes 8-15: N : ").append(memChk.n).append(LS);
- sb.append("Bytes 16-17: DyMinK : ").append(memChk.dyMinK).append(LS);
+ sb.append("Bytes 16-17: DyMinK : ").append(memChk.minK).append(LS);
sb.append("Byte 18 : NumLevels : ").append(memChk.numLevels).append(LS);
break;
}
@@ -231,7 +227,7 @@ static String memoryToString(final Memory mem) {
case DOUBLE_SINGLE_COMPACT:
{
sb.append("Assumed : N : ").append(memChk.n).append(LS);
- sb.append("Assumed : DyMinK : ").append(memChk.dyMinK).append(LS);
+ sb.append("Assumed : DyMinK : ").append(memChk.minK).append(LS);
sb.append("Assumed : NumLevels : ").append(memChk.numLevels).append(LS);
break;
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index df4b85db6..b98c902e4 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -27,13 +27,11 @@
import static java.lang.Math.min;
import static java.lang.Math.round;
import static org.apache.datasketches.Util.isOdd;
-import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_DOUBLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_FLOAT;
+import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
import static org.apache.datasketches.kll.KllPreambleUtil.N_LONG_ADR;
-import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_DOUBLE;
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_EMPTY_SINGLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FLOAT;
+import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_EMPTY_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_SINGLE;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
@@ -73,7 +71,7 @@
* overwritten by subsequent updates.
*
* Invariants:
- * 1) After a compaction, or an update, or a merge, all levels are sorted except for level zero.
+ * 1) After a compaction, or an update, or a merge, every level is sorted except for level zero.
* 2) After a compaction, (sum of capacities) - (sum of items) >= 1,
* so there is room for least 1 more item in level zero.
* 3) There are no gaps except at the bottom, so if levels_[0] = 0,
@@ -101,7 +99,6 @@ public abstract class KllSketch {
static final double CDF_COEF = 2.296;
static final double CDF_EXP = 0.9723;
static final Random random = new Random();
- static final boolean compatible = true; //rank 0.0 and 1.0. compatible with classic Quantiles Sketch
SketchType sketchType;
WritableMemory wmem;
MemoryRequestServer memReqSvr;
@@ -113,7 +110,10 @@ public abstract class KllSketch {
public static final int DEFAULT_K = 200;
/**
- * The default value of M
+ * The default value of M. The parameter m is the minimum level size in number of items.
+ * Currently, the public default is 8, but this can be overridden using Package Private methods to
+ * 2, 4, 6 or 8, and the sketch works just fine. The value 8 was chosen as a compromise between speed and size.
+ * Choosing smaller values of m less than 8 will make the sketch much slower.
*/
static final int DEFAULT_M = 8;
@@ -123,12 +123,12 @@ public abstract class KllSketch {
public static final int MAX_K = (1 << 16) - 1; // serialized as an unsigned short
/**
- * The maximum value of M
+ * The maximum value of M. See the Javadoc on DEFAULT_M.
*/
static final int MAX_M = 8;
/**
- * The minimum value of M
+ * The minimum value of M. See the Javadoc on DEFAULT_M.
*/
static final int MIN_M = 2;
@@ -188,6 +188,7 @@ public static int getKFromEpsilon(final double epsilon, final boolean pmf) {
* @param n stream length
* @return upper bound on the compact serialized size
* @deprecated use {@link #getMaxSerializedSizeBytes(int, long, SketchType, boolean)} instead.
+ * Version 3.2.0
*/
@Deprecated
public static int getMaxSerializedSizeBytes(final int k, final long n) {
@@ -234,44 +235,42 @@ public int getSerializedSizeBytes() {
: getCurrentCompactSerializedSizeBytes();
}
- static int getSerializedSizeBytes(final int numLevels, final int numItems,
+ //numItems can be either numRetained, or current max capacity at given K and numLevels.
+ static int getCurrentSerializedSizeBytes(final int numLevels, final int numItems,
final SketchType sketchType, final boolean updatable) {
+ final int typeBytes = (sketchType == DOUBLES_SKETCH) ? Double.BYTES : Float.BYTES;
int levelsBytes = 0;
- if (!updatable) {
- if (numItems == 0) { return N_LONG_ADR; }
- if (numItems == 1) {
- return DATA_START_ADR_SINGLE_ITEM + (sketchType == DOUBLES_SKETCH ? Double.BYTES : Float.BYTES);
- }
- levelsBytes = numLevels * Integer.BYTES;
- } else {
+ if (updatable) {
levelsBytes = (numLevels + 1) * Integer.BYTES;
- }
- if (sketchType == DOUBLES_SKETCH) {
- return DATA_START_ADR_DOUBLE + levelsBytes + (numItems + 2) * Double.BYTES; //+2 is for min & max
} else {
- return DATA_START_ADR_FLOAT + levelsBytes + (numItems + 2) * Float.BYTES;
+ if (numItems == 0) { return N_LONG_ADR; }
+ if (numItems == 1) { return DATA_START_ADR_SINGLE_ITEM + typeBytes; }
+ levelsBytes = numLevels * Integer.BYTES;
}
+ return DATA_START_ADR + levelsBytes + (numItems + 2) * typeBytes; //+2 is for min & max
}
- final static boolean isCompatible() {
- return compatible;
- }
+ enum Error {
+ TGT_IS_IMMUTABLE("Given sketch Memory is immutable, cannot write."),
+ SRC_IS_NOT_DIRECT("Given sketch must be of type Direct."),
+ SRC_IS_NOT_DOUBLE("Given sketch must be of type Double."),
+ SRC_IS_NOT_FLOAT("Given sketch must be of type Float."),
+ SRC_CANNOT_BE_DIRECT("Given sketch must not be of type Direct."),
+ MUST_NOT_CALL("This is an artifact of inheritance and should never be called.");
+
+ private String msg;
- enum Error { TGT_IS_IMMUTABLE, SRC_IS_NOT_DIRECT, SRC_IS_NOT_DOUBLE,
- SRC_IS_NOT_FLOAT, SRC_CANNOT_BE_DIRECT, MUST_NOT_CALL }
-
- final static void kllSketchThrow(final Error errType) {
- String msg = "";
- switch (errType) {
- case TGT_IS_IMMUTABLE: msg = "Given sketch Memory is immutable, cannot write."; break;
- case SRC_IS_NOT_DIRECT: msg = "Given sketch must be of type Direct."; break;
- case SRC_IS_NOT_DOUBLE: msg = "Given sketch must be of type Double."; break;
- case SRC_IS_NOT_FLOAT: msg = "Given sketch must be of type Float."; break;
- case SRC_CANNOT_BE_DIRECT: msg = "Given sketch must not be of type Direct."; break;
- case MUST_NOT_CALL: msg = "This is an artifact of inheritance and should never be called."; break;
- default: msg = "Unknown error."; break;
+ private Error(final String msg) {
+ this.msg = msg;
+ }
+
+ private String getMessage() {
+ return msg;
+ }
+
+ final static void kllSketchThrow(final Error errType) {
+ throw new SketchesArgumentException(errType.getMessage());
}
- throw new SketchesArgumentException(msg);
}
//Public Non-static methods
@@ -281,7 +280,7 @@ final static void kllSketchThrow(final Error errType) {
* @return the current compact number of bytes this sketch would require to store.
*/
public final int getCurrentCompactSerializedSizeBytes() {
- return KllSketch.getSerializedSizeBytes(getNumLevels(), getNumRetained(), sketchType, false);
+ return KllSketch.getCurrentSerializedSizeBytes(getNumLevels(), getNumRetained(), sketchType, false);
}
/**
@@ -290,7 +289,7 @@ public final int getCurrentCompactSerializedSizeBytes() {
*/
public final int getCurrentUpdatableSerializedSizeBytes() {
final int itemCap = KllHelper.computeTotalItemCapacity(getK(), getM(), getNumLevels());
- return KllSketch.getSerializedSizeBytes(getNumLevels(), itemCap, sketchType, true);
+ return KllSketch.getCurrentSerializedSizeBytes(getNumLevels(), itemCap, sketchType, true);
}
/**
@@ -300,7 +299,10 @@ public final int getCurrentUpdatableSerializedSizeBytes() {
public abstract int getK();
/**
- * Returns the configured parameter m
+ * Returns the configured parameter m, which is the minimum level size in number of items.
+ * Currently, the public default is 8, but this can be overridden using Package Private methods to
+ * 2, 4, 6 or 8, and the sketch works just fine. The value 8 was chosen as a compromise between speed and size.
+ * Choosing smaller values of m will make the sketch much slower.
* @return the configured parameter m
*/
abstract int getM();
@@ -409,7 +411,7 @@ final void buildHeapKllSketchFromMemory(final KllMemoryValidate memVal) {
final boolean updatable = memVal.updatable;
setLevelZeroSorted(memVal.level0Sorted);
setN(memVal.n);
- setMinK(memVal.dyMinK);
+ setMinK(memVal.minK);
setNumLevels(memVal.numLevels);
final int[] myLevelsArr = new int[getNumLevels() + 1];
@@ -519,10 +521,9 @@ final double getDoublesQuantile(final double fraction) {
if (fraction < 0.0 || fraction > 1.0) {
throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
}
- if (isCompatible()) {
- if (fraction == 0.0) { return getMinDoubleValue(); }
- if (fraction == 1.0) { return getMaxDoubleValue(); }
- }
+ //These two assumptions make KLL compatible with the previous classic Quantiles Sketch
+ if (fraction == 0.0) { return getMinDoubleValue(); }
+ if (fraction == 1.0) { return getMaxDoubleValue(); }
final KllDoublesQuantileCalculator quant = getDoublesQuantileCalculator();
return quant.getQuantile(fraction);
}
@@ -536,8 +537,8 @@ final double[] getDoublesQuantiles(final double[] fractions) {
if (fraction < 0.0 || fraction > 1.0) {
throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
}
- if (fraction == 0.0 && isCompatible()) { quantiles[i] = getMinDoubleValue(); }
- else if (fraction == 1.0 && isCompatible()) { quantiles[i] = getMaxDoubleValue(); }
+ if (fraction == 0.0) { quantiles[i] = getMinDoubleValue(); }
+ else if (fraction == 1.0) { quantiles[i] = getMaxDoubleValue(); }
else {
if (quant == null) {
quant = getDoublesQuantileCalculator();
@@ -622,10 +623,10 @@ final float getFloatsQuantile(final double fraction) {
if (fraction < 0.0 || fraction > 1.0) {
throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
}
- if (isCompatible()) {
- if (fraction == 0.0) { return getMinFloatValue(); }
- if (fraction == 1.0) { return getMaxFloatValue(); }
- }
+ //These two assumptions make KLL compatible with the previous classic Quantiles Sketch
+ if (fraction == 0.0) { return getMinFloatValue(); }
+ if (fraction == 1.0) { return getMaxFloatValue(); }
+
final KllFloatsQuantileCalculator quant = getFloatsQuantileCalculator();
return quant.getQuantile(fraction);
}
@@ -639,8 +640,8 @@ final float[] getFloatsQuantiles(final double[] fractions) {
if (fraction < 0.0 || fraction > 1.0) {
throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
}
- if (fraction == 0.0 && isCompatible()) { quantiles[i] = getMinFloatValue(); }
- else if (fraction == 1.0 && isCompatible()) { quantiles[i] = getMaxFloatValue(); }
+ if (fraction == 0.0) { quantiles[i] = getMinFloatValue(); }
+ else if (fraction == 1.0) { quantiles[i] = getMaxFloatValue(); }
else {
if (quant == null) {
quant = getFloatsQuantileCalculator();
@@ -701,16 +702,9 @@ static WritableMemory memorySpaceMgmt(
final int newItemsArrLen) {
final SketchType sketchType = sketch.sketchType;
final WritableMemory oldWmem = sketch.wmem;
+ final int startAdr = DATA_START_ADR;
+ final int typeBytes = (sketchType == DOUBLES_SKETCH) ? Double.BYTES : Float.BYTES;
- final int typeBytes;
- final int startAdr;
- if (sketchType == DOUBLES_SKETCH) {
- typeBytes = Double.BYTES;
- startAdr = DATA_START_ADR_DOUBLE;
- } else {
- typeBytes = Float.BYTES;
- startAdr = DATA_START_ADR_FLOAT;
- }
int requiredSketchBytes = startAdr;
requiredSketchBytes += newLevelsArrLen * Integer.BYTES;
requiredSketchBytes += 2 * typeBytes;
@@ -1020,7 +1014,7 @@ final byte[] toCompactByteArrayImpl() {
insertN(wmem, getN());
insertMinK(wmem, getMinK());
insertNumLevels(wmem, getNumLevels());
- offset = (doubleType) ? DATA_START_ADR_DOUBLE : DATA_START_ADR_FLOAT;
+ offset = DATA_START_ADR;
//LOAD LEVELS ARR the last integer in levels_ is NOT serialized
final int len = myLevelsArr.length - 1;
@@ -1051,12 +1045,9 @@ private static void loadFirst8Bytes(final KllSketch sk, final WritableMemory wme
final boolean lvlZeroSorted = sk.isLevelZeroSorted();
final boolean singleItem = sk.getN() == 1;
final boolean doubleType = (sk.sketchType == DOUBLES_SKETCH);
- final int preInts =
- updatable
- ? (doubleType ? PREAMBLE_INTS_DOUBLE : PREAMBLE_INTS_FLOAT)
- : ((empty || singleItem)
- ? PREAMBLE_INTS_EMPTY_SINGLE
- : (doubleType) ? PREAMBLE_INTS_DOUBLE : PREAMBLE_INTS_FLOAT);
+ final int preInts = updatable
+ ? PREAMBLE_INTS_FULL
+ : (empty || singleItem) ? PREAMBLE_INTS_EMPTY_SINGLE : PREAMBLE_INTS_FULL;
//load the preamble
insertPreInts(wmem, preInts);
final int server = updatable ? SERIAL_VERSION_UPDATABLE
@@ -1209,7 +1200,7 @@ final byte[] toUpdatableByteArrayImpl() {
//load data
final boolean doubleType = (sketchType == DOUBLES_SKETCH);
- int offset = (doubleType) ? DATA_START_ADR_DOUBLE : DATA_START_ADR_FLOAT;
+ int offset = DATA_START_ADR;
//LOAD LEVELS ARRAY the last integer in levels_ IS serialized
final int[] myLevelsArr = getLevelsArray();
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
index 4fcaa1bf7..7af0269f3 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
@@ -102,7 +102,7 @@ public void manyItemsEstimationMode() {
}
// test getPMF
- final double[] pmf = sketch.getPMF(new double[] {n / 2}); // split at median
+ final double[] pmf = sketch.getPMF(new double[] {n / 2.0}); // split at median
assertEquals(pmf.length, 2);
assertEquals(pmf[0], 0.5, PMF_EPS_FOR_K_256);
assertEquals(pmf[1], 0.5, PMF_EPS_FOR_K_256);
@@ -561,7 +561,6 @@ public void checkGetWritableMemory() {
assertTrue(sk.isDoublesSketch());
assertFalse(sk.isLevelZeroSorted());
assertFalse(sk.isFloatsSketch());
- assertTrue(KllSketch.isCompatible());
}
@Test
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
index 4ff004254..4f6520173 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
@@ -377,9 +377,7 @@ public void serializeDeserializeOneItemViaUpdatableWritableWrap() {
public void serializeDeserializeFullViaCompactHeapify() {
final KllDirectFloatsSketch sketch1 = getDFSketch(200, 0);
final int n = 1000;
- for (int i = 0; i < n; i++) {
- sketch1.update(i);
- }
+ for (int i = 0; i < n; i++) { sketch1.update(i); }
final byte[] bytes = sketch1.toByteArray();
final KllFloatsSketch sketch2 = KllFloatsSketch.heapify(Memory.wrap(bytes));
assertEquals(bytes.length, sketch1.getCurrentCompactSerializedSizeBytes());
@@ -561,7 +559,6 @@ public void checkGetWritableMemory() {
assertTrue(sk.isFloatsSketch());
assertFalse(sk.isLevelZeroSorted());
assertFalse(sk.isDoublesSketch());
- assertTrue(KllSketch.isCompatible());
}
@Test
diff --git a/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
index 466bdf2a3..e1a35f584 100644
--- a/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllFloatsSketchTest.java
@@ -100,7 +100,7 @@ public void manyItemsEstimationMode() {
}
// test getPMF
- final double[] pmf = sketch.getPMF(new float[] {n / 2}); // split at median
+ final double[] pmf = sketch.getPMF(new float[] {n / 2.0F}); // split at median
assertEquals(pmf.length, 2);
assertEquals(pmf[0], 0.5, PMF_EPS_FOR_K_256);
assertEquals(pmf[1], 0.5, PMF_EPS_FOR_K_256);
diff --git a/src/test/java/org/apache/datasketches/kll/MemoryValidateTest.java b/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
similarity index 72%
rename from src/test/java/org/apache/datasketches/kll/MemoryValidateTest.java
rename to src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
index 9ce967ea4..c60e65d9c 100644
--- a/src/test/java/org/apache/datasketches/kll/MemoryValidateTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
@@ -27,7 +27,7 @@
import org.testng.annotations.Test;
@SuppressWarnings("unused")
-public class MemoryValidateTest {
+public class KllMemoryValidateTest {
@Test(expectedExceptions = SketchesArgumentException.class)
public void checkInvalidFamily() {
@@ -67,98 +67,80 @@ public void checkInvalidUpdatableAndSerVer() {
}
@Test(expectedExceptions = SketchesArgumentException.class)
- public void checkInvalidPreIntsAndSingle() {
+ public void checkInvalidSingleAndPreInts() {
KllFloatsSketch sk = new KllFloatsSketch();
+ sk.update(1);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, UPDATABLE_BIT_MASK);
- insertSerVer(wmem, SERIAL_VERSION_SINGLE);
+ insertPreInts(wmem, PREAMBLE_INTS_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
- public void checkInvalidSerVerAndSingle2() {
+ public void checkInvalidSingleAndSerVer() {
KllFloatsSketch sk = new KllFloatsSketch();
+ sk.update(1);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, SINGLE_ITEM_BIT_MASK);
insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
- public void checkInvalidPreIntsAndSingle2() {
- KllFloatsSketch sk = new KllFloatsSketch();
+ public void checkInvalidEmptyDoublesAndPreIntsFull() {
+ KllDoublesSketch sk = new KllDoublesSketch();
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, SINGLE_ITEM_BIT_MASK);
- insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
+ insertPreInts(wmem, PREAMBLE_INTS_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
- public void checkInvalidPreIntsAndDouble() {
- KllFloatsSketch sk = new KllFloatsSketch();
+ public void checkInvalidSingleDoubleCompactAndSerVer() {
+ KllDoublesSketch sk = new KllDoublesSketch();
+ sk.update(1);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, DOUBLES_SKETCH_BIT_MASK);
- insertPreInts(wmem, PREAMBLE_INTS_DOUBLE);
- insertSerVer(wmem, SERIAL_VERSION_SINGLE);
- KllMemoryValidate memVal = new KllMemoryValidate(wmem);
- }
-
- @Test(expectedExceptions = SketchesArgumentException.class)
- public void checkInvalidDoubleCompactAndSingle() {
- KllFloatsSketch sk = new KllFloatsSketch();
- byte[] byteArr = sk.toByteArray();
- WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, SINGLE_ITEM_BIT_MASK | DOUBLES_SKETCH_BIT_MASK);
- insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
- public void checkInvalidDoubleUpdatableAndSerVer() {
- KllFloatsSketch sk = new KllFloatsSketch();
- byte[] byteArr = sk.toByteArray();
+ public void checkInvalidDoubleUpdatableAndPreInts() {
+ KllDoublesSketch sk = new KllDoublesSketch();
+ byte[] byteArr = sk.toUpdatableByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertSerVer(wmem, SERIAL_VERSION_UPDATABLE);
- insertFlags(wmem, DOUBLES_SKETCH_BIT_MASK | UPDATABLE_BIT_MASK);
- insertPreInts(wmem, PREAMBLE_INTS_DOUBLE - 1);
+ insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
public void checkInvalidFloatFullAndPreInts() {
KllFloatsSketch sk = new KllFloatsSketch();
+ sk.update(1); sk.update(2);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, 0); //float full
- insertSerVer(wmem, SERIAL_VERSION_SINGLE); //should be 1
- insertPreInts(wmem, PREAMBLE_INTS_FLOAT);
+ insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
public void checkInvalidFloatUpdatableFullAndPreInts() {
KllFloatsSketch sk = new KllFloatsSketch();
- byte[] byteArr = sk.toByteArray();
+ sk.update(1); sk.update(2);
+ byte[] byteArr = sk.toUpdatableByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, UPDATABLE_BIT_MASK); //float updatable full
- insertSerVer(wmem, SERIAL_VERSION_UPDATABLE);
- insertPreInts(wmem, 0);//should be 5
+ insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@Test(expectedExceptions = SketchesArgumentException.class)
public void checkInvalidDoubleCompactSingleAndPreInts() {
- KllFloatsSketch sk = new KllFloatsSketch();
+ KllDoublesSketch sk = new KllDoublesSketch();
+ sk.update(1);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, DOUBLES_SKETCH_BIT_MASK | SINGLE_ITEM_BIT_MASK);
- insertPreInts(wmem, 5);//should be 2
- insertSerVer(wmem, SERIAL_VERSION_SINGLE); //should be 2
+ insertPreInts(wmem, PREAMBLE_INTS_FULL);//should be 2, single
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
From 2a65b3169036960134dbd60edcbef096a5acb0ef Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Mon, 4 Apr 2022 18:16:47 -0700
Subject: [PATCH 28/31] This push fixes David's method naming issue.
---
.../kll/KllDirectDoublesSketch.java | 36 ++++----
.../kll/KllDirectFloatsSketch.java | 36 ++++----
.../datasketches/kll/KllDirectSketch.java | 48 +++++------
.../datasketches/kll/KllMemoryValidate.java | 62 ++++++-------
.../datasketches/kll/KllPreambleUtil.java | 86 +++++++++----------
.../apache/datasketches/kll/KllSketch.java | 58 ++++++-------
.../kll/KllMemoryValidateTest.java | 26 +++---
7 files changed, 176 insertions(+), 176 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 82ac35344..834760696 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -26,15 +26,15 @@
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.UPDATABLE_BIT_MASK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertFamilyID;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertFlags;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertM;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertN;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryFamilyID;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryFlags;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryM;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryN;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryNumLevels;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
@@ -100,15 +100,15 @@ public static KllDirectDoublesSketch newInstance(final int k, final WritableMemo
*/
static KllDirectDoublesSketch newInstance(final int k, final int m, final WritableMemory dstMem,
final MemoryRequestServer memReqSvr) {
- insertPreInts(dstMem, PREAMBLE_INTS_FULL);
- insertSerVer(dstMem, SERIAL_VERSION_UPDATABLE);
- insertFamilyID(dstMem, Family.KLL.getID());
- insertFlags(dstMem, DOUBLES_SKETCH_BIT_MASK | UPDATABLE_BIT_MASK);
- insertK(dstMem, k);
- insertM(dstMem, m);
- insertN(dstMem, 0);
- insertMinK(dstMem, k);
- insertNumLevels(dstMem, 1);
+ setMemoryPreInts(dstMem, PREAMBLE_INTS_FULL);
+ setMemorySerVer(dstMem, SERIAL_VERSION_UPDATABLE);
+ setMemoryFamilyID(dstMem, Family.KLL.getID());
+ setMemoryFlags(dstMem, DOUBLES_SKETCH_BIT_MASK | UPDATABLE_BIT_MASK);
+ setMemoryK(dstMem, k);
+ setMemoryM(dstMem, m);
+ setMemoryN(dstMem, 0);
+ setMemoryMinK(dstMem, k);
+ setMemoryNumLevels(dstMem, 1);
int offset = DATA_START_ADR;
dstMem.putIntArray(offset, new int[] {k, k}, 0, 2);
offset += 2 * Integer.BYTES;
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index bd3091452..6e7d89192 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -25,15 +25,15 @@
import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
import static org.apache.datasketches.kll.KllPreambleUtil.UPDATABLE_BIT_MASK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertFamilyID;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertFlags;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertM;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertN;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryFamilyID;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryFlags;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryM;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryN;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryNumLevels;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
@@ -100,15 +100,15 @@ public static KllDirectFloatsSketch newInstance(final int k, final WritableMemor
*/
static KllDirectFloatsSketch newInstance(final int k, final int m, final WritableMemory dstMem,
final MemoryRequestServer memReqSvr) {
- insertPreInts(dstMem, PREAMBLE_INTS_FULL);
- insertSerVer(dstMem, SERIAL_VERSION_UPDATABLE);
- insertFamilyID(dstMem, Family.KLL.getID());
- insertFlags(dstMem, UPDATABLE_BIT_MASK);
- insertK(dstMem, k);
- insertM(dstMem, m);
- insertN(dstMem, 0);
- insertMinK(dstMem, k);
- insertNumLevels(dstMem, 1);
+ setMemoryPreInts(dstMem, PREAMBLE_INTS_FULL);
+ setMemorySerVer(dstMem, SERIAL_VERSION_UPDATABLE);
+ setMemoryFamilyID(dstMem, Family.KLL.getID());
+ setMemoryFlags(dstMem, UPDATABLE_BIT_MASK);
+ setMemoryK(dstMem, k);
+ setMemoryM(dstMem, m);
+ setMemoryN(dstMem, 0);
+ setMemoryMinK(dstMem, k);
+ setMemoryNumLevels(dstMem, 1);
int offset = DATA_START_ADR;
dstMem.putIntArray(offset, new int[] {k, k}, 0, 2);
offset += 2 * Integer.BYTES;
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index 5a4b6e8e7..ac0a14458 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -19,16 +19,16 @@
package org.apache.datasketches.kll;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractMinK;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractK;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractLevelZeroSortedFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractM;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractN;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractNumLevels;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertLevelZeroSortedFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertN;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryK;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryLevelZeroSortedFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryM;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryN;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryNumLevels;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryLevelZeroSortedFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryN;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryNumLevels;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
@@ -62,17 +62,17 @@ abstract class KllDirectSketch extends KllSketch {
@Override
public int getK() {
- return extractK(wmem);
+ return getMemoryK(wmem);
}
@Override
int getM() {
- return extractM(wmem);
+ return getMemoryM(wmem);
}
@Override
public long getN() {
- return extractN(wmem);
+ return getMemoryN(wmem);
}
@Override
@@ -106,7 +106,7 @@ public byte[] toUpdatableByteArray() {
@Override
int getMinK() {
- return extractMinK(wmem);
+ return getMemoryMinK(wmem);
}
int getItemsArrLengthItems() {
@@ -128,32 +128,32 @@ int getLevelsArrayAt(final int index) {
@Override
int getNumLevels() {
- return extractNumLevels(wmem);
+ return getMemoryNumLevels(wmem);
}
@Override
void incN() {
if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- long n = extractN(wmem);
- insertN(wmem, ++n);
+ long n = getMemoryN(wmem);
+ setMemoryN(wmem, ++n);
}
@Override
void incNumLevels() {
if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- int numLevels = extractNumLevels(wmem);
- insertNumLevels(wmem, ++numLevels);
+ int numLevels = getMemoryNumLevels(wmem);
+ setMemoryNumLevels(wmem, ++numLevels);
}
@Override
boolean isLevelZeroSorted() {
- return extractLevelZeroSortedFlag(wmem);
+ return getMemoryLevelZeroSortedFlag(wmem);
}
@Override
void setMinK(final int minK) {
if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- insertMinK(wmem, minK);
+ setMemoryMinK(wmem, minK);
}
@Override
@@ -194,7 +194,7 @@ void setLevelsArrayUpdatable(final WritableMemory levelsMem) {
@Override
void setLevelZeroSorted(final boolean sorted) {
if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- insertLevelZeroSortedFlag(wmem, sorted);
+ setMemoryLevelZeroSortedFlag(wmem, sorted);
}
@Override
@@ -205,13 +205,13 @@ void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) {
@Override
void setN(final long n) {
if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- insertN(wmem, n);
+ setMemoryN(wmem, n);
}
@Override
void setNumLevels(final int numLevels) {
if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- insertNumLevels(wmem, numLevels);
+ setMemoryNumLevels(wmem, numLevels);
}
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
index 214bbc675..187866dfe 100644
--- a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
+++ b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
@@ -36,20 +36,20 @@
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_EMPTY_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_SINGLE;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractDoubleSketchFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractMinK;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractEmptyFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractFamilyID;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractFlags;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractK;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractLevelZeroSortedFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractM;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractN;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractNumLevels;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractPreInts;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractSerVer;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractSingleItemFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.extractUpdatableFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryDoubleSketchFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryEmptyFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryFamilyID;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryFlags;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryK;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryLevelZeroSortedFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryM;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryN;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryNumLevels;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryPreInts;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemorySerVer;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemorySingleItemFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.getMemoryUpdatableFlag;
import org.apache.datasketches.Family;
import org.apache.datasketches.SketchesArgumentException;
@@ -101,20 +101,20 @@ final class KllMemoryValidate {
KllMemoryValidate(final Memory srcMem) {
memCapacity = (int) srcMem.getCapacity();
- preInts = extractPreInts(srcMem);
- serVer = extractSerVer(srcMem);
+ preInts = getMemoryPreInts(srcMem);
+ serVer = getMemorySerVer(srcMem);
- familyID = extractFamilyID(srcMem);
+ familyID = getMemoryFamilyID(srcMem);
if (familyID != Family.KLL.getID()) { memoryValidateThrow(SRC_NOT_KLL, familyID); }
famName = idToFamily(familyID).toString();
- flags = extractFlags(srcMem);
- empty = extractEmptyFlag(srcMem);
- level0Sorted = extractLevelZeroSortedFlag(srcMem);
- singleItem = extractSingleItemFlag(srcMem);
- doublesSketch = extractDoubleSketchFlag(srcMem);
- updatable = extractUpdatableFlag(srcMem);
- k = extractK(srcMem);
- m = extractM(srcMem);
+ flags = getMemoryFlags(srcMem);
+ empty = getMemoryEmptyFlag(srcMem);
+ level0Sorted = getMemoryLevelZeroSortedFlag(srcMem);
+ singleItem = getMemorySingleItemFlag(srcMem);
+ doublesSketch = getMemoryDoubleSketchFlag(srcMem);
+ updatable = getMemoryUpdatableFlag(srcMem);
+ k = getMemoryK(srcMem);
+ m = getMemoryM(srcMem);
KllHelper.checkM(m);
KllHelper.checkK(k, m);
if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(UPDATABLEBIT_AND_SER_VER, 1); }
@@ -132,9 +132,9 @@ void compactMemoryValidate(final Memory srcMem) {
if (preInts != PREAMBLE_INTS_FULL) { memoryValidateThrow(INVALID_PREINTS, preInts); }
if (serVer != SERIAL_VERSION_EMPTY_FULL) { memoryValidateThrow(EMPTYBIT_AND_SER_VER, serVer); }
layout = doublesSketch ? Layout.DOUBLE_FULL_COMPACT : Layout.FLOAT_FULL_COMPACT;
- n = extractN(srcMem);
- minK = extractMinK(srcMem);
- numLevels = extractNumLevels(srcMem);
+ n = getMemoryN(srcMem);
+ minK = getMemoryMinK(srcMem);
+ numLevels = getMemoryNumLevels(srcMem);
int offset = DATA_START_ADR;
// LEVELS MEM
@@ -222,11 +222,11 @@ void updatableMemoryValidate(final WritableMemory wSrcMem) {
if (preInts != PREAMBLE_INTS_FULL) { memoryValidateThrow(INVALID_PREINTS, preInts); }
layout = doublesSketch ? Layout.DOUBLE_UPDATABLE : Layout.FLOAT_UPDATABLE;
- n = extractN(wSrcMem);
+ n = getMemoryN(wSrcMem);
empty = n == 0; //empty & singleItem are set for convenience
singleItem = n == 1; // there is no error checking on these bits
- minK = extractMinK(wSrcMem);
- numLevels = extractNumLevels(wSrcMem);
+ minK = getMemoryMinK(wSrcMem);
+ numLevels = getMemoryNumLevels(wSrcMem);
int offset = DATA_START_ADR;
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index bd64b5ca7..381af3134 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -240,120 +240,120 @@ static String memoryToString(final Memory mem) {
return sb.toString();
}
- static int extractPreInts(final Memory mem) {
+ static int getMemoryPreInts(final Memory mem) {
return mem.getByte(PREAMBLE_INTS_BYTE_ADR) & 0XFF;
}
- static int extractSerVer(final Memory mem) {
+ static int getMemorySerVer(final Memory mem) {
return mem.getByte(SER_VER_BYTE_ADR) & 0XFF;
}
- static int extractFamilyID(final Memory mem) {
+ static int getMemoryFamilyID(final Memory mem) {
return mem.getByte(FAMILY_BYTE_ADR) & 0XFF;
}
- static int extractFlags(final Memory mem) {
+ static int getMemoryFlags(final Memory mem) {
return mem.getByte(FLAGS_BYTE_ADR) & 0XFF;
}
- static boolean extractEmptyFlag(final Memory mem) {
- return (extractFlags(mem) & EMPTY_BIT_MASK) != 0;
+ static boolean getMemoryEmptyFlag(final Memory mem) {
+ return (getMemoryFlags(mem) & EMPTY_BIT_MASK) != 0;
}
- static boolean extractLevelZeroSortedFlag(final Memory mem) {
- return (extractFlags(mem) & LEVEL_ZERO_SORTED_BIT_MASK) != 0;
+ static boolean getMemoryLevelZeroSortedFlag(final Memory mem) {
+ return (getMemoryFlags(mem) & LEVEL_ZERO_SORTED_BIT_MASK) != 0;
}
- static boolean extractSingleItemFlag(final Memory mem) {
- return (extractFlags(mem) & SINGLE_ITEM_BIT_MASK) != 0;
+ static boolean getMemorySingleItemFlag(final Memory mem) {
+ return (getMemoryFlags(mem) & SINGLE_ITEM_BIT_MASK) != 0;
}
- static boolean extractDoubleSketchFlag(final Memory mem) {
- return (extractFlags(mem) & DOUBLES_SKETCH_BIT_MASK) != 0;
+ static boolean getMemoryDoubleSketchFlag(final Memory mem) {
+ return (getMemoryFlags(mem) & DOUBLES_SKETCH_BIT_MASK) != 0;
}
- static boolean extractUpdatableFlag(final Memory mem) {
- return (extractFlags(mem) & UPDATABLE_BIT_MASK) != 0;
+ static boolean getMemoryUpdatableFlag(final Memory mem) {
+ return (getMemoryFlags(mem) & UPDATABLE_BIT_MASK) != 0;
}
- static int extractK(final Memory mem) {
+ static int getMemoryK(final Memory mem) {
return mem.getShort(K_SHORT_ADR) & 0XFFFF;
}
- static int extractM(final Memory mem) {
+ static int getMemoryM(final Memory mem) {
return mem.getByte(M_BYTE_ADR) & 0XFF;
}
- static long extractN(final Memory mem) {
+ static long getMemoryN(final Memory mem) {
return mem.getLong(N_LONG_ADR);
}
- static int extractMinK(final Memory mem) {
+ static int getMemoryMinK(final Memory mem) {
return mem.getShort(MIN_K_SHORT_ADR) & 0XFFFF;
}
- static int extractNumLevels(final Memory mem) {
+ static int getMemoryNumLevels(final Memory mem) {
return mem.getByte(NUM_LEVELS_BYTE_ADR) & 0XFF;
}
- static void insertPreInts(final WritableMemory wmem, final int value) {
+ static void setMemoryPreInts(final WritableMemory wmem, final int value) {
wmem.putByte(PREAMBLE_INTS_BYTE_ADR, (byte) value);
}
- static void insertSerVer(final WritableMemory wmem, final int value) {
+ static void setMemorySerVer(final WritableMemory wmem, final int value) {
wmem.putByte(SER_VER_BYTE_ADR, (byte) value);
}
- static void insertFamilyID(final WritableMemory wmem, final int value) {
+ static void setMemoryFamilyID(final WritableMemory wmem, final int value) {
wmem.putByte(FAMILY_BYTE_ADR, (byte) value);
}
- static void insertFlags(final WritableMemory wmem, final int value) {
+ static void setMemoryFlags(final WritableMemory wmem, final int value) {
wmem.putByte(FLAGS_BYTE_ADR, (byte) value);
}
- static void insertEmptyFlag(final WritableMemory wmem, final boolean empty) {
- final int flags = extractFlags(wmem);
- insertFlags(wmem, empty ? flags | EMPTY_BIT_MASK : flags & ~EMPTY_BIT_MASK);
+ static void setMemoryEmptyFlag(final WritableMemory wmem, final boolean empty) {
+ final int flags = getMemoryFlags(wmem);
+ setMemoryFlags(wmem, empty ? flags | EMPTY_BIT_MASK : flags & ~EMPTY_BIT_MASK);
}
- static void insertLevelZeroSortedFlag(final WritableMemory wmem, final boolean levelZeroSorted) {
- final int flags = extractFlags(wmem);
- insertFlags(wmem, levelZeroSorted ? flags | LEVEL_ZERO_SORTED_BIT_MASK : flags & ~LEVEL_ZERO_SORTED_BIT_MASK);
+ static void setMemoryLevelZeroSortedFlag(final WritableMemory wmem, final boolean levelZeroSorted) {
+ final int flags = getMemoryFlags(wmem);
+ setMemoryFlags(wmem, levelZeroSorted ? flags | LEVEL_ZERO_SORTED_BIT_MASK : flags & ~LEVEL_ZERO_SORTED_BIT_MASK);
}
- static void insertSingleItemFlag(final WritableMemory wmem, final boolean singleItem) {
- final int flags = extractFlags(wmem);
- insertFlags(wmem, singleItem ? flags | SINGLE_ITEM_BIT_MASK : flags & ~SINGLE_ITEM_BIT_MASK);
+ static void setMemorySingleItemFlag(final WritableMemory wmem, final boolean singleItem) {
+ final int flags = getMemoryFlags(wmem);
+ setMemoryFlags(wmem, singleItem ? flags | SINGLE_ITEM_BIT_MASK : flags & ~SINGLE_ITEM_BIT_MASK);
}
- static void insertDoubleSketchFlag(final WritableMemory wmem, final boolean doubleSketch) {
- final int flags = extractFlags(wmem);
- insertFlags(wmem, doubleSketch ? flags | DOUBLES_SKETCH_BIT_MASK : flags & ~DOUBLES_SKETCH_BIT_MASK);
+ static void setMemoryDoubleSketchFlag(final WritableMemory wmem, final boolean doubleSketch) {
+ final int flags = getMemoryFlags(wmem);
+ setMemoryFlags(wmem, doubleSketch ? flags | DOUBLES_SKETCH_BIT_MASK : flags & ~DOUBLES_SKETCH_BIT_MASK);
}
- static void insertUpdatableFlag(final WritableMemory wmem, final boolean updatable) {
- final int flags = extractFlags(wmem);
- insertFlags(wmem, updatable ? flags | UPDATABLE_BIT_MASK : flags & ~UPDATABLE_BIT_MASK);
+ static void setMemoryUpdatableFlag(final WritableMemory wmem, final boolean updatable) {
+ final int flags = getMemoryFlags(wmem);
+ setMemoryFlags(wmem, updatable ? flags | UPDATABLE_BIT_MASK : flags & ~UPDATABLE_BIT_MASK);
}
- static void insertK(final WritableMemory wmem, final int value) {
+ static void setMemoryK(final WritableMemory wmem, final int value) {
wmem.putShort(K_SHORT_ADR, (short) value);
}
- static void insertM(final WritableMemory wmem, final int value) {
+ static void setMemoryM(final WritableMemory wmem, final int value) {
wmem.putByte(M_BYTE_ADR, (byte) value);
}
- static void insertN(final WritableMemory wmem, final long value) {
+ static void setMemoryN(final WritableMemory wmem, final long value) {
wmem.putLong(N_LONG_ADR, value);
}
- static void insertMinK(final WritableMemory wmem, final int value) {
+ static void setMemoryMinK(final WritableMemory wmem, final int value) {
wmem.putShort(MIN_K_SHORT_ADR, (short) value);
}
- static void insertNumLevels(final WritableMemory wmem, final int value) {
+ static void setMemoryNumLevels(final WritableMemory wmem, final int value) {
wmem.putByte(NUM_LEVELS_BYTE_ADR, (byte) value);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index b98c902e4..680da9380 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -35,19 +35,19 @@
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_EMPTY_FULL;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_SINGLE;
import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertDoubleSketchFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertMinK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertEmptyFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertFamilyID;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertK;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertLevelZeroSortedFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertM;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertN;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertNumLevels;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertPreInts;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertSerVer;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertSingleItemFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.insertUpdatableFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryDoubleSketchFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryEmptyFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryFamilyID;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryLevelZeroSortedFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryM;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryN;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryNumLevels;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySingleItemFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryUpdatableFlag;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
import static org.apache.datasketches.kll.KllSketch.SketchType.FLOATS_SKETCH;
@@ -1011,9 +1011,9 @@ final byte[] toCompactByteArrayImpl() {
}
} else { // n > 1
//remainder of preamble after first 8 bytes
- insertN(wmem, getN());
- insertMinK(wmem, getMinK());
- insertNumLevels(wmem, getNumLevels());
+ setMemoryN(wmem, getN());
+ setMemoryMinK(wmem, getMinK());
+ setMemoryNumLevels(wmem, getNumLevels());
offset = DATA_START_ADR;
//LOAD LEVELS ARR the last integer in levels_ is NOT serialized
@@ -1049,18 +1049,18 @@ private static void loadFirst8Bytes(final KllSketch sk, final WritableMemory wme
? PREAMBLE_INTS_FULL
: (empty || singleItem) ? PREAMBLE_INTS_EMPTY_SINGLE : PREAMBLE_INTS_FULL;
//load the preamble
- insertPreInts(wmem, preInts);
+ setMemoryPreInts(wmem, preInts);
final int server = updatable ? SERIAL_VERSION_UPDATABLE
: (singleItem ? SERIAL_VERSION_SINGLE : SERIAL_VERSION_EMPTY_FULL);
- insertSerVer(wmem, server);
- insertFamilyID(wmem, Family.KLL.getID());
- insertEmptyFlag(wmem, empty);
- insertLevelZeroSortedFlag(wmem, lvlZeroSorted);
- insertSingleItemFlag(wmem, singleItem);
- insertDoubleSketchFlag(wmem, doubleType);
- insertUpdatableFlag(wmem, updatable);
- insertK(wmem, sk.getK());
- insertM(wmem, sk.getM());
+ setMemorySerVer(wmem, server);
+ setMemoryFamilyID(wmem, Family.KLL.getID());
+ setMemoryEmptyFlag(wmem, empty);
+ setMemoryLevelZeroSortedFlag(wmem, lvlZeroSorted);
+ setMemorySingleItemFlag(wmem, singleItem);
+ setMemoryDoubleSketchFlag(wmem, doubleType);
+ setMemoryUpdatableFlag(wmem, updatable);
+ setMemoryK(wmem, sk.getK());
+ setMemoryM(wmem, sk.getM());
}
@SuppressWarnings("null")
@@ -1194,9 +1194,9 @@ final byte[] toUpdatableByteArrayImpl() {
final WritableMemory wmem = WritableMemory.writableWrap(byteArr);
loadFirst8Bytes(this, wmem, true);
//remainder of preamble after first 8 bytes
- insertN(wmem, getN());
- insertMinK(wmem, getMinK());
- insertNumLevels(wmem, getNumLevels());
+ setMemoryN(wmem, getN());
+ setMemoryMinK(wmem, getMinK());
+ setMemoryNumLevels(wmem, getNumLevels());
//load data
final boolean doubleType = (sketchType == DOUBLES_SKETCH);
diff --git a/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java b/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
index c60e65d9c..324954156 100644
--- a/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllMemoryValidateTest.java
@@ -34,7 +34,7 @@ public void checkInvalidFamily() {
KllFloatsSketch sk = new KllFloatsSketch();
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFamilyID(wmem, Family.KLL.getID() - 1);
+ setMemoryFamilyID(wmem, Family.KLL.getID() - 1);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -43,7 +43,7 @@ public void checkInvalidSerVer() {
KllFloatsSketch sk = new KllFloatsSketch();
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL - 1);
+ setMemorySerVer(wmem, SERIAL_VERSION_EMPTY_FULL - 1);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -52,7 +52,7 @@ public void checkInvalidEmptyAndSingle() {
KllFloatsSketch sk = new KllFloatsSketch();
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, EMPTY_BIT_MASK | SINGLE_ITEM_BIT_MASK);
+ setMemoryFlags(wmem, EMPTY_BIT_MASK | SINGLE_ITEM_BIT_MASK);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -61,8 +61,8 @@ public void checkInvalidUpdatableAndSerVer() {
KllFloatsSketch sk = new KllFloatsSketch();
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertFlags(wmem, UPDATABLE_BIT_MASK);
- insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
+ setMemoryFlags(wmem, UPDATABLE_BIT_MASK);
+ setMemorySerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -72,7 +72,7 @@ public void checkInvalidSingleAndPreInts() {
sk.update(1);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertPreInts(wmem, PREAMBLE_INTS_FULL);
+ setMemoryPreInts(wmem, PREAMBLE_INTS_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -82,7 +82,7 @@ public void checkInvalidSingleAndSerVer() {
sk.update(1);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
+ setMemorySerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -91,7 +91,7 @@ public void checkInvalidEmptyDoublesAndPreIntsFull() {
KllDoublesSketch sk = new KllDoublesSketch();
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertPreInts(wmem, PREAMBLE_INTS_FULL);
+ setMemoryPreInts(wmem, PREAMBLE_INTS_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -101,7 +101,7 @@ public void checkInvalidSingleDoubleCompactAndSerVer() {
sk.update(1);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertSerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
+ setMemorySerVer(wmem, SERIAL_VERSION_EMPTY_FULL);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -110,7 +110,7 @@ public void checkInvalidDoubleUpdatableAndPreInts() {
KllDoublesSketch sk = new KllDoublesSketch();
byte[] byteArr = sk.toUpdatableByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
+ setMemoryPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -120,7 +120,7 @@ public void checkInvalidFloatFullAndPreInts() {
sk.update(1); sk.update(2);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
+ setMemoryPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -130,7 +130,7 @@ public void checkInvalidFloatUpdatableFullAndPreInts() {
sk.update(1); sk.update(2);
byte[] byteArr = sk.toUpdatableByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
+ setMemoryPreInts(wmem, PREAMBLE_INTS_EMPTY_SINGLE);
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
@@ -140,7 +140,7 @@ public void checkInvalidDoubleCompactSingleAndPreInts() {
sk.update(1);
byte[] byteArr = sk.toByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- insertPreInts(wmem, PREAMBLE_INTS_FULL);//should be 2, single
+ setMemoryPreInts(wmem, PREAMBLE_INTS_FULL);//should be 2, single
KllMemoryValidate memVal = new KllMemoryValidate(wmem);
}
From e93e8cdcf245b638c4a28aafb98effd5cbd8ded8 Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Mon, 4 Apr 2022 20:34:33 -0700
Subject: [PATCH 29/31] Interim 12
---
.../kll/KllDirectDoublesSketch.java | 16 +++-----
.../kll/KllDirectFloatsSketch.java | 16 +++-----
.../datasketches/kll/KllDirectSketch.java | 7 ++++
.../datasketches/kll/KllDoublesSketch.java | 4 +-
.../datasketches/kll/KllFloatsSketch.java | 4 +-
.../datasketches/kll/KllPreambleUtil.java | 4 +-
.../apache/datasketches/kll/KllSketch.java | 38 ++++++++++---------
7 files changed, 45 insertions(+), 44 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 834760696..9560c8799 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -36,8 +36,8 @@
import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DOUBLE;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
@@ -150,9 +150,7 @@ public double[] getCDF(final double[] splitPoints) {
*
* @return the max value of the stream
*/
- public double getMaxValue() {
- return getMaxDoubleValue();
- }
+ public double getMaxValue() { return getMaxDoubleValue(); }
/**
* Returns the min value of the stream.
@@ -160,9 +158,7 @@ public double getMaxValue() {
*
* @return the min value of the stream
*/
- public double getMinValue() {
- return getMinDoubleValue();
- }
+ public double getMinValue() { return getMinDoubleValue(); }
/**
* Returns an approximation to the Probability Mass Function (PMF) of the input stream
@@ -303,8 +299,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(SRC_IS_NOT_DIRECT); }
- if (!other.isDoublesSketch()) { kllSketchThrow(SRC_IS_NOT_DOUBLE); }
+ if (!other.isDirect()) { kllSketchThrow(SRC_MUST_BE_DIRECT); }
+ if (!other.isDoublesSketch()) { kllSketchThrow(SRC_MUST_BE_DOUBLE); }
mergeDoubleImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index 6e7d89192..3ebb9c7e6 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -35,8 +35,8 @@
import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DIRECT;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DIRECT;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_FLOAT;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
@@ -150,9 +150,7 @@ public double[] getCDF(final float[] splitPoints) {
*
* @return the max value of the stream
*/
- public float getMaxValue() {
- return getMaxFloatValue();
- }
+ public float getMaxValue() { return getMaxFloatValue(); }
/**
* Returns the min value of the stream.
@@ -160,9 +158,7 @@ public float getMaxValue() {
*
* @return the min value of the stream
*/
- public float getMinValue() {
- return getMinFloatValue();
- }
+ public float getMinValue() { return getMinFloatValue(); }
/**
* Returns an approximation to the Probability Mass Function (PMF) of the input stream
@@ -303,8 +299,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(SRC_IS_NOT_DIRECT); }
- if (!other.isFloatsSketch()) { kllSketchThrow(SRC_IS_NOT_FLOAT); }
+ if (!other.isDirect()) { kllSketchThrow(SRC_MUST_BE_DIRECT); }
+ if (!other.isFloatsSketch()) { kllSketchThrow(SRC_MUST_BE_FLOAT); }
mergeFloatImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index ac0a14458..556b8dbf9 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -77,6 +77,7 @@ public long getN() {
@Override
public void reset() {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
final int k = getK();
setN(0);
setMinK(k);
@@ -158,6 +159,7 @@ void setMinK(final int minK) {
@Override
void setItemsArrayUpdatable(final WritableMemory itemsMem) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable = itemsMem;
}
@@ -169,11 +171,13 @@ void setLevelsArray(final int[] levelsArr) {
@Override
void setLevelsArrayAt(final int index, final int value) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
levelsArrUpdatable.putInt((long)index * Integer.BYTES, value);
}
@Override
void setLevelsArrayAtMinusEq(final int index, final int minusEq) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
final int offset = index * Integer.BYTES;
final int curV = levelsArrUpdatable.getInt(offset);
levelsArrUpdatable.putInt(offset, curV - minusEq);
@@ -181,6 +185,7 @@ void setLevelsArrayAtMinusEq(final int index, final int minusEq) {
@Override
void setLevelsArrayAtPlusEq(final int index, final int plusEq) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
final int offset = index * Integer.BYTES;
final int curV = levelsArrUpdatable.getInt(offset);
levelsArrUpdatable.putInt(offset, curV + plusEq);
@@ -188,6 +193,7 @@ void setLevelsArrayAtPlusEq(final int index, final int plusEq) {
@Override
void setLevelsArrayUpdatable(final WritableMemory levelsMem) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
levelsArrUpdatable = levelsMem;
}
@@ -199,6 +205,7 @@ void setLevelZeroSorted(final boolean sorted) {
@Override
void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) {
+ if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable = minMaxMem;
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index dc7ad92b5..63a333afa 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -21,7 +21,7 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_DOUBLE;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DOUBLE;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
@@ -284,7 +284,7 @@ public KllDoublesSketchIterator iterator() {
*/
public void merge(final KllSketch other) {
if (other.isDirect()) { kllSketchThrow(SRC_CANNOT_BE_DIRECT); }
- if (!other.isDoublesSketch()) { kllSketchThrow(SRC_IS_NOT_DOUBLE); }
+ if (!other.isDoublesSketch()) { kllSketchThrow(SRC_MUST_BE_DOUBLE); }
mergeDoubleImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index 0fbabb909..b6c1956c7 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -21,7 +21,7 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_IS_NOT_FLOAT;
+import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_FLOAT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
@@ -284,7 +284,7 @@ public KllFloatsSketchIterator iterator() {
*/
public void merge(final KllFloatsSketch other) {
if (other.isDirect()) { kllSketchThrow(SRC_CANNOT_BE_DIRECT); }
- if (!other.isFloatsSketch()) { kllSketchThrow(SRC_IS_NOT_FLOAT); }
+ if (!other.isFloatsSketch()) { kllSketchThrow(SRC_MUST_BE_FLOAT); }
mergeFloatImpl(other);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index 381af3134..548bd045e 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -217,7 +217,7 @@ static String memoryToString(final Memory mem) {
case DOUBLE_UPDATABLE:
{
sb.append("Bytes 8-15: N : ").append(memChk.n).append(LS);
- sb.append("Bytes 16-17: DyMinK : ").append(memChk.minK).append(LS);
+ sb.append("Bytes 16-17: MinK : ").append(memChk.minK).append(LS);
sb.append("Byte 18 : NumLevels : ").append(memChk.numLevels).append(LS);
break;
}
@@ -227,7 +227,7 @@ static String memoryToString(final Memory mem) {
case DOUBLE_SINGLE_COMPACT:
{
sb.append("Assumed : N : ").append(memChk.n).append(LS);
- sb.append("Assumed : DyMinK : ").append(memChk.minK).append(LS);
+ sb.append("Assumed : MinK : ").append(memChk.minK).append(LS);
sb.append("Assumed : NumLevels : ").append(memChk.numLevels).append(LS);
break;
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index 680da9380..b366e38b1 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -252,10 +252,10 @@ static int getCurrentSerializedSizeBytes(final int numLevels, final int numItems
enum Error {
TGT_IS_IMMUTABLE("Given sketch Memory is immutable, cannot write."),
- SRC_IS_NOT_DIRECT("Given sketch must be of type Direct."),
- SRC_IS_NOT_DOUBLE("Given sketch must be of type Double."),
- SRC_IS_NOT_FLOAT("Given sketch must be of type Float."),
- SRC_CANNOT_BE_DIRECT("Given sketch must not be of type Direct."),
+ SRC_MUST_BE_DIRECT("Given sketch must be of type Direct."),
+ SRC_MUST_BE_DOUBLE("Given sketch must be of type Double."),
+ SRC_MUST_BE_FLOAT("Given sketch must be of type Float."),
+ SRC_CANNOT_BE_DIRECT("Given sketch cannot be of type Direct."),
MUST_NOT_CALL("This is an artifact of inheritance and should never be called.");
private String msg;
@@ -740,6 +740,7 @@ final void mergeDoubleImpl(final KllSketch other) {
final long finalN = getN() + other.getN();
//update this sketch with level0 items from the other sketch
final double[] otherDoubleItemsArr = other.getDoubleItemsArray();
+ final int otherNumLevels = other.getNumLevels();
final int[] otherLevelsArr = other.getLevelsArray();
for (int i = otherLevelsArr[0]; i < otherLevelsArr[1]; i++) {
updateDouble(otherDoubleItemsArr[i]);
@@ -747,7 +748,7 @@ final void mergeDoubleImpl(final KllSketch other) {
// after the level 0 update, we capture the key mutable variables
final double myMin = getMinDoubleValue();
final double myMax = getMaxDoubleValue();
- final int myDyMinK = getMinK();
+ final int myMinK = getMinK();
final int myCurNumLevels = getNumLevels();
final int[] myCurLevelsArr = getLevelsArray();
@@ -757,21 +758,21 @@ final void mergeDoubleImpl(final KllSketch other) {
final int[] myNewLevelsArr;
final double[] myNewDoubleItemsArr;
- if (other.getNumLevels() > 1) { //now merge other levels if they exist
+ if (otherNumLevels > 1) { //now merge other levels if they exist
final int tmpSpaceNeeded = getNumRetained()
- + KllHelper.getNumRetainedAboveLevelZero(other.getNumLevels(), otherLevelsArr);
+ + KllHelper.getNumRetainedAboveLevelZero(otherNumLevels, otherLevelsArr);
final double[] workbuf = new double[tmpSpaceNeeded];
final int ub = KllHelper.ubOnNumLevels(finalN);
final int[] worklevels = new int[ub + 2]; // ub+1 does not work
final int[] outlevels = new int[ub + 2];
- final int provisionalNumLevels = max(myCurNumLevels, other.getNumLevels());
+ final int provisionalNumLevels = max(myCurNumLevels, otherNumLevels);
populateDoubleWorkArrays(other, workbuf, worklevels, provisionalNumLevels);
// notice that workbuf is being used as both the input and output
- final int[] result = KllDoublesHelper.generalDoublesCompress(getK(), getM(), provisionalNumLevels, workbuf,
- worklevels, workbuf, outlevels, isLevelZeroSorted(), random);
+ final int[] result = KllDoublesHelper.generalDoublesCompress(getK(), getM(), provisionalNumLevels,
+ workbuf, worklevels, workbuf, outlevels, isLevelZeroSorted(), random);
final int targetItemCount = result[1]; //was finalCapacity. Max size given k, m, numLevels
final int curItemCount = result[2]; //was finalPop
@@ -815,7 +816,7 @@ final void mergeDoubleImpl(final KllSketch other) {
//Update Preamble:
setN(finalN);
if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
- setMinK(min(myDyMinK, other.getMinK()));
+ setMinK(min(myMinK, other.getMinK()));
}
//Update min, max values
@@ -850,6 +851,7 @@ final void mergeFloatImpl(final KllSketch other) {
final long finalN = getN() + other.getN();
//update this sketch with level0 items from the other sketch
final float[] otherFloatItemsArr = other.getFloatItemsArray();
+ final int otherNumLevels = other.getNumLevels();
final int[] otherLevelsArr = other.getLevelsArray();
for (int i = otherLevelsArr[0]; i < otherLevelsArr[1]; i++) {
updateFloat(otherFloatItemsArr[i]);
@@ -857,7 +859,7 @@ final void mergeFloatImpl(final KllSketch other) {
// after the level 0 update, we capture the key mutable variables
final float myMin = getMinFloatValue();
final float myMax = getMaxFloatValue();
- final int myDyMinK = getMinK();
+ final int myMinK = getMinK();
final int myCurNumLevels = getNumLevels();
final int[] myCurLevelsArr = getLevelsArray();
@@ -867,21 +869,21 @@ final void mergeFloatImpl(final KllSketch other) {
final int[] myNewLevelsArr;
final float[] myNewFloatItemsArr;
- if (other.getNumLevels() > 1) { //now merge other levels if they exist
+ if (otherNumLevels > 1) { //now merge higher levels if they exist
final int tmpSpaceNeeded = getNumRetained()
- + KllHelper.getNumRetainedAboveLevelZero(other.getNumLevels(), otherLevelsArr);
+ + KllHelper.getNumRetainedAboveLevelZero(otherNumLevels, otherLevelsArr);
final float[] workbuf = new float[tmpSpaceNeeded];
final int ub = KllHelper.ubOnNumLevels(finalN);
final int[] worklevels = new int[ub + 2]; // ub+1 does not work
final int[] outlevels = new int[ub + 2];
- final int provisionalNumLevels = max(myCurNumLevels, other.getNumLevels());
+ final int provisionalNumLevels = max(myCurNumLevels, otherNumLevels);
populateFloatWorkArrays(other, workbuf, worklevels, provisionalNumLevels);
// notice that workbuf is being used as both the input and output
- final int[] result = KllFloatsHelper.generalFloatsCompress(getK(), getM(), provisionalNumLevels, workbuf,
- worklevels, workbuf, outlevels, isLevelZeroSorted(), random);
+ final int[] result = KllFloatsHelper.generalFloatsCompress(getK(), getM(), provisionalNumLevels,
+ workbuf, worklevels, workbuf, outlevels, isLevelZeroSorted(), random);
final int targetItemCount = result[1]; //was finalCapacity. Max size given k, m, numLevels
final int curItemCount = result[2]; //was finalPop
@@ -925,7 +927,7 @@ final void mergeFloatImpl(final KllSketch other) {
//Update Preamble:
setN(finalN);
if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
- setMinK(min(myDyMinK, other.getMinK()));
+ setMinK(min(myMinK, other.getMinK()));
}
//Update min, max values
From 5a67bc7214690228754f15c5d35117799c876525 Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Tue, 5 Apr 2022 18:39:52 -0700
Subject: [PATCH 30/31] Interim 13
---
.../kll/KllDirectDoublesSketch.java | 50 +-
.../kll/KllDirectFloatsSketch.java | 50 +-
.../datasketches/kll/KllDirectSketch.java | 67 +-
.../datasketches/kll/KllDoublesHelper.java | 410 ++++-
.../datasketches/kll/KllDoublesSketch.java | 41 +-
.../datasketches/kll/KllFloatsHelper.java | 408 ++++-
.../datasketches/kll/KllFloatsSketch.java | 43 +-
.../datasketches/kll/KllHeapSketch.java | 30 +-
.../apache/datasketches/kll/KllHelper.java | 789 ++++++++-
.../datasketches/kll/KllMemoryValidate.java | 8 +-
.../datasketches/kll/KllPreambleUtil.java | 2 +-
.../apache/datasketches/kll/KllSketch.java | 1413 ++---------------
.../kll/KllDirectDoublesSketchTest.java | 43 +-
.../kll/KllDirectFloatsSketchTest.java | 14 +-
14 files changed, 1728 insertions(+), 1640 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
index 9560c8799..0c89ff3a6 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectDoublesSketch.java
@@ -36,12 +36,12 @@
import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DOUBLE;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
import org.apache.datasketches.Family;
+import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
@@ -67,15 +67,12 @@ private KllDirectDoublesSketch(final WritableMemory wmem, final MemoryRequestSer
}
/**
- * Wrap a sketch around the given source Memory containing sketch data that originated from
- * this sketch.
- * @param srcMem a WritableMemory that contains data.
- * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
- * @return instance of this sketch
+ * Heapifies the given Memory object and returns a KllDoublesSketch
+ * @param mem the given Memory object.
+ * @return a KllDoublesSketch
*/
- public static KllDirectDoublesSketch writableWrap(final WritableMemory srcMem, final MemoryRequestServer memReqSvr) {
- final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
- return new KllDirectDoublesSketch(srcMem, memReqSvr, memVal);
+ public static KllDoublesSketch heapify(final Memory mem) {
+ return KllDoublesSketch.heapify(mem);
}
/**
@@ -119,6 +116,18 @@ static KllDirectDoublesSketch newInstance(final int k, final int m, final Writab
return new KllDirectDoublesSketch(dstMem, memReqSvr, memVal);
}
+ /**
+ * Wrap a sketch around the given source Memory containing sketch data that originated from
+ * this sketch.
+ * @param srcMem a WritableMemory that contains data.
+ * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
+ * @return instance of this sketch
+ */
+ public static KllDirectDoublesSketch writableWrap(final WritableMemory srcMem, final MemoryRequestServer memReqSvr) {
+ final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
+ return new KllDirectDoublesSketch(srcMem, memReqSvr, memVal);
+ }
+
/**
* Returns an approximation to the Cumulative Distribution Function (CDF), which is the
* cumulative analog of the PMF, of the input stream given a set of splitPoint (values).
@@ -141,7 +150,7 @@ static KllDirectDoublesSketch newInstance(final int k, final int m, final Writab
* in positions 0 through j of the returned PMF array.
*/
public double[] getCDF(final double[] splitPoints) {
- return getDoublesPmfOrCdf(splitPoints, true);
+ return KllDoublesHelper.getDoublesPmfOrCdf(this, splitPoints, true);
}
/**
@@ -183,7 +192,7 @@ public double[] getCDF(final double[] splitPoints) {
* splitPoint, with the exception that the last interval will include maximum value.
*/
public double[] getPMF(final double[] splitPoints) {
- return getDoublesPmfOrCdf(splitPoints, false);
+ return KllDoublesHelper.getDoublesPmfOrCdf(this, splitPoints, false);
}
/**
@@ -205,7 +214,7 @@ public double[] getPMF(final double[] splitPoints) {
* @return the approximation to the value at the given fraction
*/
public double getQuantile(final double fraction) {
- return getDoublesQuantile(fraction);
+ return KllDoublesHelper.getDoublesQuantile(this, fraction);
}
/**
@@ -238,7 +247,7 @@ public double getQuantileLowerBound(final double fraction) {
* array.
*/
public double[] getQuantiles(final double[] fractions) {
- return getDoublesQuantiles(fractions);
+ return KllDoublesHelper.getDoublesQuantiles(this, fractions);
}
/**
@@ -284,7 +293,7 @@ public double getQuantileUpperBound(final double fraction) {
* @return an approximate rank of the given value
*/
public double getRank(final double value) {
- return getDoubleRank(value);
+ return KllDoublesHelper.getDoubleRank(this, value);
}
/**
@@ -299,9 +308,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(SRC_MUST_BE_DIRECT); }
if (!other.isDoublesSketch()) { kllSketchThrow(SRC_MUST_BE_DOUBLE); }
- mergeDoubleImpl(other);
+ KllDoublesHelper.mergeDoubleImpl(this, other);
}
/**
@@ -310,7 +318,7 @@ public void merge(final KllSketch other) {
* @param value an item from a stream of items. NaNs are ignored.
*/
public void update(final double value) {
- updateDouble(value);
+ KllDoublesHelper.updateDouble(this, value);
}
@Override
@@ -350,13 +358,13 @@ public void update(final double value) {
@Override
void setDoubleItemsArray(final double[] doubleItems) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putDoubleArray(0, doubleItems, 0, doubleItems.length);
}
@Override
void setDoubleItemsArrayAt(final int index, final double value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putDouble((long)index * Double.BYTES, value);
}
@@ -368,7 +376,7 @@ void setDoubleItemsArrayAt(final int index, final double value) {
@Override
void setMaxDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putDouble(Double.BYTES, value);
}
@@ -377,7 +385,7 @@ void setMaxDoubleValue(final double value) {
@Override
void setMinDoubleValue(final double value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putDouble(0, value);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
index 3ebb9c7e6..54abe54dd 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectFloatsSketch.java
@@ -35,12 +35,12 @@
import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_FLOAT;
import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_IMMUTABLE;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
import org.apache.datasketches.Family;
+import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
@@ -67,15 +67,12 @@ private KllDirectFloatsSketch(final WritableMemory wmem, final MemoryRequestServ
}
/**
- * Wrap a sketch around the given source Memory containing sketch data that originated from
- * this sketch.
- * @param srcMem a WritableMemory that contains data.
- * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
- * @return instance of this sketch
+ * Heapifies the given Memory object and returns a KllFloatsSketch
+ * @param mem the given Memory object.
+ * @return a KllFloatsSketch
*/
- public static KllDirectFloatsSketch writableWrap(final WritableMemory srcMem, final MemoryRequestServer memReqSvr) {
- final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
- return new KllDirectFloatsSketch(srcMem, memReqSvr, memVal);
+ public static KllFloatsSketch heapify(final Memory mem) {
+ return KllFloatsSketch.heapify(mem);
}
/**
@@ -119,6 +116,18 @@ static KllDirectFloatsSketch newInstance(final int k, final int m, final Writabl
return new KllDirectFloatsSketch(dstMem, memReqSvr, memVal);
}
+ /**
+ * Wrap a sketch around the given source Memory containing sketch data that originated from
+ * this sketch.
+ * @param srcMem a WritableMemory that contains data.
+ * @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
+ * @return instance of this sketch
+ */
+ public static KllDirectFloatsSketch writableWrap(final WritableMemory srcMem, final MemoryRequestServer memReqSvr) {
+ final KllMemoryValidate memVal = new KllMemoryValidate(srcMem);
+ return new KllDirectFloatsSketch(srcMem, memReqSvr, memVal);
+ }
+
/**
* Returns an approximation to the Cumulative Distribution Function (CDF), which is the
* cumulative analog of the PMF, of the input stream given a set of splitPoint (values).
@@ -141,7 +150,7 @@ static KllDirectFloatsSketch newInstance(final int k, final int m, final Writabl
* in positions 0 through j of the returned PMF array.
*/
public double[] getCDF(final float[] splitPoints) {
- return getFloatsPmfOrCdf(splitPoints, true);
+ return KllFloatsHelper.getFloatsPmfOrCdf(this, splitPoints, true);
}
/**
@@ -183,7 +192,7 @@ public double[] getCDF(final float[] splitPoints) {
* splitPoint, with the exception that the last interval will include maximum value.
*/
public double[] getPMF(final float[] splitPoints) {
- return getFloatsPmfOrCdf(splitPoints, false);
+ return KllFloatsHelper.getFloatsPmfOrCdf(this, splitPoints, false);
}
/**
@@ -205,7 +214,7 @@ public double[] getPMF(final float[] splitPoints) {
* @return the approximation to the value at the given fraction
*/
public float getQuantile(final double fraction) {
- return getFloatsQuantile(fraction);
+ return KllFloatsHelper.getFloatsQuantile(this, fraction);
}
/**
@@ -238,7 +247,7 @@ public float getQuantileLowerBound(final double fraction) {
* array.
*/
public float[] getQuantiles(final double[] fractions) {
- return getFloatsQuantiles(fractions);
+ return KllFloatsHelper.getFloatsQuantiles(this, fractions);
}
/**
@@ -284,7 +293,7 @@ public float getQuantileUpperBound(final double fraction) {
* @return an approximate rank of the given value
*/
public double getRank(final float value) {
- return getFloatRank(value);
+ return KllFloatsHelper.getFloatRank(this, value);
}
/**
@@ -299,9 +308,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (!other.isDirect()) { kllSketchThrow(SRC_MUST_BE_DIRECT); }
if (!other.isFloatsSketch()) { kllSketchThrow(SRC_MUST_BE_FLOAT); }
- mergeFloatImpl(other);
+ KllFloatsHelper.mergeFloatImpl(this, other);
}
/**
@@ -310,7 +318,7 @@ public void merge(final KllSketch other) {
* @param value an item from a stream of items. NaNs are ignored.
*/
public void update(final float value) {
- updateFloat(value);
+ KllFloatsHelper.updateFloat(this, value);
}
@Override
@@ -356,13 +364,13 @@ float getMinFloatValue() {
@Override
void setFloatItemsArray(final float[] floatItems) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putFloatArray(0, floatItems, 0, floatItems.length);
}
@Override
void setFloatItemsArrayAt(final int index, final float value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable.putFloat((long)index * Float.BYTES, value);
}
@@ -371,7 +379,7 @@ void setFloatItemsArrayAt(final int index, final float value) {
@Override
void setMaxFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putFloat(Float.BYTES, value);
}
@@ -380,7 +388,7 @@ void setMaxFloatValue(final float value) {
@Override
void setMinFloatValue(final float value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable.putFloat(0, value);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
index 556b8dbf9..959d4bd3d 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDirectSketch.java
@@ -40,14 +40,14 @@
* of the sketch type (float or double).
*/
abstract class KllDirectSketch extends KllSketch {
- final boolean updatable = true;
+ final boolean updatableMemory;
WritableMemory levelsArrUpdatable;
WritableMemory minMaxArrUpdatable;
WritableMemory itemsArrUpdatable;
/**
- * For the direct sketches it is important that the methods implemented here are designed to work dynamically
- * as the sketch grows off-heap.
+ * For the direct sketches it is important that the methods implemented here are designed to
+ * work dynamically as the sketch grows off-heap.
* @param sketchType either DOUBLE_SKETCH or FLOAT_SKETCH
* @param wmem the current WritableMemory
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
@@ -55,6 +55,7 @@ abstract class KllDirectSketch extends KllSketch {
KllDirectSketch(final SketchType sketchType, final WritableMemory wmem, final MemoryRequestServer memReqSvr,
final KllMemoryValidate memVal) {
super(sketchType, wmem, memReqSvr);
+ updatableMemory = memVal.updatableMemory && memReqSvr != null;
levelsArrUpdatable = memVal.levelsArrUpdatable;
minMaxArrUpdatable = memVal.minMaxArrUpdatable;
itemsArrUpdatable = memVal.itemsArrUpdatable;
@@ -65,11 +66,6 @@ public int getK() {
return getMemoryK(wmem);
}
- @Override
- int getM() {
- return getMemoryM(wmem);
- }
-
@Override
public long getN() {
return getMemoryN(wmem);
@@ -77,7 +73,7 @@ public long getN() {
@Override
public void reset() {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
final int k = getK();
setN(0);
setMinK(k);
@@ -86,7 +82,7 @@ public void reset() {
setLevelZeroSorted(false);
final int newLevelsArrLen = 2 * Integer.BYTES;
final int newItemsArrLen = k;
- KllSketch.memorySpaceMgmt(this, newLevelsArrLen, newItemsArrLen);
+ KllHelper.memorySpaceMgmt(this, newLevelsArrLen, newItemsArrLen);
levelsArrUpdatable.putIntArray(0L, new int[] {k, k}, 0, 2);
if (sketchType == SketchType.DOUBLES_SKETCH) {
minMaxArrUpdatable.putDoubleArray(0L, new double[] {Double.NaN, Double.NaN}, 0, 2);
@@ -105,11 +101,6 @@ public byte[] toUpdatableByteArray() {
return byteArr;
}
- @Override
- int getMinK() {
- return getMemoryMinK(wmem);
- }
-
int getItemsArrLengthItems() {
return getLevelsArray()[getNumLevels()];
}
@@ -127,6 +118,16 @@ int getLevelsArrayAt(final int index) {
return levelsArrUpdatable.getInt((long)index * Integer.BYTES);
}
+ @Override
+ int getM() {
+ return getMemoryM(wmem);
+ }
+
+ @Override
+ int getMinK() {
+ return getMemoryMinK(wmem);
+ }
+
@Override
int getNumLevels() {
return getMemoryNumLevels(wmem);
@@ -134,14 +135,14 @@ int getNumLevels() {
@Override
void incN() {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
long n = getMemoryN(wmem);
setMemoryN(wmem, ++n);
}
@Override
void incNumLevels() {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
int numLevels = getMemoryNumLevels(wmem);
setMemoryNumLevels(wmem, ++numLevels);
}
@@ -151,33 +152,27 @@ boolean isLevelZeroSorted() {
return getMemoryLevelZeroSortedFlag(wmem);
}
- @Override
- void setMinK(final int minK) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
- setMemoryMinK(wmem, minK);
- }
-
@Override
void setItemsArrayUpdatable(final WritableMemory itemsMem) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
itemsArrUpdatable = itemsMem;
}
@Override
void setLevelsArray(final int[] levelsArr) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
levelsArrUpdatable.putIntArray(0, levelsArr, 0, levelsArr.length);
}
@Override
void setLevelsArrayAt(final int index, final int value) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
levelsArrUpdatable.putInt((long)index * Integer.BYTES, value);
}
@Override
void setLevelsArrayAtMinusEq(final int index, final int minusEq) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
final int offset = index * Integer.BYTES;
final int curV = levelsArrUpdatable.getInt(offset);
levelsArrUpdatable.putInt(offset, curV - minusEq);
@@ -185,7 +180,7 @@ void setLevelsArrayAtMinusEq(final int index, final int minusEq) {
@Override
void setLevelsArrayAtPlusEq(final int index, final int plusEq) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
final int offset = index * Integer.BYTES;
final int curV = levelsArrUpdatable.getInt(offset);
levelsArrUpdatable.putInt(offset, curV + plusEq);
@@ -193,31 +188,37 @@ void setLevelsArrayAtPlusEq(final int index, final int plusEq) {
@Override
void setLevelsArrayUpdatable(final WritableMemory levelsMem) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
levelsArrUpdatable = levelsMem;
}
@Override
void setLevelZeroSorted(final boolean sorted) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
setMemoryLevelZeroSortedFlag(wmem, sorted);
}
+ @Override
+ void setMinK(final int minK) {
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ setMemoryMinK(wmem, minK);
+ }
+
@Override
void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
minMaxArrUpdatable = minMaxMem;
}
@Override
void setN(final long n) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
setMemoryN(wmem, n);
}
@Override
void setNumLevels(final int numLevels) {
- if (!updatable) { kllSketchThrow(TGT_IS_IMMUTABLE); }
+ if (!updatableMemory) { kllSketchThrow(TGT_IS_IMMUTABLE); }
setMemoryNumLevels(wmem, numLevels);
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesHelper.java b/src/main/java/org/apache/datasketches/kll/KllDoublesHelper.java
index 9049775a1..25a71f699 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesHelper.java
@@ -19,6 +19,8 @@
package org.apache.datasketches.kll;
+import static java.lang.Math.max;
+import static java.lang.Math.min;
import static org.apache.datasketches.Util.isEven;
import static org.apache.datasketches.Util.isOdd;
@@ -32,7 +34,281 @@
* @author Kevin Lang
* @author Alexander Saydakov
*/
-class KllDoublesHelper {
+final class KllDoublesHelper {
+
+ static double getDoubleRank(final KllSketch mine, final double value) {
+ if (mine.isEmpty()) { return Double.NaN; }
+ int level = 0;
+ int weight = 1;
+ long total = 0;
+ final double[] myDoubleItemsArr = mine.getDoubleItemsArray();
+ final int[] myLevelsArr = mine.getLevelsArray();
+ while (level < mine.getNumLevels()) {
+ final int fromIndex = myLevelsArr[level];
+ final int toIndex = myLevelsArr[level + 1]; // exclusive
+ for (int i = fromIndex; i < toIndex; i++) {
+ if (myDoubleItemsArr[i] < value) {
+ total += weight;
+ } else if (level > 0 || mine.isLevelZeroSorted()) {
+ break; // levels above 0 are sorted, no point comparing further
+ }
+ }
+ level++;
+ weight *= 2;
+ }
+ return (double) total / mine.getN();
+ }
+
+ static double[] getDoublesPmfOrCdf(final KllSketch mine, final double[] splitPoints, final boolean isCdf) {
+ if (mine.isEmpty()) { return null; }
+ validateDoubleValues(splitPoints);
+ final double[] buckets = new double[splitPoints.length + 1];
+ final int myNumLevels = mine.getNumLevels();
+ final int[] myLevelsArr = mine.getLevelsArray();
+ int level = 0;
+ int weight = 1;
+ while (level < myNumLevels) {
+ final int fromIndex = myLevelsArr[level];
+ final int toIndex = myLevelsArr[level + 1]; // exclusive
+ if (level == 0 && !mine.isLevelZeroSorted()) {
+ KllDoublesHelper.incrementDoublesBucketsUnsortedLevel(mine, fromIndex, toIndex, weight, splitPoints, buckets);
+ } else {
+ KllDoublesHelper.incrementDoublesBucketsSortedLevel(mine, fromIndex, toIndex, weight, splitPoints, buckets);
+ }
+ level++;
+ weight *= 2;
+ }
+ // normalize and, if CDF, convert to cumulative
+ if (isCdf) {
+ double subtotal = 0;
+ for (int i = 0; i < buckets.length; i++) {
+ subtotal += buckets[i];
+ buckets[i] = subtotal / mine.getN();
+ }
+ } else {
+ for (int i = 0; i < buckets.length; i++) {
+ buckets[i] /= mine.getN();
+ }
+ }
+ return buckets;
+ }
+
+ static double getDoublesQuantile(final KllSketch mine, final double fraction) {
+ if (mine.isEmpty()) { return Double.NaN; }
+ if (fraction < 0.0 || fraction > 1.0) {
+ throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
+ }
+ //These two assumptions make KLL compatible with the previous classic Quantiles Sketch
+ if (fraction == 0.0) { return mine.getMinDoubleValue(); }
+ if (fraction == 1.0) { return mine.getMaxDoubleValue(); }
+ final KllDoublesQuantileCalculator quant = KllDoublesHelper.getDoublesQuantileCalculator(mine);
+ return quant.getQuantile(fraction);
+ }
+
+ static double[] getDoublesQuantiles(final KllSketch mine, final double[] fractions) {
+ if (mine.isEmpty()) { return null; }
+ KllDoublesQuantileCalculator quant = null;
+ final double[] quantiles = new double[fractions.length];
+ for (int i = 0; i < fractions.length; i++) {
+ final double fraction = fractions[i];
+ if (fraction < 0.0 || fraction > 1.0) {
+ throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
+ }
+ if (fraction == 0.0) { quantiles[i] = mine.getMinDoubleValue(); }
+ else if (fraction == 1.0) { quantiles[i] = mine.getMaxDoubleValue(); }
+ else {
+ if (quant == null) {
+ quant = KllDoublesHelper.getDoublesQuantileCalculator(mine);
+ }
+ quantiles[i] = quant.getQuantile(fraction);
+ }
+ }
+ return quantiles;
+ }
+
+ static void mergeDoubleImpl(final KllSketch mine, final KllSketch other) {
+ if (other.isEmpty()) { return; }
+ final long finalN = mine.getN() + other.getN();
+ //update this sketch with level0 items from the other sketch
+ final double[] otherDoubleItemsArr = other.getDoubleItemsArray();
+ final int otherNumLevels = other.getNumLevels();
+ final int[] otherLevelsArr = other.getLevelsArray();
+ for (int i = otherLevelsArr[0]; i < otherLevelsArr[1]; i++) {
+ KllDoublesHelper.updateDouble(mine, otherDoubleItemsArr[i]);
+ }
+ // after the level 0 update, we capture the key mutable variables
+ final double myMin = mine.getMinDoubleValue();
+ final double myMax = mine.getMaxDoubleValue();
+ final int myMinK = mine.getMinK();
+
+ final int myCurNumLevels = mine.getNumLevels();
+ final int[] myCurLevelsArr = mine.getLevelsArray();
+ final double[] myCurDoubleItemsArr = mine.getDoubleItemsArray();
+
+ final int myNewNumLevels;
+ final int[] myNewLevelsArr;
+ final double[] myNewDoubleItemsArr;
+
+ if (otherNumLevels > 1) { //now merge other levels if they exist
+ final int tmpSpaceNeeded = mine.getNumRetained()
+ + KllHelper.getNumRetainedAboveLevelZero(otherNumLevels, otherLevelsArr);
+ final double[] workbuf = new double[tmpSpaceNeeded];
+ final int ub = KllHelper.ubOnNumLevels(finalN);
+ final int[] worklevels = new int[ub + 2]; // ub+1 does not work
+ final int[] outlevels = new int[ub + 2];
+
+ final int provisionalNumLevels = max(myCurNumLevels, otherNumLevels);
+
+ populateDoubleWorkArrays(mine, other, workbuf, worklevels, provisionalNumLevels);
+
+ // notice that workbuf is being used as both the input and output
+ final int[] result = generalDoublesCompress(mine.getK(), mine.getM(), provisionalNumLevels,
+ workbuf, worklevels, workbuf, outlevels, mine.isLevelZeroSorted(), KllSketch.random);
+ final int targetItemCount = result[1]; //was finalCapacity. Max size given k, m, numLevels
+ final int curItemCount = result[2]; //was finalPop
+
+ // now we need to finalize the results for the "self" sketch
+
+ //THE NEW NUM LEVELS
+ myNewNumLevels = result[0]; //was finalNumLevels
+ assert myNewNumLevels <= ub; // ub may be much bigger
+
+ // THE NEW ITEMS ARRAY (was newbuf)
+ myNewDoubleItemsArr = (targetItemCount == myCurDoubleItemsArr.length)
+ ? myCurDoubleItemsArr
+ : new double[targetItemCount];
+ final int freeSpaceAtBottom = targetItemCount - curItemCount;
+ //shift the new items array
+ System.arraycopy(workbuf, outlevels[0], myNewDoubleItemsArr, freeSpaceAtBottom, curItemCount);
+ final int theShift = freeSpaceAtBottom - outlevels[0];
+
+ //calculate the new levels array length
+ final int finalLevelsArrLen;
+ if (myCurLevelsArr.length < myNewNumLevels + 1) { finalLevelsArrLen = myNewNumLevels + 1; }
+ else { finalLevelsArrLen = myCurLevelsArr.length; }
+
+ //THE NEW LEVELS ARRAY
+ myNewLevelsArr = new int[finalLevelsArrLen];
+ for (int lvl = 0; lvl < myNewNumLevels + 1; lvl++) { // includes the "extra" index
+ myNewLevelsArr[lvl] = outlevels[lvl] + theShift;
+ }
+
+ //MEMORY SPACE MANAGEMENT
+ if (mine.updatablMemory) {
+ mine.wmem = KllHelper.memorySpaceMgmt(mine, myNewLevelsArr.length, myNewDoubleItemsArr.length);
+ }
+
+ } else {
+ myNewNumLevels = myCurNumLevels;
+ myNewLevelsArr = myCurLevelsArr;
+ myNewDoubleItemsArr = myCurDoubleItemsArr;
+ }
+
+ //Update Preamble:
+ mine.setN(finalN);
+ if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
+ mine.setMinK(min(myMinK, other.getMinK()));
+ }
+
+ //Update min, max values
+ final double otherMin = other.getMinDoubleValue();
+ final double otherMax = other.getMaxDoubleValue();
+ mine.setMinDoubleValue(resolveDoubleMinValue(myMin, otherMin));
+ mine.setMaxDoubleValue(resolveDoubleMaxValue(myMax, otherMax));
+
+ //Update numLevels, levelsArray, items
+ mine.setNumLevels(myNewNumLevels);
+ mine.setLevelsArray(myNewLevelsArr);
+ mine.setDoubleItemsArray(myNewDoubleItemsArr);
+ assert KllHelper.sumTheSampleWeights(mine.getNumLevels(), mine.getLevelsArray()) == mine.getN();
+ }
+
+ static void mergeSortedDoubleArrays(
+ final double[] bufA, final int startA, final int lenA,
+ final double[] bufB, final int startB, final int lenB,
+ final double[] bufC, final int startC) {
+ final int lenC = lenA + lenB;
+ final int limA = startA + lenA;
+ final int limB = startB + lenB;
+ final int limC = startC + lenC;
+
+ int a = startA;
+ int b = startB;
+
+ for (int c = startC; c < limC; c++) {
+ if (a == limA) {
+ bufC[c] = bufB[b];
+ b++;
+ } else if (b == limB) {
+ bufC[c] = bufA[a];
+ a++;
+ } else if (bufA[a] < bufB[b]) {
+ bufC[c] = bufA[a];
+ a++;
+ } else {
+ bufC[c] = bufB[b];
+ b++;
+ }
+ }
+ assert a == limA;
+ assert b == limB;
+ }
+
+ /**
+ * Validation Method. This must be modified to test validation
+ * @param buf the items array
+ * @param start data start
+ * @param length items length
+ * @param random instance of Random
+ */
+ static void randomlyHalveDownDoubles(final double[] buf, final int start, final int length, final Random random) {
+ assert isEven(length);
+ final int half_length = length / 2;
+ final int offset = random.nextInt(2); // disable for validation
+ //final int offset = deterministicOffset(); // enable for validation
+ int j = start + offset;
+ for (int i = start; i < (start + half_length); i++) {
+ buf[i] = buf[j];
+ j += 2;
+ }
+ }
+
+ /**
+ * Validation Method. This must be modified to test validation
+ * @param buf the items array
+ * @param start data start
+ * @param length items length
+ * @param random instance of Random
+ */
+ static void randomlyHalveUpDoubles(final double[] buf, final int start, final int length, final Random random) {
+ assert isEven(length);
+ final int half_length = length / 2;
+ final int offset = random.nextInt(2); // disable for validation
+ //final int offset = deterministicOffset(); // enable for validation
+ int j = (start + length) - 1 - offset;
+ for (int i = (start + length) - 1; i >= (start + half_length); i--) {
+ buf[i] = buf[j];
+ j -= 2;
+ }
+ }
+
+ static void updateDouble(final KllSketch mine, final double value) {
+ if (Double.isNaN(value)) { return; }
+ if (mine.isEmpty()) {
+ mine.setMinDoubleValue(value);
+ mine.setMaxDoubleValue(value);
+ } else {
+ if (value < mine.getMinDoubleValue()) { mine.setMinDoubleValue(value); }
+ if (value > mine.getMaxDoubleValue()) { mine.setMaxDoubleValue(value); }
+ }
+ if (mine.getLevelsArrayAt(0) == 0) { KllHelper.compressWhileUpdatingSketch(mine); }
+ mine.incN();
+ mine.setLevelZeroSorted(false);
+ final int nextPos = mine.getLevelsArrayAt(0) - 1;
+ assert mine.getLevelsArrayAt(0) >= 0;
+ mine.setLevelsArrayAt(0, nextPos);
+ mine.setDoubleItemsArrayAt(nextPos, value);
+ }
/**
* Compression algorithm used to merge higher levels.
@@ -67,7 +343,7 @@ class KllDoublesHelper {
* @param random instance of java.util.Random
* @return int array of: {numLevels, targetItemCount, currentItemCount)
*/
- static int[] generalDoublesCompress(
+ private static int[] generalDoublesCompress(
final int k,
final int m,
final int numLevelsIn,
@@ -155,69 +431,103 @@ static int[] generalDoublesCompress(
return new int[] {numLevels, targetItemCount, currentItemCount};
}
- static void mergeSortedDoubleArrays(
- final double[] bufA, final int startA, final int lenA,
- final double[] bufB, final int startB, final int lenB,
- final double[] bufC, final int startC) {
- final int lenC = lenA + lenB;
- final int limA = startA + lenA;
- final int limB = startB + lenB;
- final int limC = startC + lenC;
-
- int a = startA;
- int b = startB;
+ private static KllDoublesQuantileCalculator getDoublesQuantileCalculator(final KllSketch mine) {
+ final int[] myLevelsArr = mine.getLevelsArray();
+ final double[] myDoubleItemsArr = mine.getDoubleItemsArray();
+ if (!mine.isLevelZeroSorted()) {
+ Arrays.sort(mine.getDoubleItemsArray(), myLevelsArr[0], myLevelsArr[1]);
+ mine.setLevelZeroSorted(true);
+ }
+ return new KllDoublesQuantileCalculator(myDoubleItemsArr, myLevelsArr, mine.getNumLevels(), mine.getN());
+ }
- for (int c = startC; c < limC; c++) {
- if (a == limA) {
- bufC[c] = bufB[b];
- b++;
- } else if (b == limB) {
- bufC[c] = bufA[a];
- a++;
- } else if (bufA[a] < bufB[b]) {
- bufC[c] = bufA[a];
- a++;
+ private static void incrementDoublesBucketsSortedLevel(
+ final KllSketch mine, final int fromIndex, final int toIndex,
+ final int weight, final double[] splitPoints, final double[] buckets) {
+ final double[] myDoubleItemsArr = mine.getDoubleItemsArray();
+ int i = fromIndex;
+ int j = 0;
+ while (i < toIndex && j < splitPoints.length) {
+ if (myDoubleItemsArr[i] < splitPoints[j]) {
+ buckets[j] += weight; // this sample goes into this bucket
+ i++; // move on to next sample and see whether it also goes into this bucket
} else {
- bufC[c] = bufB[b];
- b++;
+ j++; // no more samples for this bucket
}
}
- assert a == limA;
- assert b == limB;
+ // now either i == toIndex (we are out of samples), or
+ // j == numSplitPoints (we are out of buckets, but there are more samples remaining)
+ // we only need to do something in the latter case
+ if (j == splitPoints.length) {
+ buckets[j] += weight * (toIndex - i);
+ }
}
- //This must be modified for validation
- static void randomlyHalveDownDoubles(final double[] buf, final int start, final int length, final Random random) {
- assert isEven(length);
- final int half_length = length / 2;
- final int offset = random.nextInt(2); // disable for validation
- //final int offset = deterministicOffset(); // enable for validation
- int j = start + offset;
- for (int i = start; i < (start + half_length); i++) {
- buf[i] = buf[j];
- j += 2;
+ private static void incrementDoublesBucketsUnsortedLevel(
+ final KllSketch mine, final int fromIndex, final int toIndex,
+ final int weight, final double[] splitPoints, final double[] buckets) {
+ final double[] myDoubleItemsArr = mine.getDoubleItemsArray();
+ for (int i = fromIndex; i < toIndex; i++) {
+ int j;
+ for (j = 0; j < splitPoints.length; j++) {
+ if (myDoubleItemsArr[i] < splitPoints[j]) {
+ break;
+ }
+ }
+ buckets[j] += weight;
}
}
- //This must be modified for validation
- static void randomlyHalveUpDoubles(final double[] buf, final int start, final int length, final Random random) {
- assert isEven(length);
- final int half_length = length / 2;
- final int offset = random.nextInt(2); // disable for validation
- //final int offset = deterministicOffset(); // enable for validation
- int j = (start + length) - 1 - offset;
- for (int i = (start + length) - 1; i >= (start + half_length); i--) {
- buf[i] = buf[j];
- j -= 2;
+ private static void populateDoubleWorkArrays(final KllSketch mine, final KllSketch other, final double[] workbuf,
+ final int[] worklevels, final int provisionalNumLevels) {
+ worklevels[0] = 0;
+ final int[] myLevelsArr = mine.getLevelsArray();
+ final int[] otherLevelsArr = other.getLevelsArray();
+ final double[] myDoubleItemsArr = mine.getDoubleItemsArray();
+ final double[] otherDoubleItemsArr = other.getDoubleItemsArray();
+
+ // Note: the level zero data from "other" was already inserted into "self"
+ final int selfPopZero = KllHelper.currentLevelSize(0, mine.getNumLevels(),myLevelsArr);
+ System.arraycopy(myDoubleItemsArr, myLevelsArr[0], workbuf, worklevels[0], selfPopZero);
+ worklevels[1] = worklevels[0] + selfPopZero;
+
+ for (int lvl = 1; lvl < provisionalNumLevels; lvl++) {
+ final int selfPop = KllHelper.currentLevelSize(lvl, mine.getNumLevels(), myLevelsArr);
+ final int otherPop = KllHelper.currentLevelSize(lvl, other.getNumLevels(), otherLevelsArr);
+ worklevels[lvl + 1] = worklevels[lvl] + selfPop + otherPop;
+
+ if (selfPop > 0 && otherPop == 0) {
+ System.arraycopy(myDoubleItemsArr, myLevelsArr[lvl], workbuf, worklevels[lvl], selfPop);
+ } else if (selfPop == 0 && otherPop > 0) {
+ System.arraycopy(otherDoubleItemsArr, otherLevelsArr[lvl], workbuf, worklevels[lvl], otherPop);
+ } else if (selfPop > 0 && otherPop > 0) {
+ mergeSortedDoubleArrays(myDoubleItemsArr, myLevelsArr[lvl], selfPop, otherDoubleItemsArr,
+ otherLevelsArr[lvl], otherPop, workbuf, worklevels[lvl]);
+ }
}
}
+ private static double resolveDoubleMaxValue(final double myMax, final double otherMax) {
+ if (Double.isNaN(myMax) && Double.isNaN(otherMax)) { return Double.NaN; }
+ if (Double.isNaN(myMax)) { return otherMax; }
+ if (Double.isNaN(otherMax)) { return myMax; }
+ return max(myMax, otherMax);
+ }
+
+ private static double resolveDoubleMinValue(final double myMin, final double otherMin) {
+ if (Double.isNaN(myMin) && Double.isNaN(otherMin)) { return Double.NaN; }
+ if (Double.isNaN(myMin)) { return otherMin; }
+ if (Double.isNaN(otherMin)) { return myMin; }
+ return min(myMin, otherMin);
+ }
+
/**
+ * Validation Method.
* Checks the sequential validity of the given array of double values.
* They must be unique, monotonically increasing and not NaN.
* @param values the given array of values
*/
- static void validateDoubleValues(final double[] values) {
+ private static void validateDoubleValues(final double[] values) {
for (int i = 0; i < values.length; i++) {
if (!Double.isFinite(values[i])) {
throw new SketchesArgumentException("Values must be finite");
@@ -230,11 +540,11 @@ static void validateDoubleValues(final double[] values) {
}
/*
+ * Validation Method.
* The following must be enabled for use with the KllDoublesValidationTest,
- * which is only enabled for manual testing. In addition, two methods
+ * which is only enabled for manual testing. In addition, two Validation Methods
* above need to be modified as commented.
*/
-
// static int nextOffset = 0;
//
// private static int deterministicOffset() {
diff --git a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
index 63a333afa..c5aadebf0 100644
--- a/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllDoublesSketch.java
@@ -22,11 +22,9 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_DOUBLE;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
-import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
/**
@@ -49,7 +47,7 @@ public final class KllDoublesSketch extends KllHeapSketch {
*/
private KllDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
super(memVal.k, memVal.m, SketchType.DOUBLES_SKETCH);
- buildHeapKllSketchFromMemory(memVal);
+ KllHelper.buildHeapKllSketchFromMemory(this, memVal);
}
/**
@@ -57,7 +55,7 @@ private KllDoublesSketch(final Memory mem, final KllMemoryValidate memVal) {
* This will have a rank error of about 1.65%.
*/
public KllDoublesSketch() {
- this(KllSketch.DEFAULT_K);
+ this(KllSketch.DEFAULT_K, KllSketch.DEFAULT_M);
}
/**
@@ -71,15 +69,15 @@ public KllDoublesSketch(final int k) {
}
/**
- * Heap constructor with a given parameter k and m.
- * k can be any value between DEFAULT_M and 65535, inclusive.
+ * Heap constructor with a given parameters k and m.
+ *
+ * @param k parameter that controls size of the sketch and accuracy of estimates.
+ * k can be any value between m and 65535, inclusive.
* The default k = 200 results in a normalized rank error of about 1.65%.
- * Higher values of K will have smaller error but the sketch will be larger (and slower).
- * The DEFAULT_M, which is 8 is recommended for the given parameter m.
- * Other values of m should be considered experimental as they have not been
- * as well characterized.
- * @param k parameter that controls size of the sketch and accuracy of estimates
- * @param m parameter that controls the minimum level width in items.
+ * Higher values of k will have smaller error but the sketch will be larger (and slower).
+ * @param m parameter controls the minimum level width in items. It can be 2, 4, 6 or 8.
+ * The DEFAULT_M, which is 8 is recommended. Other values of m should be considered
+ * experimental as they have not been as well characterized.
*/
KllDoublesSketch(final int k, final int m) {
super(k, m, SketchType.DOUBLES_SKETCH);
@@ -97,9 +95,7 @@ public KllDoublesSketch(final int k) {
*/
public static KllDoublesSketch heapify(final Memory mem) {
final KllMemoryValidate memChk = new KllMemoryValidate(mem);
- if (!memChk.doublesSketch) {
- throw new SketchesArgumentException("Memory object is not a KllDoublesSketch.");
- }
+ if (!memChk.doublesSketch) { Error.kllSketchThrow(SRC_MUST_BE_DOUBLE); }
return new KllDoublesSketch(mem, memChk);
}
@@ -125,7 +121,7 @@ public static KllDoublesSketch heapify(final Memory mem) {
* in positions 0 through j of the returned PMF array.
*/
public double[] getCDF(final double[] splitPoints) {
- return getDoublesPmfOrCdf(splitPoints, true);
+ return KllDoublesHelper.getDoublesPmfOrCdf(this, splitPoints, true);
}
/**
@@ -167,7 +163,7 @@ public double[] getCDF(final double[] splitPoints) {
* splitPoint, with the exception that the last interval will include maximum value.
*/
public double[] getPMF(final double[] splitPoints) {
- return getDoublesPmfOrCdf(splitPoints, false);
+ return KllDoublesHelper.getDoublesPmfOrCdf(this, splitPoints, false);
}
/**
@@ -189,7 +185,7 @@ public double[] getPMF(final double[] splitPoints) {
* @return the approximation to the value at the given fraction
*/
public double getQuantile(final double fraction) {
- return getDoublesQuantile(fraction);
+ return KllDoublesHelper.getDoublesQuantile(this, fraction);
}
/**
@@ -222,7 +218,7 @@ public double getQuantileLowerBound(final double fraction) {
* array.
*/
public double[] getQuantiles(final double[] fractions) {
- return getDoublesQuantiles(fractions);
+ return KllDoublesHelper.getDoublesQuantiles(this, fractions);
}
/**
@@ -268,7 +264,7 @@ public double getQuantileUpperBound(final double fraction) {
* @return an approximate rank of the given value
*/
public double getRank(final double value) {
- return getDoubleRank(value);
+ return KllDoublesHelper.getDoubleRank(this, value);
}
/**
@@ -283,9 +279,8 @@ public KllDoublesSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllSketch other) {
- if (other.isDirect()) { kllSketchThrow(SRC_CANNOT_BE_DIRECT); }
if (!other.isDoublesSketch()) { kllSketchThrow(SRC_MUST_BE_DOUBLE); }
- mergeDoubleImpl(other);
+ KllDoublesHelper.mergeDoubleImpl(this, other);
}
@Override
@@ -307,7 +302,7 @@ public void reset() {
* @param value an item from a stream of items. NaNs are ignored.
*/
public void update(final double value) {
- updateDouble(value);
+ KllDoublesHelper.updateDouble(this, value);
}
@Override //Used internally
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsHelper.java b/src/main/java/org/apache/datasketches/kll/KllFloatsHelper.java
index 6f15baf3c..85742f9bb 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsHelper.java
@@ -19,6 +19,8 @@
package org.apache.datasketches.kll;
+import static java.lang.Math.max;
+import static java.lang.Math.min;
import static org.apache.datasketches.Util.isEven;
import static org.apache.datasketches.Util.isOdd;
@@ -32,7 +34,281 @@
* @author Kevin Lang
* @author Alexander Saydakov
*/
-class KllFloatsHelper {
+final class KllFloatsHelper {
+
+ static double getFloatRank(final KllSketch mine, final float value) {
+ if (mine.isEmpty()) { return Double.NaN; }
+ int level = 0;
+ int weight = 1;
+ long total = 0;
+ final float[] myFloatItemsArr = mine.getFloatItemsArray();
+ final int[] myLevelsArr = mine.getLevelsArray();
+ while (level < mine.getNumLevels()) {
+ final int fromIndex = myLevelsArr[level];
+ final int toIndex = myLevelsArr[level + 1]; // exclusive
+ for (int i = fromIndex; i < toIndex; i++) {
+ if (myFloatItemsArr[i] < value) {
+ total += weight;
+ } else if (level > 0 || mine.isLevelZeroSorted()) {
+ break; // levels above 0 are sorted, no point comparing further
+ }
+ }
+ level++;
+ weight *= 2;
+ }
+ return (double) total / mine.getN();
+ }
+
+ static double[] getFloatsPmfOrCdf(final KllSketch mine, final float[] splitPoints, final boolean isCdf) {
+ if (mine.isEmpty()) { return null; }
+ validateFloatValues(splitPoints);
+ final double[] buckets = new double[splitPoints.length + 1];
+ final int myNumLevels = mine.getNumLevels();
+ final int[] myLevelsArr = mine.getLevelsArray();
+ int level = 0;
+ int weight = 1;
+ while (level < myNumLevels) {
+ final int fromIndex = myLevelsArr[level];
+ final int toIndex = myLevelsArr[level + 1]; // exclusive
+ if (level == 0 && !mine.isLevelZeroSorted()) {
+ KllFloatsHelper.incrementFloatBucketsUnsortedLevel(mine, fromIndex, toIndex, weight, splitPoints, buckets);
+ } else {
+ KllFloatsHelper.incrementFloatBucketsSortedLevel(mine, fromIndex, toIndex, weight, splitPoints, buckets);
+ }
+ level++;
+ weight *= 2;
+ }
+ // normalize and, if CDF, convert to cumulative
+ if (isCdf) {
+ double subtotal = 0;
+ for (int i = 0; i < buckets.length; i++) {
+ subtotal += buckets[i];
+ buckets[i] = subtotal / mine.getN();
+ }
+ } else {
+ for (int i = 0; i < buckets.length; i++) {
+ buckets[i] /= mine.getN();
+ }
+ }
+ return buckets;
+ }
+
+ static float getFloatsQuantile(final KllSketch mine, final double fraction) {
+ if (mine.isEmpty()) { return Float.NaN; }
+ if (fraction < 0.0 || fraction > 1.0) {
+ throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
+ }
+ //These two assumptions make KLL compatible with the previous classic Quantiles Sketch
+ if (fraction == 0.0) { return mine.getMinFloatValue(); }
+ if (fraction == 1.0) { return mine.getMaxFloatValue(); }
+ final KllFloatsQuantileCalculator quant = KllFloatsHelper.getFloatsQuantileCalculator(mine);
+ return quant.getQuantile(fraction);
+ }
+
+ static float[] getFloatsQuantiles(final KllSketch mine, final double[] fractions) {
+ if (mine.isEmpty()) { return null; }
+ KllFloatsQuantileCalculator quant = null;
+ final float[] quantiles = new float[fractions.length];
+ for (int i = 0; i < fractions.length; i++) {
+ final double fraction = fractions[i];
+ if (fraction < 0.0 || fraction > 1.0) {
+ throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
+ }
+ if (fraction == 0.0) { quantiles[i] = mine.getMinFloatValue(); }
+ else if (fraction == 1.0) { quantiles[i] = mine.getMaxFloatValue(); }
+ else {
+ if (quant == null) {
+ quant = KllFloatsHelper.getFloatsQuantileCalculator(mine);
+ }
+ quantiles[i] = quant.getQuantile(fraction);
+ }
+ }
+ return quantiles;
+ }
+
+ static void mergeFloatImpl(final KllSketch mine, final KllSketch other) {
+ if (other.isEmpty()) { return; }
+ final long finalN = mine.getN() + other.getN();
+ //update this sketch with level0 items from the other sketch
+ final float[] otherFloatItemsArr = other.getFloatItemsArray();
+ final int otherNumLevels = other.getNumLevels();
+ final int[] otherLevelsArr = other.getLevelsArray();
+ for (int i = otherLevelsArr[0]; i < otherLevelsArr[1]; i++) {
+ KllFloatsHelper.updateFloat(mine, otherFloatItemsArr[i]);
+ }
+ // after the level 0 update, we capture the key mutable variables
+ final float myMin = mine.getMinFloatValue();
+ final float myMax = mine.getMaxFloatValue();
+ final int myMinK = mine.getMinK();
+
+ final int myCurNumLevels = mine.getNumLevels();
+ final int[] myCurLevelsArr = mine.getLevelsArray();
+ final float[] myCurFloatItemsArr = mine.getFloatItemsArray();
+
+ final int myNewNumLevels;
+ final int[] myNewLevelsArr;
+ final float[] myNewFloatItemsArr;
+
+ if (otherNumLevels > 1) { //now merge higher levels if they exist
+ final int tmpSpaceNeeded = mine.getNumRetained()
+ + KllHelper.getNumRetainedAboveLevelZero(otherNumLevels, otherLevelsArr);
+ final float[] workbuf = new float[tmpSpaceNeeded];
+ final int ub = KllHelper.ubOnNumLevels(finalN);
+ final int[] worklevels = new int[ub + 2]; // ub+1 does not work
+ final int[] outlevels = new int[ub + 2];
+
+ final int provisionalNumLevels = max(myCurNumLevels, otherNumLevels);
+
+ populateFloatWorkArrays(mine, other, workbuf, worklevels, provisionalNumLevels);
+
+ // notice that workbuf is being used as both the input and output
+ final int[] result = generalFloatsCompress(mine.getK(), mine.getM(), provisionalNumLevels,
+ workbuf, worklevels, workbuf, outlevels, mine.isLevelZeroSorted(), KllSketch.random);
+ final int targetItemCount = result[1]; //was finalCapacity. Max size given k, m, numLevels
+ final int curItemCount = result[2]; //was finalPop
+
+ // now we need to finalize the results for the "self" sketch
+
+ //THE NEW NUM LEVELS
+ myNewNumLevels = result[0]; //was finalNumLevels
+ assert myNewNumLevels <= ub; // ub may be much bigger
+
+ // THE NEW ITEMS ARRAY (was newbuf)
+ myNewFloatItemsArr = (targetItemCount == myCurFloatItemsArr.length)
+ ? myCurFloatItemsArr
+ : new float[targetItemCount];
+ final int freeSpaceAtBottom = targetItemCount - curItemCount;
+ //shift the new items array
+ System.arraycopy(workbuf, outlevels[0], myNewFloatItemsArr, freeSpaceAtBottom, curItemCount);
+ final int theShift = freeSpaceAtBottom - outlevels[0];
+
+ //calculate the new levels array length
+ final int finalLevelsArrLen;
+ if (myCurLevelsArr.length < myNewNumLevels + 1) { finalLevelsArrLen = myNewNumLevels + 1; }
+ else { finalLevelsArrLen = myCurLevelsArr.length; }
+
+ //THE NEW LEVELS ARRAY
+ myNewLevelsArr = new int[finalLevelsArrLen];
+ for (int lvl = 0; lvl < myNewNumLevels + 1; lvl++) { // includes the "extra" index
+ myNewLevelsArr[lvl] = outlevels[lvl] + theShift;
+ }
+
+ //MEMORY SPACE MANAGEMENT
+ if (mine.updatablMemory) {
+ mine.wmem = KllHelper.memorySpaceMgmt(mine, myNewLevelsArr.length, myNewFloatItemsArr.length);
+ }
+
+ } else {
+ myNewNumLevels = myCurNumLevels;
+ myNewLevelsArr = myCurLevelsArr;
+ myNewFloatItemsArr = myCurFloatItemsArr;
+ }
+
+ //Update Preamble:
+ mine.setN(finalN);
+ if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
+ mine.setMinK(min(myMinK, other.getMinK()));
+ }
+
+ //Update min, max values
+ final float otherMin = other.getMinFloatValue();
+ final float otherMax = other.getMaxFloatValue();
+ mine.setMinFloatValue(resolveFloatMinValue(myMin, otherMin));
+ mine.setMaxFloatValue(resolveFloatMaxValue(myMax, otherMax));
+
+ //Update numLevels, levelsArray, items
+ mine.setNumLevels(myNewNumLevels);
+ mine.setLevelsArray(myNewLevelsArr);
+ mine.setFloatItemsArray(myNewFloatItemsArr);
+ assert KllHelper.sumTheSampleWeights(mine.getNumLevels(), mine.getLevelsArray()) == mine.getN();
+ }
+
+ static void mergeSortedFloatArrays(
+ final float[] bufA, final int startA, final int lenA,
+ final float[] bufB, final int startB, final int lenB,
+ final float[] bufC, final int startC) {
+ final int lenC = lenA + lenB;
+ final int limA = startA + lenA;
+ final int limB = startB + lenB;
+ final int limC = startC + lenC;
+
+ int a = startA;
+ int b = startB;
+
+ for (int c = startC; c < limC; c++) {
+ if (a == limA) {
+ bufC[c] = bufB[b];
+ b++;
+ } else if (b == limB) {
+ bufC[c] = bufA[a];
+ a++;
+ } else if (bufA[a] < bufB[b]) {
+ bufC[c] = bufA[a];
+ a++;
+ } else {
+ bufC[c] = bufB[b];
+ b++;
+ }
+ }
+ assert a == limA;
+ assert b == limB;
+ }
+
+ /**
+ * Validation Method. This must be modified to test validation
+ * @param buf the items array
+ * @param start data start
+ * @param length items length
+ * @param random instance of Random
+ */
+ static void randomlyHalveDownFloats(final float[] buf, final int start, final int length, final Random random) {
+ assert isEven(length);
+ final int half_length = length / 2;
+ final int offset = random.nextInt(2); // disable for validation
+ //final int offset = deterministicOffset(); // enable for validation
+ int j = start + offset;
+ for (int i = start; i < (start + half_length); i++) {
+ buf[i] = buf[j];
+ j += 2;
+ }
+ }
+
+ /**
+ * Validation Method. This must be modified to test validation
+ * @param buf the items array
+ * @param start data start
+ * @param length items length
+ * @param random instance of Random
+ */
+ static void randomlyHalveUpFloats(final float[] buf, final int start, final int length, final Random random) {
+ assert isEven(length);
+ final int half_length = length / 2;
+ final int offset = random.nextInt(2); // disable for validation
+ //final int offset = deterministicOffset(); // enable for validation
+ int j = (start + length) - 1 - offset;
+ for (int i = (start + length) - 1; i >= (start + half_length); i--) {
+ buf[i] = buf[j];
+ j -= 2;
+ }
+ }
+
+ static void updateFloat(final KllSketch mine, final float value) {
+ if (Float.isNaN(value)) { return; }
+ if (mine.isEmpty()) {
+ mine.setMinFloatValue(value);
+ mine.setMaxFloatValue(value);
+ } else {
+ if (value < mine.getMinFloatValue()) { mine.setMinFloatValue(value); }
+ if (value > mine.getMaxFloatValue()) { mine.setMaxFloatValue(value); }
+ }
+ if (mine.getLevelsArrayAt(0) == 0) { KllHelper.compressWhileUpdatingSketch(mine); }
+ mine.incN();
+ mine.setLevelZeroSorted(false);
+ final int nextPos = mine.getLevelsArrayAt(0) - 1;
+ assert mine.getLevelsArrayAt(0) >= 0;
+ mine.setLevelsArrayAt(0, nextPos);
+ mine.setFloatItemsArrayAt(nextPos, value);
+ }
/**
* Compression algorithm used to merge higher levels.
@@ -67,7 +343,7 @@ class KllFloatsHelper {
* @param random instance of java.util.Random
* @return int array of: {numLevels, targetItemCount, currentItemCount)
*/
- static int[] generalFloatsCompress(
+ private static int[] generalFloatsCompress(
final int k,
final int m,
final int numLevelsIn,
@@ -155,69 +431,103 @@ static int[] generalFloatsCompress(
return new int[] {numLevels, targetItemCount, currentItemCount};
}
- static void mergeSortedFloatArrays(
- final float[] bufA, final int startA, final int lenA,
- final float[] bufB, final int startB, final int lenB,
- final float[] bufC, final int startC) {
- final int lenC = lenA + lenB;
- final int limA = startA + lenA;
- final int limB = startB + lenB;
- final int limC = startC + lenC;
-
- int a = startA;
- int b = startB;
+ private static KllFloatsQuantileCalculator getFloatsQuantileCalculator(final KllSketch mine) {
+ final int[] myLevelsArr = mine.getLevelsArray();
+ final float[] myFloatItemsArr = mine.getFloatItemsArray();
+ if (!mine.isLevelZeroSorted()) {
+ Arrays.sort(myFloatItemsArr, myLevelsArr[0], myLevelsArr[1]);
+ mine.setLevelZeroSorted(true);
+ }
+ return new KllFloatsQuantileCalculator(myFloatItemsArr, myLevelsArr, mine.getNumLevels(), mine.getN());
+ }
- for (int c = startC; c < limC; c++) {
- if (a == limA) {
- bufC[c] = bufB[b];
- b++;
- } else if (b == limB) {
- bufC[c] = bufA[a];
- a++;
- } else if (bufA[a] < bufB[b]) {
- bufC[c] = bufA[a];
- a++;
+ private static void incrementFloatBucketsSortedLevel(
+ final KllSketch mine, final int fromIndex, final int toIndex,
+ final int weight, final float[] splitPoints, final double[] buckets) {
+ final float[] myFloatItemsArr = mine.getFloatItemsArray();
+ int i = fromIndex;
+ int j = 0;
+ while (i < toIndex && j < splitPoints.length) {
+ if (myFloatItemsArr[i] < splitPoints[j]) {
+ buckets[j] += weight; // this sample goes into this bucket
+ i++; // move on to next sample and see whether it also goes into this bucket
} else {
- bufC[c] = bufB[b];
- b++;
+ j++; // no more samples for this bucket
}
}
- assert a == limA;
- assert b == limB;
+ // now either i == toIndex (we are out of samples), or
+ // j == numSplitPoints (we are out of buckets, but there are more samples remaining)
+ // we only need to do something in the latter case
+ if (j == splitPoints.length) {
+ buckets[j] += weight * (toIndex - i);
+ }
}
- //This must be modified for validation
- static void randomlyHalveDownFloats(final float[] buf, final int start, final int length, final Random random) {
- assert isEven(length);
- final int half_length = length / 2;
- final int offset = random.nextInt(2); // disable for validation
- //final int offset = deterministicOffset(); // enable for validation
- int j = start + offset;
- for (int i = start; i < (start + half_length); i++) {
- buf[i] = buf[j];
- j += 2;
+ private static void incrementFloatBucketsUnsortedLevel(
+ final KllSketch mine, final int fromIndex, final int toIndex,
+ final int weight, final float[] splitPoints, final double[] buckets) {
+ final float[] myFloatItemsArr = mine.getFloatItemsArray();
+ for (int i = fromIndex; i < toIndex; i++) {
+ int j;
+ for (j = 0; j < splitPoints.length; j++) {
+ if (myFloatItemsArr[i] < splitPoints[j]) {
+ break;
+ }
+ }
+ buckets[j] += weight;
}
}
- //This must be modified for validation
- static void randomlyHalveUpFloats(final float[] buf, final int start, final int length, final Random random) {
- assert isEven(length);
- final int half_length = length / 2;
- final int offset = random.nextInt(2); // disable for validation
- //final int offset = deterministicOffset(); // enable for validation
- int j = (start + length) - 1 - offset;
- for (int i = (start + length) - 1; i >= (start + half_length); i--) {
- buf[i] = buf[j];
- j -= 2;
+ private static void populateFloatWorkArrays(final KllSketch mine, final KllSketch other, final float[] workbuf,
+ final int[] worklevels, final int provisionalNumLevels) {
+ worklevels[0] = 0;
+ final int[] myLevelsArr = mine.getLevelsArray();
+ final int[] otherLevelsArr = other.getLevelsArray();
+ final float[] myFloatItemsArr = mine.getFloatItemsArray();
+ final float[] otherFloatItemsArr = other.getFloatItemsArray();
+
+ // Note: the level zero data from "other" was already inserted into "self"
+ final int selfPopZero = KllHelper.currentLevelSize(0, mine.getNumLevels(), myLevelsArr);
+ System.arraycopy( myFloatItemsArr, myLevelsArr[0], workbuf, worklevels[0], selfPopZero);
+ worklevels[1] = worklevels[0] + selfPopZero;
+
+ for (int lvl = 1; lvl < provisionalNumLevels; lvl++) {
+ final int selfPop = KllHelper.currentLevelSize(lvl, mine.getNumLevels(), myLevelsArr);
+ final int otherPop = KllHelper.currentLevelSize(lvl, other.getNumLevels(), otherLevelsArr);
+ worklevels[lvl + 1] = worklevels[lvl] + selfPop + otherPop;
+
+ if (selfPop > 0 && otherPop == 0) {
+ System.arraycopy( myFloatItemsArr, myLevelsArr[lvl], workbuf, worklevels[lvl], selfPop);
+ } else if (selfPop == 0 && otherPop > 0) {
+ System.arraycopy(otherFloatItemsArr, otherLevelsArr[lvl], workbuf, worklevels[lvl], otherPop);
+ } else if (selfPop > 0 && otherPop > 0) {
+ mergeSortedFloatArrays( myFloatItemsArr, myLevelsArr[lvl], selfPop, otherFloatItemsArr,
+ otherLevelsArr[lvl], otherPop, workbuf, worklevels[lvl]);
+ }
}
}
+ private static float resolveFloatMaxValue(final float myMax, final float otherMax) {
+ if (Float.isNaN(myMax) && Float.isNaN(otherMax)) { return Float.NaN; }
+ if (Float.isNaN(myMax)) { return otherMax; }
+ if (Float.isNaN(otherMax)) { return myMax; }
+ return max(myMax, otherMax);
+ }
+
+ private static float resolveFloatMinValue(final float myMin, final float otherMin) {
+ if (Float.isNaN(myMin) && Float.isNaN(otherMin)) { return Float.NaN; }
+ if (Float.isNaN(myMin)) { return otherMin; }
+ if (Float.isNaN(otherMin)) { return myMin; }
+ return min(myMin, otherMin);
+ }
+
/**
+ * Validation Method.
* Checks the sequential validity of the given array of float values.
* They must be unique, monotonically increasing and not NaN.
* @param values the given array of values
*/
- static void validateFloatValues(final float[] values) {
+ private static void validateFloatValues(final float[] values) {
for (int i = 0; i < values.length; i++) {
if (!Float.isFinite(values[i])) {
throw new SketchesArgumentException("Values must be finite");
@@ -230,11 +540,11 @@ static void validateFloatValues(final float[] values) {
}
/*
+ * Validation Method.
* The following must be enabled for use with the KllFloatsValidationTest,
* which is only enabled for manual testing. In addition, two methods
* above need to be modified as commented.
*/
-
// static int nextOffset = 0;
//
// private static int deterministicOffset() {
diff --git a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
index b6c1956c7..2ef1c3de4 100644
--- a/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllFloatsSketch.java
@@ -22,11 +22,9 @@
import static java.lang.Math.max;
import static java.lang.Math.min;
import static org.apache.datasketches.kll.KllSketch.Error.SRC_MUST_BE_FLOAT;
-import static org.apache.datasketches.kll.KllSketch.Error.SRC_CANNOT_BE_DIRECT;
import static org.apache.datasketches.kll.KllSketch.Error.MUST_NOT_CALL;
import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow;
-import org.apache.datasketches.SketchesArgumentException;
import org.apache.datasketches.memory.Memory;
/**
@@ -49,7 +47,7 @@ public final class KllFloatsSketch extends KllHeapSketch {
*/
private KllFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
super(memVal.k, memVal.m, SketchType.FLOATS_SKETCH);
- buildHeapKllSketchFromMemory(memVal);
+ KllHelper.buildHeapKllSketchFromMemory(this, memVal);
}
/**
@@ -57,11 +55,11 @@ private KllFloatsSketch(final Memory mem, final KllMemoryValidate memVal) {
* This will have a rank error of about 1.65%.
*/
public KllFloatsSketch() {
- this(KllSketch.DEFAULT_K);
+ this(KllSketch.DEFAULT_K, KllSketch.DEFAULT_M);
}
/**
- * Heap constructor with a given parameter k. k can be any value between DEFAULT_M and
+ * Heap constructor with a given parameter k. k can be any value between 8 and
* 65535, inclusive. The default k = 200 results in a normalized rank error of about
* 1.65%. Higher values of K will have smaller error but the sketch will be larger (and slower).
* @param k parameter that controls size of the sketch and accuracy of estimates
@@ -71,15 +69,15 @@ public KllFloatsSketch(final int k) {
}
/**
- * Heap constructor with a given parameter k and m.
- * k can be any value between DEFAULT_M and 65535, inclusive.
+ * Heap constructor with a given parameters k and m.
+ *
+ * @param k parameter that controls size of the sketch and accuracy of estimates.
+ * k can be any value between m and 65535, inclusive.
* The default k = 200 results in a normalized rank error of about 1.65%.
- * Higher values of K will have smaller error but the sketch will be larger (and slower).
- * The DEFAULT_M, which is 8 is recommended for the given parameter m.
- * Other values of m should be considered experimental as they have not been
- * as well characterized.
- * @param k parameter that controls size of the sketch and accuracy of estimates
- * @param m parameter that controls the minimum level width in items.
+ * Higher values of k will have smaller error but the sketch will be larger (and slower).
+ * @param m parameter that controls the minimum level width in items. It can be 2, 4, 6 or 8.
+ * The DEFAULT_M, which is 8 is recommended. Other values of m should be considered
+ * experimental as they have not been as well characterized.
*/
KllFloatsSketch(final int k, final int m) {
super(k, m, SketchType.FLOATS_SKETCH);
@@ -97,9 +95,7 @@ public KllFloatsSketch(final int k) {
*/
public static KllFloatsSketch heapify(final Memory mem) {
final KllMemoryValidate memVal = new KllMemoryValidate(mem);
- if (memVal.doublesSketch) {
- throw new SketchesArgumentException("Memory object is not a KllFloatsSketch.");
- }
+ if (memVal.doublesSketch) { Error.kllSketchThrow(SRC_MUST_BE_FLOAT); }
return new KllFloatsSketch(mem, memVal);
}
@@ -125,7 +121,7 @@ public static KllFloatsSketch heapify(final Memory mem) {
* in positions 0 through j of the returned PMF array.
*/
public double[] getCDF(final float[] splitPoints) {
- return getFloatsPmfOrCdf(splitPoints, true);
+ return KllFloatsHelper.getFloatsPmfOrCdf(this, splitPoints, true);
}
/**
@@ -167,7 +163,7 @@ public double[] getCDF(final float[] splitPoints) {
* splitPoint, with the exception that the last interval will include maximum value.
*/
public double[] getPMF(final float[] splitPoints) {
- return getFloatsPmfOrCdf(splitPoints, false);
+ return KllFloatsHelper.getFloatsPmfOrCdf(this, splitPoints, false);
}
/**
@@ -189,7 +185,7 @@ public double[] getPMF(final float[] splitPoints) {
* @return the approximation to the value at the given fraction
*/
public float getQuantile(final double fraction) {
- return getFloatsQuantile(fraction);
+ return KllFloatsHelper.getFloatsQuantile(this, fraction);
}
/**
@@ -222,7 +218,7 @@ public float getQuantileLowerBound(final double fraction) {
* array.
*/
public float[] getQuantiles(final double[] fractions) {
- return getFloatsQuantiles(fractions);
+ return KllFloatsHelper.getFloatsQuantiles(this, fractions);
}
/**
@@ -268,7 +264,7 @@ public float getQuantileUpperBound(final double fraction) {
* @return an approximate rank of the given value
*/
public double getRank(final float value) {
- return getFloatRank(value);
+ return KllFloatsHelper.getFloatRank(this, value);
}
/**
@@ -283,9 +279,8 @@ public KllFloatsSketchIterator iterator() {
* @param other sketch to merge into this one
*/
public void merge(final KllFloatsSketch other) {
- if (other.isDirect()) { kllSketchThrow(SRC_CANNOT_BE_DIRECT); }
if (!other.isFloatsSketch()) { kllSketchThrow(SRC_MUST_BE_FLOAT); }
- mergeFloatImpl(other);
+ KllFloatsHelper.mergeFloatImpl(this, other);
}
@Override
@@ -307,7 +302,7 @@ public void reset() {
* @param value an item from a stream of items. NaNs are ignored.
*/
public void update(final float value) {
- updateFloat(value);
+ KllFloatsHelper.updateFloat(this, value);
}
@Override //Dummy
diff --git a/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java b/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
index fcfcda642..f50cc2132 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHeapSketch.java
@@ -60,21 +60,11 @@ public int getK() {
return k;
}
- @Override
- int getM() {
- return m;
- }
-
@Override
public long getN() {
return n_;
}
- @Override
- int getMinK() {
- return minK_;
- }
-
@Override
int[] getLevelsArray() {
return levels_;
@@ -83,6 +73,16 @@ int[] getLevelsArray() {
@Override
int getLevelsArrayAt(final int index) { return levels_[index]; }
+ @Override
+ int getM() {
+ return m;
+ }
+
+ @Override
+ int getMinK() {
+ return minK_;
+ }
+
@Override
int getNumLevels() {
return numLevels_;
@@ -103,11 +103,6 @@ boolean isLevelZeroSorted() {
return isLevelZeroSorted_;
}
- @Override
- void setMinK(final int minK) {
- minK_ = minK;
- }
-
@Override
void setItemsArrayUpdatable(final WritableMemory itemsMem) { } //dummy
@@ -137,6 +132,11 @@ void setLevelZeroSorted(final boolean sorted) {
this.isLevelZeroSorted_ = sorted;
}
+ @Override
+ void setMinK(final int minK) {
+ minK_ = minK;
+ }
+
@Override
void setMinMaxArrayUpdatable(final WritableMemory minMaxMem) { } //dummy
diff --git a/src/main/java/org/apache/datasketches/kll/KllHelper.java b/src/main/java/org/apache/datasketches/kll/KllHelper.java
index 0b24fffc6..93ad2ce82 100644
--- a/src/main/java/org/apache/datasketches/kll/KllHelper.java
+++ b/src/main/java/org/apache/datasketches/kll/KllHelper.java
@@ -19,29 +19,55 @@
package org.apache.datasketches.kll;
+import static java.lang.Math.abs;
+import static java.lang.Math.ceil;
+import static java.lang.Math.exp;
+import static java.lang.Math.log;
+import static java.lang.Math.max;
+import static java.lang.Math.min;
import static java.lang.Math.pow;
+import static java.lang.Math.round;
import static org.apache.datasketches.Util.floorPowerOf2;
+import static org.apache.datasketches.Util.isOdd;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
-import static org.apache.datasketches.kll.KllSketch.CDF_COEF;
-import static org.apache.datasketches.kll.KllSketch.CDF_EXP;
-import static org.apache.datasketches.kll.KllSketch.PMF_COEF;
-import static org.apache.datasketches.kll.KllSketch.PMF_EXP;
+import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
+import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_EMPTY_SINGLE;
+import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
+import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_EMPTY_FULL;
+import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_SINGLE;
+import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryDoubleSketchFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryEmptyFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryFamilyID;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryLevelZeroSortedFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryM;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryMinK;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryN;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryNumLevels;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySingleItemFlag;
+import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryUpdatableFlag;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
+import java.util.Arrays;
+
+import org.apache.datasketches.Family;
import org.apache.datasketches.SketchesArgumentException;
+import org.apache.datasketches.Util;
import org.apache.datasketches.kll.KllSketch.SketchType;
+import org.apache.datasketches.memory.WritableMemory;
/**
- * This class provides some useful sketch analysis tools that are used internally and also can be used by
- * interested users to understand the internal structure of the sketch as well as the growth properties of the
- * sketch given a stream length.
+ * This class provides some useful sketch analysis tools that are used internally.
*
* @author lrhodes
*
*/
-public class KllHelper {
+final class KllHelper {
- public static class GrowthStats {
+ static class GrowthStats {
SketchType sketchType;
int k;
int m;
@@ -53,7 +79,7 @@ public static class GrowthStats {
int updatableBytes;
}
- public static class LevelStats {
+ static class LevelStats {
long n;
int numLevels;
int items;
@@ -65,16 +91,274 @@ public static class LevelStats {
}
}
+ static final double EPS_DELTA_THRESHOLD = 1E-6;
+ static final double MIN_EPS = 4.7634E-5;
+ static final double PMF_COEF = 2.446;
+ static final double PMF_EXP = 0.9433;
+ static final double CDF_COEF = 2.296;
+ static final double CDF_EXP = 0.9723;
+
/**
* This is the exact powers of 3 from 3^0 to 3^30 where the exponent is the index
*/
- private static final long[] powersOfThree =
+ private static long[] powersOfThree =
new long[] {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441,
1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467,
3486784401L, 10460353203L, 31381059609L, 94143178827L, 282429536481L,
847288609443L, 2541865828329L, 7625597484987L, 22876792454961L, 68630377364883L,
205891132094649L};
+ static void buildHeapKllSketchFromMemory(final KllSketch mine, final KllMemoryValidate memVal) {
+ final boolean doubleType = (mine.sketchType == DOUBLES_SKETCH);
+ mine.setLevelZeroSorted(memVal.level0Sorted);
+ mine.setN(memVal.n);
+ mine.setMinK(memVal.minK);
+ mine.setNumLevels(memVal.numLevels);
+ final int[] myLevelsArr = new int[mine.getNumLevels() + 1];
+
+ if (memVal.updatableMemory) {
+ memVal.levelsArrUpdatable.getIntArray(0, myLevelsArr, 0, mine.getNumLevels() + 1);
+ mine.setLevelsArray(myLevelsArr);
+ if (doubleType) {
+ mine.setMinDoubleValue(memVal.minMaxArrUpdatable.getDouble(0));
+ mine.setMaxDoubleValue(memVal.minMaxArrUpdatable.getDouble(Double.BYTES));
+ final int itemsCap = (int)memVal.itemsArrUpdatable.getCapacity() / Double.BYTES;
+ final double[] myItemsArr = new double[itemsCap];
+ memVal.itemsArrUpdatable.getDoubleArray(0, myItemsArr, 0, itemsCap);
+ mine.setDoubleItemsArray(myItemsArr);
+ } else { //float
+ mine.setMinFloatValue(memVal.minMaxArrUpdatable.getFloat(0));
+ mine.setMaxFloatValue(memVal.minMaxArrUpdatable.getFloat(Float.BYTES));
+ final int itemsCap = (int)memVal.itemsArrUpdatable.getCapacity() / Float.BYTES;
+ final float[] myItemsArr = new float[itemsCap];
+ memVal.itemsArrUpdatable.getFloatArray(0, myItemsArr, 0, itemsCap);
+ mine.setFloatItemsArray(myItemsArr);
+ }
+ } else { //compact
+ memVal.levelsArrCompact.getIntArray(0, myLevelsArr, 0, mine.getNumLevels() + 1);
+ mine.setLevelsArray(myLevelsArr);
+ if (doubleType) {
+ mine.setMinDoubleValue(memVal.minMaxArrCompact.getDouble(0));
+ mine.setMaxDoubleValue(memVal.minMaxArrCompact.getDouble(Double.BYTES));
+ final int itemsCap = (int)memVal.itemsArrCompact.getCapacity() / Double.BYTES;
+ final double[] myItemsArr = new double[itemsCap];
+ memVal.itemsArrCompact.getDoubleArray(0, myItemsArr, 0, itemsCap);
+ mine.setDoubleItemsArray(myItemsArr);
+ } else { //float
+ mine.setMinFloatValue(memVal.minMaxArrCompact.getFloat(0));
+ mine.setMaxFloatValue(memVal.minMaxArrCompact.getFloat(Float.BYTES));
+ final int itemsCap = (int)memVal.itemsArrCompact.getCapacity() / Float.BYTES;
+ final float[] myItemsArr = new float[itemsCap];
+ memVal.itemsArrCompact.getFloatArray(0, myItemsArr, 0, itemsCap);
+ mine.setFloatItemsArray(myItemsArr);
+ }
+ }
+ }
+
+ /**
+ * Checks the validity of the given value k
+ * @param k must be greater than 7 and less than 65536.
+ */
+ static void checkK(final int k, final int m) {
+ if (k < m || k > KllSketch.MAX_K) {
+ throw new SketchesArgumentException(
+ "K must be >= " + m + " and <= " + KllSketch.MAX_K + ": " + k);
+ }
+ }
+
+ static void checkM(final int m) {
+ if (m < KllSketch.MIN_M || m > KllSketch.MAX_M || ((m & 1) == 1)) {
+ throw new SketchesArgumentException(
+ "M must be >= 2, <= 8 and even: " + m);
+ }
+ }
+
+ /**
+ * The following code is only valid in the special case of exactly reaching capacity while updating.
+ * It cannot be used while merging, while reducing k, or anything else.
+ * @param mine the current sketch
+ */
+ static void compressWhileUpdatingSketch(final KllSketch mine) {
+ final int level =
+ findLevelToCompact(mine.getK(), mine.getM(), mine.getNumLevels(), mine.getLevelsArray());
+ if (level == mine.getNumLevels() - 1) {
+ //The level to compact is the top level, thus we need to add a level.
+ //Be aware that this operation grows the items array,
+ //shifts the items data and the level boundaries of the data,
+ //and grows the levels array and increments numLevels_.
+ KllHelper.addEmptyTopLevelToCompletelyFullSketch(mine);
+ }
+
+ final int[] myLevelsArr = mine.getLevelsArray();
+ final int rawBeg = myLevelsArr[level];
+ final int rawEnd = myLevelsArr[level + 1];
+ // +2 is OK because we already added a new top level if necessary
+ final int popAbove = myLevelsArr[level + 2] - rawEnd;
+ final int rawPop = rawEnd - rawBeg;
+ final boolean oddPop = isOdd(rawPop);
+ final int adjBeg = oddPop ? rawBeg + 1 : rawBeg;
+ final int adjPop = oddPop ? rawPop - 1 : rawPop;
+ final int halfAdjPop = adjPop / 2;
+
+ // level zero might not be sorted, so we must sort it if we wish to compact it
+ float[] myFloatItemsArr;
+ double[] myDoubleItemsArr;
+
+ if (mine.sketchType == DOUBLES_SKETCH) {
+ myFloatItemsArr = null;
+ myDoubleItemsArr = mine.getDoubleItemsArray();
+ if (level == 0) {
+ if (mine.updatablMemory) {
+ myDoubleItemsArr = mine.getDoubleItemsArray();
+ Arrays.sort(myDoubleItemsArr, adjBeg, adjBeg + adjPop);
+ mine.setDoubleItemsArray(myDoubleItemsArr);
+ } else {
+ Arrays.sort(mine.getDoubleItemsArray(), adjBeg, adjBeg + adjPop);
+ }
+ }
+ if (popAbove == 0) {
+ if (mine.updatablMemory) {
+ myDoubleItemsArr = mine.getDoubleItemsArray();
+ KllDoublesHelper.randomlyHalveUpDoubles(myDoubleItemsArr, adjBeg, adjPop, KllSketch.random);
+ mine.setDoubleItemsArray(myDoubleItemsArr);
+ } else {
+ KllDoublesHelper.randomlyHalveUpDoubles(mine.getDoubleItemsArray(), adjBeg, adjPop, KllSketch.random);
+ }
+ } else {
+ if (mine.updatablMemory) {
+ myDoubleItemsArr = mine.getDoubleItemsArray();
+ KllDoublesHelper.randomlyHalveDownDoubles(myDoubleItemsArr, adjBeg, adjPop, KllSketch.random);
+ mine.setDoubleItemsArray(myDoubleItemsArr);
+ } else {
+ KllDoublesHelper.randomlyHalveDownDoubles(mine.getDoubleItemsArray(), adjBeg, adjPop, KllSketch.random);
+ }
+ if (mine.updatablMemory ) {
+ myDoubleItemsArr = mine.getDoubleItemsArray();
+ KllDoublesHelper.mergeSortedDoubleArrays(
+ myDoubleItemsArr, adjBeg, halfAdjPop,
+ myDoubleItemsArr, rawEnd, popAbove,
+ myDoubleItemsArr, adjBeg + halfAdjPop);
+ mine.setDoubleItemsArray(myDoubleItemsArr);
+ } else {
+ myDoubleItemsArr = mine.getDoubleItemsArray();
+ KllDoublesHelper.mergeSortedDoubleArrays(
+ myDoubleItemsArr, adjBeg, halfAdjPop,
+ myDoubleItemsArr, rawEnd, popAbove,
+ myDoubleItemsArr, adjBeg + halfAdjPop);
+ }
+ }
+ } else { //Float sketch
+ myFloatItemsArr = mine.getFloatItemsArray();
+ myDoubleItemsArr = null;
+ if (level == 0) {
+ if (mine.updatablMemory) {
+ myFloatItemsArr = mine.getFloatItemsArray();
+ Arrays.sort(myFloatItemsArr, adjBeg, adjBeg + adjPop);
+ mine.setFloatItemsArray(myFloatItemsArr);
+ } else {
+ Arrays.sort(mine.getFloatItemsArray(), adjBeg, adjBeg + adjPop);
+ }
+ }
+ if (popAbove == 0) {
+ if (mine.updatablMemory) {
+ myFloatItemsArr = mine.getFloatItemsArray();
+ KllFloatsHelper.randomlyHalveUpFloats(myFloatItemsArr, adjBeg, adjPop, KllSketch.random);
+ mine.setFloatItemsArray(myFloatItemsArr);
+ } else {
+ KllFloatsHelper.randomlyHalveUpFloats(mine.getFloatItemsArray(), adjBeg, adjPop, KllSketch.random);
+ }
+ } else {
+ if (mine.updatablMemory) {
+ myFloatItemsArr = mine.getFloatItemsArray();
+ KllFloatsHelper.randomlyHalveDownFloats(myFloatItemsArr, adjBeg, adjPop, KllSketch.random);
+ mine.setFloatItemsArray(myFloatItemsArr);
+ } else {
+ KllFloatsHelper.randomlyHalveDownFloats(mine.getFloatItemsArray(), adjBeg, adjPop, KllSketch.random);
+ }
+ if (mine.updatablMemory ) {
+ myFloatItemsArr = mine.getFloatItemsArray();
+ KllFloatsHelper.mergeSortedFloatArrays(
+ myFloatItemsArr, adjBeg, halfAdjPop,
+ myFloatItemsArr, rawEnd, popAbove,
+ myFloatItemsArr, adjBeg + halfAdjPop);
+ mine.setFloatItemsArray(myFloatItemsArr);
+ } else {
+ myFloatItemsArr = mine.getFloatItemsArray();
+ KllFloatsHelper.mergeSortedFloatArrays(
+ myFloatItemsArr, adjBeg, halfAdjPop,
+ myFloatItemsArr, rawEnd, popAbove,
+ myFloatItemsArr, adjBeg + halfAdjPop);
+ }
+ }
+ }
+ mine.setLevelsArrayAtMinusEq(level + 1, halfAdjPop); // adjust boundaries of the level above
+
+ if (oddPop) {
+ mine.setLevelsArrayAt(level, mine.getLevelsArrayAt(level + 1) - 1); // the current level now contains one item
+ if (mine.sketchType == DOUBLES_SKETCH) {
+ mine.setDoubleItemsArrayAt(
+ mine.getLevelsArrayAt(level), mine.getDoubleItemsArrayAt(rawBeg)); // namely this leftover guy
+ } else {
+ mine.setFloatItemsArrayAt(
+ mine.getLevelsArrayAt(level), mine.getFloatItemsArrayAt(rawBeg)); // namely this leftover guy
+ }
+
+ } else {
+ mine.setLevelsArrayAt(level, mine.getLevelsArrayAt(level + 1)); // the current level is now empty
+ }
+
+ // verify that we freed up halfAdjPop array slots just below the current level
+ assert mine.getLevelsArrayAt(level) == rawBeg + halfAdjPop;
+
+ // finally, we need to shift up the data in the levels below
+ // so that the freed-up space can be used by level zero
+ if (level > 0) {
+ final int amount = rawBeg - mine.getLevelsArrayAt(0);
+ if (mine.sketchType == DOUBLES_SKETCH) {
+ if (mine.updatablMemory) {
+ myDoubleItemsArr = mine.getDoubleItemsArray();
+ System.arraycopy(myDoubleItemsArr, myLevelsArr[0], myDoubleItemsArr, myLevelsArr[0] + halfAdjPop, amount);
+ mine.setDoubleItemsArray(myDoubleItemsArr);
+ } else {
+ System.arraycopy(myDoubleItemsArr, myLevelsArr[0], myDoubleItemsArr, myLevelsArr[0] + halfAdjPop, amount);
+ }
+ } else {
+ if (mine.updatablMemory) {
+ myFloatItemsArr = mine.getFloatItemsArray();
+ System.arraycopy(myFloatItemsArr, myLevelsArr[0], myFloatItemsArr, myLevelsArr[0] + halfAdjPop, amount);
+ mine.setFloatItemsArray(myFloatItemsArr);
+ } else {
+ System.arraycopy(myFloatItemsArr, myLevelsArr[0], myFloatItemsArr, myLevelsArr[0] + halfAdjPop, amount);
+ }
+ }
+ for (int lvl = 0; lvl < level; lvl++) {
+ mine.setLevelsArrayAtPlusEq(lvl, halfAdjPop);
+ }
+ }
+ }
+
+ /**
+ * Returns the maximum number of items that this sketch can handle
+ * @param k The sizing / accuracy parameter of the sketch in items.
+ * Note: this method actually works for k values up to k = 2^29 and 61 levels,
+ * however only k values up to (2^16 - 1) are currently used by the sketch.
+ * @param m the size of the smallest level in items. Default is 8.
+ * @param numLevels the upper bound number of levels based on n items.
+ * @return the total item capacity of the sketch.
+ */
+ static int computeTotalItemCapacity(final int k, final int m, final int numLevels) {
+ long total = 0;
+ for (int level = 0; level < numLevels; level++) {
+ total += levelCapacity(k, numLevels, level, m);
+ }
+ return (int) total;
+ }
+
+ static int currentLevelSize(final int level, final int numLevels, final int[] levels) {
+ if (level >= numLevels) { return 0; }
+ return levels[level + 1] - levels[level];
+ }
+
/**
* Given k, m, and numLevels, this computes and optionally prints the structure of the sketch when the given
* number of levels are completely filled.
@@ -85,7 +369,7 @@ public static class LevelStats {
* @return LevelStats with the final summary of the sketch's cumulative N,
* and cumulative items at the given numLevels.
*/
- public static LevelStats getFinalSketchStatsAtNumLevels(
+ static LevelStats getFinalSketchStatsAtNumLevels(
final int k,
final int m,
final int numLevels,
@@ -120,7 +404,7 @@ public static LevelStats getFinalSketchStatsAtNumLevels(
* @param printGrowthScheme if true the entire growth scheme of the sketch will be printed.
* @return GrowthStats with the final values of the growth scheme
*/
- public static GrowthStats getGrowthSchemeForGivenN(
+ static GrowthStats getGrowthSchemeForGivenN(
final int k,
final int m,
final long n,
@@ -163,6 +447,20 @@ public static GrowthStats getGrowthSchemeForGivenN(
return gStats;
}
+ // constants were derived as the best fit to 99 percentile empirically measured max error in
+ // thousands of trials
+ static int getKFromEpsilon(final double epsilon, final boolean pmf) {
+ //Ensure that eps is >= than the lowest possible eps given MAX_K and pmf=false.
+ final double eps = max(epsilon, MIN_EPS);
+ final double kdbl = pmf
+ ? exp(log(PMF_COEF / eps) / PMF_EXP)
+ : exp(log(CDF_COEF / eps) / CDF_EXP);
+ final double krnd = round(kdbl);
+ final double del = abs(krnd - kdbl);
+ final int k = (int) (del < EPS_DELTA_THRESHOLD ? krnd : ceil(kdbl));
+ return max(KllSketch.MIN_M, min(KllSketch.MAX_K, k));
+ }
+
/**
* Given k, m, numLevels, this computes the item capacity of a single level.
* @param k the given user sketch configuration parameter
@@ -171,7 +469,7 @@ public static GrowthStats getGrowthSchemeForGivenN(
* @param level the specific level to compute its item capacity
* @return LevelStats with the computed N and items for the given level.
*/
- public static LevelStats getLevelCapacityItems(
+ static LevelStats getLevelCapacityItems(
final int k,
final int m,
final int numLevels,
@@ -181,66 +479,6 @@ public static LevelStats getLevelCapacityItems(
return new LevelStats(n, numLevels, items);
}
- /**
- * Checks the validity of the given value k
- * @param k must be greater than 7 and less than 65536.
- */
- static void checkK(final int k, final int m) {
- if (k < m || k > KllSketch.MAX_K) {
- throw new SketchesArgumentException(
- "K must be >= " + m + " and <= " + KllSketch.MAX_K + ": " + k);
- }
- }
-
- static void checkM(final int m) {
- if (m < KllSketch.MIN_M || m > KllSketch.MAX_M || ((m & 1) == 1)) {
- throw new SketchesArgumentException(
- "M must be >= 2, <= 8 and even: " + m);
- }
- }
-
- /**
- * Returns the maximum number of items that this sketch can handle
- * @param k The sizing / accuracy parameter of the sketch in items.
- * Note: this method actually works for k values up to k = 2^29 and 61 levels,
- * however only k values up to (2^16 - 1) are currently used by the sketch.
- * @param m the size of the smallest level in items. Default is 8.
- * @param numLevels the upper bound number of levels based on n items.
- * @return the total item capacity of the sketch.
- */
- static int computeTotalItemCapacity(final int k, final int m, final int numLevels) {
- long total = 0;
- for (int level = 0; level < numLevels; level++) {
- total += levelCapacity(k, numLevels, level, m);
- }
- return (int) total;
- }
-
- static int currentLevelSize(final int level, final int numLevels, final int[] levels) {
- if (level >= numLevels) { return 0; }
- return levels[level + 1] - levels[level];
- }
-
- /**
- * Finds the first level starting with level 0 that exceeds its nominal capacity
- * @param k configured size of sketch. Range [m, 2^16]
- * @param m minimum level size. Default is 8.
- * @param numLevels one-based number of current levels
- * @return level to compact
- */
- static int findLevelToCompact(final int k, final int m, final int numLevels, final int[] levels) {
- int level = 0;
- while (true) {
- assert level < numLevels;
- final int pop = levels[level + 1] - levels[level];
- final int cap = KllHelper.levelCapacity(k, numLevels, level, m);
- if (pop >= cap) {
- return level;
- }
- level++;
- }
- }
-
/**
* Gets the normalized rank error given k and pmf.
* Static method version of the getNormalizedRankError(boolean).
@@ -281,6 +519,131 @@ static int levelCapacity(final int k, final int numLevels, final int level, fina
return (int) Math.max(m, intCapAux(k, depth));
}
+ /**
+ * This method is for direct Double and Float sketches only and does the following:
+ *
+ * - Determines if the required sketch bytes will fit in the current Memory.
+ * If so, it will stretch the positioning of the arrays to fit. Otherwise:
+ *
- Allocates a new WritableMemory of the required size
+ * - Copies over the preamble as is (20 bytes)
+ * - Creates new memory regions for Levels Array, Min/Max Array, Items Array, but
+ * does not fill them. They may contain garbage.
+ *
+ * The caller is responsible for filling these regions and updating the preamble.
+ * @param sketch The current sketch that needs to be expanded.
+ * @param newLevelsArrLen the element length of the new Levels array.
+ * @param newItemsArrLen the element length of the new Items array.
+ * @return the new expanded memory with preamble.
+ */
+ static WritableMemory memorySpaceMgmt(
+ final KllSketch sketch,
+ final int newLevelsArrLen,
+ final int newItemsArrLen) {
+ final KllSketch.SketchType sketchType = sketch.sketchType;
+ final WritableMemory oldWmem = sketch.wmem;
+ final int startAdr = DATA_START_ADR;
+ final int typeBytes = (sketchType == DOUBLES_SKETCH) ? Double.BYTES : Float.BYTES;
+
+ int requiredSketchBytes = startAdr;
+ requiredSketchBytes += newLevelsArrLen * Integer.BYTES;
+ requiredSketchBytes += 2 * typeBytes;
+ requiredSketchBytes += newItemsArrLen * typeBytes;
+ final WritableMemory newWmem;
+
+ if (requiredSketchBytes > oldWmem.getCapacity()) { //Acquire new WritableMemory
+ newWmem = sketch.memReqSvr.request(oldWmem, requiredSketchBytes);
+ oldWmem.copyTo(0, newWmem, 0, startAdr); //copy preamble
+ }
+ else { //Expand or contract in current memory
+ newWmem = oldWmem;
+ }
+
+ int offset = startAdr;
+ //LEVELS ARR
+ int lengthBytes = newLevelsArrLen * Integer.BYTES;
+ sketch.setLevelsArrayUpdatable(newWmem.writableRegion(offset, lengthBytes)); //
+ offset += lengthBytes;
+ //MIN MAX ARR
+ lengthBytes = 2 * typeBytes;
+ sketch.setMinMaxArrayUpdatable(newWmem.writableRegion(offset, lengthBytes));
+ offset += lengthBytes;
+ //ITEMS ARR
+ lengthBytes = newItemsArrLen * typeBytes;
+ sketch.setItemsArrayUpdatable(newWmem.writableRegion(offset, lengthBytes));
+ assert requiredSketchBytes <= newWmem.getCapacity();
+ return newWmem;
+ }
+
+ static String outputData(final boolean doubleType, final int numLevels, final int[] levelsArr,
+ final float[] floatItemsArr, final double[] doubleItemsArr) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("### KLL items data {index, item}:").append(Util.LS);
+ if (levelsArr[0] > 0) {
+ sb.append(" Garbage:" + Util.LS);
+ if (doubleType) {
+ for (int i = 0; i < levelsArr[0]; i++) {
+ sb.append(" ").append(i + ", ").append(doubleItemsArr[i]).append(Util.LS);
+ }
+ } else {
+ for (int i = 0; i < levelsArr[0]; i++) {
+ sb.append(" ").append(i + ", ").append(floatItemsArr[i]).append(Util.LS);
+ }
+ }
+ }
+ int level = 0;
+ if (doubleType) {
+ while (level < numLevels) {
+ final int fromIndex = levelsArr[level];
+ final int toIndex = levelsArr[level + 1]; // exclusive
+ if (fromIndex < toIndex) {
+ sb.append(" level[").append(level).append("]: offset: " + levelsArr[level] + " wt: " + (1 << level));
+ sb.append(Util.LS);
+ }
+
+ for (int i = fromIndex; i < toIndex; i++) {
+ sb.append(" ").append(i + ", ").append(doubleItemsArr[i]).append(Util.LS);
+ }
+ level++;
+ }
+ }
+ else {
+ while (level < numLevels) {
+ final int fromIndex = levelsArr[level];
+ final int toIndex = levelsArr[level + 1]; // exclusive
+ if (fromIndex <= toIndex) {
+ sb.append(" level[").append(level).append("]: offset: " + levelsArr[level] + " wt: " + (1 << level));
+ sb.append(Util.LS);
+ }
+
+ for (int i = fromIndex; i < toIndex; i++) {
+ sb.append(" ").append(i + ", ").append(floatItemsArr[i]).append(Util.LS);
+ }
+ level++;
+ }
+ }
+ sb.append(" level[" + level + "]: offset: " + levelsArr[level] + " (Exclusive)");
+ sb.append(Util.LS);
+ sb.append("### End items data").append(Util.LS);
+
+ return sb.toString();
+ }
+
+ static String outputLevels(final int k, final int m, final int numLevels, final int[] levelsArr) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("### KLL levels array:").append(Util.LS)
+ .append(" level, offset: nominal capacity, actual size").append(Util.LS);
+ int level = 0;
+ for ( ; level < numLevels; level++) {
+ sb.append(" ").append(level).append(", ").append(levelsArr[level]).append(": ")
+ .append(KllHelper.levelCapacity(k, numLevels, level, m))
+ .append(", ").append(KllHelper.currentLevelSize(level, numLevels, levelsArr)).append(Util.LS);
+ }
+ sb.append(" ").append(level).append(", ").append(levelsArr[level]).append(": (Exclusive)")
+ .append(Util.LS);
+ sb.append("### End levels array").append(Util.LS);
+ return sb.toString();
+ }
+
static long sumTheSampleWeights(final int num_levels, final int[] levels) {
long total = 0;
long weight = 1;
@@ -291,6 +654,146 @@ static long sumTheSampleWeights(final int num_levels, final int[] levels) {
return total;
}
+ static byte[] toCompactByteArrayImpl(final KllSketch mine) {
+ final byte[] byteArr = new byte[mine.getCurrentCompactSerializedSizeBytes()];
+ final WritableMemory wmem = WritableMemory.writableWrap(byteArr);
+ loadFirst8Bytes(mine, wmem, false);
+ if (mine.getN() == 0) { return byteArr; } //empty
+ final boolean doubleType = (mine.sketchType == DOUBLES_SKETCH);
+
+ //load data
+ int offset = DATA_START_ADR_SINGLE_ITEM;
+ final int[] myLevelsArr = mine.getLevelsArray();
+ if (mine.getN() == 1) { //single item
+ if (doubleType) {
+ wmem.putDouble(offset, mine.getDoubleItemsArray()[myLevelsArr[0]]);
+ } else {
+ wmem.putFloat(offset, mine.getFloatItemsArray()[myLevelsArr[0]]);
+ }
+ } else { // n > 1
+ //remainder of preamble after first 8 bytes
+ setMemoryN(wmem, mine.getN());
+ setMemoryMinK(wmem, mine.getMinK());
+ setMemoryNumLevels(wmem, mine.getNumLevels());
+ offset = DATA_START_ADR;
+
+ //LOAD LEVELS ARR the last integer in levels_ is NOT serialized
+ final int len = myLevelsArr.length - 1;
+ wmem.putIntArray(offset, myLevelsArr, 0, len);
+ offset += len * Integer.BYTES;
+
+ //LOAD MIN, MAX VALUES FOLLOWED BY ITEMS ARRAY
+ if (doubleType) {
+ wmem.putDouble(offset,mine. getMinDoubleValue());
+ offset += Double.BYTES;
+ wmem.putDouble(offset, mine.getMaxDoubleValue());
+ offset += Double.BYTES;
+ wmem.putDoubleArray(offset, mine.getDoubleItemsArray(), myLevelsArr[0], mine.getNumRetained());
+ } else {
+ wmem.putFloat(offset, mine.getMinFloatValue());
+ offset += Float.BYTES;
+ wmem.putFloat(offset, mine.getMaxFloatValue());
+ offset += Float.BYTES;
+ wmem.putFloatArray(offset, mine.getFloatItemsArray(), myLevelsArr[0], mine.getNumRetained());
+ }
+ }
+ return byteArr;
+ }
+
+ @SuppressWarnings("null")
+ static String toStringImpl(final KllSketch mine, final boolean withLevels, final boolean withData) {
+ final boolean doubleType = (mine.sketchType == DOUBLES_SKETCH);
+ final int k = mine.getK();
+ final int m = mine.getM();
+ final String epsPct = String.format("%.3f%%", mine.getNormalizedRankError(false) * 100);
+ final String epsPMFPct = String.format("%.3f%%", mine.getNormalizedRankError(true) * 100);
+ final StringBuilder sb = new StringBuilder();
+ final String skType = (mine.updatablMemory ? "Direct" : "") + (doubleType ? "Doubles" : "Floats");
+ sb.append(Util.LS).append("### Kll").append(skType).append("Sketch Summary:").append(Util.LS);
+ sb.append(" K : ").append(k).append(Util.LS);
+ sb.append(" Dynamic min K : ").append(mine.getMinK()).append(Util.LS);
+ sb.append(" M : ").append(m).append(Util.LS);
+ sb.append(" N : ").append(mine.getN()).append(Util.LS);
+ sb.append(" Epsilon : ").append(epsPct).append(Util.LS);
+ sb.append(" Epsison PMF : ").append(epsPMFPct).append(Util.LS);
+ sb.append(" Empty : ").append(mine.isEmpty()).append(Util.LS);
+ sb.append(" Estimation Mode : ").append(mine.isEstimationMode()).append(Util.LS);
+ sb.append(" Levels : ").append(mine.getNumLevels()).append(Util.LS);
+ sb.append(" Level 0 Sorted : ").append(mine.isLevelZeroSorted()).append(Util.LS);
+ final int cap = (doubleType) ? mine.getDoubleItemsArray().length : mine.getFloatItemsArray().length;
+ sb.append(" Capacity Items : ").append(cap).append(Util.LS);
+ sb.append(" Retained Items : ").append(mine.getNumRetained()).append(Util.LS);
+ if (mine.updatablMemory) {
+ sb.append(" Updatable Storage Bytes: ").append(mine.getCurrentUpdatableSerializedSizeBytes()).append(Util.LS);
+ } else {
+ sb.append(" Compact Storage Bytes : ").append(mine.getCurrentCompactSerializedSizeBytes()).append(Util.LS);
+ }
+
+ if (doubleType) {
+ sb.append(" Min Value : ").append(mine.getMinDoubleValue()).append(Util.LS);
+ sb.append(" Max Value : ").append(mine.getMaxDoubleValue()).append(Util.LS);
+ } else {
+ sb.append(" Min Value : ").append(mine.getMinFloatValue()).append(Util.LS);
+ sb.append(" Max Value : ").append(mine.getMaxFloatValue()).append(Util.LS);
+ }
+ sb.append("### End sketch summary").append(Util.LS);
+
+ final int myNumLevels = mine.getNumLevels();
+ final int[] myLevelsArr = mine.getLevelsArray();
+ double[] myDoubleItemsArr = null;
+ float[] myFloatItemsArr = null;
+ if (doubleType) {
+ myDoubleItemsArr = mine.getDoubleItemsArray();
+ } else {
+ myFloatItemsArr = mine.getFloatItemsArray();
+ }
+ if (withLevels) {
+ sb.append(outputLevels(k, m, myNumLevels, myLevelsArr));
+ }
+ if (withData) {
+ sb.append(outputData(doubleType, myNumLevels, myLevelsArr, myFloatItemsArr, myDoubleItemsArr));
+ }
+ return sb.toString();
+ }
+
+ static byte[] toUpdatableByteArrayImpl(final KllSketch mine) {
+ final byte[] byteArr = new byte[mine.getCurrentUpdatableSerializedSizeBytes()];
+ final WritableMemory wmem = WritableMemory.writableWrap(byteArr);
+ loadFirst8Bytes(mine, wmem, true);
+ //remainder of preamble after first 8 bytes
+ setMemoryN(wmem, mine.getN());
+ setMemoryMinK(wmem, mine.getMinK());
+ setMemoryNumLevels(wmem, mine.getNumLevels());
+
+ //load data
+ final boolean doubleType = (mine.sketchType == DOUBLES_SKETCH);
+ int offset = DATA_START_ADR;
+
+ //LOAD LEVELS ARRAY the last integer in levels_ IS serialized
+ final int[] myLevelsArr = mine.getLevelsArray();
+ final int len = myLevelsArr.length;
+ wmem.putIntArray(offset, myLevelsArr, 0, len);
+ offset += len * Integer.BYTES;
+
+ //LOAD MIN, MAX VALUES FOLLOWED BY ITEMS ARRAY
+ if (doubleType) {
+ wmem.putDouble(offset, mine.getMinDoubleValue());
+ offset += Double.BYTES;
+ wmem.putDouble(offset, mine.getMaxDoubleValue());
+ offset += Double.BYTES;
+ final double[] doubleItemsArr = mine.getDoubleItemsArray();
+ wmem.putDoubleArray(offset, doubleItemsArr, 0, doubleItemsArr.length);
+ } else {
+ wmem.putFloat(offset, mine.getMinFloatValue());
+ offset += Float.BYTES;
+ wmem.putFloat(offset,mine.getMaxFloatValue());
+ offset += Float.BYTES;
+ final float[] floatItemsArr = mine.getFloatItemsArray();
+ wmem.putFloatArray(offset, floatItemsArr, 0, floatItemsArr.length);
+ }
+ return byteArr;
+ }
+
/**
* Returns very conservative upper bound of the number of levels based on n.
* @param n the length of the stream
@@ -300,6 +803,118 @@ static int ubOnNumLevels(final long n) {
return 1 + Long.numberOfTrailingZeros(floorPowerOf2(n));
}
+ /**
+ * This grows the levels arr by 1 (if needed) and increases the capacity of the items array
+ * at the bottom. Only numLevels, the levels array and the items array are affected.
+ * @param mine the current sketch
+ */
+ @SuppressWarnings("null")
+ private static void addEmptyTopLevelToCompletelyFullSketch(final KllSketch mine) {
+ final int[] myCurLevelsArr = mine.getLevelsArray();
+ final int myCurNumLevels = mine.getNumLevels();
+ final int myCurTotalItemsCapacity = myCurLevelsArr[myCurNumLevels];
+ double minDouble = Double.NaN;
+ double maxDouble = Double.NaN;
+ float minFloat = Float.NaN;
+ float maxFloat = Float.NaN;
+
+ double[] myCurDoubleItemsArr = null;
+ float[] myCurFloatItemsArr = null;
+
+ final int myNewNumLevels;
+ final int[] myNewLevelsArr;
+ final int myNewTotalItemsCapacity;
+
+ float[] myNewFloatItemsArr = null;
+ double[] myNewDoubleItemsArr = null;
+
+ if (mine.sketchType == DOUBLES_SKETCH) {
+ minDouble = mine.getMinDoubleValue();
+ maxDouble = mine.getMaxDoubleValue();
+ myCurDoubleItemsArr = mine.getDoubleItemsArray();
+ //assert we are following a certain growth scheme
+ assert myCurDoubleItemsArr.length == myCurTotalItemsCapacity;
+ } else { //FLOATS_SKETCH
+ minFloat = mine.getMinFloatValue();
+ maxFloat = mine.getMaxFloatValue();
+ myCurFloatItemsArr = mine.getFloatItemsArray();
+ assert myCurFloatItemsArr.length == myCurTotalItemsCapacity;
+ }
+ assert myCurLevelsArr[0] == 0; //definition of full is part of the growth scheme
+
+ final int deltaItemsCap = levelCapacity(mine.getK(), myCurNumLevels + 1, 0, mine.getM());
+ myNewTotalItemsCapacity = myCurTotalItemsCapacity + deltaItemsCap;
+
+ // Check if growing the levels arr if required.
+ // Note that merging MIGHT over-grow levels_, in which case we might not have to grow it
+ final boolean growLevelsArr = myCurLevelsArr.length < myCurNumLevels + 2;
+
+ // GROW LEVELS ARRAY
+ if (growLevelsArr) {
+ //grow levels arr by one and copy the old data to the new array, extra space at the top.
+ myNewLevelsArr = Arrays.copyOf(myCurLevelsArr, myCurNumLevels + 2);
+ assert myNewLevelsArr.length == myCurLevelsArr.length + 1;
+ myNewNumLevels = myCurNumLevels + 1;
+ mine.incNumLevels(); //increment the class member
+ } else {
+ myNewLevelsArr = myCurLevelsArr;
+ myNewNumLevels = myCurNumLevels;
+ }
+ // This loop updates all level indices EXCLUDING the "extra" index at the top
+ for (int level = 0; level <= myNewNumLevels - 1; level++) {
+ myNewLevelsArr[level] += deltaItemsCap;
+ }
+ myNewLevelsArr[myNewNumLevels] = myNewTotalItemsCapacity; // initialize the new "extra" index at the top
+
+ // GROW ITEMS ARRAY
+ if (mine.sketchType == DOUBLES_SKETCH) {
+ myNewDoubleItemsArr = new double[myNewTotalItemsCapacity];
+ // copy and shift the current data into the new array
+ System.arraycopy(myCurDoubleItemsArr, 0, myNewDoubleItemsArr, deltaItemsCap, myCurTotalItemsCapacity);
+ } else {
+ myNewFloatItemsArr = new float[myNewTotalItemsCapacity];
+ // copy and shift the current items data into the new array
+ System.arraycopy(myCurFloatItemsArr, 0, myNewFloatItemsArr, deltaItemsCap, myCurTotalItemsCapacity);
+ }
+
+ //MEMORY SPACE MANAGEMENT
+ if (mine.updatablMemory) {
+ mine.wmem = memorySpaceMgmt(mine, myNewLevelsArr.length, myNewTotalItemsCapacity);
+ }
+ //update our sketch with new expanded spaces
+ mine.setNumLevels(myNewNumLevels);
+ mine.setLevelsArray(myNewLevelsArr);
+ if (mine.sketchType == DOUBLES_SKETCH) {
+ mine.setMinDoubleValue(minDouble);
+ mine.setMaxDoubleValue(maxDouble);
+ mine.setDoubleItemsArray(myNewDoubleItemsArr);
+ } else { //Float sketch
+ mine.setMinFloatValue(minFloat);
+ mine.setMaxFloatValue(maxFloat);
+ mine.setFloatItemsArray(myNewFloatItemsArr);
+ }
+ }
+
+ /**
+ * Finds the first level starting with level 0 that exceeds its nominal capacity
+ * @param k configured size of sketch. Range [m, 2^16]
+ * @param m minimum level size. Default is 8.
+ * @param numLevels one-based number of current levels
+ * @return level to compact
+ */
+ private static int findLevelToCompact(final int k, final int m, final int numLevels, final int[] levels) {
+ int level = 0;
+ while (true) {
+ assert level < numLevels;
+ final int pop = levels[level + 1] - levels[level];
+ final int cap = KllHelper.levelCapacity(k, numLevels, level, m);
+ if (pop >= cap) {
+ return level;
+ }
+ level++;
+ }
+ }
+
/**
* Computes the actual item capacity of a given level given its depth index.
* If the depth of levels exceeds 30, this uses a folding technique to accurately compute the
@@ -331,6 +946,30 @@ private static long intCapAuxAux(final long k, final int depth) {
return result;
}
+ private static void loadFirst8Bytes(final KllSketch sk, final WritableMemory wmem,
+ final boolean updatable) {
+ final boolean empty = sk.getN() == 0;
+ final boolean lvlZeroSorted = sk.isLevelZeroSorted();
+ final boolean singleItem = sk.getN() == 1;
+ final boolean doubleType = (sk.sketchType == DOUBLES_SKETCH);
+ final int preInts = updatable
+ ? PREAMBLE_INTS_FULL
+ : (empty || singleItem) ? PREAMBLE_INTS_EMPTY_SINGLE : PREAMBLE_INTS_FULL;
+ //load the preamble
+ setMemoryPreInts(wmem, preInts);
+ final int server = updatable ? SERIAL_VERSION_UPDATABLE
+ : (singleItem ? SERIAL_VERSION_SINGLE : SERIAL_VERSION_EMPTY_FULL);
+ setMemorySerVer(wmem, server);
+ setMemoryFamilyID(wmem, Family.KLL.getID());
+ setMemoryEmptyFlag(wmem, empty);
+ setMemoryLevelZeroSortedFlag(wmem, lvlZeroSorted);
+ setMemorySingleItemFlag(wmem, singleItem);
+ setMemoryDoubleSketchFlag(wmem, doubleType);
+ setMemoryUpdatableFlag(wmem, updatable);
+ setMemoryK(wmem, sk.getK());
+ setMemoryM(wmem, sk.getM());
+ }
+
/**
* @param fmt format
* @param args arguments
@@ -346,5 +985,5 @@ private static void printf(final String fmt, final Object ... args) {
private static void println(final Object o) {
System.out.println(o.toString());
}
-}
+}
diff --git a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
index 187866dfe..e64a4a1c0 100644
--- a/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
+++ b/src/main/java/org/apache/datasketches/kll/KllMemoryValidate.java
@@ -75,7 +75,7 @@ final class KllMemoryValidate {
boolean singleItem;
final boolean level0Sorted;
final boolean doublesSketch;
- final boolean updatable;
+ final boolean updatableMemory;
final int k;
final int m;
final int memCapacity;
@@ -112,14 +112,14 @@ final class KllMemoryValidate {
level0Sorted = getMemoryLevelZeroSortedFlag(srcMem);
singleItem = getMemorySingleItemFlag(srcMem);
doublesSketch = getMemoryDoubleSketchFlag(srcMem);
- updatable = getMemoryUpdatableFlag(srcMem);
+ updatableMemory = getMemoryUpdatableFlag(srcMem);
k = getMemoryK(srcMem);
m = getMemoryM(srcMem);
KllHelper.checkM(m);
KllHelper.checkK(k, m);
- if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatable) { memoryValidateThrow(UPDATABLEBIT_AND_SER_VER, 1); }
+ if ((serVer == SERIAL_VERSION_UPDATABLE) ^ updatableMemory) { memoryValidateThrow(UPDATABLEBIT_AND_SER_VER, 1); }
- if (updatable) { updatableMemoryValidate((WritableMemory) srcMem); }
+ if (updatableMemory) { updatableMemoryValidate((WritableMemory) srcMem); }
else { compactMemoryValidate(srcMem); }
}
diff --git a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
index 548bd045e..0c5f7d273 100644
--- a/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
@@ -205,7 +205,7 @@ static String memoryToString(final Memory mem) {
sb.append(" 1 LEVEL_ZERO_SORTED : ").append(memChk.level0Sorted).append(LS);
sb.append(" 2 SINGLE_ITEM COMPACT: ").append(memChk.singleItem).append(LS);
sb.append(" 3 DOUBLES_SKETCH : ").append(memChk.doublesSketch).append(LS);
- sb.append(" 4 UPDATABLE : ").append(memChk.updatable).append(LS);
+ sb.append(" 4 UPDATABLE : ").append(memChk.updatableMemory).append(LS);
sb.append("Bytes 4-5 : K : ").append(memChk.k).append(LS);
sb.append("Byte 6 : Min Level Cap, M : ").append(memChk.m).append(LS);
sb.append("Byte 7 : (Reserved) : ").append(LS);
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index b366e38b1..804148d47 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -19,44 +19,15 @@
package org.apache.datasketches.kll;
-import static java.lang.Math.abs;
-import static java.lang.Math.ceil;
-import static java.lang.Math.exp;
-import static java.lang.Math.log;
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-import static java.lang.Math.round;
-import static org.apache.datasketches.Util.isOdd;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR;
import static org.apache.datasketches.kll.KllPreambleUtil.DATA_START_ADR_SINGLE_ITEM;
import static org.apache.datasketches.kll.KllPreambleUtil.N_LONG_ADR;
-import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_EMPTY_SINGLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.PREAMBLE_INTS_FULL;
-import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_EMPTY_FULL;
-import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_SINGLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.SERIAL_VERSION_UPDATABLE;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryDoubleSketchFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryMinK;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryEmptyFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryFamilyID;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryK;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryLevelZeroSortedFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryM;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryN;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryNumLevels;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryPreInts;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySerVer;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemorySingleItemFlag;
-import static org.apache.datasketches.kll.KllPreambleUtil.setMemoryUpdatableFlag;
import static org.apache.datasketches.kll.KllSketch.SketchType.DOUBLES_SKETCH;
import static org.apache.datasketches.kll.KllSketch.SketchType.FLOATS_SKETCH;
-import java.util.Arrays;
import java.util.Random;
-import org.apache.datasketches.Family;
import org.apache.datasketches.SketchesArgumentException;
-import org.apache.datasketches.Util;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
@@ -92,48 +63,70 @@
* @author Lee Rhodes, Kevin Lang
*/
public abstract class KllSketch {
- static final double EPS_DELTA_THRESHOLD = 1E-6;
- static final double MIN_EPS = 4.7634E-5;
- static final double PMF_COEF = 2.446;
- static final double PMF_EXP = 0.9433;
- static final double CDF_COEF = 2.296;
- static final double CDF_EXP = 0.9723;
- static final Random random = new Random();
- SketchType sketchType;
- WritableMemory wmem;
- MemoryRequestServer memReqSvr;
- boolean direct;
+
+ public enum SketchType { FLOATS_SKETCH, DOUBLES_SKETCH }
+
+ enum Error {
+ TGT_IS_IMMUTABLE("Given sketch Memory is immutable, cannot write."),
+ SRC_MUST_BE_DIRECT("Given sketch must be of type Direct."),
+ SRC_MUST_BE_DOUBLE("Given sketch must be of type Double."),
+ SRC_MUST_BE_FLOAT("Given sketch must be of type Float."),
+ SRC_CANNOT_BE_DIRECT("Given sketch cannot be of type Direct."),
+ MUST_NOT_CALL("This is an artifact of inheritance and should never be called.");
+
+ private String msg;
+
+ private Error(final String msg) {
+ this.msg = msg;
+ }
+
+ final static void kllSketchThrow(final Error errType) {
+ throw new SketchesArgumentException(errType.getMessage());
+ }
+
+ private String getMessage() {
+ return msg;
+ }
+ }
/**
* The default value of K
*/
public static final int DEFAULT_K = 200;
+ /**
+ * The maximum value of K
+ */
+ public static final int MAX_K = (1 << 16) - 1; // serialized as an unsigned short
+
/**
* The default value of M. The parameter m is the minimum level size in number of items.
* Currently, the public default is 8, but this can be overridden using Package Private methods to
* 2, 4, 6 or 8, and the sketch works just fine. The value 8 was chosen as a compromise between speed and size.
- * Choosing smaller values of m less than 8 will make the sketch much slower.
+ * Choosing smaller values of m less than 8 will make the sketch slower.
*/
static final int DEFAULT_M = 8;
/**
- * The maximum value of K
- */
- public static final int MAX_K = (1 << 16) - 1; // serialized as an unsigned short
-
- /**
- * The maximum value of M. See the Javadoc on DEFAULT_M.
+ * The maximum value of M.
+ * @see #DEFAULT_M
*/
static final int MAX_M = 8;
/**
- * The minimum value of M. See the Javadoc on DEFAULT_M.
+ * The minimum value of M.
+ * @see #DEFAULT_M
*/
static final int MIN_M = 2;
+ static final Random random = new Random();
+ final SketchType sketchType;
+ final MemoryRequestServer memReqSvr;
+ final boolean updatablMemory;
+ WritableMemory wmem;
+
/**
- *
+ * Constructor
* @param sketchType either DOUBLE_SKETCH or FLOAT_SKETCH
* @param wmem the current WritableMemory or null
* @param memReqSvr the given MemoryRequestServer to request a larger WritableMemory
@@ -142,18 +135,14 @@ public abstract class KllSketch {
this.sketchType = sketchType;
this.wmem = wmem;
if (wmem != null) {
- this.direct = true;
+ this.updatablMemory = memReqSvr != null;
this.memReqSvr = memReqSvr;
} else {
- this.direct = false;
+ this.updatablMemory = false;
this.memReqSvr = null;
}
}
-public enum SketchType { FLOATS_SKETCH, DOUBLES_SKETCH }
-
- //Static methods
-
/**
* Gets the approximate value of k to use given epsilon, the normalized rank error.
* @param epsilon the normalized rank error between zero and one.
@@ -166,18 +155,8 @@ public enum SketchType { FLOATS_SKETCH, DOUBLES_SKETCH }
* {@link org.apache.datasketches.kll}
* @return the value of k given a value of epsilon.
*/
- // constants were derived as the best fit to 99 percentile empirically measured max error in
- // thousands of trials
public static int getKFromEpsilon(final double epsilon, final boolean pmf) {
- //Ensure that eps is >= than the lowest possible eps given MAX_K and pmf=false.
- final double eps = max(epsilon, MIN_EPS);
- final double kdbl = pmf
- ? exp(log(PMF_COEF / eps) / PMF_EXP)
- : exp(log(CDF_COEF / eps) / CDF_EXP);
- final double krnd = round(kdbl);
- final double del = abs(krnd - kdbl);
- final int k = (int) (del < EPS_DELTA_THRESHOLD ? krnd : ceil(kdbl));
- return max(KllSketch.MIN_M, min(KllSketch.MAX_K, k));
+ return KllHelper.getKFromEpsilon(epsilon, pmf);
}
/**
@@ -202,14 +181,14 @@ public static int getMaxSerializedSizeBytes(final int k, final long n) {
* @param k parameter that controls size of the sketch and accuracy of estimates
* @param n stream length
* @param sketchType either DOUBLES_SKETCH or FLOATS_SKETCH
- * @param updatable true if updatable form, otherwise the standard compact form.
+ * @param updatableMemory true if updatableMemory form, otherwise the standard compact form.
* @return upper bound on the serialized size of a KllSketch.
*/
public static int getMaxSerializedSizeBytes(final int k, final long n,
- final SketchType sketchType, final boolean updatable) {
+ final SketchType sketchType, final boolean updatableMemory) {
final KllHelper.GrowthStats gStats =
KllHelper.getGrowthSchemeForGivenN(k, KllSketch.DEFAULT_M, n, sketchType, false);
- return updatable ? gStats.updatableBytes : gStats.compactBytes;
+ return updatableMemory ? gStats.updatableBytes : gStats.compactBytes;
}
/**
@@ -225,22 +204,12 @@ public static double getNormalizedRankError(final int k, final boolean pmf) {
return KllHelper.getNormalizedRankError(k, pmf);
}
- /**
- * Returns the current number of bytes this Sketch would require if serialized.
- * @return the number of bytes this sketch would require if serialized.
- */
- public int getSerializedSizeBytes() {
- return (direct)
- ? getCurrentUpdatableSerializedSizeBytes()
- : getCurrentCompactSerializedSizeBytes();
- }
-
//numItems can be either numRetained, or current max capacity at given K and numLevels.
static int getCurrentSerializedSizeBytes(final int numLevels, final int numItems,
- final SketchType sketchType, final boolean updatable) {
+ final SketchType sketchType, final boolean updatableMemory) {
final int typeBytes = (sketchType == DOUBLES_SKETCH) ? Double.BYTES : Float.BYTES;
int levelsBytes = 0;
- if (updatable) {
+ if (updatableMemory) {
levelsBytes = (numLevels + 1) * Integer.BYTES;
} else {
if (numItems == 0) { return N_LONG_ADR; }
@@ -250,31 +219,6 @@ static int getCurrentSerializedSizeBytes(final int numLevels, final int numItems
return DATA_START_ADR + levelsBytes + (numItems + 2) * typeBytes; //+2 is for min & max
}
- enum Error {
- TGT_IS_IMMUTABLE("Given sketch Memory is immutable, cannot write."),
- SRC_MUST_BE_DIRECT("Given sketch must be of type Direct."),
- SRC_MUST_BE_DOUBLE("Given sketch must be of type Double."),
- SRC_MUST_BE_FLOAT("Given sketch must be of type Float."),
- SRC_CANNOT_BE_DIRECT("Given sketch cannot be of type Direct."),
- MUST_NOT_CALL("This is an artifact of inheritance and should never be called.");
-
- private String msg;
-
- private Error(final String msg) {
- this.msg = msg;
- }
-
- private String getMessage() {
- return msg;
- }
-
- final static void kllSketchThrow(final Error errType) {
- throw new SketchesArgumentException(errType.getMessage());
- }
- }
-
- //Public Non-static methods
-
/**
* Returns the current compact number of bytes this sketch would require to store.
* @return the current compact number of bytes this sketch would require to store.
@@ -284,8 +228,8 @@ public final int getCurrentCompactSerializedSizeBytes() {
}
/**
- * Returns the current updatable number of bytes this sketch would require to store.
- * @return the current updatable number of bytes this sketch would require to store.
+ * Returns the current updatableMemory number of bytes this sketch would require to store.
+ * @return the current updatableMemory number of bytes this sketch would require to store.
*/
public final int getCurrentUpdatableSerializedSizeBytes() {
final int itemCap = KllHelper.computeTotalItemCapacity(getK(), getM(), getNumLevels());
@@ -298,15 +242,6 @@ public final int getCurrentUpdatableSerializedSizeBytes() {
*/
public abstract int getK();
- /**
- * Returns the configured parameter m, which is the minimum level size in number of items.
- * Currently, the public default is 8, but this can be overridden using Package Private methods to
- * 2, 4, 6 or 8, and the sketch works just fine. The value 8 was chosen as a compromise between speed and size.
- * Choosing smaller values of m will make the sketch much slower.
- * @return the configured parameter m
- */
- abstract int getM();
-
/**
* Returns the length of the input stream in items.
* @return stream length
@@ -337,6 +272,16 @@ public final int getNumRetained() {
return getLevelsArray()[getNumLevels()] - getLevelsArray()[0];
}
+ /**
+ * Returns the current number of bytes this Sketch would require if serialized.
+ * @return the number of bytes this sketch would require if serialized.
+ */
+ public int getSerializedSizeBytes() {
+ return (updatablMemory)
+ ? getCurrentUpdatableSerializedSizeBytes()
+ : getCurrentCompactSerializedSizeBytes();
+ }
+
/**
* This returns the WritableMemory for Direct type sketches,
* otherwise returns null.
@@ -346,10 +291,6 @@ public WritableMemory getWritableMemory() {
return wmem;
}
- public final boolean isDirect() {
- return direct;
- }
-
/**
* Returns true if this sketch is empty.
* @return empty flag
@@ -366,6 +307,10 @@ public final boolean isEstimationMode() {
return getNumLevels() > 1;
}
+ public final boolean isUpdatableMemory() {
+ return updatablMemory;
+ }
+
/**
* This resets the current sketch back to zero entries.
* It retains key parameters such as k and
@@ -378,7 +323,7 @@ public final boolean isEstimationMode() {
* @return serialized sketch in a compact byte array form.
*/
public byte[] toByteArray() {
- return toCompactByteArrayImpl();
+ return KllHelper.toCompactByteArrayImpl(this);
}
@Override
@@ -393,273 +338,44 @@ public final String toString() {
* @return string representation of sketch summary
*/
public String toString(final boolean withLevels, final boolean withData) {
- return toStringImpl(withLevels, withData);
+ return KllHelper.toStringImpl(this, withLevels, withData);
}
/**
- * Returns serialized sketch in an updatable byte array form.
- * @return serialized sketch in an updatable byte array form.
+ * Returns serialized sketch in an updatableMemory byte array form.
+ * @return serialized sketch in an updatableMemory byte array form.
*/
public byte[] toUpdatableByteArray() {
- return toUpdatableByteArrayImpl();
- }
-
- //package-private non-static methods
-
- final void buildHeapKllSketchFromMemory(final KllMemoryValidate memVal) {
- final boolean doubleType = (sketchType == DOUBLES_SKETCH);
- final boolean updatable = memVal.updatable;
- setLevelZeroSorted(memVal.level0Sorted);
- setN(memVal.n);
- setMinK(memVal.minK);
- setNumLevels(memVal.numLevels);
- final int[] myLevelsArr = new int[getNumLevels() + 1];
-
- if (updatable) {
- memVal.levelsArrUpdatable.getIntArray(0, myLevelsArr, 0, getNumLevels() + 1);
- setLevelsArray(myLevelsArr);
- if (doubleType) {
- setMinDoubleValue(memVal.minMaxArrUpdatable.getDouble(0));
- setMaxDoubleValue(memVal.minMaxArrUpdatable.getDouble(Double.BYTES));
- final int itemsCap = (int)memVal.itemsArrUpdatable.getCapacity() / Double.BYTES;
- final double[] myItemsArr = new double[itemsCap];
- memVal.itemsArrUpdatable.getDoubleArray(0, myItemsArr, 0, itemsCap);
- setDoubleItemsArray(myItemsArr);
- } else { //float
- setMinFloatValue(memVal.minMaxArrUpdatable.getFloat(0));
- setMaxFloatValue(memVal.minMaxArrUpdatable.getFloat(Float.BYTES));
- final int itemsCap = (int)memVal.itemsArrUpdatable.getCapacity() / Float.BYTES;
- final float[] myItemsArr = new float[itemsCap];
- memVal.itemsArrUpdatable.getFloatArray(0, myItemsArr, 0, itemsCap);
- setFloatItemsArray(myItemsArr);
- }
- } else { //compact
- memVal.levelsArrCompact.getIntArray(0, myLevelsArr, 0, getNumLevels() + 1);
- setLevelsArray(myLevelsArr);
- if (doubleType) {
- setMinDoubleValue(memVal.minMaxArrCompact.getDouble(0));
- setMaxDoubleValue(memVal.minMaxArrCompact.getDouble(Double.BYTES));
- final int itemsCap = (int)memVal.itemsArrCompact.getCapacity() / Double.BYTES;
- final double[] myItemsArr = new double[itemsCap];
- memVal.itemsArrCompact.getDoubleArray(0, myItemsArr, 0, itemsCap);
- setDoubleItemsArray(myItemsArr);
- } else { //float
- setMinFloatValue(memVal.minMaxArrCompact.getFloat(0));
- setMaxFloatValue(memVal.minMaxArrCompact.getFloat(Float.BYTES));
- final int itemsCap = (int)memVal.itemsArrCompact.getCapacity() / Float.BYTES;
- final float[] myItemsArr = new float[itemsCap];
- memVal.itemsArrCompact.getFloatArray(0, myItemsArr, 0, itemsCap);
- setFloatItemsArray(myItemsArr);
- }
- }
+ return KllHelper.toUpdatableByteArrayImpl(this);
}
/**
- * @return full size of internal items array including garbage; for a floats sketch this will be null.
+ * @return full size of internal items array including garbage.
*/
abstract double[] getDoubleItemsArray();
- final double getDoubleRank(final double value) {
- if (isEmpty()) { return Double.NaN; }
- int level = 0;
- int weight = 1;
- long total = 0;
- final double[] myDoubleItemsArr = getDoubleItemsArray();
- final int[] myLevelsArr = getLevelsArray();
- while (level < getNumLevels()) {
- final int fromIndex = myLevelsArr[level];
- final int toIndex = myLevelsArr[level + 1]; // exclusive
- for (int i = fromIndex; i < toIndex; i++) {
- if (myDoubleItemsArr[i] < value) {
- total += weight;
- } else if (level > 0 || isLevelZeroSorted()) {
- break; // levels above 0 are sorted, no point comparing further
- }
- }
- level++;
- weight *= 2;
- }
- return (double) total / getN();
- }
-
- final double[] getDoublesPmfOrCdf(final double[] splitPoints, final boolean isCdf) {
- if (isEmpty()) { return null; }
- KllDoublesHelper.validateDoubleValues(splitPoints);
- final double[] buckets = new double[splitPoints.length + 1];
- final int myNumLevels = getNumLevels();
- final int[] myLevelsArr = getLevelsArray();
- int level = 0;
- int weight = 1;
- while (level < myNumLevels) {
- final int fromIndex = myLevelsArr[level];
- final int toIndex = myLevelsArr[level + 1]; // exclusive
- if (level == 0 && !isLevelZeroSorted()) {
- incrementDoublesBucketsUnsortedLevel(fromIndex, toIndex, weight, splitPoints, buckets);
- } else {
- incrementDoublesBucketsSortedLevel(fromIndex, toIndex, weight, splitPoints, buckets);
- }
- level++;
- weight *= 2;
- }
- // normalize and, if CDF, convert to cumulative
- if (isCdf) {
- double subtotal = 0;
- for (int i = 0; i < buckets.length; i++) {
- subtotal += buckets[i];
- buckets[i] = subtotal / getN();
- }
- } else {
- for (int i = 0; i < buckets.length; i++) {
- buckets[i] /= getN();
- }
- }
- return buckets;
- }
-
- final double getDoublesQuantile(final double fraction) {
- if (isEmpty()) { return Double.NaN; }
- if (fraction < 0.0 || fraction > 1.0) {
- throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
- }
- //These two assumptions make KLL compatible with the previous classic Quantiles Sketch
- if (fraction == 0.0) { return getMinDoubleValue(); }
- if (fraction == 1.0) { return getMaxDoubleValue(); }
- final KllDoublesQuantileCalculator quant = getDoublesQuantileCalculator();
- return quant.getQuantile(fraction);
- }
-
- final double[] getDoublesQuantiles(final double[] fractions) {
- if (isEmpty()) { return null; }
- KllDoublesQuantileCalculator quant = null;
- final double[] quantiles = new double[fractions.length];
- for (int i = 0; i < fractions.length; i++) {
- final double fraction = fractions[i];
- if (fraction < 0.0 || fraction > 1.0) {
- throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
- }
- if (fraction == 0.0) { quantiles[i] = getMinDoubleValue(); }
- else if (fraction == 1.0) { quantiles[i] = getMaxDoubleValue(); }
- else {
- if (quant == null) {
- quant = getDoublesQuantileCalculator();
- }
- quantiles[i] = quant.getQuantile(fraction);
- }
- }
- return quantiles;
- }
-
- /**
- * MinK is the value of K that results from a merge with a sketch configured with a value of K lower than
- * the k of this sketch. This value is then used in computing the estimated upper and lower bounds of error.
- * @return The minimum K as a result of merging with lower values of k.
- */
- abstract int getMinK();
+ abstract double getDoubleItemsArrayAt(int index);
/**
- * @return full size of internal items array including garbage; for a doubles sketch this will be null.
+ * @return full size of internal items array including garbage.
*/
abstract float[] getFloatItemsArray();
- final double getFloatRank(final float value) {
- if (isEmpty()) { return Double.NaN; }
- int level = 0;
- int weight = 1;
- long total = 0;
- final float[] myFloatItemsArr = getFloatItemsArray();
- final int[] myLevelsArr = getLevelsArray();
- while (level < getNumLevels()) {
- final int fromIndex = myLevelsArr[level];
- final int toIndex = myLevelsArr[level + 1]; // exclusive
- for (int i = fromIndex; i < toIndex; i++) {
- if (myFloatItemsArr[i] < value) {
- total += weight;
- } else if (level > 0 || isLevelZeroSorted()) {
- break; // levels above 0 are sorted, no point comparing further
- }
- }
- level++;
- weight *= 2;
- }
- return (double) total / getN();
- }
-
- final double[] getFloatsPmfOrCdf(final float[] splitPoints, final boolean isCdf) {
- if (isEmpty()) { return null; }
- KllFloatsHelper.validateFloatValues(splitPoints);
- final double[] buckets = new double[splitPoints.length + 1];
- final int myNumLevels = getNumLevels();
- final int[] myLevelsArr = getLevelsArray();
- int level = 0;
- int weight = 1;
- while (level < myNumLevels) {
- final int fromIndex = myLevelsArr[level];
- final int toIndex = myLevelsArr[level + 1]; // exclusive
- if (level == 0 && !isLevelZeroSorted()) {
- incrementFloatBucketsUnsortedLevel(fromIndex, toIndex, weight, splitPoints, buckets);
- } else {
- incrementFloatBucketsSortedLevel(fromIndex, toIndex, weight, splitPoints, buckets);
- }
- level++;
- weight *= 2;
- }
- // normalize and, if CDF, convert to cumulative
- if (isCdf) {
- double subtotal = 0;
- for (int i = 0; i < buckets.length; i++) {
- subtotal += buckets[i];
- buckets[i] = subtotal / getN();
- }
- } else {
- for (int i = 0; i < buckets.length; i++) {
- buckets[i] /= getN();
- }
- }
- return buckets;
- }
-
- final float getFloatsQuantile(final double fraction) {
- if (isEmpty()) { return Float.NaN; }
- if (fraction < 0.0 || fraction > 1.0) {
- throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
- }
- //These two assumptions make KLL compatible with the previous classic Quantiles Sketch
- if (fraction == 0.0) { return getMinFloatValue(); }
- if (fraction == 1.0) { return getMaxFloatValue(); }
-
- final KllFloatsQuantileCalculator quant = getFloatsQuantileCalculator();
- return quant.getQuantile(fraction);
- }
-
- final float[] getFloatsQuantiles(final double[] fractions) {
- if (isEmpty()) { return null; }
- KllFloatsQuantileCalculator quant = null;
- final float[] quantiles = new float[fractions.length];
- for (int i = 0; i < fractions.length; i++) {
- final double fraction = fractions[i];
- if (fraction < 0.0 || fraction > 1.0) {
- throw new SketchesArgumentException("Fraction cannot be less than zero nor greater than 1.0");
- }
- if (fraction == 0.0) { quantiles[i] = getMinFloatValue(); }
- else if (fraction == 1.0) { quantiles[i] = getMaxFloatValue(); }
- else {
- if (quant == null) {
- quant = getFloatsQuantileCalculator();
- }
- quantiles[i] = quant.getQuantile(fraction);
- }
- }
- return quantiles;
- }
-
- abstract double getDoubleItemsArrayAt(int index);
-
abstract float getFloatItemsArrayAt(int index);
abstract int[] getLevelsArray();
abstract int getLevelsArrayAt(int index);
+ /**
+ * Returns the configured parameter m, which is the minimum level size in number of items.
+ * Currently, the public default is 8, but this can be overridden using Package Private methods to
+ * 2, 4, 6 or 8, and the sketch works just fine. The value 8 was chosen as a compromise between speed and size.
+ * Choosing smaller values of m will make the sketch much slower.
+ * @return the configured parameter m
+ */
+ abstract int getM();
+
abstract double getMaxDoubleValue();
abstract float getMaxFloatValue();
@@ -668,6 +384,13 @@ final float[] getFloatsQuantiles(final double[] fractions) {
abstract float getMinFloatValue();
+ /**
+ * MinK is the value of K that results from a merge with a sketch configured with a value of K lower than
+ * the k of this sketch. This value is then used in computing the estimated upper and lower bounds of error.
+ * @return The minimum K as a result of merging with lower values of k.
+ */
+ abstract int getMinK();
+
abstract int getNumLevels();
abstract void incN();
@@ -680,289 +403,10 @@ final float[] getFloatsQuantiles(final double[] fractions) {
abstract boolean isLevelZeroSorted();
- /**
- * This method is for direct Double and Float sketches only and does the following:
- *
- * - Determines if the required sketch bytes will fit in the current Memory.
- * If so, it will stretch the positioning of the arrays to fit. Otherwise:
- *
- Allocates a new WritableMemory of the required size
- * - Copies over the preamble as is (20 bytes)
- * - Creates new memory regions for Levels Array, Min/Max Array, Items Array, but
- * does not fill them. They may contain garbage.
- *
- * The caller is responsible for filling these regions and updating the preamble.
- * @param sketch The current sketch that needs to be expanded.
- * @param newLevelsArrLen the element length of the new Levels array.
- * @param newItemsArrLen the element length of the new Items array.
- * @return the new expanded memory with preamble.
- */
- static WritableMemory memorySpaceMgmt(
- final KllSketch sketch,
- final int newLevelsArrLen,
- final int newItemsArrLen) {
- final SketchType sketchType = sketch.sketchType;
- final WritableMemory oldWmem = sketch.wmem;
- final int startAdr = DATA_START_ADR;
- final int typeBytes = (sketchType == DOUBLES_SKETCH) ? Double.BYTES : Float.BYTES;
-
- int requiredSketchBytes = startAdr;
- requiredSketchBytes += newLevelsArrLen * Integer.BYTES;
- requiredSketchBytes += 2 * typeBytes;
- requiredSketchBytes += newItemsArrLen * typeBytes;
- final WritableMemory newWmem;
-
- if (requiredSketchBytes > oldWmem.getCapacity()) { //Acquire new WritableMemory
- newWmem = sketch.memReqSvr.request(oldWmem, requiredSketchBytes);
- oldWmem.copyTo(0, newWmem, 0, startAdr); //copy preamble
- }
- else { //Expand or contract in current memory
- newWmem = oldWmem;
- }
-
- int offset = startAdr;
- //LEVELS ARR
- int lengthBytes = newLevelsArrLen * Integer.BYTES;
- sketch.setLevelsArrayUpdatable(newWmem.writableRegion(offset, lengthBytes)); //
- offset += lengthBytes;
- //MIN MAX ARR
- lengthBytes = 2 * typeBytes;
- sketch.setMinMaxArrayUpdatable(newWmem.writableRegion(offset, lengthBytes));
- offset += lengthBytes;
- //ITEMS ARR
- lengthBytes = newItemsArrLen * typeBytes;
- sketch.setItemsArrayUpdatable(newWmem.writableRegion(offset, lengthBytes));
- assert requiredSketchBytes <= newWmem.getCapacity();
- return newWmem;
- }
-
- final void mergeDoubleImpl(final KllSketch other) {
- if (other.isEmpty()) { return; }
- final long finalN = getN() + other.getN();
- //update this sketch with level0 items from the other sketch
- final double[] otherDoubleItemsArr = other.getDoubleItemsArray();
- final int otherNumLevels = other.getNumLevels();
- final int[] otherLevelsArr = other.getLevelsArray();
- for (int i = otherLevelsArr[0]; i < otherLevelsArr[1]; i++) {
- updateDouble(otherDoubleItemsArr[i]);
- }
- // after the level 0 update, we capture the key mutable variables
- final double myMin = getMinDoubleValue();
- final double myMax = getMaxDoubleValue();
- final int myMinK = getMinK();
-
- final int myCurNumLevels = getNumLevels();
- final int[] myCurLevelsArr = getLevelsArray();
- final double[] myCurDoubleItemsArr = getDoubleItemsArray();
-
- final int myNewNumLevels;
- final int[] myNewLevelsArr;
- final double[] myNewDoubleItemsArr;
-
- if (otherNumLevels > 1) { //now merge other levels if they exist
- final int tmpSpaceNeeded = getNumRetained()
- + KllHelper.getNumRetainedAboveLevelZero(otherNumLevels, otherLevelsArr);
- final double[] workbuf = new double[tmpSpaceNeeded];
- final int ub = KllHelper.ubOnNumLevels(finalN);
- final int[] worklevels = new int[ub + 2]; // ub+1 does not work
- final int[] outlevels = new int[ub + 2];
-
- final int provisionalNumLevels = max(myCurNumLevels, otherNumLevels);
-
- populateDoubleWorkArrays(other, workbuf, worklevels, provisionalNumLevels);
-
- // notice that workbuf is being used as both the input and output
- final int[] result = KllDoublesHelper.generalDoublesCompress(getK(), getM(), provisionalNumLevels,
- workbuf, worklevels, workbuf, outlevels, isLevelZeroSorted(), random);
- final int targetItemCount = result[1]; //was finalCapacity. Max size given k, m, numLevels
- final int curItemCount = result[2]; //was finalPop
-
- // now we need to finalize the results for the "self" sketch
-
- //THE NEW NUM LEVELS
- myNewNumLevels = result[0]; //was finalNumLevels
- assert myNewNumLevels <= ub; // ub may be much bigger
-
- // THE NEW ITEMS ARRAY (was newbuf)
- myNewDoubleItemsArr = (targetItemCount == myCurDoubleItemsArr.length)
- ? myCurDoubleItemsArr
- : new double[targetItemCount];
- final int freeSpaceAtBottom = targetItemCount - curItemCount;
- //shift the new items array
- System.arraycopy(workbuf, outlevels[0], myNewDoubleItemsArr, freeSpaceAtBottom, curItemCount);
- final int theShift = freeSpaceAtBottom - outlevels[0];
-
- //calculate the new levels array length
- final int finalLevelsArrLen;
- if (myCurLevelsArr.length < myNewNumLevels + 1) { finalLevelsArrLen = myNewNumLevels + 1; }
- else { finalLevelsArrLen = myCurLevelsArr.length; }
-
- //THE NEW LEVELS ARRAY
- myNewLevelsArr = new int[finalLevelsArrLen];
- for (int lvl = 0; lvl < myNewNumLevels + 1; lvl++) { // includes the "extra" index
- myNewLevelsArr[lvl] = outlevels[lvl] + theShift;
- }
-
- //MEMORY SPACE MANAGEMENT
- if (direct) {
- wmem = memorySpaceMgmt(this, myNewLevelsArr.length, myNewDoubleItemsArr.length);
- } //End direct
-
- } else {
- myNewNumLevels = myCurNumLevels;
- myNewLevelsArr = myCurLevelsArr;
- myNewDoubleItemsArr = myCurDoubleItemsArr;
- }
-
- //Update Preamble:
- setN(finalN);
- if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
- setMinK(min(myMinK, other.getMinK()));
- }
-
- //Update min, max values
- final double otherMin = other.getMinDoubleValue();
- final double otherMax = other.getMaxDoubleValue();
- setMinDoubleValue(resolveDoubleMinValue(myMin, otherMin));
- setMaxDoubleValue(resolveDoubleMaxValue(myMax, otherMax));
-
- //Update numLevels, levelsArray, items
- setNumLevels(myNewNumLevels);
- setLevelsArray(myNewLevelsArr);
- setDoubleItemsArray(myNewDoubleItemsArr);
- assert KllHelper.sumTheSampleWeights(getNumLevels(), getLevelsArray()) == getN();
- }
-
- private static double resolveDoubleMinValue(final double myMin, final double otherMin) {
- if (Double.isNaN(myMin) && Double.isNaN(otherMin)) { return Double.NaN; }
- if (Double.isNaN(myMin)) { return otherMin; }
- if (Double.isNaN(otherMin)) { return myMin; }
- return min(myMin, otherMin);
- }
-
- private static double resolveDoubleMaxValue(final double myMax, final double otherMax) {
- if (Double.isNaN(myMax) && Double.isNaN(otherMax)) { return Double.NaN; }
- if (Double.isNaN(myMax)) { return otherMax; }
- if (Double.isNaN(otherMax)) { return myMax; }
- return max(myMax, otherMax);
- }
-
- final void mergeFloatImpl(final KllSketch other) {
- if (other.isEmpty()) { return; }
- final long finalN = getN() + other.getN();
- //update this sketch with level0 items from the other sketch
- final float[] otherFloatItemsArr = other.getFloatItemsArray();
- final int otherNumLevels = other.getNumLevels();
- final int[] otherLevelsArr = other.getLevelsArray();
- for (int i = otherLevelsArr[0]; i < otherLevelsArr[1]; i++) {
- updateFloat(otherFloatItemsArr[i]);
- }
- // after the level 0 update, we capture the key mutable variables
- final float myMin = getMinFloatValue();
- final float myMax = getMaxFloatValue();
- final int myMinK = getMinK();
-
- final int myCurNumLevels = getNumLevels();
- final int[] myCurLevelsArr = getLevelsArray();
- final float[] myCurFloatItemsArr = getFloatItemsArray();
-
- final int myNewNumLevels;
- final int[] myNewLevelsArr;
- final float[] myNewFloatItemsArr;
-
- if (otherNumLevels > 1) { //now merge higher levels if they exist
- final int tmpSpaceNeeded = getNumRetained()
- + KllHelper.getNumRetainedAboveLevelZero(otherNumLevels, otherLevelsArr);
- final float[] workbuf = new float[tmpSpaceNeeded];
- final int ub = KllHelper.ubOnNumLevels(finalN);
- final int[] worklevels = new int[ub + 2]; // ub+1 does not work
- final int[] outlevels = new int[ub + 2];
-
- final int provisionalNumLevels = max(myCurNumLevels, otherNumLevels);
-
- populateFloatWorkArrays(other, workbuf, worklevels, provisionalNumLevels);
-
- // notice that workbuf is being used as both the input and output
- final int[] result = KllFloatsHelper.generalFloatsCompress(getK(), getM(), provisionalNumLevels,
- workbuf, worklevels, workbuf, outlevels, isLevelZeroSorted(), random);
- final int targetItemCount = result[1]; //was finalCapacity. Max size given k, m, numLevels
- final int curItemCount = result[2]; //was finalPop
-
- // now we need to finalize the results for the "self" sketch
-
- //THE NEW NUM LEVELS
- myNewNumLevels = result[0]; //was finalNumLevels
- assert myNewNumLevels <= ub; // ub may be much bigger
-
- // THE NEW ITEMS ARRAY (was newbuf)
- myNewFloatItemsArr = (targetItemCount == myCurFloatItemsArr.length)
- ? myCurFloatItemsArr
- : new float[targetItemCount];
- final int freeSpaceAtBottom = targetItemCount - curItemCount;
- //shift the new items array
- System.arraycopy(workbuf, outlevels[0], myNewFloatItemsArr, freeSpaceAtBottom, curItemCount);
- final int theShift = freeSpaceAtBottom - outlevels[0];
-
- //calculate the new levels array length
- final int finalLevelsArrLen;
- if (myCurLevelsArr.length < myNewNumLevels + 1) { finalLevelsArrLen = myNewNumLevels + 1; }
- else { finalLevelsArrLen = myCurLevelsArr.length; }
-
- //THE NEW LEVELS ARRAY
- myNewLevelsArr = new int[finalLevelsArrLen];
- for (int lvl = 0; lvl < myNewNumLevels + 1; lvl++) { // includes the "extra" index
- myNewLevelsArr[lvl] = outlevels[lvl] + theShift;
- }
-
- //MEMORY SPACE MANAGEMENT
- if (direct) {
- wmem = memorySpaceMgmt(this, myNewLevelsArr.length, myNewFloatItemsArr.length);
- } //End direct
-
- } else {
- myNewNumLevels = myCurNumLevels;
- myNewLevelsArr = myCurLevelsArr;
- myNewFloatItemsArr = myCurFloatItemsArr;
- }
-
- //Update Preamble:
- setN(finalN);
- if (other.isEstimationMode()) { //otherwise the merge brings over exact items.
- setMinK(min(myMinK, other.getMinK()));
- }
-
- //Update min, max values
- final float otherMin = other.getMinFloatValue();
- final float otherMax = other.getMaxFloatValue();
- setMinFloatValue(resolveFloatMinValue(myMin, otherMin));
- setMaxFloatValue(resolveFloatMaxValue(myMax, otherMax));
-
- //Update numLevels, levelsArray, items
- setNumLevels(myNewNumLevels);
- setLevelsArray(myNewLevelsArr);
- setFloatItemsArray(myNewFloatItemsArr);
- assert KllHelper.sumTheSampleWeights(getNumLevels(), getLevelsArray()) == getN();
- }
-
- private static float resolveFloatMinValue(final float myMin, final float otherMin) {
- if (Float.isNaN(myMin) && Float.isNaN(otherMin)) { return Float.NaN; }
- if (Float.isNaN(myMin)) { return otherMin; }
- if (Float.isNaN(otherMin)) { return myMin; }
- return min(myMin, otherMin);
- }
-
- private static float resolveFloatMaxValue(final float myMax, final float otherMax) {
- if (Float.isNaN(myMax) && Float.isNaN(otherMax)) { return Float.NaN; }
- if (Float.isNaN(myMax)) { return otherMax; }
- if (Float.isNaN(otherMax)) { return myMax; }
- return max(myMax, otherMax);
- }
-
abstract void setDoubleItemsArray(double[] floatItems);
abstract void setDoubleItemsArrayAt(int index, double value);
- abstract void setMinK(int minK);
-
abstract void setFloatItemsArray(float[] floatItems);
abstract void setFloatItemsArrayAt(int index, float value);
@@ -973,10 +417,10 @@ private static float resolveFloatMaxValue(final float myMax, final float otherMa
abstract void setLevelsArrayAt(int index, int value);
- abstract void setLevelsArrayAtPlusEq(int index, int plusEq);
-
abstract void setLevelsArrayAtMinusEq(int index, int minusEq);
+ abstract void setLevelsArrayAtPlusEq(int index, int plusEq);
+
abstract void setLevelsArrayUpdatable(WritableMemory levelsMem);
abstract void setLevelZeroSorted(boolean sorted);
@@ -989,681 +433,12 @@ private static float resolveFloatMaxValue(final float myMax, final float otherMa
abstract void setMinFloatValue(float value);
+ abstract void setMinK(int minK);
+
abstract void setMinMaxArrayUpdatable(WritableMemory minMaxMem);
abstract void setN(long n);
abstract void setNumLevels(int numLevels);
- final byte[] toCompactByteArrayImpl() {
- final byte[] byteArr = new byte[getCurrentCompactSerializedSizeBytes()];
- final WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- loadFirst8Bytes(this, wmem, false);
- if (getN() == 0) { return byteArr; } //empty
- final boolean doubleType = (sketchType == DOUBLES_SKETCH);
-
- //load data
- int offset = DATA_START_ADR_SINGLE_ITEM;
- final int[] myLevelsArr = getLevelsArray();
- if (getN() == 1) { //single item
- if (doubleType) {
- wmem.putDouble(offset, getDoubleItemsArray()[myLevelsArr[0]]);
- } else {
- wmem.putFloat(offset, getFloatItemsArray()[myLevelsArr[0]]);
- }
- } else { // n > 1
- //remainder of preamble after first 8 bytes
- setMemoryN(wmem, getN());
- setMemoryMinK(wmem, getMinK());
- setMemoryNumLevels(wmem, getNumLevels());
- offset = DATA_START_ADR;
-
- //LOAD LEVELS ARR the last integer in levels_ is NOT serialized
- final int len = myLevelsArr.length - 1;
- wmem.putIntArray(offset, myLevelsArr, 0, len);
- offset += len * Integer.BYTES;
-
- //LOAD MIN, MAX VALUES FOLLOWED BY ITEMS ARRAY
- if (doubleType) {
- wmem.putDouble(offset, getMinDoubleValue());
- offset += Double.BYTES;
- wmem.putDouble(offset, getMaxDoubleValue());
- offset += Double.BYTES;
- wmem.putDoubleArray(offset, getDoubleItemsArray(), myLevelsArr[0], getNumRetained());
- } else {
- wmem.putFloat(offset, getMinFloatValue());
- offset += Float.BYTES;
- wmem.putFloat(offset, getMaxFloatValue());
- offset += Float.BYTES;
- wmem.putFloatArray(offset, getFloatItemsArray(), myLevelsArr[0], getNumRetained());
- }
- }
- return byteArr;
- }
-
- private static void loadFirst8Bytes(final KllSketch sk, final WritableMemory wmem,
- final boolean updatable) {
- final boolean empty = sk.getN() == 0;
- final boolean lvlZeroSorted = sk.isLevelZeroSorted();
- final boolean singleItem = sk.getN() == 1;
- final boolean doubleType = (sk.sketchType == DOUBLES_SKETCH);
- final int preInts = updatable
- ? PREAMBLE_INTS_FULL
- : (empty || singleItem) ? PREAMBLE_INTS_EMPTY_SINGLE : PREAMBLE_INTS_FULL;
- //load the preamble
- setMemoryPreInts(wmem, preInts);
- final int server = updatable ? SERIAL_VERSION_UPDATABLE
- : (singleItem ? SERIAL_VERSION_SINGLE : SERIAL_VERSION_EMPTY_FULL);
- setMemorySerVer(wmem, server);
- setMemoryFamilyID(wmem, Family.KLL.getID());
- setMemoryEmptyFlag(wmem, empty);
- setMemoryLevelZeroSortedFlag(wmem, lvlZeroSorted);
- setMemorySingleItemFlag(wmem, singleItem);
- setMemoryDoubleSketchFlag(wmem, doubleType);
- setMemoryUpdatableFlag(wmem, updatable);
- setMemoryK(wmem, sk.getK());
- setMemoryM(wmem, sk.getM());
- }
-
- @SuppressWarnings("null")
- final String toStringImpl(final boolean withLevels, final boolean withData) {
- final boolean doubleType = (sketchType == DOUBLES_SKETCH);
- final int k = getK();
- final int m = getM();
- final String epsPct = String.format("%.3f%%", getNormalizedRankError(false) * 100);
- final String epsPMFPct = String.format("%.3f%%", getNormalizedRankError(true) * 100);
- final StringBuilder sb = new StringBuilder();
- final String skType = (direct ? "Direct" : "") + (doubleType ? "Doubles" : "Floats");
- sb.append(Util.LS).append("### Kll").append(skType).append("Sketch Summary:").append(Util.LS);
- sb.append(" K : ").append(k).append(Util.LS);
- sb.append(" Dynamic min K : ").append(getMinK()).append(Util.LS);
- sb.append(" M : ").append(m).append(Util.LS);
- sb.append(" N : ").append(getN()).append(Util.LS);
- sb.append(" Epsilon : ").append(epsPct).append(Util.LS);
- sb.append(" Epsison PMF : ").append(epsPMFPct).append(Util.LS);
- sb.append(" Empty : ").append(isEmpty()).append(Util.LS);
- sb.append(" Estimation Mode : ").append(isEstimationMode()).append(Util.LS);
- sb.append(" Levels : ").append(getNumLevels()).append(Util.LS);
- sb.append(" Level 0 Sorted : ").append(isLevelZeroSorted()).append(Util.LS);
- final int cap = (doubleType) ? getDoubleItemsArray().length : getFloatItemsArray().length;
- sb.append(" Capacity Items : ").append(cap).append(Util.LS);
- sb.append(" Retained Items : ").append(getNumRetained()).append(Util.LS);
- if (direct) {
- sb.append(" Updatable Storage Bytes: ").append(getCurrentUpdatableSerializedSizeBytes()).append(Util.LS);
- } else {
- sb.append(" Compact Storage Bytes : ").append(getCurrentCompactSerializedSizeBytes()).append(Util.LS);
- }
-
- if (doubleType) {
- sb.append(" Min Value : ").append(getMinDoubleValue()).append(Util.LS);
- sb.append(" Max Value : ").append(getMaxDoubleValue()).append(Util.LS);
- } else {
- sb.append(" Min Value : ").append(getMinFloatValue()).append(Util.LS);
- sb.append(" Max Value : ").append(getMaxFloatValue()).append(Util.LS);
- }
- sb.append("### End sketch summary").append(Util.LS);
-
- final int myNumLevels = getNumLevels();
- final int[] myLevelsArr = getLevelsArray();
- double[] myDoubleItemsArr = null;
- float[] myFloatItemsArr = null;
- if (doubleType) {
- myDoubleItemsArr = getDoubleItemsArray();
- } else {
- myFloatItemsArr = getFloatItemsArray();
- }
- if (withLevels) {
- sb.append(outputLevels(k, m, myNumLevels, myLevelsArr));
- }
- if (withData) {
- sb.append(outputData(doubleType, myNumLevels, myLevelsArr, myFloatItemsArr, myDoubleItemsArr));
- }
- return sb.toString();
- }
-
- static String outputLevels(final int k, final int m, final int numLevels, final int[] levelsArr) {
- final StringBuilder sb = new StringBuilder();
- sb.append("### KLL levels array:").append(Util.LS)
- .append(" level, offset: nominal capacity, actual size").append(Util.LS);
- int level = 0;
- for ( ; level < numLevels; level++) {
- sb.append(" ").append(level).append(", ").append(levelsArr[level]).append(": ")
- .append(KllHelper.levelCapacity(k, numLevels, level, m))
- .append(", ").append(KllHelper.currentLevelSize(level, numLevels, levelsArr)).append(Util.LS);
- }
- sb.append(" ").append(level).append(", ").append(levelsArr[level]).append(": (Exclusive)")
- .append(Util.LS);
- sb.append("### End levels array").append(Util.LS);
- return sb.toString();
- }
-
- static String outputData(final boolean doubleType, final int numLevels, final int[] levelsArr,
- final float[] floatItemsArr, final double[] doubleItemsArr) {
- final StringBuilder sb = new StringBuilder();
- sb.append("### KLL items data {index, item}:").append(Util.LS);
- if (levelsArr[0] > 0) {
- sb.append(" Garbage:" + Util.LS);
- if (doubleType) {
- for (int i = 0; i < levelsArr[0]; i++) {
- sb.append(" ").append(i + ", ").append(doubleItemsArr[i]).append(Util.LS);
- }
- } else {
- for (int i = 0; i < levelsArr[0]; i++) {
- sb.append(" ").append(i + ", ").append(floatItemsArr[i]).append(Util.LS);
- }
- }
- }
- int level = 0;
- if (doubleType) {
- while (level < numLevels) {
- final int fromIndex = levelsArr[level];
- final int toIndex = levelsArr[level + 1]; // exclusive
- if (fromIndex < toIndex) {
- sb.append(" level[").append(level).append("]: offset: " + levelsArr[level] + " wt: " + (1 << level));
- sb.append(Util.LS);
- }
-
- for (int i = fromIndex; i < toIndex; i++) {
- sb.append(" ").append(i + ", ").append(doubleItemsArr[i]).append(Util.LS);
- }
- level++;
- }
- }
- else {
- while (level < numLevels) {
- final int fromIndex = levelsArr[level];
- final int toIndex = levelsArr[level + 1]; // exclusive
- if (fromIndex <= toIndex) {
- sb.append(" level[").append(level).append("]: offset: " + levelsArr[level] + " wt: " + (1 << level));
- sb.append(Util.LS);
- }
-
- for (int i = fromIndex; i < toIndex; i++) {
- sb.append(" ").append(i + ", ").append(floatItemsArr[i]).append(Util.LS);
- }
- level++;
- }
- }
- sb.append(" level[" + level + "]: offset: " + levelsArr[level] + " (Exclusive)");
- sb.append(Util.LS);
- sb.append("### End items data").append(Util.LS);
-
- return sb.toString();
- }
-
- final byte[] toUpdatableByteArrayImpl() {
- final byte[] byteArr = new byte[getCurrentUpdatableSerializedSizeBytes()];
- final WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- loadFirst8Bytes(this, wmem, true);
- //remainder of preamble after first 8 bytes
- setMemoryN(wmem, getN());
- setMemoryMinK(wmem, getMinK());
- setMemoryNumLevels(wmem, getNumLevels());
-
- //load data
- final boolean doubleType = (sketchType == DOUBLES_SKETCH);
- int offset = DATA_START_ADR;
-
- //LOAD LEVELS ARRAY the last integer in levels_ IS serialized
- final int[] myLevelsArr = getLevelsArray();
- final int len = myLevelsArr.length;
- wmem.putIntArray(offset, myLevelsArr, 0, len);
- offset += len * Integer.BYTES;
-
- //LOAD MIN, MAX VALUES FOLLOWED BY ITEMS ARRAY
- if (doubleType) {
- wmem.putDouble(offset, getMinDoubleValue());
- offset += Double.BYTES;
- wmem.putDouble(offset, getMaxDoubleValue());
- offset += Double.BYTES;
- final double[] doubleItemsArr = getDoubleItemsArray();
- wmem.putDoubleArray(offset, doubleItemsArr, 0, doubleItemsArr.length);
- } else {
- wmem.putFloat(offset, getMinFloatValue());
- offset += Float.BYTES;
- wmem.putFloat(offset, getMaxFloatValue());
- offset += Float.BYTES;
- final float[] floatItemsArr = getFloatItemsArray();
- wmem.putFloatArray(offset, floatItemsArr, 0, floatItemsArr.length);
- }
- return byteArr;
- }
-
- final void updateDouble(final double value) {
- if (Double.isNaN(value)) { return; }
- if (isEmpty()) {
- setMinDoubleValue(value);
- setMaxDoubleValue(value);
- } else {
- if (value < getMinDoubleValue()) { setMinDoubleValue(value); }
- if (value > getMaxDoubleValue()) { setMaxDoubleValue(value); }
- }
- if (getLevelsArrayAt(0) == 0) { compressWhileUpdatingSketch(); }
- incN();
- setLevelZeroSorted(false);
- final int nextPos = getLevelsArrayAt(0) - 1;
- assert getLevelsArrayAt(0) >= 0;
- setLevelsArrayAt(0, nextPos);
- setDoubleItemsArrayAt(nextPos, value);
- }
-
- final void updateFloat(final float value) {
- if (Float.isNaN(value)) { return; }
- if (isEmpty()) {
- setMinFloatValue(value);
- setMaxFloatValue(value);
- } else {
- if (value < getMinFloatValue()) { setMinFloatValue(value); }
- if (value > getMaxFloatValue()) { setMaxFloatValue(value); }
- }
-
- if (getLevelsArrayAt(0) == 0) { compressWhileUpdatingSketch(); }
- incN();
- setLevelZeroSorted(false);
- final int nextPos = getLevelsArrayAt(0) - 1;
- assert getLevelsArrayAt(0) >= 0;
- setLevelsArrayAt(0, nextPos);
- setFloatItemsArrayAt(nextPos, value);
- }
-
- //Private non-static methods
-
- /**
- * This grows the levels arr by 1 (if needed) and increases the capacity of the items array
- * at the bottom. Only numLevels, the levels array and the items array are affected.
- */
- @SuppressWarnings("null")
- private void addEmptyTopLevelToCompletelyFullSketch() {
- final int[] myCurLevelsArr = getLevelsArray();
- final int myCurNumLevels = getNumLevels();
- final int myCurTotalItemsCapacity = myCurLevelsArr[myCurNumLevels];
- double minDouble = Double.NaN;
- double maxDouble = Double.NaN;
- float minFloat = Float.NaN;
- float maxFloat = Float.NaN;
-
- double[] myCurDoubleItemsArr = null;
- float[] myCurFloatItemsArr = null;
-
- final int myNewNumLevels;
- final int[] myNewLevelsArr;
- final int myNewTotalItemsCapacity;
-
- float[] myNewFloatItemsArr = null;
- double[] myNewDoubleItemsArr = null;
-
- if (sketchType == DOUBLES_SKETCH) {
- minDouble = getMinDoubleValue();
- maxDouble = getMaxDoubleValue();
- myCurDoubleItemsArr = getDoubleItemsArray();
- //assert we are following a certain growth scheme
- assert myCurDoubleItemsArr.length == myCurTotalItemsCapacity;
- } else { //FLOATS_SKETCH
- minFloat = getMinFloatValue();
- maxFloat = getMaxFloatValue();
- myCurFloatItemsArr = getFloatItemsArray();
- assert myCurFloatItemsArr.length == myCurTotalItemsCapacity;
- }
- assert myCurLevelsArr[0] == 0; //definition of full is part of the growth scheme
-
- final int deltaItemsCap = KllHelper.levelCapacity(getK(), myCurNumLevels + 1, 0, getM());
- myNewTotalItemsCapacity = myCurTotalItemsCapacity + deltaItemsCap;
-
- // Check if growing the levels arr if required.
- // Note that merging MIGHT over-grow levels_, in which case we might not have to grow it
- final boolean growLevelsArr = myCurLevelsArr.length < myCurNumLevels + 2;
-
- // GROW LEVELS ARRAY
- if (growLevelsArr) {
- //grow levels arr by one and copy the old data to the new array, extra space at the top.
- myNewLevelsArr = Arrays.copyOf(myCurLevelsArr, myCurNumLevels + 2);
- assert myNewLevelsArr.length == myCurLevelsArr.length + 1;
- myNewNumLevels = myCurNumLevels + 1;
- incNumLevels(); //increment the class member
- } else {
- myNewLevelsArr = myCurLevelsArr;
- myNewNumLevels = myCurNumLevels;
- }
- // This loop updates all level indices EXCLUDING the "extra" index at the top
- for (int level = 0; level <= myNewNumLevels - 1; level++) {
- myNewLevelsArr[level] += deltaItemsCap;
- }
- myNewLevelsArr[myNewNumLevels] = myNewTotalItemsCapacity; // initialize the new "extra" index at the top
-
- // GROW ITEMS ARRAY
- if (sketchType == DOUBLES_SKETCH) {
- myNewDoubleItemsArr = new double[myNewTotalItemsCapacity];
- // copy and shift the current data into the new array
- System.arraycopy(myCurDoubleItemsArr, 0, myNewDoubleItemsArr, deltaItemsCap, myCurTotalItemsCapacity);
- } else {
- myNewFloatItemsArr = new float[myNewTotalItemsCapacity];
- // copy and shift the current items data into the new array
- System.arraycopy(myCurFloatItemsArr, 0, myNewFloatItemsArr, deltaItemsCap, myCurTotalItemsCapacity);
- }
-
- //MEMORY SPACE MANAGEMENT
- if (direct) {
- wmem = memorySpaceMgmt(this, myNewLevelsArr.length, myNewTotalItemsCapacity);
- }
- //update our sketch with new expanded spaces
- setNumLevels(myNewNumLevels);
- setLevelsArray(myNewLevelsArr);
- if (sketchType == DOUBLES_SKETCH) {
- setMinDoubleValue(minDouble);
- setMaxDoubleValue(maxDouble);
- setDoubleItemsArray(myNewDoubleItemsArr);
- } else { //Float sketch
- setMinFloatValue(minFloat);
- setMaxFloatValue(maxFloat);
- setFloatItemsArray(myNewFloatItemsArr);
- }
- }
-
- // The following code is only valid in the special case of exactly reaching capacity while updating.
- // It cannot be used while merging, while reducing k, or anything else.
- @SuppressWarnings("null")
- private void compressWhileUpdatingSketch() {
- final int level = KllHelper.findLevelToCompact(getK(), getM(), getNumLevels(), getLevelsArray());
- if (level == getNumLevels() - 1) {
- //The level to compact is the top level, thus we need to add a level.
- //Be aware that this operation grows the items array,
- //shifts the items data and the level boundaries of the data,
- //and grows the levels array and increments numLevels_.
- addEmptyTopLevelToCompletelyFullSketch();
- }
-
- final int[] myLevelsArr = getLevelsArray();
- final int rawBeg = myLevelsArr[level];
- final int rawEnd = myLevelsArr[level + 1];
- // +2 is OK because we already added a new top level if necessary
- final int popAbove = myLevelsArr[level + 2] - rawEnd;
- final int rawPop = rawEnd - rawBeg;
- final boolean oddPop = isOdd(rawPop);
- final int adjBeg = oddPop ? rawBeg + 1 : rawBeg;
- final int adjPop = oddPop ? rawPop - 1 : rawPop;
- final int halfAdjPop = adjPop / 2;
-
- // level zero might not be sorted, so we must sort it if we wish to compact it
- float[] myFloatItemsArr;
- double[] myDoubleItemsArr;
-
- if (sketchType == DOUBLES_SKETCH) {
- myFloatItemsArr = null;
- myDoubleItemsArr = getDoubleItemsArray();
- if (level == 0) {
- if (direct) {
- myDoubleItemsArr = getDoubleItemsArray();
- Arrays.sort(myDoubleItemsArr, adjBeg, adjBeg + adjPop);
- setDoubleItemsArray(myDoubleItemsArr);
- } else {
- Arrays.sort(getDoubleItemsArray(), adjBeg, adjBeg + adjPop);
- }
- }
- if (popAbove == 0) {
- if (direct) {
- myDoubleItemsArr = getDoubleItemsArray();
- KllDoublesHelper.randomlyHalveUpDoubles(myDoubleItemsArr, adjBeg, adjPop, random);
- setDoubleItemsArray(myDoubleItemsArr);
- } else {
- KllDoublesHelper.randomlyHalveUpDoubles(getDoubleItemsArray(), adjBeg, adjPop, random);
- }
- } else {
- if (direct) {
- myDoubleItemsArr = getDoubleItemsArray();
- KllDoublesHelper.randomlyHalveDownDoubles(myDoubleItemsArr, adjBeg, adjPop, random);
- setDoubleItemsArray(myDoubleItemsArr);
- } else {
- KllDoublesHelper.randomlyHalveDownDoubles(getDoubleItemsArray(), adjBeg, adjPop, random);
- }
- if (direct ) {
- myDoubleItemsArr = getDoubleItemsArray();
- KllDoublesHelper.mergeSortedDoubleArrays(
- myDoubleItemsArr, adjBeg, halfAdjPop,
- myDoubleItemsArr, rawEnd, popAbove,
- myDoubleItemsArr, adjBeg + halfAdjPop);
- setDoubleItemsArray(myDoubleItemsArr);
- } else {
- myDoubleItemsArr = getDoubleItemsArray();
- KllDoublesHelper.mergeSortedDoubleArrays(
- myDoubleItemsArr, adjBeg, halfAdjPop,
- myDoubleItemsArr, rawEnd, popAbove,
- myDoubleItemsArr, adjBeg + halfAdjPop);
- }
- }
- } else { //Float sketch
- myFloatItemsArr = getFloatItemsArray();
- myDoubleItemsArr = null;
- if (level == 0) {
- if (direct) {
- myFloatItemsArr = getFloatItemsArray();
- Arrays.sort(myFloatItemsArr, adjBeg, adjBeg + adjPop);
- setFloatItemsArray(myFloatItemsArr);
- } else {
- Arrays.sort(getFloatItemsArray(), adjBeg, adjBeg + adjPop);
- }
- }
- if (popAbove == 0) {
- if (direct) {
- myFloatItemsArr = getFloatItemsArray();
- KllFloatsHelper.randomlyHalveUpFloats(myFloatItemsArr, adjBeg, adjPop, random);
- setFloatItemsArray(myFloatItemsArr);
- } else {
- KllFloatsHelper.randomlyHalveUpFloats(getFloatItemsArray(), adjBeg, adjPop, random);
- }
- } else {
- if (direct) {
- myFloatItemsArr = getFloatItemsArray();
- KllFloatsHelper.randomlyHalveDownFloats(myFloatItemsArr, adjBeg, adjPop, random);
- setFloatItemsArray(myFloatItemsArr);
- } else {
- KllFloatsHelper.randomlyHalveDownFloats(getFloatItemsArray(), adjBeg, adjPop, random);
- }
- if (direct ) {
- myFloatItemsArr = getFloatItemsArray();
- KllFloatsHelper.mergeSortedFloatArrays(
- myFloatItemsArr, adjBeg, halfAdjPop,
- myFloatItemsArr, rawEnd, popAbove,
- myFloatItemsArr, adjBeg + halfAdjPop);
- setFloatItemsArray(myFloatItemsArr);
- } else {
- myFloatItemsArr = getFloatItemsArray();
- KllFloatsHelper.mergeSortedFloatArrays(
- myFloatItemsArr, adjBeg, halfAdjPop,
- myFloatItemsArr, rawEnd, popAbove,
- myFloatItemsArr, adjBeg + halfAdjPop);
- }
- }
- }
- setLevelsArrayAtMinusEq(level + 1, halfAdjPop); // adjust boundaries of the level above
-
- if (oddPop) {
- setLevelsArrayAt(level, getLevelsArrayAt(level + 1) - 1); // the current level now contains one item
- if (sketchType == DOUBLES_SKETCH) {
- setDoubleItemsArrayAt(getLevelsArrayAt(level), getDoubleItemsArrayAt(rawBeg)); // namely this leftover guy
- } else {
- setFloatItemsArrayAt(getLevelsArrayAt(level), getFloatItemsArrayAt(rawBeg)); // namely this leftover guy
- }
-
- } else {
- setLevelsArrayAt(level, getLevelsArrayAt(level + 1)); // the current level is now empty
- }
-
- // verify that we freed up halfAdjPop array slots just below the current level
- assert getLevelsArrayAt(level) == rawBeg + halfAdjPop;
-
- // finally, we need to shift up the data in the levels below
- // so that the freed-up space can be used by level zero
- if (level > 0) {
- final int amount = rawBeg - getLevelsArrayAt(0);
- if (sketchType == DOUBLES_SKETCH) {
- if (direct) {
- myDoubleItemsArr = getDoubleItemsArray();
- System.arraycopy(myDoubleItemsArr, myLevelsArr[0], myDoubleItemsArr, myLevelsArr[0] + halfAdjPop, amount);
- setDoubleItemsArray(myDoubleItemsArr);
- } else {
- System.arraycopy(myDoubleItemsArr, myLevelsArr[0], myDoubleItemsArr, myLevelsArr[0] + halfAdjPop, amount);
- }
- } else {
- if (direct) {
- myFloatItemsArr = getFloatItemsArray();
- System.arraycopy(myFloatItemsArr, myLevelsArr[0], myFloatItemsArr, myLevelsArr[0] + halfAdjPop, amount);
- setFloatItemsArray(myFloatItemsArr);
- } else {
- System.arraycopy(myFloatItemsArr, myLevelsArr[0], myFloatItemsArr, myLevelsArr[0] + halfAdjPop, amount);
- }
- }
- for (int lvl = 0; lvl < level; lvl++) {
- setLevelsArrayAtPlusEq(lvl, halfAdjPop);
- }
- }
- }
-
- private KllDoublesQuantileCalculator getDoublesQuantileCalculator() {
- final int[] myLevelsArr = getLevelsArray();
- final double[] myDoubleItemsArr = getDoubleItemsArray();
- if (!isLevelZeroSorted()) {
- Arrays.sort(getDoubleItemsArray(), myLevelsArr[0], myLevelsArr[1]);
- setLevelZeroSorted(true);
- }
- return new KllDoublesQuantileCalculator(myDoubleItemsArr, myLevelsArr, getNumLevels(), getN());
- }
-
- private KllFloatsQuantileCalculator getFloatsQuantileCalculator() {
- final int[] myLevelsArr = getLevelsArray();
- final float[] myFloatItemsArr = getFloatItemsArray();
- if (!isLevelZeroSorted()) {
- Arrays.sort(myFloatItemsArr, myLevelsArr[0], myLevelsArr[1]);
- setLevelZeroSorted(true);
- }
- return new KllFloatsQuantileCalculator(myFloatItemsArr, myLevelsArr, getNumLevels(), getN());
- }
-
- private void incrementDoublesBucketsSortedLevel(final int fromIndex, final int toIndex,
- final int weight, final double[] splitPoints, final double[] buckets) {
- final double[] myDoubleItemsArr = getDoubleItemsArray();
- int i = fromIndex;
- int j = 0;
- while (i < toIndex && j < splitPoints.length) {
- if (myDoubleItemsArr[i] < splitPoints[j]) {
- buckets[j] += weight; // this sample goes into this bucket
- i++; // move on to next sample and see whether it also goes into this bucket
- } else {
- j++; // no more samples for this bucket
- }
- }
- // now either i == toIndex (we are out of samples), or
- // j == numSplitPoints (we are out of buckets, but there are more samples remaining)
- // we only need to do something in the latter case
- if (j == splitPoints.length) {
- buckets[j] += weight * (toIndex - i);
- }
- }
-
- private void incrementDoublesBucketsUnsortedLevel(final int fromIndex, final int toIndex,
- final int weight, final double[] splitPoints, final double[] buckets) {
- final double[] myDoubleItemsArr = getDoubleItemsArray();
- for (int i = fromIndex; i < toIndex; i++) {
- int j;
- for (j = 0; j < splitPoints.length; j++) {
- if (myDoubleItemsArr[i] < splitPoints[j]) {
- break;
- }
- }
- buckets[j] += weight;
- }
- }
-
- private void incrementFloatBucketsSortedLevel(final int fromIndex, final int toIndex,
- final int weight, final float[] splitPoints, final double[] buckets) {
- final float[] myFloatItemsArr = getFloatItemsArray();
- int i = fromIndex;
- int j = 0;
- while (i < toIndex && j < splitPoints.length) {
- if (myFloatItemsArr[i] < splitPoints[j]) {
- buckets[j] += weight; // this sample goes into this bucket
- i++; // move on to next sample and see whether it also goes into this bucket
- } else {
- j++; // no more samples for this bucket
- }
- }
- // now either i == toIndex (we are out of samples), or
- // j == numSplitPoints (we are out of buckets, but there are more samples remaining)
- // we only need to do something in the latter case
- if (j == splitPoints.length) {
- buckets[j] += weight * (toIndex - i);
- }
- }
-
- private void incrementFloatBucketsUnsortedLevel(final int fromIndex, final int toIndex,
- final int weight, final float[] splitPoints, final double[] buckets) {
- final float[] myFloatItemsArr = getFloatItemsArray();
- for (int i = fromIndex; i < toIndex; i++) {
- int j;
- for (j = 0; j < splitPoints.length; j++) {
- if (myFloatItemsArr[i] < splitPoints[j]) {
- break;
- }
- }
- buckets[j] += weight;
- }
- }
-
- private void populateDoubleWorkArrays(final KllSketch other, final double[] workbuf,
- final int[] worklevels, final int provisionalNumLevels) {
- worklevels[0] = 0;
- final int[] myLevelsArr = getLevelsArray();
- final int[] otherLevelsArr = other.getLevelsArray();
- final double[] myDoubleItemsArr = getDoubleItemsArray();
- final double[] otherDoubleItemsArr = other.getDoubleItemsArray();
-
- // Note: the level zero data from "other" was already inserted into "self"
- final int selfPopZero = KllHelper.currentLevelSize(0, getNumLevels(),myLevelsArr);
- System.arraycopy(myDoubleItemsArr, myLevelsArr[0], workbuf, worklevels[0], selfPopZero);
- worklevels[1] = worklevels[0] + selfPopZero;
-
- for (int lvl = 1; lvl < provisionalNumLevels; lvl++) {
- final int selfPop = KllHelper.currentLevelSize(lvl, getNumLevels(), myLevelsArr);
- final int otherPop = KllHelper.currentLevelSize(lvl, other.getNumLevels(), otherLevelsArr);
- worklevels[lvl + 1] = worklevels[lvl] + selfPop + otherPop;
-
- if (selfPop > 0 && otherPop == 0) {
- System.arraycopy(myDoubleItemsArr, myLevelsArr[lvl], workbuf, worklevels[lvl], selfPop);
- } else if (selfPop == 0 && otherPop > 0) {
- System.arraycopy(otherDoubleItemsArr, otherLevelsArr[lvl], workbuf, worklevels[lvl], otherPop);
- } else if (selfPop > 0 && otherPop > 0) {
- KllDoublesHelper.mergeSortedDoubleArrays(myDoubleItemsArr, myLevelsArr[lvl], selfPop, otherDoubleItemsArr,
- otherLevelsArr[lvl], otherPop, workbuf, worklevels[lvl]);
- }
- }
- }
-
- private void populateFloatWorkArrays(final KllSketch other, final float[] workbuf,
- final int[] worklevels, final int provisionalNumLevels) {
- worklevels[0] = 0;
- final int[] myLevelsArr = getLevelsArray();
- final int[] otherLevelsArr = other.getLevelsArray();
- final float[] myFloatItemsArr = getFloatItemsArray();
- final float[] otherFloatItemsArr = other.getFloatItemsArray();
-
- // Note: the level zero data from "other" was already inserted into "self"
- final int selfPopZero = KllHelper.currentLevelSize(0, getNumLevels(), myLevelsArr);
- System.arraycopy( myFloatItemsArr, myLevelsArr[0], workbuf, worklevels[0], selfPopZero);
- worklevels[1] = worklevels[0] + selfPopZero;
-
- for (int lvl = 1; lvl < provisionalNumLevels; lvl++) {
- final int selfPop = KllHelper.currentLevelSize(lvl, getNumLevels(), myLevelsArr);
- final int otherPop = KllHelper.currentLevelSize(lvl, other.getNumLevels(), otherLevelsArr);
- worklevels[lvl + 1] = worklevels[lvl] + selfPop + otherPop;
-
- if (selfPop > 0 && otherPop == 0) {
- System.arraycopy( myFloatItemsArr, myLevelsArr[lvl], workbuf, worklevels[lvl], selfPop);
- } else if (selfPop == 0 && otherPop > 0) {
- System.arraycopy(otherFloatItemsArr, otherLevelsArr[lvl], workbuf, worklevels[lvl], otherPop);
- } else if (selfPop > 0 && otherPop > 0) {
- KllFloatsHelper.mergeSortedFloatArrays( myFloatItemsArr, myLevelsArr[lvl], selfPop, otherFloatItemsArr,
- otherLevelsArr[lvl], otherPop, workbuf, worklevels[lvl]);
- }
- }
- }
-
}
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
index 7af0269f3..e07d7d3c7 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectDoublesSketchTest.java
@@ -545,7 +545,7 @@ public void checkGetWritableMemory() {
assertEquals(sketch.getK(), 200);
assertEquals(sketch.getN(), 200);
assertFalse(sketch.isEmpty());
- assertTrue(sketch.isDirect());
+ assertTrue(sketch.isUpdatableMemory());
assertFalse(sketch.isEstimationMode());
assertTrue(sketch.isDoublesSketch());
assertFalse(sketch.isLevelZeroSorted());
@@ -556,7 +556,7 @@ public void checkGetWritableMemory() {
assertEquals(sk.getK(), 200);
assertEquals(sk.getN(), 200);
assertFalse(sk.isEmpty());
- assertFalse(sk.isDirect());
+ assertFalse(sk.isUpdatableMemory());
assertFalse(sk.isEstimationMode());
assertTrue(sk.isDoublesSketch());
assertFalse(sk.isLevelZeroSorted());
@@ -581,12 +581,49 @@ public void checkReset() {
assertEquals(max2, max1);
}
+ @Test
+ public void checkHeapify() {
+ WritableMemory dstMem = WritableMemory.allocate(6000);
+ KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(20, dstMem, memReqSvr);
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ KllDoublesSketch sk2 = KllDirectDoublesSketch.heapify(dstMem);
+ assertEquals(sk2.getMinValue(), 1.0);
+ assertEquals(sk2.getMaxValue(), 100.0);
+ }
+
+ @Test
+ public void checkMergeKllDoublesSketch() {
+ WritableMemory dstMem = WritableMemory.allocate(6000);
+ KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(20, dstMem, memReqSvr);
+ for (int i = 1; i <= 21; i++) { sk.update(i); }
+ KllDoublesSketch sk2 = new KllDoublesSketch(20);
+ for (int i = 1; i <= 21; i++ ) { sk2.update(i + 100); }
+ sk.merge(sk2);
+ }
+
+ @Test
+ public void checkReverseMergeKllDoubleSketch() {
+ WritableMemory dstMem = WritableMemory.allocate(6000);
+ KllDirectDoublesSketch sk = KllDirectDoublesSketch.newInstance(20, dstMem, memReqSvr);
+ for (int i = 1; i <= 21; i++) { sk.update(i); }
+ KllDoublesSketch sk2 = new KllDoublesSketch(20);
+ for (int i = 1; i <= 21; i++ ) { sk2.update(i + 100); }
+ sk2.merge(sk);
+ }
+
+// @Test
+// public void checkWrapKllDoubleSketch() {
+// KllDoublesSketch sk = new KllDoublesSketch(20);
+// for (int i = 1; i <= 21; i++ ) { sk.update(i); }
+// Memory srcMem = Memory.wrap(sk.toByteArray());
+// KllDirectDoublesSketch sk2 = KllDirectDoublesSketch.writableWrap(srcMem, memReqSvr);
+// }
+
private static KllDirectDoublesSketch getDDSketch(final int k, final int n) {
KllDoublesSketch sk = new KllDoublesSketch(k);
for (int i = 1; i <= n; i++) { sk.update(i); }
byte[] byteArr = sk.toUpdatableByteArray();
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
-
KllDirectDoublesSketch ddsk = KllDirectDoublesSketch.writableWrap(wmem, memReqSvr);
return ddsk;
}
diff --git a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
index 4f6520173..025004380 100644
--- a/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
+++ b/src/test/java/org/apache/datasketches/kll/KllDirectFloatsSketchTest.java
@@ -543,7 +543,7 @@ public void checkGetWritableMemory() {
assertEquals(sketch.getK(), 200);
assertEquals(sketch.getN(), 200);
assertFalse(sketch.isEmpty());
- assertTrue(sketch.isDirect());
+ assertTrue(sketch.isUpdatableMemory());
assertFalse(sketch.isEstimationMode());
assertTrue(sketch.isFloatsSketch());
assertFalse(sketch.isLevelZeroSorted());
@@ -554,7 +554,7 @@ public void checkGetWritableMemory() {
assertEquals(sk.getK(), 200);
assertEquals(sk.getN(), 200);
assertFalse(sk.isEmpty());
- assertFalse(sk.isDirect());
+ assertFalse(sk.isUpdatableMemory());
assertFalse(sk.isEstimationMode());
assertTrue(sk.isFloatsSketch());
assertFalse(sk.isLevelZeroSorted());
@@ -579,6 +579,16 @@ public void checkReset() {
assertEquals(max2, max1);
}
+ @Test
+ public void checkHeapify() {
+ WritableMemory dstMem = WritableMemory.allocate(6000);
+ KllDirectFloatsSketch sk = KllDirectFloatsSketch.newInstance(20, dstMem, memReqSvr);
+ for (int i = 1; i <= 100; i++) { sk.update(i); }
+ KllFloatsSketch sk2 = KllDirectFloatsSketch.heapify(dstMem);
+ assertEquals(sk2.getMinValue(), 1.0);
+ assertEquals(sk2.getMaxValue(), 100.0);
+ }
+
private static KllDirectFloatsSketch getDFSketch(final int k, final int n) {
KllFloatsSketch sk = new KllFloatsSketch(k);
for (int i = 1; i <= n; i++) { sk.update(i); }
From 934e26ab30c8a9e47105597afe11f6cdd62b453a Mon Sep 17 00:00:00 2001
From: Lee Rhodes
Date: Wed, 6 Apr 2022 11:17:09 -0700
Subject: [PATCH 31/31] Added isSameResource(Memory).
---
.../java/org/apache/datasketches/kll/KllSketch.java | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java
index 804148d47..faa5d1081 100644
--- a/src/main/java/org/apache/datasketches/kll/KllSketch.java
+++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java
@@ -28,6 +28,7 @@
import java.util.Random;
import org.apache.datasketches.SketchesArgumentException;
+import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
@@ -311,6 +312,18 @@ public final boolean isUpdatableMemory() {
return updatablMemory;
}
+ /**
+ * Returns true if the backing resource of this is identical with the backing resource
+ * of that. The capacities must be the same. If this is a region,
+ * the region offset must also be the same.
+ * @param that A different non-null object
+ * @return true if the backing resource of this is the same as the backing resource
+ * of that.
+ */
+ public final boolean isSameResource(final Memory that) {
+ return wmem.isSameResource(that);
+ }
+
/**
* This resets the current sketch back to zero entries.
* It retains key parameters such as k and