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 = "ROWS_SCANNED";
52    public static final String COUNT_OF_ROWS_FILTERED_KEY = "ROWS_FILTERED";
53  
54    /**
55     * number of rows filtered during scan RPC
56     */
57    public final AtomicLong countOfRowsFiltered = createCounter(COUNT_OF_ROWS_FILTERED_KEY);
58  
59    /**
60     * number of rows scanned during scan RPC. Not every row scanned will be returned to the client
61     * since rows may be filtered.
62     */
63    public final AtomicLong countOfRowsScanned = createCounter(COUNT_OF_ROWS_SCANNED_KEY);
64  
65    /**
66     * @param counterName
67     * @param value
68     */
69    public void setCounter(String counterName, long value) {
70      AtomicLong c = this.counters.get(counterName);
71      if (c != null) {
72        c.set(value);
73      }
74    }
75  
76    /**
77     * @param counterName
78     * @return true if a counter exists with the counterName
79     */
80    public boolean hasCounter(String counterName) {
81      return this.counters.containsKey(counterName);
82    }
83  
84    /**
85     * @param counterName
86     * @return {@link AtomicLong} instance for this counter name, null if counter does not exist.
87     */
88    public AtomicLong getCounter(String counterName) {
89      return this.counters.get(counterName);
90    }
91  
92    /**
93     * @param counterName
94     * @param delta
95     */
96    public void addToCounter(String counterName, long delta) {
97      AtomicLong c = this.counters.get(counterName);
98      if (c != null) {
99        c.addAndGet(delta);
100     }
101   }
102 
103   /**
104    * Get all of the values since the last time this function was called. Calling this function will
105    * reset all AtomicLongs in the instance back to 0.
106    * @return A Map of String -&gt; Long for metrics
107    */
108   public Map<String, Long> getMetricsMap() {
109     // Create a builder
110     ImmutableMap.Builder<String, Long> builder = ImmutableMap.builder();
111     // For every entry add the value and reset the AtomicLong back to zero
112     for (Map.Entry<String, AtomicLong> e : this.counters.entrySet()) {
113       builder.put(e.getKey(), e.getValue().getAndSet(0));
114     }
115     // Build the immutable map so that people can't mess around with it.
116     return builder.build();
117   }
118 }