in hll/include/Hll4Array-internal.hpp [170:236]
void Hll4Array<A>::internalHll4Update(uint32_t slotNo, uint8_t newVal) {
const uint8_t rawStoredOldValue = getSlot(slotNo); // could be a 0
// this is provably a LB:
const uint8_t lbOnOldValue = rawStoredOldValue + this->curMin_; // lower bound, could be 0
if (newVal > lbOnOldValue) { // 842
// Note: if an AUX_TOKEN exists, then auxHashMap must already exist
// 846: rawStoredOldValue == AUX_TOKEN
const uint8_t actualOldValue = (rawStoredOldValue < hll_constants::AUX_TOKEN)
? (lbOnOldValue) : (auxHashMap_->mustFindValueFor(slotNo));
if (newVal > actualOldValue) { // 848: actualOldValue could still be 0; newValue > 0
// we know that the array will change, but we haven't actually updated yet
this->hipAndKxQIncrementalUpdate(actualOldValue, newVal);
// newVal >= curMin
const uint8_t shiftedNewValue = newVal - this->curMin_; // 874
// redundant since we know newVal >= curMin,
// and lgConfigK bounds do not allow overflowing an int
//assert(shiftedNewValue >= 0);
if (rawStoredOldValue == hll_constants::AUX_TOKEN) { // 879
// Given that we have an AUX_TOKEN, there are 4 cases for how to
// actually modify the data structure
if (shiftedNewValue >= hll_constants::AUX_TOKEN) { // case 1: 881
// the byte array already contains aux token
// This is the case where old and new values are both exceptions.
// The 4-bit array already is AUX_TOKEN, only need to update auxHashMap
auxHashMap_->mustReplace(slotNo, newVal);
}
else { // case 2: 885
// This is the hypothetical case where the old value is an exception and the new one is not,
// which is impossible given that curMin has not changed here and newVal > oldValue
}
} else { // rawStoredOldValue != AUX_TOKEN
if (shiftedNewValue >= hll_constants::AUX_TOKEN) { // case 3: 892
// This is the case where the old value is not an exception and the new value is.
// The AUX_TOKEN must be stored in the 4-bit array and the new value
// added to the exception table
putSlot(slotNo, hll_constants::AUX_TOKEN);
if (auxHashMap_ == nullptr) {
auxHashMap_ = AuxHashMap<A>::newAuxHashMap(hll_constants::LG_AUX_ARR_INTS[this->lgConfigK_],
this->lgConfigK_, this->getAllocator());
}
auxHashMap_->mustAdd(slotNo, newVal);
}
else { // case 4: 897
// This is the case where neither the old value nor the new value is an exception.
// We just overwrite the 4-bit array with the shifted new value.
putSlot(slotNo, shiftedNewValue);
}
}
// we just increased a pair value, so it might be time to change curMin
if (actualOldValue == this->curMin_) { // 908
--(this->numAtCurMin_);
while (this->numAtCurMin_ == 0) {
shiftToBiggerCurMin(); // increases curMin by 1, builds a new aux table
// shifts values in 4-bit table and recounts curMin
}
}
} // end newVal <= actualOldValue
} // end newValue <= lbOnOldValue -> return, no need to update array
}