/** * '$RCSfile$' * Copyright: 2010 Regents of the University of California and the * National Center for Ecological Analysis and Synthesis * * '$Author: $' * '$Date: 2009-06-13 15:28:13 +0300 $' * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package edu.ucsb.nceas.metacat; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; /** * @author berkley * Singleton to track metacat profile stats and print them to a CSV file */ public class MetacatProfiler { private static MetacatProfiler profiler = null; private Hashtable profiles; private String log = ""; private int callOrderCount = 0; private boolean aggregateMethodCalls = true; /** * private constructor */ private MetacatProfiler() { profiles = new Hashtable(); } /** * get a singleton instance * @return */ public static MetacatProfiler getInstance() { if(profiler == null) { profiler = new MetacatProfiler(); } return profiler; } /** * return a hashtable of the profiles * @return */ public Hashtable getProfiles() { return profiles; } /** * reset all times in the singleton */ public void reset() { profiles = new Hashtable(); log = ""; } /** * print a message to the log in real-time * @param msg */ public void printLogMsg(String msg) { log += "//" + new Date().toString() + ":" + msg + "\n"; } /** * start the timing on a profile * @param profileName */ public void startTime(String profileName) { long start = new Date().getTime(); Profile p = profiles.get(profileName); if(!aggregateMethodCalls || p == null) { p = new Profile(); p.name = profileName; p.start = start; p.methodcalls = 0; p.total = 0; p.callorder = callOrderCount; callOrderCount++; profiles.put(profileName, p); } else { p.start = start; profiles.put(profileName, p); } } /** * stop the timing on a profile * @param profileName */ public void stopTime(String profileName) { //System.out.println("\n==================stop=================="); long stop = new Date().getTime(); boolean found = false; Profile p = profiles.get(profileName); if(p == null) { System.out.println("WARNING: profile " + profileName + " not registered with MetacatProfiler"); } else { p.stop = stop; } if(!aggregateMethodCalls) { log += p.toString(); } else { if(p != null) { //System.out.println("p: " + p.toString()); p.total += p.stop - p.start; p.methodcalls = p.methodcalls + 1; //System.out.println("newp: " + p.toString()); profiles.put(profileName, p); } else { p = new Profile(); p.methodcalls = 1; profiles.put(profileName, p); } } } /** * sort the profiles by "callorder", "callcount" or "total" * @param sortKey * @return */ public Profile[] sortProfiles(String sortKey) { Vector v = new Vector(); Enumeration keys = profiles.keys(); Profile[] pArr = new Profile[profiles.size()]; int i = 0; while(keys.hasMoreElements()) { String key = (String)keys.nextElement(); pArr[i] = profiles.get(key); i++; } int n = profiles.size(); for (int pass=1; pass < n; pass++) { // count how many times // This next loop becomes shorter and shorter for (i=0; i < n-pass; i++) { long x = 0; long y = 0; if(sortKey.equals("callorder")) { x = pArr[i].callorder; y = pArr[i+1].callorder; } else if(sortKey.equals("callcount")) { x = pArr[i].methodcalls; y = pArr[i+1].methodcalls; } else { //default by total x = pArr[i].total; y = pArr[i+1].total; } if (x < y) { // exchange elements Profile temp = pArr[i]; pArr[i] = pArr[i+1]; pArr[i+1] = temp; } } } return pArr; } /** * print a sorted CSV file. The sortKey can be "callorder", "callcount" or "total" * @param f * @param sortKey * @throws IOException */ public void printSortedCSV(File f, String sortKey) throws IOException { Profile[] p = sortProfiles(sortKey); String log2 = ""; log2 = "\n" + log + "\n" + "=======profile entries sorted by " + sortKey + "========\n"; for(int i=0; i