com.espertech.esper.runtime.internal.timer.TimeSourceServiceImpl Maven / Gradle / Ivy
/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.runtime.internal.timer;
import com.espertech.esper.common.internal.schedule.TimeSourceService;
/**
* Allow for different strategies for getting VM (wall clock) time.
* See JIRA issue ESPER-191 Support nano/microsecond resolution for more
* information on Java system time-call performance, accuracy and drift.
*
* @author Jerry Shea
*/
public class TimeSourceServiceImpl implements TimeSourceService {
private static final long MICROS_TO_MILLIS = 1000;
private static final long NANOS_TO_MICROS = 1000;
/**
* A public variable indicating whether to use the System millisecond time or
* nano time, to be configured through the runtimesettings.
*/
public static boolean isSystemCurrentTime = true;
private final long wallClockOffset;
private final String description;
/**
* Ctor.
*/
public TimeSourceServiceImpl() {
this.wallClockOffset = System.currentTimeMillis() * MICROS_TO_MILLIS - this.getTimeMicros();
this.description = String.format("%s: resolution %d microsecs",
this.getClass().getSimpleName(), this.calculateResolution());
}
/**
* Convenience method to get time in milliseconds
*
* @return wall-clock time in milliseconds
*/
public long getTimeMillis() {
if (isSystemCurrentTime) {
return System.currentTimeMillis();
}
return getTimeMicros() / MICROS_TO_MILLIS;
}
private long getTimeMicros() {
return (System.nanoTime() / NANOS_TO_MICROS) + wallClockOffset;
}
/**
* Calculate resolution of this timer in microseconds i.e. what is the resolution
* of the underlying platform's timer.
*
* @return timer resolution
*/
protected long calculateResolution() {
final int loops = 5;
long totalResolution = 0;
long time = this.getTimeMicros(), prevTime = time;
for (int i = 0; i < loops; i++) {
// wait until time changes
while (time == prevTime)
time = this.getTimeMicros();
totalResolution += time - prevTime;
prevTime = time;
}
return totalResolution / loops;
}
@Override
public String toString() {
return description;
}
}