package org.gridkit.jvmtool.stacktrace.analytics; import java.util.HashMap; import java.util.Map; import org.gridkit.jvmtool.stacktrace.ThreadCounters; import org.gridkit.jvmtool.stacktrace.ThreadSnapshot; class CpuAggregatorFactory implements ThreadDumpAggregator, ThreadDumpAggregatorFactory { @Override public ThreadDumpAggregator newInstance() { return new CpuAggregatorFactory(); } private Map<Long, ThreadTrack> info = new HashMap<Long, ThreadTrack>(); @Override public void aggregate(ThreadSnapshot threadInfo) { if (threadInfo.counters().getValue(ThreadCounters.CPU_TIME_MS) != Long.MIN_VALUE) { ThreadTrack tt = info.get(threadInfo.threadId()); if (tt == null) { tt = new ThreadTrack(); tt.firstTimestamp = threadInfo.timestamp(); tt.lastTimestamp = threadInfo.timestamp(); tt.fisrtCPU = threadInfo.counters().getValue(ThreadCounters.CPU_TIME_MS); tt.lastCPU = threadInfo.counters().getValue(ThreadCounters.CPU_TIME_MS); info.put(threadInfo.threadId(), tt); } else { if (tt.firstTimestamp > threadInfo.timestamp()) { tt.firstTimestamp = threadInfo.timestamp(); tt.fisrtCPU = threadInfo.counters().getValue(ThreadCounters.CPU_TIME_MS); } if (tt.lastTimestamp < threadInfo.timestamp()) { tt.lastTimestamp = threadInfo.timestamp(); tt.lastCPU = threadInfo.counters().getValue(ThreadCounters.CPU_TIME_MS); } } } } @Override public Object info() { long totalCPU = 0; long minTs = Long.MAX_VALUE; long maxTs = Long.MIN_VALUE; for(ThreadTrack tt: info.values()) { totalCPU += tt.lastCPU - tt.fisrtCPU; minTs = Math.min(minTs, tt.firstTimestamp); maxTs = Math.max(maxTs, tt.lastTimestamp); } if (minTs == Long.MAX_VALUE || minTs == maxTs) { return Double.NaN; } else { return (((double)totalCPU) / (maxTs - minTs)); } } private static class ThreadTrack { long firstTimestamp; long fisrtCPU; long lastTimestamp; long lastCPU; } }