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