package lsr.paxos.idgen; import static lsr.common.ProcessDescriptor.processDescriptor; import java.util.concurrent.atomic.AtomicLong; /** * Constructs ID as composite of number and view/epoch * * a long number 0x0123456789abcdef is divided (at lenght of {@link #SHIFT}) to * two parts - one for view/epoch, other for sequence no (as in * {@link SimpleIdGenerator}). * * Eg: * * | 01 23 45 | 67 89 ab cd ef | * * |view/epoch| . . clientNo . | * * This class guarantees that client ID's remain correct unless either * * 2^(62-SHIFT) - currently 16 million - view / epoch changes happen * * or * * 2^SHIFT/N - currently 10 milliard for 11 replicas - clients call for ID in * the same view/epoch */ public class ViewEpochIdGenerator implements IdGenerator { /** initial view or epoch of the replica (at the moment of replica start) */ private final long viewOrEpochShifted; /** SHIFT bytes for unique client ID, 64-SHIFT bytes for view/epoch */ private static final int SHIFT = 40; private final AtomicLong current = new AtomicLong(processDescriptor.localId); public ViewEpochIdGenerator(long viewOrEpoch) { this.viewOrEpochShifted = viewOrEpoch << SHIFT; } @Override public long next() { long base = current.addAndGet(processDescriptor.numReplicas); return viewOrEpochShifted | base; } }