code: public List<Long> getQuantilesUpperBound(List<Double> quantiles)
      {
          checkArgument(Ordering.natural().isOrdered(quantiles), "quantiles must be sorted in increasing order");
          for (double quantile : quantiles) {
              checkArgument(quantile >= 0 && quantile <= 1, "quantile must be between [0,1]");
          }
  
          final ImmutableList.Builder<Long> builder = ImmutableList.builder();
          final PeekingIterator<Double> iterator = Iterators.peekingIterator(quantiles.iterator());
  
          postOrderTraversal(root, new Callback()
          {
              private double sum;
  
              public boolean process(int node)
              {
                  sum += counts[node];
  
                  while (iterator.hasNext() && sum > iterator.peek() * weightedCount) {
                      iterator.next();
  
                      // we know the max value ever seen, so cap the percentile to provide better error
                      // bounds in this case
                      long value = Math.min(upperBound(node), max);
  
                      builder.add(value);
                  }
  
                  return iterator.hasNext();
              }
          });
  
          // we finished the traversal without consuming all quantiles. This means the remaining quantiles
          // correspond to the max known value
          while (iterator.hasNext()) {
              builder.add(max);
              iterator.next();
          }
  
          return builder.build();
      }
docs: Get an upper bound on the quantiles for the given proportions. A returned q quantile is guaranteed to be within
  the q and q + maxError quantiles.
  <p>
  The input list of quantile proportions must be sorted in increasing order, and each value must be in the range [0, 1]