@Override public void saveSnapshotData(Snapshot snapshot, long offset, byte[] data) { Path filePath = this.snapshotStore.resolve(String.format("%d-%d.s", snapshot.getLastLogIndex(), snapshot.getLastLogTerm())); try{ if(!Files.exists(filePath)){ Files.write(this.snapshotStore.resolve(String.format("%d.cnf", snapshot.getLastLogIndex())), snapshot.getLastConfig().toBytes(), StandardOpenOption.CREATE); } RandomAccessFile snapshotFile = new RandomAccessFile(filePath.toString(), "rw"); snapshotFile.seek(offset); snapshotFile.write(data); snapshotFile.close(); }catch(Exception error){ throw new RuntimeException(error.getMessage()); } }
@Override public void saveSnapshotData(Snapshot snapshot, long offset, byte[] data) { Path filePath = this.snapshotStore.resolve(String.format("%d-%d.s", snapshot.getLastLogIndex(), snapshot.getLastLogTerm())); try{ if(!Files.exists(filePath)){ Files.write(this.snapshotStore.resolve(String.format("%d.cnf", snapshot.getLastLogIndex())), snapshot.getLastConfig().toBytes(), StandardOpenOption.CREATE); } RandomAccessFile snapshotFile = new RandomAccessFile(filePath.toString(), "rw"); snapshotFile.seek(offset); snapshotFile.write(data); snapshotFile.close(); }catch(Exception error){ throw new RuntimeException(error.getMessage()); } }
public byte[] toBytes(){ byte[] configData = this.snapshot.getLastConfig().toBytes(); int size = Long.BYTES * 3 + configData.length + Integer.BYTES * 2 + data.length + 1; ByteBuffer buffer = ByteBuffer.allocate(size); buffer.putLong(snapshot.getLastLogIndex()); buffer.putLong(snapshot.getLastLogTerm()); buffer.putInt(configData.length); buffer.put(configData); buffer.putLong(this.offset); buffer.putInt(this.data.length); buffer.put(this.data); buffer.put(this.done ? (byte)1 : (byte)0); return buffer.array(); }
public byte[] toBytes(){ byte[] configData = this.snapshot.getLastConfig().toBytes(); int size = Long.BYTES * 3 + configData.length + Integer.BYTES * 2 + data.length + 1; ByteBuffer buffer = ByteBuffer.allocate(size); buffer.putLong(snapshot.getLastLogIndex()); buffer.putLong(snapshot.getLastLogTerm()); buffer.putInt(configData.length); buffer.put(configData); buffer.putLong(this.offset); buffer.putInt(this.data.length); buffer.put(this.data); buffer.put(this.done ? (byte)1 : (byte)0); return buffer.array(); }
public byte[] toBytes(){ byte[] configData = this.snapshot.getLastConfig().toBytes(); int size = Long.BYTES * 3 + configData.length + Integer.BYTES * 2 + data.length + 1; ByteBuffer buffer = ByteBuffer.allocate(size); buffer.putLong(snapshot.getLastLogIndex()); buffer.putLong(snapshot.getLastLogTerm()); buffer.putInt(configData.length); buffer.put(configData); buffer.putLong(this.offset); buffer.putInt(this.data.length); buffer.put(this.data); buffer.put(this.done ? (byte)1 : (byte)0); return buffer.array(); }
@Override public int readSnapshotData(Snapshot snapshot, long offset, byte[] buffer) { Path filePath = this.snapshotStore.resolve(String.format("%d-%d.s", snapshot.getLastLogIndex(), snapshot.getLastLogTerm())); if(!Files.exists(filePath)){ return -1; } try{ RandomAccessFile snapshotFile = new RandomAccessFile(filePath.toString(), "rw"); snapshotFile.seek(offset); int bytesRead = read(snapshotFile, buffer); snapshotFile.close(); return bytesRead; }catch(Exception error){ LogManager.getLogger(getClass()).error("failed read data from snapshot", error); return -1; } }
@Override public int readSnapshotData(Snapshot snapshot, long offset, byte[] buffer) { Path filePath = this.snapshotStore.resolve(String.format("%d-%d.s", snapshot.getLastLogIndex(), snapshot.getLastLogTerm())); if(!Files.exists(filePath)){ return -1; } try{ RandomAccessFile snapshotFile = new RandomAccessFile(filePath.toString(), "rw"); snapshotFile.seek(offset); int bytesRead = read(snapshotFile, buffer); snapshotFile.close(); return bytesRead; }catch(Exception error){ LogManager.getLogger(getClass()).error("failed read data from snapshot", error); return -1; } }
@Override public boolean applySnapshot(Snapshot snapshot) { Path filePath = this.snapshotStore.resolve(String.format("%d-%d.s", snapshot.getLastLogIndex(), snapshot.getLastLogTerm())); if(!Files.exists(filePath)){ return false; } try{ FileInputStream input = new FileInputStream(filePath.toString()); InputStreamReader reader = new InputStreamReader(input, StandardCharsets.UTF_8); BufferedReader bufferReader = new BufferedReader(reader); synchronized(this.messages){ this.messages.clear(); String line = null; while((line = bufferReader.readLine()) != null){ if(line.length() > 0){ System.out.printf("from snapshot: %s\n", line); this.addMessage(line); } } this.commitIndex = snapshot.getLastLogIndex(); } bufferReader.close(); reader.close(); input.close(); }catch(Exception error){ LogManager.getLogger(getClass()).error("failed to apply the snapshot", error); return false; } return true; }
@Override public CompletableFuture<Boolean> createSnapshot(Snapshot snapshot) { if(snapshot.getLastLogIndex() > this.commitIndex){ return CompletableFuture.completedFuture(false); Path filePath = this.snapshotStore.resolve(String.format("%d-%d.s", snapshot.getLastLogIndex(), snapshot.getLastLogTerm())); try{ if(!Files.exists(filePath)){ Files.write(this.snapshotStore.resolve(String.format("%d.cnf", snapshot.getLastLogIndex())), snapshot.getLastConfig().toBytes(), StandardOpenOption.CREATE);
@Override public boolean applySnapshot(Snapshot snapshot) { Path filePath = this.snapshotStore.resolve(String.format("%d-%d.s", snapshot.getLastLogIndex(), snapshot.getLastLogTerm())); if(!Files.exists(filePath)){ return false; } try{ FileInputStream input = new FileInputStream(filePath.toString()); InputStreamReader reader = new InputStreamReader(input, StandardCharsets.UTF_8); BufferedReader bufferReader = new BufferedReader(reader); synchronized(this.messages){ this.messages.clear(); String line = null; while((line = bufferReader.readLine()) != null){ if(line.length() > 0){ System.out.printf("from snapshot: %s\n", line); this.addMessage(line); } } this.commitIndex = snapshot.getLastLogIndex(); } bufferReader.close(); reader.close(); input.close(); }catch(Exception error){ LogManager.getLogger(getClass()).error("failed to apply the snapshot", error); return false; } return true; }
@Override public CompletableFuture<Boolean> createSnapshot(Snapshot snapshot) { if(snapshot.getLastLogIndex() > this.commitIndex){ return CompletableFuture.completedFuture(false); Path filePath = this.snapshotStore.resolve(String.format("%d-%d.s", snapshot.getLastLogIndex(), snapshot.getLastLogTerm())); try{ if(!Files.exists(filePath)){ Files.write(this.snapshotStore.resolve(String.format("%d.cnf", snapshot.getLastLogIndex())), snapshot.getLastConfig().toBytes(), StandardOpenOption.CREATE);
private long termForLastLog(long logIndex){ if(logIndex == 0){ return 0; } if(logIndex >= this.logStore.getStartIndex()){ return this.logStore.getLogEntryAt(logIndex).getTerm(); } Snapshot lastSnapshot = this.stateMachine.getLastSnapshot(); if(lastSnapshot == null || logIndex != lastSnapshot.getLastLogIndex()){ throw new IllegalArgumentException("logIndex is beyond the range that no term could be retrieved"); } return lastSnapshot.getLastLogTerm(); }
private long termForLastLog(long logIndex){ if(logIndex == 0){ return 0; } if(logIndex >= this.logStore.getStartIndex()){ return this.logStore.getLogEntryAt(logIndex).getTerm(); } Snapshot lastSnapshot = this.stateMachine.getLastSnapshot(); if(lastSnapshot == null || logIndex != lastSnapshot.getLastLogIndex()){ throw new IllegalArgumentException("logIndex is beyond the range that no term could be retrieved"); } return lastSnapshot.getLastLogTerm(); }
private long termForLastLog(long logIndex){ if(logIndex == 0){ return 0; } if(logIndex >= this.logStore.getStartIndex()){ return this.logStore.getLogEntryAt(logIndex).getTerm(); } Snapshot lastSnapshot = this.stateMachine.getLastSnapshot(); if(lastSnapshot == null || logIndex != lastSnapshot.getLastLogIndex()){ throw new IllegalArgumentException("logIndex is beyond the range that no term could be retrieved"); } return lastSnapshot.getLastLogTerm(); }
if(this.logStore.compact(snapshotSyncRequest.getSnapshot().getLastLogIndex())){ this.state.setCommitIndex(snapshotSyncRequest.getSnapshot().getLastLogIndex()); this.quickCommitIndex = snapshotSyncRequest.getSnapshot().getLastLogIndex(); this.context.getServerStateManager().persistState(this.state); this.logger.info("snapshot is successfully applied");
if(this.logStore.compact(snapshotSyncRequest.getSnapshot().getLastLogIndex())){ this.state.setCommitIndex(snapshotSyncRequest.getSnapshot().getLastLogIndex()); this.quickCommitIndex = snapshotSyncRequest.getSnapshot().getLastLogIndex(); this.context.getServerStateManager().persistState(this.state); this.logger.info("snapshot is successfully applied");
if(response.getNextIndex() >= context.getSnapshot().getSize()){ this.logger.debug("snapshot sync is done"); peer.setNextLogIndex(context.getSnapshot().getLastLogIndex() + 1); peer.setMatchedIndex(context.getSnapshot().getLastLogIndex()); peer.setSnapshotInSync(null); needToCatchup = peer.clearPendingCommit() || response.getNextIndex() < this.logStore.getFirstAvailableIndex();
if(response.getNextIndex() >= context.getSnapshot().getSize()){ this.logger.debug("snapshot sync is done"); peer.setNextLogIndex(context.getSnapshot().getLastLogIndex() + 1); peer.setMatchedIndex(context.getSnapshot().getLastLogIndex()); peer.setSnapshotInSync(null); needToCatchup = peer.clearPendingCommit() || response.getNextIndex() < this.logStore.getFirstAvailableIndex();
if(response.getNextIndex() >= context.getSnapshot().getSize()){ this.logger.debug("snapshot sync is done"); peer.setNextLogIndex(context.getSnapshot().getLastLogIndex() + 1); peer.setMatchedIndex(context.getSnapshot().getLastLogIndex()); peer.setSnapshotInSync(null); needToCatchup = peer.clearPendingCommit() || response.getNextIndex() < this.logStore.getFirstAvailableIndex();
if(snapshotSyncRequest.getSnapshot().getLastLogIndex() <= this.quickCommitIndex){ this.logger.error("Received a snapshot which is older than this server (%d)", this.id); response.setNextIndex(0);