func shiftToBiggerCurMin()

in hll/hll_4update.go [128:225]


func shiftToBiggerCurMin(h *hll4ArrayImpl) error {
	var (
		oldCurMin   = h.curMin
		newCurMin   = oldCurMin + 1
		lgConfigK   = h.lgConfigK
		configK     = 1 << lgConfigK
		configKmask = configK - 1

		numAtNewCurMin = 0
		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 i := 0; i < configK; i++ { //724
		oldStoredNibble := uint64(h.getNibble(i))
		if oldStoredNibble == 0 {
			return fmt.Errorf("array slots cannot be 0 at this point")
		}
		if oldStoredNibble < auxToken {
			oldStoredNibble--
			h.putNibble(i, byte(oldStoredNibble))
			if oldStoredNibble == 0 {
				numAtNewCurMin++
			}
		} else { //oldStoredNibble == AUX_TOKEN
			numAuxTokens++
			if h.auxHashMap == nil {
				return fmt.Errorf("auxHashMap cannot be nil at this point")
			}
		}
	}
	// If old auxHashMap exists, walk through it updating some slots and build a new auxHashMap
	// if needed.
	var (
		newAuxMap *auxHashMap
		oldAuxMap = h.auxHashMap
	)

	if oldAuxMap != nil {
		var (
			slotNum       int
			oldActualVal  int
			newShiftedVal int
			err           error
		)

		itr := oldAuxMap.iterator()
		for itr.nextValid() {
			slotNum = itr.getKey() & configKmask
			oldActualVal, err = itr.getValue()
			if err != nil {
				return err
			}
			newShiftedVal = oldActualVal - newCurMin
			if newShiftedVal < 0 {
				return fmt.Errorf("newShiftedVal < 0")
			}
			if h.getNibble(slotNum) != auxToken {
				return fmt.Errorf(fmt.Sprintf("Array slot != AUX_TOKEN %d", h.getNibble(slotNum)))
			}
			if newShiftedVal < auxToken {
				if newShiftedVal != 14 {
					return fmt.Errorf("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).
				h.putNibble(slotNum, byte(newShiftedVal))
				numAuxTokens--
			} else { // newShiftedVal >= AUX_TOKEN
				// the former exception remains an exception, so must be added to the newAuxMap
				if newAuxMap == nil {
					newAuxMap = h.getNewAuxHashMap()
				}
				err := newAuxMap.mustAdd(slotNum, oldActualVal)
				if err != nil {
					return err
				}
			}
		}
	} else {
		if numAuxTokens != 0 {
			return fmt.Errorf("numAuxTokens != 0")
		}
	}
	if newAuxMap != nil {
		if newAuxMap.getAuxCount() != numAuxTokens {
			return fmt.Errorf("newAuxMap.getAuxCount() != numAuxTokens")
		}
	}
	h.auxHashMap = newAuxMap
	h.curMin = newCurMin
	h.numAtCurMin = numAtNewCurMin
	return nil
}