Package org.apache.hadoop.hbase.metrics

Source Code of org.apache.hadoop.hbase.metrics.ExactCounterMetric

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hadoop.hbase.metrics;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.metrics.MetricsRecord;
import org.apache.hadoop.metrics.util.MetricsBase;
import org.apache.hadoop.metrics.util.MetricsRegistry;
import org.cliffc.high_scale_lib.Counter;

import com.google.common.collect.Lists;

@Deprecated
public class ExactCounterMetric extends MetricsBase {

  private static final int DEFAULT_TOP_N = 5;

  // only publish stats on the topN items (default to DEFAULT_TOP_N)
  private final int topN;
  private final ConcurrentMap<String, Counter> counts = new ConcurrentHashMap<String, Counter>();

  // all access to the 'counts' map should use this lock.
  // take a write lock iff you want to guarantee exclusive access
  // (the map stripes locks internally, so it's already thread safe -
  // this lock is just so you can take a consistent snapshot of data)
  private final ReadWriteLock lock;

    /**
     * Constructor to create a new counter metric
     * @param nam         the name to publish this metric under
     * @param registry    where the metrics object will be registered
     * @param description metrics description
     * @param topN        how many 'keys' to publish metrics on
     */
  public ExactCounterMetric(final String nam, final MetricsRegistry registry,
      final String description, int topN) {
    super(nam, description);

    this.lock = new ReentrantReadWriteLock();
    this.topN = topN;

    if (registry != null) {
      registry.add(nam, this);     
    }
  }

  /**
   * Constructor creates a new ExactCounterMetric
   * @param nam       the name of the metrics to be used to publish the metric
   * @param registry  where the metrics object will be registered
   */
  public ExactCounterMetric(final String nam, MetricsRegistry registry) {
    this(nam, registry, NO_DESCRIPTION, DEFAULT_TOP_N);
  }

  /**
   * Relies on an external lock on {@link #lock} for thread safety.
   */
  private Counter getOrCreateCounter(String type){
    Counter cnt = counts.get(type);
    if (cnt == null){
      cnt = new Counter();
      counts.put(type, cnt);
    }
    return cnt;
  }

  public void update(String type) {
    this.lock.readLock().lock();
    try {
      getOrCreateCounter(type).increment();
    } finally {
      this.lock.readLock().unlock();
    }
  }
 
  public void update(String type, long count) {
    this.lock.readLock().lock();
    try {
      getOrCreateCounter(type).add(count);
    } finally {
      this.lock.readLock().unlock();
    }
  }
 
  public List<Pair<String, Long>> getTop(int n) {
    final List<Pair<String, Long>> countsSnapshot =
        Lists.newArrayListWithCapacity(this.counts.size());
   
    // no updates are allowed while I'm holding this lock, so move fast
    this.lock.writeLock().lock();
    try {
      for(Entry<String, Counter> entry : this.counts.entrySet()) {
        countsSnapshot.add(Pair.newPair(entry.getKey(),
            entry.getValue().get()));
      }
    } finally {
      this.lock.writeLock().unlock();
    }
   
    Collections.sort(countsSnapshot, new Comparator<Pair<String, Long>>() {
      @Override
      public int compare(Pair<String, Long> a, Pair<String, Long> b) {
        return b.getSecond().compareTo(a.getSecond());
      }     
    });
   
    return countsSnapshot.subList(0, Math.min(n, countsSnapshot.size()));
  }
 
  @Override
  public void pushMetric(MetricsRecord mr) {
    final List<Pair<String, Long>> topKeys = getTop(Integer.MAX_VALUE);
    int sum = 0;
   
    int counter = 0;
    for (Pair<String, Long> keyCount : topKeys) {
      counter++;
      // only push stats on the topN keys
      if (counter <= this.topN) {
        mr.setMetric(getName() + "_" + keyCount.getFirst(),
            keyCount.getSecond());       
      }
      sum += keyCount.getSecond();
    }
    mr.setMetric(getName() + "_map_size", this.counts.size());
    mr.setMetric(getName() + "_total_count", sum);
  }
 
}
TOP

Related Classes of org.apache.hadoop.hbase.metrics.ExactCounterMetric

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.