public static EbppsItemsSketch heapify()

in src/main/java/org/apache/datasketches/sampling/EbppsItemsSketch.java [117:210]


  public static <T> EbppsItemsSketch<T> heapify(final Memory srcMem,
                                                final ArrayOfItemsSerDe<T> serDe)
  {
    final int numPreLongs = PreambleUtil.getAndCheckPreLongs(srcMem);
    final int serVer = PreambleUtil.extractSerVer(srcMem);
    final int familyId = PreambleUtil.extractFamilyID(srcMem);
    final int flags = PreambleUtil.extractFlags(srcMem);
    final boolean isEmpty = (flags & EMPTY_FLAG_MASK) != 0;
    final boolean hasPartialItem = (flags & HAS_PARTIAL_ITEM_MASK) != 0;

    // Check values
    if (isEmpty) {
      if (numPreLongs != Family.EBPPS.getMinPreLongs()) {
        throw new SketchesArgumentException("Possible corruption: Must be " + Family.EBPPS.getMinPreLongs()
                + " for an empty sketch. Found: " + numPreLongs);
      }
    } else {
      if (numPreLongs != Family.EBPPS.getMaxPreLongs()) {
        throw new SketchesArgumentException("Possible corruption: Must be "
                + Family.EBPPS.getMaxPreLongs() + " for a non-empty sketch. Found: " + numPreLongs);
      }
    }
    if (serVer != EBPPS_SER_VER) {
        throw new SketchesArgumentException(
                "Possible Corruption: Ser Ver must be " + EBPPS_SER_VER + ": " + serVer);
    }
    final int reqFamilyId = Family.EBPPS.getID();
    if (familyId != reqFamilyId) {
      throw new SketchesArgumentException(
              "Possible Corruption: FamilyID must be " + reqFamilyId + ": " + familyId);
    }

    final int k = PreambleUtil.extractK(srcMem);
    if (k < 1 || k > MAX_K) {
      throw new SketchesArgumentException("Possible Corruption: k must be at least 1 "
              + "and less than " + MAX_K + ". Found: " + k);
    }

    if (isEmpty) {
      return new EbppsItemsSketch<>(k);
    }

    final long n = PreambleUtil.extractN(srcMem);
    if (n < 0) {
      throw new SketchesArgumentException("Possible Corruption: n cannot be negative: " + n);
    }

    final double cumWt = PreambleUtil.extractEbppsCumulativeWeight(srcMem);
    if (cumWt < 0.0 || Double.isNaN(cumWt) || Double.isInfinite(cumWt)) {
      throw new SketchesArgumentException("Possible Corruption: cumWt must be nonnegative and finite: " + cumWt);
    }

    final double maxWt = PreambleUtil.extractEbppsMaxWeight(srcMem);
    if (maxWt < 0.0 || Double.isNaN(maxWt) || Double.isInfinite(maxWt)) {
      throw new SketchesArgumentException("Possible Corruption: maxWt must be nonnegative and finite: " + maxWt);
    }

    final double rho = PreambleUtil.extractEbppsRho(srcMem);
    if (rho < 0.0 || rho > 1.0 ||  Double.isNaN(rho) || Double.isInfinite(rho)) {
      throw new SketchesArgumentException("Possible Corruption: rho must be in [0.0, 1.0]: " + rho);
    }

    // extract C (part of sample_, not the preamble)
    // due to numeric precision issues, c may occasionally be very slightly larger than k
    final double c = srcMem.getDouble(EBPPS_C_DOUBLE);
    if (c < 0 || c >= (k + 1) || Double.isNaN(c) || Double.isInfinite(c)) {
      throw new SketchesArgumentException("Possible Corruption: c must be between 0 and k: " + c);
    }

    // extract items
    final int numTotalItems = (int) Math.ceil(c);
    final int numFullItems = (int) Math.floor(c); // floor() not strictly necessary
    final int offsetBytes = EBPPS_ITEMS_START;
    final T[] rawItems = serDe.deserializeFromMemory(
            srcMem.region(offsetBytes, srcMem.getCapacity() - offsetBytes), 0, numTotalItems);
    final List<T> itemsList = Arrays.asList(rawItems);
    final ArrayList<T> data;
    final T partialItem;
    if (hasPartialItem) {
      if (numFullItems >= numTotalItems) {
        throw new SketchesArgumentException("Possible Corruption: Expected partial item but none found");
      }

      data = new ArrayList<>(itemsList.subList(0, numFullItems));
      partialItem = itemsList.get(numFullItems); // 0-based, so last item
    } else {
      data = new ArrayList<>(itemsList);
      partialItem = null; // just to be explicit
    }

    final EbppsItemsSample<T> sample = new EbppsItemsSample<>(data, partialItem, c);

    return new EbppsItemsSketch<>(sample, k, n, cumWt, maxWt, rho);
  }