package org.sef4j.callstack.stats;
import java.util.concurrent.Callable;
import org.sef4j.callstack.CallStackElt;
import org.sef4j.core.util.ICopySupport;
/**
* class for aggregating PendingPerfCount + BasicTimeStatsLogHistogram (elapsed,threadUser,threadCpu)
*
* this class is thread-safe, and lock-FREE !
*/
public final class PerfStats implements ICopySupport<PerfStats> {
private PendingPerfCount pendingCounts = new PendingPerfCount();
private BasicTimeStatsLogHistogram elapsedTimeStats = new BasicTimeStatsLogHistogram();
private BasicTimeStatsLogHistogram threadUserTimeStats = new BasicTimeStatsLogHistogram();
private BasicTimeStatsLogHistogram threadCpuTimeStats = new BasicTimeStatsLogHistogram();
// ------------------------------------------------------------------------
public PerfStats() {
}
public PerfStats(PerfStats src) {
set(src);
}
public static final Callable<PerfStats> FACTORY = new Callable<PerfStats>() {
@Override
public PerfStats call() throws Exception {
return new PerfStats();
}
};
// ------------------------------------------------------------------------
public PendingPerfCount getPendingCounts() {
return pendingCounts;
}
public BasicTimeStatsLogHistogram getElapsedTimeStats() {
return elapsedTimeStats;
}
public BasicTimeStatsLogHistogram getThreadUserTimeStats() {
return threadUserTimeStats;
}
public BasicTimeStatsLogHistogram getThreadCpuTimeStats() {
return threadCpuTimeStats;
}
public int getPendingCount() {
return pendingCounts.getPendingCount();
}
public long getPendingSumStartTime() {
return pendingCounts.getPendingSumStartTime();
}
@Override /* java.lang.Object */
public PerfStats clone() {
return copy();
}
@Override /* ICopySupport<> */
public PerfStats copy() {
return new PerfStats(this);
}
public void set(PerfStats src) {
this.elapsedTimeStats.set(src.elapsedTimeStats);
threadUserTimeStats.set(src.threadUserTimeStats);
threadCpuTimeStats.set(src.threadCpuTimeStats);
pendingCounts.set(src.pendingCounts);
}
// ------------------------------------------------------------------------
public void addPending(long currTime) {
pendingCounts.addPending(currTime);
}
public void removePending(long startedTime) {
pendingCounts.removePending(startedTime);
}
public void incrAndRemovePending(long startTime, long threadUserStartTime, long threadCpuStartTime,
long endTime, long threadUserEndTime, long threadCpuEndTime) {
incr(endTime-startTime, threadUserEndTime-threadUserStartTime, threadCpuEndTime-threadCpuStartTime);
pendingCounts.removePending(startTime);
}
public void incr(long elapsedTime, long elapsedThreadUserTime, long elapsedThreadCpuTime) {
elapsedTimeStats.incr(elapsedTime);
threadUserTimeStats.incr(elapsedThreadUserTime);
threadCpuTimeStats.incr(elapsedThreadCpuTime);
}
// Helper method using StackElt start/end times
// ------------------------------------------------------------------------
public void addPending(CallStackElt stackElt) {
pendingCounts.addPending(stackElt);
}
public void incrAndRemovePending(CallStackElt stackElt) {
long elapsedTime = stackElt.getEndTime() - stackElt.getStartTime();
long elapsedThreadUserTime = stackElt.getThreadUserEndTime() - stackElt.getThreadUserStartTime();
long elapsedThreadCpuTime = stackElt.getThreadCpuEndTime() - stackElt.getThreadCpuStartTime();
incr(elapsedTime, elapsedThreadUserTime, elapsedThreadCpuTime);
pendingCounts.removePending(stackElt);
}
// ------------------------------------------------------------------------
@Override
public String toString() {
int pendingCount = pendingCounts.getPendingCount();
return "PerfStats ["
+ ((pendingCount != 0)? "pending:" + pendingCount + ", ": "")
+ "count:" + elapsedTimeStats.cumulatedCount()
+ ", sum ms elapsed: " + elapsedTimeStats.cumulatedSum()
+ ", cpu:" + threadCpuTimeStats.cumulatedSum()
+ ", user:" + threadUserTimeStats.cumulatedSum()
+ "]";
}
}