package lsr.paxos.storage;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SynchronousConsensusInstace extends ConsensusInstance {
private final DiscWriter writer;
public SynchronousConsensusInstace(Integer nextId, LogEntryState known, int view, byte[] value,
DiscWriter writer) {
super(nextId, known, view, value);
this.writer = writer;
}
public SynchronousConsensusInstace(Integer id, DiscWriter writer) {
super(id);
this.writer = writer;
}
public SynchronousConsensusInstace(ConsensusInstance instance, DiscWriter writer) {
super(instance.getId(), instance.getState(), instance.getView(), instance.getValue());
this.writer = writer;
}
protected void setValue(int view, byte[] value) {
assert this.view <= view : "Cannot set smaller view.";
assert value != null : "value cannot be null. View: " + view;
assert state != LogEntryState.DECIDED
|| Arrays.equals(this.value, value) : view + " " + value + " " + this;
assert state != LogEntryState.KNOWN
|| view != this.view
|| Arrays.equals(this.value, value) : view + " " + value + " " + this;
writeViewAndOrValue(view, value);
if (state != LogEntryState.DECIDED) {
state = LogEntryState.KNOWN;
}
onValueChange();
}
private void writeViewAndOrValue(int view, byte[] value) {
if (view == this.view) {
if (this.value == null) {
writer.changeInstanceValue(id, view, value);
this.value = value;
}
} else { // view > this.view
if (Arrays.equals(this.value, value)) {
setView(view);
} else {
writer.changeInstanceValue(id, view, value);
this.value = value;
this.view = view;
}
}
}
public void setView(int view) {
assert this.view <= view : "Cannot set smaller view.";
assert state != LogEntryState.DECIDED || view == this.view;
if (this.view < view) {
writer.changeInstanceView(id, view);
accepts.clear();
this.view = view;
}
}
public void setDecided() {
super.setDecided();
writer.decideInstance(id);
}
@Override
public void updateStateFromDecision(int newView, byte[] newValue) {
assert newValue != null;
if (state == LogEntryState.DECIDED) {
logger.error("Updating a decided instance from a catchup message: {}", this);
// The value must be the same as the local value. No change.
assert Arrays.equals(newValue, value) : "Values don't match. New view: " + newView +
", local: " + this;
return;
}
writeViewAndOrValue(newView, newValue);
onValueChange();
}
public boolean equals(Object obj) {
return super.equals(obj);
}
public int hashCode() {
return super.hashCode();
}
private static final long serialVersionUID = 1L;
private final static Logger logger = LoggerFactory.getLogger(SynchronousConsensusInstace.class);
}