2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.raft;
10 import java.util.ArrayList;
11 import java.util.List;
14 * Abstract class handling the mapping of
15 * logical LogEntry Index and the physical list index.
17 public abstract class AbstractReplicatedLogImpl implements ReplicatedLog {
19 protected final List<ReplicatedLogEntry> journal;
20 protected final Object snapshot;
21 protected long snapshotIndex = -1;
22 protected long snapshotTerm = -1;
24 public AbstractReplicatedLogImpl(Object state, long snapshotIndex,
25 long snapshotTerm, List<ReplicatedLogEntry> unAppliedEntries) {
26 this.snapshot = state;
27 this.snapshotIndex = snapshotIndex;
28 this.snapshotTerm = snapshotTerm;
29 this.journal = new ArrayList<>(unAppliedEntries);
33 public AbstractReplicatedLogImpl() {
35 this.journal = new ArrayList<>();
38 protected int adjustedIndex(long logEntryIndex) {
39 if(snapshotIndex < 0){
40 return (int) logEntryIndex;
42 return (int) (logEntryIndex - (snapshotIndex + 1));
46 public ReplicatedLogEntry get(long logEntryIndex) {
47 int adjustedIndex = adjustedIndex(logEntryIndex);
49 if (adjustedIndex < 0 || adjustedIndex >= journal.size()) {
50 // physical index should be less than list size and >= 0
54 return journal.get(adjustedIndex);
58 public ReplicatedLogEntry last() {
59 if (journal.isEmpty()) {
62 // get the last entry directly from the physical index
63 return journal.get(journal.size() - 1);
67 public long lastIndex() {
68 if (journal.isEmpty()) {
69 // it can happen that after snapshot, all the entries of the
70 // journal are trimmed till lastApplied, so lastIndex = snapshotIndex
73 return last().getIndex();
77 public long lastTerm() {
78 if (journal.isEmpty()) {
79 // it can happen that after snapshot, all the entries of the
80 // journal are trimmed till lastApplied, so lastTerm = snapshotTerm
83 return last().getTerm();
87 public void removeFrom(long logEntryIndex) {
88 int adjustedIndex = adjustedIndex(logEntryIndex);
89 if (adjustedIndex < 0 || adjustedIndex >= journal.size()) {
90 // physical index should be less than list size and >= 0
93 journal.subList(adjustedIndex , journal.size()).clear();
97 public void append(ReplicatedLogEntry replicatedLogEntry) {
98 journal.add(replicatedLogEntry);
102 public List<ReplicatedLogEntry> getFrom(long logEntryIndex) {
103 return getFrom(logEntryIndex, journal.size());
107 public List<ReplicatedLogEntry> getFrom(long logEntryIndex, int max) {
108 int adjustedIndex = adjustedIndex(logEntryIndex);
109 int size = journal.size();
110 List<ReplicatedLogEntry> entries = new ArrayList<>(100);
111 if (adjustedIndex >= 0 && adjustedIndex < size) {
112 // physical index should be less than list size and >= 0
113 int maxIndex = adjustedIndex + max;
117 entries.addAll(journal.subList(adjustedIndex, maxIndex));
125 return journal.size();
129 public boolean isPresent(long logEntryIndex) {
130 if (logEntryIndex > lastIndex()) {
131 // if the request logical index is less than the last present in the list
134 int adjustedIndex = adjustedIndex(logEntryIndex);
135 return (adjustedIndex >= 0);
139 public boolean isInSnapshot(long logEntryIndex) {
140 return logEntryIndex <= snapshotIndex;
144 public Object getSnapshot() {
149 public long getSnapshotIndex() {
150 return snapshotIndex;
154 public long getSnapshotTerm() {
159 public abstract void appendAndPersist(ReplicatedLogEntry replicatedLogEntry);
162 public abstract void removeFromAndPersist(long index);