All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dell.doradus.utilities.TimerGroup Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2014 Dell, Inc.
 * 
 * Licensed 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 com.dell.doradus.utilities;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class logs the operation execution time.
 * Time spans are measured in nanoseconds. Output is truncated to milliseconds.
 */
public class TimerGroup {
	private boolean m_condition;
	private Logger m_logger;
	
	long m_startTime;
	long m_nextLog;
	long m_logIntervalNano;
	
	private TimerGroupItem m_total = new TimerGroupItem("TOTAL");
	
	HashMap m_timers = new HashMap();
	HashMap m_counters = new HashMap();

	/**
	 * Create TimerGroup.
	 */
	public TimerGroup(Logger logger, long logIntervalNano) {
		m_logger = logger;
		m_condition = m_logger.isDebugEnabled();
		m_logIntervalNano = logIntervalNano;
		m_startTime = System.nanoTime();
		if (m_logIntervalNano == 0){
			m_nextLog = Long.MAX_VALUE;
		}else {
			m_nextLog = m_startTime + m_logIntervalNano;
		}
	}

	public TimerGroup(Logger logger) {
		this(logger, 0);
	}

	public TimerGroup(String loggerName, long logIntervalNano) {
		this(LoggerFactory.getLogger(loggerName), logIntervalNano);
	}

	public TimerGroup(String loggerName) {
		this(LoggerFactory.getLogger(loggerName));
	}

	public void start(String name){
		if (m_condition){
			long time = System.nanoTime();
			start(time, name);
			checkLog(time);
		}
	}

	public void start(String name, String details){
			if (m_condition){
				long time = System.nanoTime();
	//			start(time, name);
				start(time, getDetailsName(name,details));
				checkLog(time);
			}
		}

	public long stop(String name){
		if (m_condition){
			long time = System.nanoTime();			
			long elapsedTime = stop(time, name);
			checkLog(time);
			return elapsedTime;
		}
		return 0;
	}

	public long stop(String name, int value){
		if (m_condition){
			long time = System.nanoTime();			
			long elapsedTime = stop(time, name, value);
			checkLog(time);
			return elapsedTime;
		}
		return 0;
	}

	public long stop(String name, String details){
			if (m_condition){
				long time = System.nanoTime();
	//			stop(time, name);
				long elapsedTime = stop(time, getDetailsName(name,details));
				checkLog(time);
				return elapsedTime;
			}
			return 0;
		}

	public long stop(String name, String details, int value){
			if (m_condition){
				long time = System.nanoTime();
	//			stop(time, name,value);
				long elapsedTime = stop(time, getDetailsName(name,details),value);
				checkLog(time);
				return elapsedTime;
			}
			return 0;
		}

	public void add(String name, int value){
		if (m_condition){
			name = getName(name);
			Counter counter = m_counters.get(name);
			if (counter == null){
				counter = new Counter();
				m_counters.put(name, counter);
			}
			counter.add(value);
			checkLog(System.nanoTime());
		}
	}

	public void log(String format, Object... args) {
		log(true, format, args);
	}

	public void log() {
		log(true, null);
	}

	/** 
	 * Start the named timer if the condition is true.
	 */
	private void start(long time, String name){
		name = getName(name);
		TimerGroupItem timer = m_timers.get(name);
		if (timer == null){
			timer = new TimerGroupItem(name);
			m_timers.put(name, timer);
		}
		timer.start(time);
		m_total.start(time);
	}

	private String getDetailsName(String name, String details){
		return name + " / " + details;
	}
	
	private String getName(String name){
		return "(" + Thread.currentThread().getName() + ") " + name;
	}
	/** 
	 * Stop the named timer if the condition is true.
	 */
	private long stop(long time, String name){
		m_total.stop(time);
		TimerGroupItem timer = m_timers.get(getName(name));
		long elapsedTime = 0;
		if (timer != null){
			elapsedTime = timer.stop(time);
		}
		checkLog(time);
		return elapsedTime;
	}

	private long stop(long time, String name, int value){
		m_total.stop(time);
		TimerGroupItem timer = m_timers.get(getName(name));
		long elapsedTime = 0;
		if (timer != null){
			elapsedTime = timer.stop(time, value);
		}
		checkLog(time);
		return elapsedTime;
	}

	/** 
	 * Log elapsed time of all named timers if the condition is true.
	 */
	private void log(boolean finalLog, String format, Object... args) {
		if (m_condition){
			if (format != null ){
				m_logger.debug(String.format(format, args));
			}
			ArrayList timerNames = new ArrayList(m_timers.keySet());
			Collections.sort(timerNames);
			for (String name : timerNames){
				TimerGroupItem timer = m_timers.get(name);
				if (finalLog || timer.changed()){
					m_logger.debug(timer.toString(finalLog));
				}
			}		
			m_logger.debug(m_total.toString(finalLog));
			ArrayList counterNames = new ArrayList(m_counters.keySet());
			Collections.sort(counterNames);
			for (String name : counterNames){
				Counter counter = m_counters.get(name);
				if (finalLog || counter.changed()){
					String text = String.format("%s: (%s)", name, counter.toString(finalLog));
					m_logger.debug(text);
				}
			}		
		}
	}

	private void checkLog(long time) {
		if (m_nextLog <= time){
			log(false, "Intermediate timing ... %s (%s)", Timer.toString(time - m_startTime), Timer.toString(time - m_nextLog));
			m_nextLog = time + m_logIntervalNano;
		}
	}
}

class Counter {
	int m_value;
	int m_lastValue;
	void add(int value){
		m_value +=value;
	}
	
	int value(){
		return m_value;
	}
	
	boolean changed(){
		return m_value != m_lastValue;
	}
	
	public String toString(boolean finalLog){
		m_lastValue = m_value;
		return Integer.toString(finalLog? m_value : m_value - m_lastValue);
	}
}

class TimerGroupItem{

	String m_name;
	Timer m_timer;
	int m_count;
	int m_value;
	boolean m_hasValue;
	int m_lastCount;
	int m_lastValue;
	long m_lastTime;

	TimerGroupItem(String name){
		m_name = name;
		m_timer = new Timer();
	}
	
	public void start(long time) {
		m_count++;
		m_timer.start(time);
	}
		
	public long stop(long time, int value){
		m_value += value;
		m_hasValue = true;
		return m_timer.stop(time);
	}
	
	public long stop(long time){
		return m_timer.stop(time);
	}
	
	boolean changed(){
		return (m_hasValue && m_lastCount != m_count);
	}
	
	public String toString(boolean finalLog){
		long time = m_timer.getElapsedTime();
		int count = m_count;
		int value = m_value;
		
		String text;
		if (!finalLog){
			if (m_hasValue){
				text = String.format("%s: %s/%s (%d/%d) %d/%d", m_name, Timer.toString(time), Timer.toString(time-m_lastTime), count, count - m_lastCount, value, value - m_lastValue);
			}
			else {
				text = String.format("%s: %s/%s (%d/%d)", m_name, Timer.toString(time), Timer.toString(time-m_lastTime), count, count - m_lastCount);
			}
		} else {
			if (m_hasValue){
				text = String.format("%s: %s (%d) %d", m_name, Timer.toString(time), count, value);
			}
			else {
				text = String.format("%s: %s (%d)", m_name, Timer.toString(time), count);
			}
		}
		m_lastTime = time;
		m_lastCount = count;
		m_lastValue = value;
		return text;	
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy