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  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",
25    justification="FindBugs seems confused; says globalLimiter and lastUpdate " +
26    "are mostly synchronized...but to me it looks like they are totally synchronized")
27  public class QuotaState {
28    private long lastUpdate = 0;
29    private long lastQuery = 0;
30    private QuotaLimiter globalLimiter = NoopQuotaLimiter.get();
31  
32    public QuotaState() {
33      this(0);
34    }
35  
36    public QuotaState(final long updateTs) {
37      lastUpdate = updateTs;
38    }
39  
40    public synchronized long getLastUpdate() {
41      return lastUpdate;
42    }
43  
44    public synchronized long getLastQuery() {
45      return lastQuery;
46    }
47  
48    @Override
49    public synchronized String toString() {
50      StringBuilder builder = new StringBuilder();
51      builder.append("QuotaState(ts=" + getLastUpdate());
52      if (isBypass()) {
53        builder.append(" bypass");
54      } else {
55        if (globalLimiter != NoopQuotaLimiter.get()) {
56          // builder.append(" global-limiter");
57          builder.append(" " + globalLimiter);
58        }
59      }
60      builder.append(')');
61      return builder.toString();
62    }
63  
64    /**
65     * @return true if there is no quota information associated to this object
66     */
67    public synchronized boolean isBypass() {
68      return globalLimiter == NoopQuotaLimiter.get();
69    }
70  
71    /**
72     * Setup the global quota information. (This operation is part of the QuotaState setup)
73     */
74    public synchronized void setQuotas(final Quotas quotas) {
75      if (quotas.hasThrottle()) {
76        globalLimiter = QuotaLimiterFactory.fromThrottle(quotas.getThrottle());
77      } else {
78        globalLimiter = NoopQuotaLimiter.get();
79      }
80    }
81  
82    /**
83     * Perform an update of the quota info based on the other quota info object. (This operation is
84     * executed by the QuotaCache)
85     */
86    public synchronized void update(final QuotaState other) {
87      if (globalLimiter == NoopQuotaLimiter.get()) {
88        globalLimiter = other.globalLimiter;
89      } else if (other.globalLimiter == NoopQuotaLimiter.get()) {
90        globalLimiter = NoopQuotaLimiter.get();
91      } else {
92        globalLimiter = QuotaLimiterFactory.update(globalLimiter, other.globalLimiter);
93      }
94      lastUpdate = other.lastUpdate;
95    }
96  
97    /**
98     * Return the limiter associated with this quota.
99     * @return the quota limiter
100    */
101   public synchronized QuotaLimiter getGlobalLimiter() {
102     setLastQuery(EnvironmentEdgeManager.currentTime());
103     return globalLimiter;
104   }
105 
106   /**
107    * Return the limiter associated with this quota without updating internal last query stats
108    * @return the quota limiter
109    */
110   synchronized QuotaLimiter getGlobalLimiterWithoutUpdatingLastQuery() {
111     return globalLimiter;
112   }
113 
114   public synchronized void setLastQuery(long lastQuery) {
115     this.lastQuery = lastQuery;
116   }
117 }