001package io.prometheus.metrics.model.snapshots;
002
003import java.util.*;
004
005/**
006 * Immutable list of quantiles.
007 */
008public class Quantiles implements Iterable<Quantile> {
009
010    private final List<Quantile> quantiles;
011    public static final Quantiles EMPTY = new Quantiles(Collections.emptyList());
012
013    private Quantiles(List<Quantile> quantiles) {
014        quantiles = new ArrayList<>(quantiles);
015        quantiles.sort(Comparator.comparing(Quantile::getQuantile));
016        this.quantiles = Collections.unmodifiableList(quantiles);
017        validate();
018    }
019
020    private void validate() {
021        for (int i=0; i< quantiles.size() - 1; i++) {
022            if (quantiles.get(i).getQuantile() == quantiles.get(i+1).getQuantile()) {
023                throw new IllegalArgumentException("Duplicate " + quantiles.get(i).getQuantile() + " quantile.");
024            }
025        }
026    }
027
028     /**
029     * Create a new Quantiles instance.
030     * You can either create Quantiles with one of the static {@code Quantiles.of(...)} methods,
031     * or you can use the {@link Quantiles#builder()}.
032     */
033    public static Quantiles of(List<Quantile> quantiles) {
034        return new Quantiles(quantiles);
035    }
036
037    /**
038     * Create a new Quantiles instance.
039     * You can either create Quantiles with one of the static {@code Quantiles.of(...)} methods,
040     * or you can use the {@link Quantiles#builder()}.
041     */
042    public static Quantiles of(Quantile... quantiles) {
043        return of(Arrays.asList(quantiles));
044    }
045
046    public int size() {
047        return quantiles.size();
048    }
049
050    public Quantile get(int i) {
051        return quantiles.get(i);
052    }
053
054    @Override
055    public Iterator<Quantile> iterator() {
056        return quantiles.iterator();
057    }
058
059    public static Builder builder() {
060        return new Builder();
061    }
062
063    public static class Builder {
064
065        private final List<Quantile> quantiles = new ArrayList<>();
066
067        private Builder() {
068        }
069
070        /**
071         * Add a quantile. Call multiple times to add multiple quantiles.
072         */
073        public Builder quantile(Quantile quantile) {
074            quantiles.add(quantile);
075            return this;
076        }
077
078        /**
079         * Add a quantile. Call multiple times to add multiple quantiles.
080         * @param quantile 0.0 &lt;= quantile &lt;= 1.0
081         */
082        public Builder quantile(double quantile, double value) {
083            quantiles.add(new Quantile(quantile, value));
084            return this;
085        }
086
087        public Quantiles build() {
088            return new Quantiles(quantiles);
089        }
090    }
091
092}