001package net.sf.jkniv.experimental; 002 003import java.text.DecimalFormat; 004import java.util.concurrent.ConcurrentHashMap; 005import java.util.concurrent.atomic.AtomicLong; 006 007public class Chrono implements Comparable<Chrono> 008{ 009 private static final DecimalFormat df = new DecimalFormat("0.00"); 010 private String name; 011 private String status; 012 private AtomicLong milliseconds; 013 //private AtomicLong startTime; 014 private long times; 015 private long min; 016 private long max; 017 private ConcurrentHashMap<String, ChronoSlice> chronoSlices; 018 019 Chrono(String name) 020 { 021 this.name = name; 022 this.chronoSlices = new ConcurrentHashMap<String, ChronoSlice>(); 023 reset(); 024 } 025 026 private void reset() 027 { 028 this.times = 0L; 029 this.milliseconds = new AtomicLong(); 030 this.min = Long.MAX_VALUE; 031 this.max = 0L; 032 this.status = "pause"; 033 chronoSlices.clear(); 034 } 035 036 protected void clear() 037 { 038 TimerKeeper.clear(); 039 reset(); 040 } 041 042 long changeTimer(boolean pause) 043 { 044 if (pause) 045 { 046 //System.out.println("pause ["+name+"] thread: " + Thread.currentThread().getName()); 047 ChronoSlice chronoSlice = chronoSlices.remove(Thread.currentThread().getName()); 048 if (chronoSlice != null) 049 { 050 chronoSlice.changeTimer(pause); 051 if (chronoSlice.milliseconds > 0) 052 { 053 long sliceTime = chronoSlice.milliseconds; 054 this.milliseconds.addAndGet(sliceTime); 055 if (this.min > sliceTime) 056 this.min = sliceTime; 057 if (this.max < sliceTime) 058 this.max = sliceTime; 059 } 060 if (chronoSlices.size() == 0) 061 this.status = "paused"; 062 } 063 } 064 else 065 { 066 ChronoSlice chronoSlice = chronoSlices.get(Thread.currentThread().getName()); 067 if (chronoSlice == null) 068 { 069 chronoSlice = new ChronoSlice(); 070 chronoSlices.put(Thread.currentThread().getName(), chronoSlice); 071 } 072 this.times++; 073 this.status = "running"; 074 long sliceTime = chronoSlice.changeTimer(pause); 075 076 if (sliceTime > 0L) 077 { 078 this.milliseconds.addAndGet(sliceTime); 079 } 080 } 081 return this.milliseconds.get(); 082 } 083 084 public double avg() 085 { 086 return times > 0 ? (double) (this.milliseconds.get() / times) : 0D; 087 } 088 089 public long times() 090 { 091 return this.times; 092 } 093 094 public long time() 095 { 096 return this.milliseconds.get(); 097 } 098 099 public long max() 100 { 101 return this.max; 102 } 103 104 public long min() 105 { 106 return this.min; 107 } 108 109 public String getTime() 110 { 111 String value = milliseconds + " ms"; 112 double seconds = milliseconds.get() / 1000L; 113 if (seconds > 1) 114 value = df.format(seconds) + " seg"; 115 double minutes = seconds / 60L; 116 if (minutes > 1) 117 value = df.format(minutes) + " min"; 118 double hours = minutes / 60L; 119 if (hours > 1) 120 value = df.format(hours) + " h"; 121 return value; 122 } 123 124 @Override 125 public String toString() 126 { 127 return "Chrono [name=" + name + ", milliseconds=" + milliseconds.get() + ", times=" + times + ", status=" 128 + status + ", min=" + min + ", max=" + max + ", avg=" + avg() + "]"; 129 } 130 131 @Override 132 public int compareTo(Chrono o) 133 { 134 if (o == null) 135 return -1; 136 else if (milliseconds.get() < o.milliseconds.get()) 137 return 1; 138 else if (milliseconds.get() > o.milliseconds.get()) 139 return -1; 140 else 141 return 0; 142 } 143 144 /** 145 * slice time for threads for same tag name 146 */ 147 class ChronoSlice 148 { 149 private long milliseconds; 150 private long startTime; 151 152 ChronoSlice() 153 { 154 this.milliseconds = 0L; 155 this.startTime = 0L; 156 } 157 158 long changeTimer(boolean pause) 159 { 160 if (pause) 161 { 162 long sliceTime = 0; 163 if (startTime > 0) 164 { 165 sliceTime = System.currentTimeMillis() - startTime; 166 this.milliseconds += sliceTime; 167 } 168 startTime = 0; 169 } 170 else 171 { 172 if (startTime > 0L) 173 { 174 long sliceTime = System.currentTimeMillis() - startTime; 175 this.milliseconds += sliceTime; 176 } 177 this.startTime = System.currentTimeMillis(); 178 } 179 return this.milliseconds; 180 } 181 182 } 183 184}