Java tutorial
/* Copyright (c) 2015 University of Massachusetts * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * Initial developer(s): V. Arun */ package edu.umass.cs.gigapaxos.paxospackets; import java.io.UnsupportedEncodingException; import java.net.UnknownHostException; import java.nio.ByteBuffer; import org.json.JSONException; import org.json.JSONObject; import edu.umass.cs.gigapaxos.paxosutil.Ballot; /** * @author arun * * A <slot, ballot, request> three-tuple. The slot and request are * within the proposal here. A pvalue is used internally by paxos * acceptors and coordinators. It also acts as a DECISION packet as * every committed request must be associated with some slot, and * ballot. */ @SuppressWarnings("javadoc") public class PValuePacket extends ProposalPacket { /** * A ballot is a {@code <ballotNumber:ballotCoordinator>} two-tuple. A * PValuePacket is a <ballot, proposal> two-tuple, or equivalently a * <ballot, slot, request> three-tuple, or equivalently a <ballotNumber: * balltoCoordinator, slot, request> four-tuple. */ public final Ballot ballot; /** * Whether this is a decision being replayed under recovery. */ private boolean recovery; /** * For garbage collection, similar to that in AcceptPacket. This is the slot * up to which the median node (or above) has checkpointed when nodes in the * paxos replica group are ordered by their macCheckpointedSlot. */ private int medianCheckpointedSlot; private boolean noCoalesce = false; static enum Fields implements GetType { ballot(Ballot.class), recovery(boolean.class), medianCheckpointedSlot(int.class), noCoalesce(boolean.class); final Class<?> type; Fields(Class<?> type) { this.type = type; } @Override public Class<?> getType() { return this.type; } } static { checkFields(PValuePacket.class, Fields.values()); } protected static final int SIZEOF_PVALUE = 4 + 4 + 1 + 4 + 1; public PValuePacket(Ballot b, ProposalPacket p) { super(p); this.ballot = b; this.medianCheckpointedSlot = -1; this.recovery = false; // true only when created from json // packet type needs to be explicitly assigned later } // Super-called by inheritors and by PaxosInstanceStateMachine public PValuePacket(PValuePacket pvalue) { super(pvalue); this.ballot = pvalue.ballot; this.medianCheckpointedSlot = pvalue.medianCheckpointedSlot; this.packetType = pvalue.getType(); this.recovery = false; // true only when created from json } public PValuePacket(JSONObject json) throws JSONException { super(json); this.ballot = new Ballot(json.getString(PaxosPacket.NodeIDKeys.B.toString())); this.medianCheckpointedSlot = json.getInt(PaxosPacket.Keys.GC_S.toString()); this.recovery = json.optBoolean(PaxosPacket.Keys.RCVRY.toString()); this.packetType = PaxosPacket.getPaxosPacketType(json); this.noCoalesce = json.optBoolean(PaxosPacket.Keys.NO_COALESCE.toString()); } public PValuePacket(net.minidev.json.JSONObject json) throws JSONException { super(json); this.ballot = new Ballot((String) json.get(PaxosPacket.NodeIDKeys.B.toString())); this.medianCheckpointedSlot = (Integer) json.get(PaxosPacket.Keys.GC_S.toString()); this.recovery = json.containsKey(PaxosPacket.Keys.RCVRY.toString()) ? (Boolean) json.get(PaxosPacket.Keys.RCVRY.toString()) : false; this.packetType = PaxosPacket.getPaxosPacketType(json); this.noCoalesce = json.containsKey(PaxosPacket.Keys.NO_COALESCE.toString()) ? (Boolean) json.get(PaxosPacket.Keys.NO_COALESCE.toString()) : false; } protected PValuePacket(ByteBuffer bbuf) throws UnsupportedEncodingException, UnknownHostException { super(bbuf); this.ballot = new Ballot(bbuf.getInt(), bbuf.getInt()); this.recovery = bbuf.get() == (byte) 1; this.medianCheckpointedSlot = bbuf.getInt(); this.noCoalesce = bbuf.get() == (byte) 1; } public PValuePacket makeDecision(int mcSlot) { this.packetType = PaxosPacketType.DECISION; this.medianCheckpointedSlot = mcSlot; this.setStringifiedSelf(null); /* Only prepares, accepts, and decisions are replyed, so we should never * be making a decision out of a recovery packet, hence the assert. */ assert (!recovery); return (this); } public PValuePacket preempt() { // Note: preemption does not change final fields this.packetType = PaxosPacketType.PREEMPTED; return this; } public boolean isCoalescable() { return !this.noCoalesce && this.getType().equals(PaxosPacket.PaxosPacketType.DECISION); } public int getMedianCheckpointedSlot() { return this.medianCheckpointedSlot; } protected void setMedianCheckpointedSlot(int slot) { this.medianCheckpointedSlot = slot; } public boolean isRecovery() { return this.recovery; } public PValuePacket setRecovery() { return this.setRecovery(true); } public PValuePacket setRecovery(boolean b) { this.recovery = b; return this; } @Override protected String getSummaryString() { return ballot + ", " + super.getSummaryString() + (this.isRecovery() ? "(recovery)" : ""); } @Override public JSONObject toJSONObjectImpl() throws JSONException { JSONObject json = super.toJSONObjectImpl(); json.put(PaxosPacket.NodeIDKeys.B.toString(), ballot.toString()); json.put(PaxosPacket.Keys.GC_S.toString(), this.medianCheckpointedSlot); if (this.recovery) json.put(PaxosPacket.Keys.RCVRY.toString(), this.recovery); if (this.noCoalesce) json.put(PaxosPacket.Keys.NO_COALESCE.toString(), this.noCoalesce); return json; } @Override public net.minidev.json.JSONObject toJSONSmartImpl() throws JSONException { net.minidev.json.JSONObject json = super.toJSONSmartImpl(); json.put(PaxosPacket.NodeIDKeys.B.toString(), ballot.toString()); json.put(PaxosPacket.Keys.GC_S.toString(), this.medianCheckpointedSlot); if (this.recovery) json.put(PaxosPacket.Keys.RCVRY.toString(), this.recovery); if (this.noCoalesce) json.put(PaxosPacket.Keys.NO_COALESCE.toString(), this.noCoalesce); return json; } public PValuePacket setNoCoalesce() { this.noCoalesce = true; return this; } public PValuePacket getMetaDecision() { PValuePacket meta = new PValuePacket(this.ballot, new ProposalPacket(this.slot, new RequestPacket(this.requestID, null, this.stop, this).getFirstOnly())); meta.packetType = PaxosPacketType.DECISION; return meta; } public static void main(String[] args) { } }