content: /*
   * Copyright 1999-2018 Alibaba Group Holding Ltd.
   *
   * 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.
   */
  package com.alibaba.csp.sentinel.slots.statistic.data;
  
  import com.alibaba.csp.sentinel.config.SentinelConfig;
  import com.alibaba.csp.sentinel.slots.statistic.MetricEvent;
  import java.util.concurrent.atomic.LongAdder;
  
  /**
   * Represents metrics data in a period of time span.
   *
   * @author jialiang.linjl
   * @author Eric Zhao
   */
  public class MetricBucket {
  
      private final LongAdder[] counters;
  
      private volatile long minRt;
  
      public MetricBucket() {
          MetricEvent[] events = MetricEvent.values();
          this.counters = new LongAdder[events.length];
          for (MetricEvent event : events) {
              counters[event.ordinal()] = new LongAdder();
          }
          initMinRt();
      }
  
      public MetricBucket reset(MetricBucket bucket) {
          for (MetricEvent event : MetricEvent.values()) {
              counters[event.ordinal()].reset();
              counters[event.ordinal()].add(bucket.get(event));
          }
          initMinRt();
          return this;
      }
  
      private void initMinRt() {
          this.minRt = SentinelConfig.statisticMaxRt();
      }
  
      /**
       * Reset the adders.
       *
       * @return new metric bucket in initial state
       */
      public MetricBucket reset() {
          for (MetricEvent event : MetricEvent.values()) {
              counters[event.ordinal()].reset();
          }
          initMinRt();
          return this;
      }
  
      public long get(MetricEvent event) {
          return counters[event.ordinal()].sum();
      }
  
      public MetricBucket add(MetricEvent event, long n) {
          counters[event.ordinal()].add(n);
          return this;
      }
  
      public long pass() {
          return get(MetricEvent.PASS);
      }
  
      public long occupiedPass() {
          return get(MetricEvent.OCCUPIED_PASS);
      }
  
      public long block() {
          return get(MetricEvent.BLOCK);
      }
  
      public long exception() {
          return get(MetricEvent.EXCEPTION);
      }
  
      public long rt() {
          return get(MetricEvent.RT);
      }
  
      public long minRt() {
          return minRt;
      }
  
      public long success() {
          return get(MetricEvent.SUCCESS);
      }
  
      public void addPass(int n) {
          add(MetricEvent.PASS, n);
      }
  
      public void addOccupiedPass(int n) {
          add(MetricEvent.OCCUPIED_PASS, n);
      }
  
      public void addException(int n) {
          add(MetricEvent.EXCEPTION, n);
      }
  
      public void addBlock(int n) {
          add(MetricEvent.BLOCK, n);
      }
  
      public void addSuccess(int n) {
          add(MetricEvent.SUCCESS, n);
      }
  
      public void addRT(long rt) {
          add(MetricEvent.RT, rt);
  
          // Not thread-safe, but it's okay.
          if (rt < minRt) {
              minRt = rt;
          }
      }
  
      @Override
      public String toString() {
          return "p: " + pass() + ", b: " + block() + ", w: " + occupiedPass();
      }
  }
  