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  
12  package org.apache.hadoop.hbase.quotas;
13  
14  import org.apache.hadoop.hbase.classification.InterfaceAudience;
15  import org.apache.hadoop.hbase.classification.InterfaceStability;
16  import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
17  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
18  
19  /**
20   * In-Memory state of table or namespace quotas
21   */
22  @InterfaceAudience.Private
23  @InterfaceStability.Evolving
24  public class QuotaState {
25    private long lastUpdate = 0;
26    private long lastQuery = 0;
27    private QuotaLimiter globalLimiter = NoopQuotaLimiter.get();
28  
29    public QuotaState() {
30      this(0);
31    }
32  
33    public QuotaState(final long updateTs) {
34      lastUpdate = updateTs;
35    }
36  
37    public synchronized long getLastUpdate() {
38      return lastUpdate;
39    }
40  
41    public synchronized long getLastQuery() {
42      return lastQuery;
43    }
44  
45    @Override
46    public synchronized String toString() {
47      StringBuilder builder = new StringBuilder();
48      builder.append("QuotaState(ts=" + getLastUpdate());
49      if (isBypass()) {
50        builder.append(" bypass");
51      } else {
52        if (globalLimiter != NoopQuotaLimiter.get()) {
53          // builder.append(" global-limiter");
54          builder.append(" " + globalLimiter);
55        }
56      }
57      builder.append(')');
58      return builder.toString();
59    }
60  
61    /**
62     * @return true if there is no quota information associated to this object
63     */
64    public synchronized boolean isBypass() {
65      return globalLimiter == NoopQuotaLimiter.get();
66    }
67  
68    /**
69     * Setup the global quota information. (This operation is part of the QuotaState setup)
70     */
71    public synchronized void setQuotas(final Quotas quotas) {
72      if (quotas.hasThrottle()) {
73        globalLimiter = QuotaLimiterFactory.fromThrottle(quotas.getThrottle());
74      } else {
75        globalLimiter = NoopQuotaLimiter.get();
76      }
77    }
78  
79    /**
80     * Perform an update of the quota info based on the other quota info object. (This operation is
81     * executed by the QuotaCache)
82     */
83    public synchronized void update(final QuotaState other) {
84      if (globalLimiter == NoopQuotaLimiter.get()) {
85        globalLimiter = other.globalLimiter;
86      } else if (other.globalLimiter == NoopQuotaLimiter.get()) {
87        globalLimiter = NoopQuotaLimiter.get();
88      } else {
89        globalLimiter = QuotaLimiterFactory.update(globalLimiter, other.globalLimiter);
90      }
91      lastUpdate = other.lastUpdate;
92    }
93  
94    /**
95     * Return the limiter associated with this quota.
96     * @return the quota limiter
97     */
98    public synchronized QuotaLimiter getGlobalLimiter() {
99      setLastQuery(EnvironmentEdgeManager.currentTime());
100     return globalLimiter;
101   }
102 
103   /**
104    * Return the limiter associated with this quota without updating internal last query stats
105    * @return the quota limiter
106    */
107   synchronized QuotaLimiter getGlobalLimiterWithoutUpdatingLastQuery() {
108     return globalLimiter;
109   }
110 
111   public synchronized void setLastQuery(long lastQuery) {
112     this.lastQuery = lastQuery;
113   }
114 }