in src/main/java/org/apache/datasketches/kll/KllHelper.java [575:723]
static void addEmptyTopLevelToCompletelyFullSketch(final KllSketch sketch) {
final SketchType sketchType = sketch.sketchType;
final int[] myCurLevelsArr = sketch.getLevelsArray(sketch.sketchStructure);
final int myCurNumLevels = sketch.getNumLevels();
final int myCurTotalItemsCapacity = myCurLevelsArr[myCurNumLevels];
final int myNewNumLevels;
final int[] myNewLevelsArr;
final int myNewTotalItemsCapacity;
double[] myCurDoubleItemsArr = null;
double[] myNewDoubleItemsArr = null;
double minDouble = Double.NaN;
double maxDouble = Double.NaN;
float[] myCurFloatItemsArr = null;
float[] myNewFloatItemsArr = null;
float minFloat = Float.NaN;
float maxFloat = Float.NaN;
long[] myCurLongItemsArr = null;
long[] myNewLongItemsArr = null;
long minLong = Long.MAX_VALUE;
long maxLong = Long.MIN_VALUE;
Object[] myCurItemsArr = null;
Object[] myNewItemsArr = null;
Object minItem = null;
Object maxItem = null;
if (sketchType == DOUBLES_SKETCH) {
final KllDoublesSketch dblSk = (KllDoublesSketch) sketch;
myCurDoubleItemsArr = dblSk.getDoubleItemsArray();
minDouble = dblSk.getMinItem();
maxDouble = dblSk.getMaxItem();
//assert we are following a certain growth scheme
assert myCurDoubleItemsArr.length == myCurTotalItemsCapacity;
}
else if (sketchType == FLOATS_SKETCH) {
final KllFloatsSketch fltSk = (KllFloatsSketch) sketch;
myCurFloatItemsArr = fltSk.getFloatItemsArray();
minFloat = fltSk.getMinItem();
maxFloat = fltSk.getMaxItem();
//assert we are following a certain growth scheme
assert myCurFloatItemsArr.length == myCurTotalItemsCapacity;
}
else if (sketchType == LONGS_SKETCH) {
final KllLongsSketch lngSk = (KllLongsSketch) sketch;
myCurLongItemsArr = lngSk.getLongItemsArray();
minLong = lngSk.getMinItem();
maxLong = lngSk.getMaxItem();
//assert we are following a certain growth scheme
assert myCurLongItemsArr.length == myCurTotalItemsCapacity;
}
else { //sketchType == ITEMS_SKETCH
final KllItemsSketch<?> itmSk = (KllItemsSketch<?>) sketch;
myCurItemsArr = itmSk.getTotalItemsArray();
minItem = itmSk.getMinItem();
maxItem = itmSk.getMaxItem();
}
assert myCurLevelsArr[0] == 0; //definition of full is part of the growth scheme
final int deltaItemsCap = levelCapacity(sketch.getK(), myCurNumLevels + 1, 0, sketch.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;
sketch.incNumLevels(); //increment for off-heap
} 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 if (sketchType == FLOATS_SKETCH) {
myNewFloatItemsArr = new float[myNewTotalItemsCapacity];
// copy and shift the current items data into the new array
System.arraycopy(myCurFloatItemsArr, 0, myNewFloatItemsArr, deltaItemsCap, myCurTotalItemsCapacity);
}
else if (sketchType == LONGS_SKETCH) {
myNewLongItemsArr = new long[myNewTotalItemsCapacity];
// copy and shift the current items data into the new array
System.arraycopy(myCurLongItemsArr, 0, myNewLongItemsArr, deltaItemsCap, myCurTotalItemsCapacity);
}
else { //sketchType == ITEMS_SKETCH
myNewItemsArr = new Object[myNewTotalItemsCapacity];
// copy and shift the current items data into the new array
System.arraycopy(myCurItemsArr, 0, myNewItemsArr, deltaItemsCap, myCurTotalItemsCapacity);
}
//MEMORY SPACE MANAGEMENT
if (sketch.getWritableMemory() != null) {
final WritableMemory oldWmem = sketch.getWritableMemory();
final WritableMemory wmem = memorySpaceMgmt(sketch, myNewLevelsArr.length, myNewTotalItemsCapacity);
if (!wmem.isSameResource(oldWmem)) {
sketch.getMemoryRequestServer().requestClose(oldWmem);
}
sketch.setWritableMemory(wmem);
}
//update our sketch with new expanded spaces
sketch.setNumLevels(myNewNumLevels); //for off-heap only
sketch.setLevelsArray(myNewLevelsArr); //the KllSketch copy
if (sketchType == DOUBLES_SKETCH) {
final KllDoublesSketch dblSk = (KllDoublesSketch) sketch;
dblSk.setMinItem(minDouble);
dblSk.setMaxItem(maxDouble);
dblSk.setDoubleItemsArray(myNewDoubleItemsArr);
}
else if (sketchType == FLOATS_SKETCH) {
final KllFloatsSketch fltSk = (KllFloatsSketch) sketch;
fltSk.setMinItem(minFloat);
fltSk.setMaxItem(maxFloat);
fltSk.setFloatItemsArray(myNewFloatItemsArr);
}
else if (sketchType == LONGS_SKETCH) {
final KllLongsSketch lngSk = (KllLongsSketch) sketch;
lngSk.setMinItem(minLong);
lngSk.setMaxItem(maxLong);
lngSk.setLongItemsArray(myNewLongItemsArr);
}
else { //sketchType == ITEMS_SKETCH
final KllItemsSketch<?> itmSk = (KllItemsSketch<?>) sketch;
itmSk.setMinItem(minItem);
itmSk.setMaxItem(maxItem);
itmSk.setItemsArray(myNewItemsArr);
}
}