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