package edu.washington.escience.myria.parallel;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import edu.washington.escience.myria.proto.QueryProto;
/**
* This data structure records the various statistics of the execution of a query or subquery.
*/
public class ExecutionStatistics {
/** Constant to use when times have not been set. */
private static final long MISSING_TIME = -1;
/**
* Start timestamp. This timestamp is machine specific.
*/
private transient volatile long startAtInNano = MISSING_TIME;
/**
* End timestamp. This timestamp is machine specific.
*/
private transient volatile long endAtInNano = MISSING_TIME;
/** Start time. */
private transient volatile DateTime startTime;
/** End time. */
private transient volatile DateTime endTime;
/**
* Set the start time to now.
*/
public final void markStart() {
Preconditions.checkArgument(startTime == null, "can't re-mark start");
startAtInNano = System.nanoTime();
startTime = DateTime.now();
}
/**
* Set the end time to now.
*/
public final void markEnd() {
Preconditions.checkArgument(endTime == null, "can't re-mark end");
endAtInNano = System.nanoTime();
endTime = DateTime.now();
}
/**
* @return the elapsed time, in nanoseconds.
*/
@Nullable
public final Long getQueryExecutionElapse() {
if (startTime == null) {
return null;
}
if (endTime == null) {
return System.nanoTime() - startAtInNano;
}
return endAtInNano - startAtInNano;
}
/**
* @return the protobuf message representation of this class.
*/
public final QueryProto.ExecutionStatistics toProtobuf() {
Long elapsed = MoreObjects.firstNonNull(getQueryExecutionElapse(), MISSING_TIME);
return QueryProto.ExecutionStatistics.newBuilder().setElapse(elapsed).build();
}
/**
* @return the start time, in ISO8601 datetime format.
*/
protected final DateTime getStartTime() {
return startTime;
}
/**
* @return the end time, in ISO8601 datetime format.
*/
protected final DateTime getEndTime() {
return endTime;
}
/**
* Resets the start and end times measured by this object.
*/
public final void reset() {
startAtInNano = MISSING_TIME;
endAtInNano = MISSING_TIME;
startTime = null;
endTime = null;
}
}