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 */ 018 019package org.apache.hadoop.hbase.util; 020 021import org.apache.yetus.audience.InterfaceAudience; 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024 025/** 026 * The purpose of introduction of {@link MovingAverage} mainly is to measure execution time of a 027 * specific method, which can help us to know its performance fluctuation in response to different 028 * machine states or situations, better case, then to act accordingly. 029 * <br> 030 * In different situation, different {@link MovingAverage} algorithm can be used based on needs. 031 */ 032@InterfaceAudience.Private 033public abstract class MovingAverage<T> { 034 private final static Logger LOG = LoggerFactory.getLogger(MovingAverage.class); 035 036 protected final String label; 037 038 protected MovingAverage(String label) { 039 this.label = label; 040 } 041 042 /** 043 * Mark start time of an execution. 044 * @return time in ns. 045 */ 046 protected long start() { 047 return System.nanoTime(); 048 } 049 050 /** 051 * Mark end time of an execution, and return its interval. 052 * @param startTime start time of an execution 053 * @return elapsed time 054 */ 055 protected long stop(long startTime) { 056 return System.nanoTime() - startTime; 057 } 058 059 /** 060 * Measure elapsed time of a measurable method. 061 * @param measurable method implements {@link TimeMeasurable} 062 * @return T it refers to the original return type of the measurable method 063 */ 064 public T measure(TimeMeasurable<T> measurable) { 065 long startTime = start(); 066 LOG.trace("{} - start to measure at: {} ns.", label, startTime); 067 // Here may throw exceptions which should be taken care by caller, not here. 068 // If exception occurs, this time wouldn't count. 069 T result = measurable.measure(); 070 long elapsed = stop(startTime); 071 LOG.trace("{} - elapse: {} ns.", label, elapsed); 072 updateMostRecentTime(elapsed); 073 return result; 074 } 075 076 /** 077 * Update the most recent data. 078 * @param elapsed elapsed time of the most recent measurement 079 */ 080 protected abstract void updateMostRecentTime(long elapsed); 081 082 /** 083 * Get average execution time of the measured method. 084 * @return average time in ns 085 */ 086 public abstract double getAverageTime(); 087}