001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client.metrics; 019 020import java.util.HashMap; 021import java.util.Map; 022import java.util.concurrent.atomic.AtomicLong; 023import org.apache.yetus.audience.InterfaceAudience; 024 025import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableMap; 026 027/** 028 * Provides server side metrics related to scan operations. 029 */ 030@InterfaceAudience.Public 031public class ServerSideScanMetrics { 032 /** 033 * Hash to hold the String -> Atomic Long mappings for each metric 034 */ 035 private final Map<String, AtomicLong> counters = new HashMap<>(); 036 037 /** 038 * Create a new counter with the specified name n * @return {@link AtomicLong} instance for the 039 * counter with counterName 040 */ 041 protected AtomicLong createCounter(String counterName) { 042 AtomicLong c = new AtomicLong(0); 043 counters.put(counterName, c); 044 return c; 045 } 046 047 public static final String COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME = "ROWS_SCANNED"; 048 public static final String COUNT_OF_ROWS_FILTERED_KEY_METRIC_NAME = "ROWS_FILTERED"; 049 050 /** 051 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 052 * (<a href="https://issues.apache.org/jira/browse/HBASE-17886">HBASE-17886</a>). Use 053 * {@link #COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME}. 054 */ 055 @Deprecated 056 public static final String COUNT_OF_ROWS_SCANNED_KEY = COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME; 057 058 /** 059 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 060 * (<a href="https://issues.apache.org/jira/browse/HBASE-17886">HBASE-17886</a>). Use 061 * {@link #COUNT_OF_ROWS_FILTERED_KEY_METRIC_NAME}. 062 */ 063 @Deprecated 064 public static final String COUNT_OF_ROWS_FILTERED_KEY = COUNT_OF_ROWS_FILTERED_KEY_METRIC_NAME; 065 066 /** 067 * number of rows filtered during scan RPC 068 */ 069 public final AtomicLong countOfRowsFiltered = 070 createCounter(COUNT_OF_ROWS_FILTERED_KEY_METRIC_NAME); 071 072 /** 073 * number of rows scanned during scan RPC. Not every row scanned will be returned to the client 074 * since rows may be filtered. 075 */ 076 public final AtomicLong countOfRowsScanned = createCounter(COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME); 077 078 /** 079 * nn 080 */ 081 public void setCounter(String counterName, long value) { 082 AtomicLong c = this.counters.get(counterName); 083 if (c != null) { 084 c.set(value); 085 } 086 } 087 088 /** 089 * n * @return true if a counter exists with the counterName 090 */ 091 public boolean hasCounter(String counterName) { 092 return this.counters.containsKey(counterName); 093 } 094 095 /** 096 * n * @return {@link AtomicLong} instance for this counter name, null if counter does not exist. 097 */ 098 public AtomicLong getCounter(String counterName) { 099 return this.counters.get(counterName); 100 } 101 102 /** 103 * nn 104 */ 105 public void addToCounter(String counterName, long delta) { 106 AtomicLong c = this.counters.get(counterName); 107 if (c != null) { 108 c.addAndGet(delta); 109 } 110 } 111 112 /** 113 * Get all of the values since the last time this function was called. Calling this function will 114 * reset all AtomicLongs in the instance back to 0. 115 * @return A Map of String -> Long for metrics 116 */ 117 public Map<String, Long> getMetricsMap() { 118 return getMetricsMap(true); 119 } 120 121 /** 122 * Get all of the values. If reset is true, we will reset the all AtomicLongs back to 0. 123 * @param reset whether to reset the AtomicLongs to 0. 124 * @return A Map of String -> Long for metrics 125 */ 126 public Map<String, Long> getMetricsMap(boolean reset) { 127 // Create a builder 128 ImmutableMap.Builder<String, Long> builder = ImmutableMap.builder(); 129 for (Map.Entry<String, AtomicLong> e : this.counters.entrySet()) { 130 long value = reset ? e.getValue().getAndSet(0) : e.getValue().get(); 131 builder.put(e.getKey(), value); 132 } 133 // Build the immutable map so that people can't mess around with it. 134 return builder.build(); 135 } 136}