View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.client.metrics;
19  
20  import java.util.HashMap;
21  import java.util.Map;
22  import java.util.concurrent.atomic.AtomicLong;
23  
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.classification.InterfaceStability;
26  
27  import com.google.common.collect.ImmutableMap;
28  
29  /**
30   * Provides server side metrics related to scan operations.
31   */
32  @InterfaceAudience.Public
33  @InterfaceStability.Evolving
34  public class ServerSideScanMetrics {
35    /**
36     * Hash to hold the String -> Atomic Long mappings for each metric
37     */
38    private final Map<String, AtomicLong> counters = new HashMap<String, AtomicLong>();
39  
40    /**
41     * Create a new counter with the specified name
42     * @param counterName
43     * @return {@link AtomicLong} instance for the counter with counterName
44     */
45    protected AtomicLong createCounter(String counterName) {
46      AtomicLong c = new AtomicLong(0);
47      counters.put(counterName, c);
48      return c;
49    }
50  
51    public static final String COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME = "ROWS_SCANNED";
52    public static final String COUNT_OF_ROWS_FILTERED_KEY_METRIC_NAME = "ROWS_FILTERED";
53  
54    /** @deprecated Use {@link #COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME} instead */
55    public static final String COUNT_OF_ROWS_SCANNED_KEY = COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME;
56    /** @deprecated Use {@link #COUNT_OF_ROWS_FILTERED_KEY_METRIC_NAME} instead */
57    public static final String COUNT_OF_ROWS_FILTERED_KEY = COUNT_OF_ROWS_FILTERED_KEY_METRIC_NAME;
58  
59    /**
60     * number of rows filtered during scan RPC
61     */
62    public final AtomicLong countOfRowsFiltered = createCounter(COUNT_OF_ROWS_FILTERED_KEY_METRIC_NAME);
63  
64    /**
65     * number of rows scanned during scan RPC. Not every row scanned will be returned to the client
66     * since rows may be filtered.
67     */
68    public final AtomicLong countOfRowsScanned = createCounter(COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME);
69  
70    /**
71     * @param counterName
72     * @param value
73     */
74    public void setCounter(String counterName, long value) {
75      AtomicLong c = this.counters.get(counterName);
76      if (c != null) {
77        c.set(value);
78      }
79    }
80  
81    /**
82     * @param counterName
83     * @return true if a counter exists with the counterName
84     */
85    public boolean hasCounter(String counterName) {
86      return this.counters.containsKey(counterName);
87    }
88  
89    /**
90     * @param counterName
91     * @return {@link AtomicLong} instance for this counter name, null if counter does not exist.
92     */
93    public AtomicLong getCounter(String counterName) {
94      return this.counters.get(counterName);
95    }
96  
97    /**
98     * @param counterName
99     * @param delta
100    */
101   public void addToCounter(String counterName, long delta) {
102     AtomicLong c = this.counters.get(counterName);
103     if (c != null) {
104       c.addAndGet(delta);
105     }
106   }
107 
108   /**
109    * Get all of the values since the last time this function was called. Calling this function will
110    * reset all AtomicLongs in the instance back to 0.
111    * @return A Map of String -&gt; Long for metrics
112    */
113   public Map<String, Long> getMetricsMap() {
114     // Create a builder
115     ImmutableMap.Builder<String, Long> builder = ImmutableMap.builder();
116     // For every entry add the value and reset the AtomicLong back to zero
117     for (Map.Entry<String, AtomicLong> e : this.counters.entrySet()) {
118       builder.put(e.getKey(), e.getValue().getAndSet(0));
119     }
120     // Build the immutable map so that people can't mess around with it.
121     return builder.build();
122   }
123 }