adc99100877c18c9a969b06b278b88b5ec1721bb
[controller.git] / atomix-storage / src / main / java / io / atomix / storage / journal / JournalSegmentFile.java
1 /*
2  * Copyright 2015-2022 Open Networking Foundation and others.  All rights reserved.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package io.atomix.storage.journal;
17
18 import static java.util.Objects.requireNonNull;
19
20 import com.google.common.base.MoreObjects;
21 import java.io.File;
22 import java.nio.file.Path;
23 import org.eclipse.jdt.annotation.NonNull;
24
25 /**
26  * Segment file utility.
27  *
28  * @author <a href="http://github.com/kuujo">Jordan Halterman</a>
29  */
30 final class JournalSegmentFile {
31     private static final char PART_SEPARATOR = '-';
32     private static final char EXTENSION_SEPARATOR = '.';
33     private static final String EXTENSION = "log";
34
35     private final @NonNull JournalSegmentDescriptor descriptor;
36     private final @NonNull Path path;
37
38     JournalSegmentFile(final Path path, final JournalSegmentDescriptor descriptor) {
39         this.path = requireNonNull(path);
40         this.descriptor = requireNonNull(descriptor);
41     }
42
43     /**
44      * Returns the segment file.
45      *
46      * @return The segment file.
47      */
48     @NonNull Path path() {
49         return path;
50     }
51
52     /**
53      * Returns the segment descriptor.
54      *
55      * @return The segment descriptor.
56      */
57     @NonNull JournalSegmentDescriptor descriptor() {
58         return descriptor;
59     }
60
61     int maxSize() {
62         return descriptor.maxSegmentSize();
63     }
64
65     @Override
66     public String toString() {
67         return MoreObjects.toStringHelper(this).add("path", path).add("descriptor", descriptor).toString();
68     }
69
70     /**
71      * Returns a boolean value indicating whether the given file appears to be a parsable segment file.
72      *
73      * @throws NullPointerException if {@code file} is null
74      */
75     public static boolean isSegmentFile(final String name, final File file) {
76         return isSegmentFile(name, file.getName());
77     }
78
79     /**
80      * Returns a boolean value indicating whether the given file appears to be a parsable segment file.
81      *
82      * @param journalName the name of the journal
83      * @param fileName the name of the file to check
84      * @throws NullPointerException if {@code file} is null
85      */
86     public static boolean isSegmentFile(final String journalName, final String fileName) {
87         requireNonNull(journalName, "journalName cannot be null");
88         requireNonNull(fileName, "fileName cannot be null");
89
90         int partSeparator = fileName.lastIndexOf(PART_SEPARATOR);
91         int extensionSeparator = fileName.lastIndexOf(EXTENSION_SEPARATOR);
92
93         if (extensionSeparator == -1 || partSeparator == -1 || extensionSeparator < partSeparator
94             || !fileName.endsWith(EXTENSION)) {
95             return false;
96         }
97
98         for (int i = partSeparator + 1; i < extensionSeparator; i++) {
99             if (!Character.isDigit(fileName.charAt(i))) {
100                 return false;
101             }
102         }
103
104         return fileName.startsWith(journalName);
105     }
106
107     /**
108      * Creates a segment file for the given directory, log name, segment ID, and segment version.
109      */
110     static File createSegmentFile(final String name, final File directory, final long id) {
111         return new File(directory, String.format("%s-%d.log", requireNonNull(name, "name cannot be null"), id));
112     }
113 }