001/* 
002 * JKNIV, SQLegance keeping queries maintainable.
003 * 
004 * Copyright (C) 2017, the original author or authors.
005 *
006 * This library is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 2.1 of the License.
010 * 
011 * This library is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 * 
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with this library; if not, write to the Free Software Foundation, Inc., 
018 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
019 */
020package net.sf.jkniv.experimental;
021
022/**
023 * Multi-thread timer keeper.
024 * 
025 * @author Alisson Gomes
026 * @since 0.6.0
027 *
028 */
029public class TimerKeeper
030{
031    private long                                  startTimer;
032    private long                                  milliseconds;
033    private long                                  times;
034    private static final ThreadLocal<TimerKeeper> TIMERS = new ThreadLocal<TimerKeeper>();
035    
036    private TimerKeeper()
037    {
038        this.startTimer = System.currentTimeMillis();
039        this.milliseconds = 0L;
040        this.times = 0;
041    }
042    
043    public static boolean isRunning()
044    {
045        TimerKeeper timerKeeper = TIMERS.get();
046        if (timerKeeper != null)
047            return timerKeeper.startTimer > 0L;
048        
049        return false;
050    }
051    
052    /**
053     * start the chronometer timer
054     * @return the started time in milliseconds sliced by pause times. 
055     * After pause <code>startTimer</code> become to zero.
056     */
057    public static long start()
058    {
059        TimerKeeper timerKeeper = TIMERS.get();
060        if (timerKeeper == null)
061        {
062            timerKeeper = new TimerKeeper();
063            TIMERS.set(timerKeeper);
064            timerKeeper.times++;
065        }
066        else if (timerKeeper.startTimer == 0)
067        {
068            timerKeeper.startTimer = System.currentTimeMillis();
069            timerKeeper.times++;
070        }
071        //      else if (timerKeeper.startTimer > 0)
072        //      {
073        //          timerKeeper.milliseconds += System.currentTimeMillis() - timerKeeper.startTimer;
074        //      }
075        return timerKeeper.startTimer;
076    }
077    
078    /**
079     * Pause the chronometer timer
080     * @return the slice from last start until this pause. To obtain the
081     * total time call {@link #time()} method.
082     */
083    public static long pause()
084    {
085        TimerKeeper timerKeeper = TIMERS.get();
086        long sliceTime = 0L;
087        if (timerKeeper == null)
088            throw new IllegalStateException("start time doesn't called");
089        
090        if (timerKeeper.startTimer > 0)
091            sliceTime = System.currentTimeMillis() - timerKeeper.startTimer;
092        
093        timerKeeper.milliseconds += sliceTime;
094        timerKeeper.startTimer = 0;
095        return sliceTime;
096    }
097    
098    public static long time()
099    {
100        TimerKeeper timerKeeper = TIMERS.get();
101        if (timerKeeper == null)
102            return 0L;
103        
104        return timerKeeper.milliseconds;
105    }
106    
107    public static long avg()
108    {
109        TimerKeeper timerKeeper = TIMERS.get();
110        if (timerKeeper == null)
111            return 0L;
112        
113        return timerKeeper.milliseconds / timerKeeper.times;
114    }
115    
116    /**
117     * remove the chronometer from thread-local 
118     * @return the time in milliseconds from chronometer
119     */
120    public static long clear()
121    {
122        TimerKeeper timerKeeper = TIMERS.get();
123        if (timerKeeper == null)
124            return 0L;
125        
126        TIMERS.remove();
127        return timerKeeper.milliseconds;
128    }
129    
130    public static long times()
131    {
132        TimerKeeper timerKeeper = TIMERS.get();
133        if (timerKeeper == null)
134            return 0L;
135        
136        return timerKeeper.times;
137    }
138}