/** * Copyright 2008 - CommonCrawl Foundation * * 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 3 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, see <http://www.gnu.org/licenses/>. * **/ package org.commoncrawl.util; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import javax.servlet.jsp.JspWriter; /** * * @author rana * */ public class RuntimeStatsCollector { public RuntimeStatsCollector() { } public static abstract class Namespace { } @SuppressWarnings("unchecked") public static void registerNames(Namespace namespaceId, Enum[] names) { for (int id=0;id<names.length;++id) { _idToNameMap.put(makeId(namespaceId,names[id]),names[id].toString()); _nameToIdMap.put(names[id].toString(),makeId(namespaceId,names[id])); } } @SuppressWarnings("unchecked") private static long makeId(Namespace namespace, Enum value) { return (((long)namespace.getClass().hashCode()) << 32) | (long)value.ordinal(); } public static class StringList implements Iterable<String>{ private int maxItemLimit; private LinkedList<String> list = new LinkedList<String>(); StringList(int maxItemLimit) { this.maxItemLimit = maxItemLimit; } public void add(String e) { if (list.size() == maxItemLimit) { list.removeFirst(); } list.addLast(e); } public Iterator<String> iterator() { return list.iterator(); } @Override public String toString() { StringBuffer buf = new StringBuffer(); for (String value : list) { buf.append(value + "\n"); } return buf.toString(); } } public static class StringVector implements Iterable<String>{ private String array[]; StringVector(int arraySize) { array = new String[arraySize]; } public void setValue(int index,String value) { if (index < array.length) { array[index] = value; } } public Iterator<String> iterator() { return Arrays.asList(array).iterator(); } @Override public String toString() { StringBuffer buf = new StringBuffer(); for (int i=0;i<array.length;++i) { if (array[i] != null) { buf.append("["); buf.append(String.format("%1$4.4s",i )); buf.append("] - "); buf.append(array[i]); buf.append("\n"); } } return buf.toString(); } } protected HashMap<Long,Object> _values = new HashMap<Long,Object>(); protected static HashMap<Long,String> _idToNameMap = new HashMap<Long,String>(); protected static HashMap<String,Long> _nameToIdMap = new HashMap<String,Long>(); @SuppressWarnings("unchecked") public synchronized int getIntValue(Enum name) { Integer value = (Integer)_values.get(name.ordinal()); if (value != null) return value; return -1; } @SuppressWarnings("unchecked") public synchronized long getLongValue(Namespace namespace,Enum name) { Long value = (Long)_values.get(makeId(namespace,name)); if (value != null) return value; return -1; } @SuppressWarnings("unchecked") public synchronized String getStringValue(Namespace namespace,Enum name) { String value = (String) _values.get(makeId(namespace,name)); if (value != null) return value; return ""; } @SuppressWarnings("unchecked") public Iterator<String> getListValues(Namespace namespace,Enum name) { StringList list = (StringList)_values.get(makeId(namespace,name)); if (list == null) { return Collections.EMPTY_LIST.iterator(); } else { return list.iterator(); } } @SuppressWarnings("unchecked") public synchronized void addListValue(Namespace namespace,Enum name,int maxItems,String value) { StringList list = (StringList) _values.get(makeId(namespace,name)); if (list == null) { list = new StringList(maxItems); _values.put(makeId(namespace,name), list); } list.add(value); } @SuppressWarnings("unchecked") public synchronized void setArrayValue(Namespace namespace,Enum name,int arraySize,int index,String value) { StringVector array = (StringVector)_values.get(makeId(namespace,name)); if (array == null) { array = new StringVector(arraySize); _values.put(makeId(namespace,name), array); } array.setValue(index, value); } @SuppressWarnings("unchecked") public synchronized void setIntValue(Namespace namespace,Enum name,int value) { _values.put(makeId(namespace,name), new Integer(value)); } @SuppressWarnings("unchecked") public synchronized void incIntValue(Namespace namespace,Enum name) { Integer value = (Integer) _values.get(makeId(namespace,name)); if (value != null) { _values.put(makeId(namespace,name), (Integer)(value + 1)); } else { _values.put(makeId(namespace,name),(Integer)1); } } @SuppressWarnings("unchecked") public synchronized void incLongValue(Namespace namespace,Enum name) { Long value = (Long)_values.get(name.ordinal()); if (value != null) { _values.put(makeId(namespace,name), (Long)(value + 1)); } else { _values.put(makeId(namespace,name),(Long)1L); } } @SuppressWarnings("unchecked") public synchronized void setLongValue(Namespace namespace,Enum name,long value) { _values.put(makeId(namespace,name), value); } @SuppressWarnings("unchecked") public synchronized void setDoubleValue(Namespace namespace,Enum name,double value) { _values.put(makeId(namespace,name), value); } @SuppressWarnings("unchecked") public synchronized void setStringValue(Namespace namespace,Enum name,String value) { _values.put(makeId(namespace,name), value); } public void dumpStatsToHTML(JspWriter out)throws IOException { out.write("<table border=1>"); out.write("<tr><td>Name</td><td width=50%>Value</td><td>Name</td><td width=50%>Value</td></tr>"); Object[] keys = _nameToIdMap.keySet().toArray(); Arrays.sort(keys); int dumpedKeyCount = 0; out.write("<tr>"); for (Object key : keys) { long id = _nameToIdMap.get(key); Object value = _values.get(id); dumpValue(out,id,value); if (++dumpedKeyCount % 2 == 0) { out.write("</tr><tr>"); } } if (dumpedKeyCount %2 != 0) { out.write("<td> </td><td> </td></tr>"); } out.write("</table>"); } public void dumpValue(JspWriter out,Object key, Object value)throws IOException { out.write("<td>"); long keyId = (Long)key; String keyName = _idToNameMap.get(keyId); if (keyName == null) keyName = "[" +(int) (keyId>> 32) + "]:["+(int)keyId+"]"; out.write(keyName); out.write("</td>"); out.write("<td><pre>"); if (value != null) out.write(value.toString()); else out.write("NULL"); out.write("</pre></td>"); } }