// Path: metrics/src/main/java/io/confluent/common/metrics/CompoundStat.java
// @Deprecated
// public interface CompoundStat extends Stat {
// 
//   public List<NamedMeasurable> stats();
// 
//   public static class NamedMeasurable {
// 
//     private final MetricName name;
//     private final Measurable stat;
// 
//     public NamedMeasurable(MetricName name, Measurable stat) {
//       super();
//       this.name = name;
//       this.stat = stat;
//     }
// 
//     public MetricName name() {
//       return name;
//     }
// 
//     public Measurable stat() {
//       return stat;
//     }
// 
//   }
// 
// }
// 
// Path: metrics/src/main/java/io/confluent/common/metrics/Measurable.java
// @Deprecated
// public interface Measurable {
// 
//   /**
//    * Measure this quantity and return the result as a double
//    *
//    * @param config The configuration for this metric
//    * @param now    The POSIX time in milliseconds the measurement is being taken
//    * @return The measured value
//    */
//   public double measure(MetricConfig config, long now);
// 
// }
// 
// Path: metrics/src/main/java/io/confluent/common/metrics/MetricConfig.java
// @Deprecated
// public class MetricConfig {
// 
//   private Quota quota;
//   private int samples;
//   private long eventWindow;
//   private long timeWindowMs;
//   private TimeUnit unit;
// 
//   public MetricConfig() {
//     super();
//     this.quota = null;
//     this.samples = 2;
//     this.eventWindow = Long.MAX_VALUE;
//     this.timeWindowMs = TimeUnit.MILLISECONDS.convert(30, TimeUnit.SECONDS);
//     this.unit = TimeUnit.SECONDS;
//   }
// 
//   public Quota quota() {
//     return this.quota;
//   }
// 
//   public MetricConfig quota(Quota quota) {
//     this.quota = quota;
//     return this;
//   }
// 
//   public long eventWindow() {
//     return eventWindow;
//   }
// 
//   public MetricConfig eventWindow(long window) {
//     this.eventWindow = window;
//     return this;
//   }
// 
//   public long timeWindowMs() {
//     return timeWindowMs;
//   }
// 
//   public MetricConfig timeWindow(long window, TimeUnit unit) {
//     this.timeWindowMs = TimeUnit.MILLISECONDS.convert(window, unit);
//     return this;
//   }
// 
//   public int samples() {
//     return this.samples;
//   }
// 
//   public MetricConfig samples(int samples) {
//     if (samples < 1) {
//       throw new IllegalArgumentException("The number of samples must be at least 1.");
//     }
//     this.samples = samples;
//     return this;
//   }
// 
//   public TimeUnit timeUnit() {
//     return unit;
//   }
// 
//   public MetricConfig timeUnit(TimeUnit unit) {
//     this.unit = unit;
//     return this;
//   }
// }


import java.util.ArrayList;
import java.util.List;
import io.confluent.common.metrics.CompoundStat;
import io.confluent.common.metrics.Measurable;
import io.confluent.common.metrics.MetricConfig;
/**
 * Copyright 2015 Confluent Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/

/**
 * Original license:
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
 * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package io.confluent.common.metrics.stats;



/**
 * A compound stat that reports one or more percentiles
 */
public class Percentiles extends SampledStat implements CompoundStat {

  private final int buckets;
  private final Percentile[] percentiles;
  private final Histogram.BinScheme binScheme;

  public Percentiles(int sizeInBytes, double max, BucketSizing bucketing,
                     Percentile... percentiles) {
    this(sizeInBytes, 0.0, max, bucketing, percentiles);
  }

  public Percentiles(int sizeInBytes, double min, double max, BucketSizing bucketing,
                     Percentile... percentiles) {
    super(0.0);
    this.percentiles = percentiles;
    this.buckets = sizeInBytes / 4;
    if (bucketing == BucketSizing.CONSTANT) {
      this.binScheme = new Histogram.ConstantBinScheme(buckets, min, max);
    } else if (bucketing == BucketSizing.LINEAR) {
      if (min != 0.0d) {
        throw new IllegalArgumentException("Linear bucket sizing requires min to be 0.0.");
      }
      this.binScheme = new Histogram.LinearBinScheme(buckets, max);
    } else {
      throw new IllegalArgumentException("Unknown bucket type: " + bucketing);
    }
  }

  @Override
  public List<CompoundStat.NamedMeasurable> stats() {
    List<NamedMeasurable> ms = new ArrayList<NamedMeasurable>(this.percentiles.length);
    for (Percentile percentile : this.percentiles) {
      final double pct = percentile.percentile();
// Path: metrics/src/main/java/io/confluent/common/metrics/CompoundStat.java
// @Deprecated
// public interface CompoundStat extends Stat {
// 
//   public List<NamedMeasurable> stats();
// 
//   public static class NamedMeasurable {
// 
//     private final MetricName name;
//     private final Measurable stat;
// 
//     public NamedMeasurable(MetricName name, Measurable stat) {
//       super();
//       this.name = name;
//       this.stat = stat;
//     }
// 
//     public MetricName name() {
//       return name;
//     }
// 
//     public Measurable stat() {
//       return stat;
//     }
// 
//   }
// 
// }
// 
// Path: metrics/src/main/java/io/confluent/common/metrics/Measurable.java
// @Deprecated
// public interface Measurable {
// 
//   /**
//    * Measure this quantity and return the result as a double
//    *
//    * @param config The configuration for this metric
//    * @param now    The POSIX time in milliseconds the measurement is being taken
//    * @return The measured value
//    */
//   public double measure(MetricConfig config, long now);
// 
// }
// 
// Path: metrics/src/main/java/io/confluent/common/metrics/MetricConfig.java
// @Deprecated
// public class MetricConfig {
// 
//   private Quota quota;
//   private int samples;
//   private long eventWindow;
//   private long timeWindowMs;
//   private TimeUnit unit;
// 
//   public MetricConfig() {
//     super();
//     this.quota = null;
//     this.samples = 2;
//     this.eventWindow = Long.MAX_VALUE;
//     this.timeWindowMs = TimeUnit.MILLISECONDS.convert(30, TimeUnit.SECONDS);
//     this.unit = TimeUnit.SECONDS;
//   }
// 
//   public Quota quota() {
//     return this.quota;
//   }
// 
//   public MetricConfig quota(Quota quota) {
//     this.quota = quota;
//     return this;
//   }
// 
//   public long eventWindow() {
//     return eventWindow;
//   }
// 
//   public MetricConfig eventWindow(long window) {
//     this.eventWindow = window;
//     return this;
//   }
// 
//   public long timeWindowMs() {
//     return timeWindowMs;
//   }
// 
//   public MetricConfig timeWindow(long window, TimeUnit unit) {
//     this.timeWindowMs = TimeUnit.MILLISECONDS.convert(window, unit);
//     return this;
//   }
// 
//   public int samples() {
//     return this.samples;
//   }
// 
//   public MetricConfig samples(int samples) {
//     if (samples < 1) {
//       throw new IllegalArgumentException("The number of samples must be at least 1.");
//     }
//     this.samples = samples;
//     return this;
//   }
// 
//   public TimeUnit timeUnit() {
//     return unit;
//   }
// 
//   public MetricConfig timeUnit(TimeUnit unit) {
//     this.unit = unit;
//     return this;
//   }
// }


// Path: metrics/src/main/java/io/confluent/common/metrics/stats/Percentiles.java
import java.util.ArrayList;
import java.util.List;
import io.confluent.common.metrics.CompoundStat;
import io.confluent.common.metrics.Measurable;
import io.confluent.common.metrics.MetricConfig;

/**
 * Copyright 2015 Confluent Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/

/**
 * Original license:
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
 * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package io.confluent.common.metrics.stats;



/**
 * A compound stat that reports one or more percentiles
 */
public class Percentiles extends SampledStat implements CompoundStat {

  private final int buckets;
  private final Percentile[] percentiles;
  private final Histogram.BinScheme binScheme;

  public Percentiles(int sizeInBytes, double max, BucketSizing bucketing,
                     Percentile... percentiles) {
    this(sizeInBytes, 0.0, max, bucketing, percentiles);
  }

  public Percentiles(int sizeInBytes, double min, double max, BucketSizing bucketing,
                     Percentile... percentiles) {
    super(0.0);
    this.percentiles = percentiles;
    this.buckets = sizeInBytes / 4;
    if (bucketing == BucketSizing.CONSTANT) {
      this.binScheme = new Histogram.ConstantBinScheme(buckets, min, max);
    } else if (bucketing == BucketSizing.LINEAR) {
      if (min != 0.0d) {
        throw new IllegalArgumentException("Linear bucket sizing requires min to be 0.0.");
      }
      this.binScheme = new Histogram.LinearBinScheme(buckets, max);
    } else {
      throw new IllegalArgumentException("Unknown bucket type: " + bucketing);
    }
  }

  @Override
  public List<CompoundStat.NamedMeasurable> stats() {
    List<NamedMeasurable> ms = new ArrayList<NamedMeasurable>(this.percentiles.length);
    for (Percentile percentile : this.percentiles) {
      final double pct = percentile.percentile();
      ms.add(new NamedMeasurable(percentile.name(), new Measurable() {