docs: void decreaseKBy1() {
      if (k_ <= 1) {
        throw new SketchesStateException("Cannot decrease k below 1 in union");
      }
  
      if ((h_ == 0) && (r_ == 0)) {
        // exact mode, but no data yet; this reduction is somewhat gratuitous
        --k_;
      } else if ((h_ > 0) && (r_ == 0)) {
        // exact mode, but we have some data
        --k_;
        if (h_ > k_) {
          transitionFromWarmup();
        }
      } else if ((h_ > 0) && (r_ > 0)) {
        // reservoir mode, but we have some exact samples.
        // Our strategy will be to pull an item out of H (which we are allowed to do since it's
        // still just data), reduce k, and then re-insert the item
  
        // first, slide the R zone to the left by 1, temporarily filling the gap
        final int oldGapIdx = h_;
        final int oldFinalRIdx = (h_ + 1 + r_) - 1;
  
        assert oldFinalRIdx == k_;
        swapValues(oldFinalRIdx, oldGapIdx);
  
        // now we pull an item out of H; any item is ok, but if we grab the rightmost and then
        // reduce h_, the heap invariant will be preserved (and the gap will be restored), plus
        // the push() of the item that will probably happen later will be cheap.
  
        final int pulledIdx = h_ - 1;
        final T pulledItem = data_.get(pulledIdx);
        final double pulledWeight = weights_.get(pulledIdx);
        final boolean pulledMark = marks_.get(pulledIdx);
  
        if (pulledMark) { --numMarksInH_; }
        weights_.set(pulledIdx, -1.0); // to make bugs easier to spot
  
        --h_;
        --k_;
        --n_; // will be re-incremented with the update
  
        update(pulledItem, pulledWeight, pulledMark);
      } else if ((h_ == 0) && (r_ > 0)) {
        // pure reservoir mode, so can simply eject a randomly chosen sample from the reservoir
        assert r_ >= 2;
  
        final int rIdxToDelete = 1 + SamplingUtil.rand.nextInt(r_); // 1 for the gap
        final int rightmostRIdx = (1 + r_) - 1;
        swapValues(rIdxToDelete, rightmostRIdx);
        weights_.set(rightmostRIdx, -1.0);
  
        --k_;
        --r_;
      }
    }