2 * Copyright (c) 2024 PANTHEON.tech, s.r.o. 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 java.util.Objects.requireNonNull;
20 import io.atomix.storage.journal.index.JournalIndex;
21 import java.nio.MappedByteBuffer;
22 import java.nio.channels.FileChannel;
23 import org.eclipse.jdt.annotation.NonNull;
24 import org.eclipse.jdt.annotation.Nullable;
26 abstract sealed class JournalSegmentWriter<E> permits DiskJournalSegmentWriter, MappedJournalSegmentWriter {
27 final @NonNull FileChannel channel;
28 final @NonNull JournalIndex index;
29 final @NonNull JournalSerdes namespace;
30 final int maxSegmentSize;
31 final int maxEntrySize;
32 final long firstIndex;
34 JournalSegmentWriter(final FileChannel channel, final JournalSegment<E> segment, final int maxEntrySize,
35 final JournalIndex index, final JournalSerdes namespace) {
36 this.channel = requireNonNull(channel);
37 this.index = requireNonNull(index);
38 this.namespace = requireNonNull(namespace);
39 maxSegmentSize = segment.descriptor().maxSegmentSize();
40 this.maxEntrySize = maxEntrySize;
41 firstIndex = segment.index();
44 JournalSegmentWriter(final JournalSegmentWriter<E> previous) {
45 channel = previous.channel;
46 index = previous.index;
47 namespace = previous.namespace;
48 maxSegmentSize = previous.maxSegmentSize;
49 maxEntrySize = previous.maxEntrySize;
50 firstIndex = previous.firstIndex;
54 * Returns the last written index.
56 * @return The last written index.
58 final long getLastIndex() {
59 final Indexed<?> lastEntry;
60 return (lastEntry = getLastEntry()) != null ? lastEntry.index() : firstIndex - 1;
64 * Returns the last entry written.
66 * @return The last entry written.
68 abstract Indexed<E> getLastEntry();
71 * Returns the next index to be written.
73 * @return The next index to be written.
75 final long getNextIndex() {
76 final Indexed<?> lastEntry;
77 return (lastEntry = getLastEntry()) != null ? lastEntry.index() + 1 : firstIndex;
81 * Appends an entry to the journal.
83 * @param entry The entry to append.
84 * @return The appended indexed entry.
86 abstract <T extends E> Indexed<T> append(T entry);
89 * Resets the head of the segment to the given index.
91 * @param index the index to which to reset the head of the segment
93 abstract void reset(long index);
96 * Truncates the log to the given index.
98 * @param index The index to which to truncate the log.
100 abstract void truncate(long index);
103 * Flushes written entries to disk.
105 abstract void flush();
108 * Closes this writer.
110 abstract void close();
113 * Returns the mapped buffer underlying the segment writer, or {@code null} if the writer does not have such a
116 * @return the mapped buffer underlying the segment writer, or {@code null}.
118 abstract @Nullable MappedByteBuffer buffer();
120 abstract @NonNull MappedJournalSegmentWriter<E> toMapped();
122 abstract @NonNull DiskJournalSegmentWriter<E> toFileChannel();