2 * Copyright 2017-2022 Open Networking Foundation and others. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package io.atomix.storage.journal;
18 import static com.google.common.base.Verify.verifyNotNull;
23 final class SegmentedJournalWriter<E> implements JournalWriter<E> {
24 private final SegmentedJournal<E> journal;
25 private JournalSegment<E> currentSegment;
26 private JournalSegmentWriter<E> currentWriter;
28 SegmentedJournalWriter(SegmentedJournal<E> journal) {
29 this.journal = journal;
30 this.currentSegment = journal.getLastSegment();
31 this.currentWriter = currentSegment.acquireWriter();
35 public long getLastIndex() {
36 return currentWriter.getLastIndex();
40 public Indexed<E> getLastEntry() {
41 return currentWriter.getLastEntry();
45 public long getNextIndex() {
46 return currentWriter.getNextIndex();
50 public void reset(long index) {
51 if (index > currentSegment.firstIndex()) {
52 currentSegment.releaseWriter();
53 currentSegment = journal.resetSegments(index);
54 currentWriter = currentSegment.acquireWriter();
58 journal.resetHead(index);
62 public void commit(long index) {
63 if (index > journal.getCommitIndex()) {
64 journal.setCommitIndex(index);
65 if (journal.isFlushOnCommit()) {
72 public <T extends E> Indexed<T> append(T entry) {
73 var indexed = currentWriter.append(entry);
74 if (indexed != null) {
78 // Slow path: we do not have enough capacity
79 currentWriter.flush();
80 currentSegment.releaseWriter();
81 currentSegment = journal.getNextSegment();
82 currentWriter = currentSegment.acquireWriter();
83 return verifyNotNull(currentWriter.append(entry));
87 public void truncate(long index) {
88 if (index < journal.getCommitIndex()) {
89 throw new IndexOutOfBoundsException("Cannot truncate committed index: " + index);
92 // Delete all segments with first indexes greater than the given index.
93 while (index < currentSegment.firstIndex() && currentSegment != journal.getFirstSegment()) {
94 currentSegment.releaseWriter();
95 journal.removeSegment(currentSegment);
96 currentSegment = journal.getLastSegment();
97 currentWriter = currentSegment.acquireWriter();
100 // Truncate the current index.
101 currentWriter.truncate(index);
103 // Reset segment readers.
104 journal.resetTail(index + 1);
108 public void flush() {
109 currentWriter.flush();