package lsr.paxos.messages; import java.io.DataInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; import lsr.paxos.storage.ConsensusInstance; /** * Represents the response to <code>Prepare</code> message. It contains view * number and list of consensus instances. If recovery with epoch vector is * used, then epoch vector is also sent. */ public class PrepareOK extends Message { private static final long serialVersionUID = 1L; private final ConsensusInstance[] prepared; private final long[] epoch; /** * Creates new <code>PrepareOK</code> message without epoch vector. * * @param view - sender view number * @param prepared - list of prepared consensus instances */ public PrepareOK(int view, ConsensusInstance[] prepared) { this(view, prepared, new long[0]); } /** * Creates new <code>PrepareOK</code> message with epoch vector. * * @param view - sender view number * @param prepared - list of prepared consensus instances * @param epoch - the epoch vector */ public PrepareOK(int view, ConsensusInstance[] prepared, long[] epoch) { super(view); assert epoch != null; this.prepared = prepared; this.epoch = epoch; } /** * Creates new <cod>PrepareOK</code> message from serialized stream. * * @param input - the input stream with serialized message * @throws IOException if I/O error occurs */ public PrepareOK(DataInputStream input) throws IOException { super(input); prepared = new ConsensusInstance[input.readInt()]; for (int i = 0; i < prepared.length; ++i) { prepared[i] = new ConsensusInstance(input); } int epochSize = input.readInt(); epoch = new long[epochSize]; for (int i = 0; i < epoch.length; ++i) { epoch[i] = input.readLong(); } } /** * Returns prepared list of consensus instances. * * @return prepared list of consensus instances. */ public ConsensusInstance[] getPrepared() { return prepared; } /** * Returns epoch vector. This value should never be equal to * <code>null</code>. If this message doesn't contain epoch vector, then it * will be represented as empty array. * * @return epoch vector */ public long[] getEpoch() { return epoch; } public MessageType getType() { return MessageType.PrepareOK; } public int byteSize() { int size = super.byteSize() + 4; for (ConsensusInstance ci : prepared) { size += ci.byteSize(); } size += epoch.length * 8 + 4; return size; } public String toString() { return "PrepareOK(" + super.toString() + ", values: " + Arrays.toString(getPrepared()) + ")"; } protected void write(ByteBuffer bb) { bb.putInt(prepared.length); for (ConsensusInstance ci : prepared) { ci.write(bb); } bb.putInt(epoch.length); for (int i = 0; i < epoch.length; ++i) { bb.putLong(epoch[i]); } } }