static void mergeFloatImpl()

in src/main/java/org/apache/datasketches/kll/KllFloatsHelper.java [38:139]


  static void mergeFloatImpl(final KllFloatsSketch mySketch, final KllSketch other) {
    final KllFloatsSketch otherFltSk = (KllFloatsSketch) other;
    if (otherFltSk.isEmpty()) { return; }
    mySketch.nullSortedView();
    final long finalN = mySketch.getN() + otherFltSk.getN();
    final int otherNumLevels = otherFltSk.getNumLevels();
    final int[] otherLevelsArr = otherFltSk.getLevelsArray();
    final float[] otherFloatItemsArr;
    //capture my min & max, minK
    final float myMin = mySketch.isEmpty() ? Float.NaN : mySketch.getMinFloatItem();
    final float myMax = mySketch.isEmpty() ? Float.NaN : mySketch.getMaxFloatItem();
    final int myMinK = mySketch.getMinK();

    //update this sketch with level0 items from the other sketch
    if (otherFltSk.isCompactSingleItem()) {
      updateFloat(mySketch, otherFltSk.getFloatSingleItem());
      otherFloatItemsArr = new float[0];
    } else {
      otherFloatItemsArr = otherFltSk.getFloatItemsArray();
      for (int i = otherLevelsArr[0]; i < otherLevelsArr[1]; i++) {
       updateFloat(mySketch, otherFloatItemsArr[i]);
      }
    }
    // after the level 0 update, we capture the state of levels and items arrays
    final int myCurNumLevels = mySketch.getNumLevels();
    final int[] myCurLevelsArr = mySketch.getLevelsArray();
    final float[] myCurFloatItemsArr = mySketch.getFloatItemsArray();

    int myNewNumLevels = myCurNumLevels;
    int[] myNewLevelsArr = myCurLevelsArr;
    float[] myNewFloatItemsArr = myCurFloatItemsArr;

    if (otherNumLevels > 1  && !otherFltSk.isCompactSingleItem()) { //now merge higher levels if they exist
      final int tmpSpaceNeeded = mySketch.getNumRetained()
          + KllHelper.getNumRetainedAboveLevelZero(otherNumLevels, otherLevelsArr);
      final float[] workbuf = new float[tmpSpaceNeeded];
      final int ub = KllHelper.ubOnNumLevels(finalN);
      final int[] worklevels = new int[ub + 2]; // ub+1 does not work
      final int[] outlevels  = new int[ub + 2];

      final int provisionalNumLevels = max(myCurNumLevels, otherNumLevels);

      populateFloatWorkArrays(workbuf, worklevels, provisionalNumLevels,
          myCurNumLevels, myCurLevelsArr, myCurFloatItemsArr,
          otherNumLevels, otherLevelsArr, otherFloatItemsArr);

      // notice that workbuf is being used as both the input and output
      final int[] result = generalFloatsCompress(mySketch.getK(), mySketch.getM(), provisionalNumLevels,
          workbuf, worklevels, workbuf, outlevels, mySketch.isLevelZeroSorted(), KllSketch.random);
      final int targetItemCount = result[1]; //was finalCapacity. Max size given k, m, numLevels
      final int curItemCount = result[2]; //was finalPop

      // now we need to finalize the results for the "self" sketch

      //THE NEW NUM LEVELS
      myNewNumLevels = result[0]; //was finalNumLevels
      assert myNewNumLevels <= ub; // ub may be much bigger

      // THE NEW ITEMS ARRAY (was newbuf)
      myNewFloatItemsArr = (targetItemCount == myCurFloatItemsArr.length)
          ? myCurFloatItemsArr
          : new float[targetItemCount];
      final int freeSpaceAtBottom = targetItemCount - curItemCount;
      //shift the new items array
      System.arraycopy(workbuf, outlevels[0], myNewFloatItemsArr, freeSpaceAtBottom, curItemCount);
      final int theShift = freeSpaceAtBottom - outlevels[0];

      //calculate the new levels array length
      final int finalLevelsArrLen;
      if (myCurLevelsArr.length < myNewNumLevels + 1) { finalLevelsArrLen = myNewNumLevels + 1; }
      else { finalLevelsArrLen = myCurLevelsArr.length; }

      //THE NEW LEVELS ARRAY
      myNewLevelsArr = new int[finalLevelsArrLen];
      for (int lvl = 0; lvl < myNewNumLevels + 1; lvl++) { // includes the "extra" index
        myNewLevelsArr[lvl] = outlevels[lvl] + theShift;
      }

      //MEMORY SPACE MANAGEMENT
      if (mySketch.serialVersionUpdatable) {
        mySketch.wmem = KllHelper.memorySpaceMgmt(mySketch, myNewLevelsArr.length, myNewFloatItemsArr.length);
      }
    }

    //Update Preamble:
    mySketch.setN(finalN);
    if (otherFltSk.isEstimationMode()) { //otherwise the merge brings over exact items.
      mySketch.setMinK(min(myMinK, otherFltSk.getMinK()));
    }

    //Update numLevels, levelsArray, items
    mySketch.setNumLevels(myNewNumLevels);
    mySketch.setLevelsArray(myNewLevelsArr);
    mySketch.setFloatItemsArray(myNewFloatItemsArr);

    //Update min, max items
    final float otherMin = otherFltSk.getMinFloatItem();
    final float otherMax = otherFltSk.getMaxFloatItem();
    mySketch.setMinFloatItem(resolveFloatMinItem(myMin, otherMin));
    mySketch.setMaxFloatItem(resolveFloatMaxItem(myMax, otherMax));
    assert KllHelper.sumTheSampleWeights(mySketch.getNumLevels(), mySketch.getLevelsArray()) == mySketch.getN();
  }