001 package railo.runtime.engine; 002 003 import java.util.Collections; 004 import java.util.HashMap; 005 import java.util.Map; 006 007 import railo.commons.lang.StringUtil; 008 import railo.runtime.PageContext; 009 import railo.runtime.op.Caster; 010 011 public abstract class ExecutionLogSupport implements ExecutionLog { 012 013 protected static final short UNIT_NANO=1; 014 protected static final short UNIT_MICRO=2; 015 protected static final short UNIT_MILLI=4; 016 protected static final short UNIT_UNDEFINED=0; 017 018 private Map<String,Pair> map=Collections.synchronizedMap(new HashMap<String,Pair>()); 019 protected long min=Long.MIN_VALUE; 020 protected short unit=UNIT_UNDEFINED; 021 022 public void init(PageContext pc,Map<String,String> arguments) { 023 // min 024 if(min==Long.MIN_VALUE) { 025 min=toNanos(arguments.get("min-time"),0); 026 } 027 // unit 028 if(UNIT_UNDEFINED==unit){ 029 unit=UNIT_NANO; 030 // unit 031 String _unit=arguments.get("unit"); 032 if(_unit!=null) { 033 _unit=_unit.trim(); 034 if(_unit.equalsIgnoreCase("micro")) unit=UNIT_MICRO; 035 else if(_unit.equalsIgnoreCase("�s")) unit=UNIT_MICRO; 036 else if(_unit.equalsIgnoreCase("milli"))unit=UNIT_MILLI; 037 else if(_unit.equalsIgnoreCase("ms")) unit=UNIT_MILLI; 038 } 039 } 040 _init(pc,arguments); 041 } 042 043 private static long toNanos(String str, int defaultValue) { 044 if(StringUtil.isEmpty(str)) return defaultValue; 045 str=str.trim().toLowerCase(); 046 long l = Caster.toLongValue(str,Long.MIN_VALUE); 047 if(l!=Long.MIN_VALUE) return l; 048 049 if(str.endsWith("ns")) { 050 String sub=str.substring(0,str.length()-2); 051 l = Caster.toLongValue(sub.trim(),Long.MIN_VALUE); 052 if(l!=Long.MIN_VALUE) return l; 053 } 054 else if(str.endsWith("�s")) { 055 String sub=str.substring(0,str.length()-2); 056 double d = Caster.toDoubleValue(sub.trim(),Double.NaN); 057 if(!Double.isNaN(d)) return (long)(d*1000); 058 } 059 else if(str.endsWith("ms")) { 060 String sub=str.substring(0,str.length()-2); 061 double d = Caster.toDoubleValue(sub.trim(),Double.NaN); 062 if(!Double.isNaN(d)) return (long)(d*1000*1000); 063 } 064 else if(str.endsWith("s")) { 065 String sub=str.substring(0,str.length()-1); 066 double d = Caster.toDoubleValue(sub.trim(),Double.NaN); 067 if(!Double.isNaN(d)) return (long)(d*1000*1000); 068 } 069 070 return defaultValue; 071 } 072 073 /*public static void main(String[] args) { 074 print.e(toNanos("123456")); 075 print.e(toNanos("123456ns")); 076 print.e(toNanos("123.456�s")); 077 print.e(toNanos("0.123456 ms")); 078 print.e(toNanos("123456 ns")); 079 }*/ 080 081 082 public final void release() { 083 map.clear(); 084 _release(); 085 } 086 087 public final void start(int pos,String id) { 088 long current = System.nanoTime(); 089 map.put(id,new Pair(current,pos)); 090 } 091 092 public final void end(int pos,String id) { 093 long current = System.nanoTime(); 094 Pair pair=map.remove(id); 095 if(pair!=null) { 096 if((current-pair.time)>=min) 097 _log(pair.pos,pos,pair.time,current); 098 } 099 } 100 protected abstract void _init(PageContext pc, Map<String, String> arguments); 101 protected abstract void _log(int startPos, int endPos, long startTime, long endTime); 102 protected abstract void _release(); 103 104 105 protected String timeLongToString(long current) { 106 if(unit==UNIT_MICRO) return (current/1000L)+" �s"; 107 if(unit==UNIT_MILLI) return (current/1000000L)+" ms"; 108 return current+" ns"; 109 } 110 protected static String unitShortToString(short unit) { 111 if(unit==UNIT_MICRO) return "�s"; 112 if(unit==UNIT_MILLI) return "ms"; 113 return "ns"; 114 } 115 116 private final static class Pair { 117 private final long time; 118 private final int pos; 119 public Pair(long time, int pos) { 120 this.time=time; 121 this.pos=pos; 122 } 123 } 124 }