in src/main/java/org/apache/datasketches/hll/Hll4Update.java [123:199]
private static final void shiftToBiggerCurMin(final AbstractHllArray host) {
final int oldCurMin = host.getCurMin();
final int newCurMin = oldCurMin + 1;
final int lgConfigK = host.getLgConfigK();
final int configK = 1 << lgConfigK;
final int configKmask = configK - 1;
int numAtNewCurMin = 0;
int numAuxTokens = 0;
// Walk through the slots of 4-bit array decrementing stored values by one unless it
// equals AUX_TOKEN, where it is left alone but counted to be checked later.
// If oldStoredValue is 0 it is an error.
// If the decremented value is 0, we increment numAtNewCurMin.
// Because getNibble is masked to 4 bits oldStoredValue can never be > 15 or negative
for (int i = 0; i < configK; i++) { //724
int oldStoredNibble = host.getNibble(i);
if (oldStoredNibble == 0) {
throw new SketchesStateException("Array slots cannot be 0 at this point.");
}
if (oldStoredNibble < AUX_TOKEN) {
host.putNibble(i, --oldStoredNibble);
if (oldStoredNibble == 0) { numAtNewCurMin++; }
} else { //oldStoredNibble == AUX_TOKEN
numAuxTokens++;
assert host.getAuxHashMap() != null : "AuxHashMap cannot be null at this point.";
}
}
//If old AuxHashMap exists, walk through it updating some slots and build a new AuxHashMap
// if needed.
AuxHashMap newAuxMap = null;
final AuxHashMap oldAuxMap = host.getAuxHashMap();
if (oldAuxMap != null) {
int slotNum;
int oldActualVal;
int newShiftedVal;
final PairIterator itr = oldAuxMap.getIterator();
while (itr.nextValid()) {
slotNum = itr.getKey() & configKmask;
oldActualVal = itr.getValue();
newShiftedVal = oldActualVal - newCurMin;
assert newShiftedVal >= 0;
assert host.getNibble(slotNum) == AUX_TOKEN
: "Array slot != AUX_TOKEN: " + host.getNibble(slotNum);
if (newShiftedVal < AUX_TOKEN) { //756
assert (newShiftedVal == 14);
// The former exception value isn't one anymore, so it stays out of new AuxHashMap.
// Correct the AUX_TOKEN value in the HLL array to the newShiftedVal (14).
host.putNibble(slotNum, newShiftedVal);
numAuxTokens--;
}
else { //newShiftedVal >= AUX_TOKEN
// the former exception remains an exception, so must be added to the newAuxMap
if (newAuxMap == null) {
//Note: even in the direct case we use a heap aux map temporarily
newAuxMap = new HeapAuxHashMap(LG_AUX_ARR_INTS[lgConfigK], lgConfigK);
}
newAuxMap.mustAdd(slotNum, oldActualVal);
}
} //end scan of oldAuxMap
} //end if (auxHashMap != null)
else { //oldAuxMap == null
assert numAuxTokens == 0 : "auxTokens: " + numAuxTokens;
}
if (newAuxMap != null) {
assert newAuxMap.getAuxCount() == numAuxTokens : "auxCount: " + newAuxMap.getAuxCount()
+ ", HLL tokens: " + numAuxTokens;
}
host.putAuxHashMap(newAuxMap, false); //if we are direct, this will do the right thing
host.putCurMin(newCurMin);
host.putNumAtCurMin(numAtNewCurMin);
} //end of shiftToBiggerCurMin