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