edu.byu.hbll.box.internal.util.CursorUtils Maven / Gradle / Ivy
package edu.byu.hbll.box.internal.util;
import java.time.Instant;
/**
* Utility class for dealing with cursors (the nanoseconds since the epoch).
*
* @author Charles Draper
*/
public class CursorUtils {
/** An object to act as a mutex. */
private static Object mutex = new Object();
/** The epoch nanosecond last time nextCursor() was called. */
private static long lastCursor = 0;
/**
* Returns the cursor for the given time. Returns the number of nanoseconds since epoch until the
* given time.
*
* @param time the given time
* @return the cursor for the given time
*/
public static long getCursor(Instant time) {
long t = (time.getEpochSecond() * 1000000000) + time.getNano();
return t;
}
/**
* Generates a timestamp based long that can be used as cursor in a database. It equals the number
* of nanoseconds since the epoch. Calls to nextCursor will always return a larger cursor than
* previous calls.
*
* With 63 bits available (64 bit long minus 1 bit for the sign), this strategy should work
* until approximately the year 2262. There is a slight chance that a distributed box application
* will create the same cursor. To overcome this, clients that read from this box should use a
* page size of at least the number of instances of the box application. There is; however, no
* chance of a single box instance creating identical cursors.
*
* @return the next cursor
*/
public static synchronized long nextCursor() {
long cursor = getCursor(Instant.now());
synchronized (mutex) {
// increment the cursor if same as last cursor
if (cursor <= lastCursor) {
cursor = lastCursor + 1;
}
lastCursor = cursor;
}
return cursor;
}
}