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    }