@Override public void setReplicaContext(ReplicaContext replicaContext) { this.config = replicaContext.getStaticConfiguration(); if (log == null) { globalCheckpointPeriod = config.getGlobalCheckpointPeriod(); replicaCkpIndex = getCheckpointPortionIndex(); checkpointPortion = globalCheckpointPeriod / config.getN(); // byte[] state = getSnapshot(); if (config.isToLog()) { int replicaId = config.getProcessId(); boolean isToLog = config.isToLog(); boolean syncLog = config.isToWriteSyncLog(); boolean syncCkp = config.isToWriteSyncCkp(); // log = new DurableStateLog(replicaId, state, computeHash(state), isToLog, syncLog, // syncCkp); log = new DurableStateLog(replicaId, null, null, isToLog, syncLog, syncCkp); CSTState storedState = log.loadDurableState(); if (storedState.getLastCID() > -1) { System.out.println("LAST CID RECOVERED FROM LOG: " + storedState.getLastCID()); setState(storedState); getStateManager().setLastCID(storedState.getLastCID()); } else { System.out.println("REPLICA IS IN INITIAL STATE"); } } getStateManager().askCurrentConsensusId(); } }
/** * Iterates over the commands to find if any replica took a checkpoint. When a replica take a * checkpoint, it is necessary to save in an auxiliary table the position in the log in which that * replica took the checkpoint. It is used during state transfer to find lower or upper log * portions to be restored in the recovering replica. This iteration over commands is needed due * to the batch execution strategy introduced with the durable techniques to improve state * management. As several consensus instances can be executed in the same batch of commands, it is * necessary to identify if the batch contains checkpoint indexes. * * @param msgCtxs the contexts of the consensus where the messages where executed. There is one * msgCtx message for each command to be executed * @return the index in which a replica is supposed to take a checkpoint. If there is no replica * taking a checkpoint during the period comprised by this command batch, it is returned -1 */ private int findCheckpointPosition(int[] cids) { if (config.getGlobalCheckpointPeriod() < 1) return -1; if (cids.length == 0) throw new IllegalArgumentException(); int firstCID = cids[0]; if ((firstCID + 1) % checkpointPortion == 0) { return cidPosition(cids, firstCID); } else { int nextCkpIndex = (((firstCID / checkpointPortion) + 1) * checkpointPortion) - 1; if (nextCkpIndex <= cids[cids.length - 1]) { return cidPosition(cids, nextCkpIndex); } } return -1; }