View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional information regarding
4    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
8    * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
9    * for the specific language governing permissions and limitations under the License.
10   */
11  package org.apache.hadoop.hbase.quotas;
12  
13  import org.apache.hadoop.hbase.classification.InterfaceAudience;
14  import org.apache.hadoop.hbase.classification.InterfaceStability;
15  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
16  import com.google.common.annotations.VisibleForTesting;
17  
18  /**
19   * This limiter will refill resources at every TimeUnit/resources interval. For example: For a
20   * limiter configured with 10resources/second, then 1 resource will be refilled after every 100ms
21   * (1sec/10resources)
22   */
23  @InterfaceAudience.Private
24  @InterfaceStability.Evolving
25  public class AverageIntervalRateLimiter extends RateLimiter {
26    private long nextRefillTime = -1L;
27  
28    @Override
29    public long refill(long limit) {
30      final long now = EnvironmentEdgeManager.currentTime();
31      if (nextRefillTime == -1) {
32        // Till now no resource has been consumed.
33        nextRefillTime = EnvironmentEdgeManager.currentTime();
34        return limit;
35      }
36  
37      long timeInterval = now - nextRefillTime;
38      long delta = 0;
39      long timeUnitInMillis = super.getTimeUnitInMillis();
40      if (timeInterval >= timeUnitInMillis) {
41        delta = limit;
42      } else if (timeInterval > 0) {
43        double r = ((double)timeInterval / (double)timeUnitInMillis) * limit;
44        delta = (long)r;
45      }
46  
47      if (delta > 0) {
48        this.nextRefillTime = now;
49      }
50  
51      return delta;
52    }
53  
54    @Override
55    public long getWaitInterval(long limit, long available, long amount) {
56      if (nextRefillTime == -1) {
57        return 0;
58      }
59  
60      double r = ((double)(amount - available)) * super.getTimeUnitInMillis() / limit;
61      return (long)r;
62    }
63  
64    // This method is for strictly testing purpose only
65    @VisibleForTesting
66    @Override
67    public void setNextRefillTime(long nextRefillTime) {
68      this.nextRefillTime = nextRefillTime;
69    }
70  
71    @VisibleForTesting
72    @Override
73    public long getNextRefillTime() {
74      return this.nextRefillTime;
75    }
76  
77  }