package edu.uw.zookeeper.protocol.server;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.concurrent.atomic.AtomicLong;
/**
* zxid composed of a 32 bit epoch (MSB) and a 32 bit counter (LSB).
*
* Threadsafe
*/
public class ZxidEpochIncrementer extends ZxidIncrementer {
// TODO: it seems like epoch and counter should be integers,
// but I'm not sure how this all interacts with signedness
// so for now we just copy ZxidUtil
public static long epochOf(long zxid) {
return zxid >> 32L;
}
public static long counterOf(long zxid) {
return zxid & 0xffffffffL;
}
public static long zxidOf(long epoch) {
return zxidOf(epoch, 0);
}
public static long zxidOf(long epoch, long counter) {
return (epoch << 32L) | (counter & 0xffffffffL);
}
public static ZxidEpochIncrementer fromZero() {
return fromEpoch(0);
}
public static ZxidEpochIncrementer fromEpoch(long epoch) {
return of(new AtomicLong(zxidOf(epoch)));
}
public static ZxidEpochIncrementer of(AtomicLong lastZxid) {
checkArgument(lastZxid.get() >= 0);
return new ZxidEpochIncrementer(lastZxid);
}
protected ZxidEpochIncrementer(AtomicLong lastZxid) {
super(lastZxid);
}
public long epoch() {
return epochOf(get());
}
public long counter() {
return counterOf(get());
}
public boolean setEpoch(long nextEpoch) {
long current = get();
long nextZxid = zxidOf(nextEpoch);
checkArgument(nextZxid > current);
return lastZxid.compareAndSet(current, nextZxid);
}
// TODO: check for counter overflow into epoch bits
// @Override
// public long next() {
// return lastZxid.incrementAndGet();
// }
}