private void percolateDown(int pos) {
    if (size == 0) {
      return;
    }
    assert pos > 0;
    assert pos <= size;
    final int id = posToId[pos];
    final double value = posToValue[pos];
    int child;
    while ((child = firstChild(pos)) <= size) {
      // optimization: this is a very hot code path for performance of k-way merging,
      // so manually-unroll the loop over the 4 child elements to find the minimum value
      int minChild = child;
      double minValue = posToValue[child], childValue;
      if (++child <= size) {
        if (comparePosPos(childValue = posToValue[child], minValue, child, minChild) < 0) {
          minChild = child;
          minValue = childValue;
        }
        if (++child <= size) {
          if (comparePosPos(childValue = posToValue[child], minValue, child, minChild) < 0) {
            minChild = child;
            minValue = childValue;
          }
          if (++child <= size &&
            comparePosPos(childValue = posToValue[child], minValue, child, minChild) < 0) {
            minChild = child;
            minValue = childValue;
          }
        }
      }
      if (compareIdPos(value, minValue, id, minChild) <= 0) {
        break;
      }
      posToValue[pos] = minValue;
      idToPos[posToId[pos] = posToId[minChild]] = pos;
      pos = minChild;
    }
    posToId[pos] = id;
    posToValue[pos] = value;
    idToPos[id] = pos;
  }
@param elements the number of elements that can be stored in this heap. Currently the heap cannot be resized or
                shrunk/trimmed after initial creation. elements-1 is the maximum id that can be stored in this heap
planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ArrayDoubleMinHeap.java