/* * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 * (the "License"). You may not use this work except in compliance with the License, which is * available at www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied, as more fully set forth in the License. * * See the NOTICE file distributed with this work for information regarding copyright ownership. */ package alluxio.master.journal.ufs; import alluxio.underfs.UfsStatus; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.annotation.concurrent.ThreadSafe; /** * This class provides a snapshot of everything in the journal and some utility methods. */ @ThreadSafe final class UfsJournalSnapshot { /** The committed checkpoints. */ private final List<UfsJournalFile> mCheckpoints; /** The journal edit logs including the incomplete log. */ private final List<UfsJournalFile> mLogs; /** The temporary checkpoint files. */ private final List<UfsJournalFile> mTemporaryCheckpoints; /** * Creates an instance of the journal snapshot. * * @param checkpoints the checkpoints * @param logs the logs including the incomplete log * @param temporaryCheckpoints the temporary checkpoint files */ private UfsJournalSnapshot(List<UfsJournalFile> checkpoints, List<UfsJournalFile> logs, List<UfsJournalFile> temporaryCheckpoints) { mCheckpoints = checkpoints; mLogs = logs; mTemporaryCheckpoints = temporaryCheckpoints; } /** * @return the checkpoints sorted by end sequence number increasingly */ List<UfsJournalFile> getCheckpoints() { return mCheckpoints; } /** * @return the latest checkpoint, null if no checkpoint exists */ UfsJournalFile getLatestCheckpoint() { if (!mCheckpoints.isEmpty()) { return mCheckpoints.get(mCheckpoints.size() - 1); } return null; } /** * @return the logs sorted by the end sequence number increasingly */ List<UfsJournalFile> getLogs() { return mLogs; } /** * @return the temporary checkpoints */ List<UfsJournalFile> getTemporaryCheckpoints() { return mTemporaryCheckpoints; } /** * Creates a snapshot of the journal. * * @return the journal snapshot */ static UfsJournalSnapshot getSnapshot(UfsJournal journal) throws IOException { // Checkpoints. List<UfsJournalFile> checkpoints = new ArrayList<>(); UfsStatus[] statuses = journal.getUfs().listStatus(journal.getCheckpointDir().toString()); if (statuses != null) { for (UfsStatus status : statuses) { UfsJournalFile file = UfsJournalFile.decodeCheckpointFile(journal, status.getName()); if (file != null) { checkpoints.add(file); } } Collections.sort(checkpoints); } List<UfsJournalFile> logs = new ArrayList<>(); statuses = journal.getUfs().listStatus(journal.getLogDir().toString()); if (statuses != null) { for (UfsStatus status : statuses) { UfsJournalFile file = UfsJournalFile.decodeLogFile(journal, status.getName()); if (file != null) { logs.add(file); } } Collections.sort(logs); } List<UfsJournalFile> tmpCheckpoints = new ArrayList<>(); statuses = journal.getUfs().listStatus(journal.getTmpDir().toString()); if (statuses != null) { for (UfsStatus status : statuses) { tmpCheckpoints.add(UfsJournalFile.decodeTemporaryCheckpointFile(journal, status.getName())); } } return new UfsJournalSnapshot(checkpoints, logs, tmpCheckpoints); } /** * Gets the current log (the incomplete log) that is being written to. * * @return the current log */ static UfsJournalFile getCurrentLog(UfsJournal journal) throws IOException { List<UfsJournalFile> logs = new ArrayList<>(); UfsStatus[] statuses = journal.getUfs().listStatus(journal.getLogDir().toString()); if (statuses != null) { for (UfsStatus status : statuses) { UfsJournalFile file = UfsJournalFile.decodeLogFile(journal, status.getName()); if (file != null) { logs.add(file); } } if (!logs.isEmpty()) { UfsJournalFile file = Collections.max(logs); if (file.isIncompleteLog()) { return file; } } } return null; } /** * Gets the first journal log sequence number that is not yet checkpointed. * * @return the first journal log sequence number that is not yet checkpointed */ static long getNextLogSequenceNumberToCheckpoint(UfsJournal journal) throws IOException { List<UfsJournalFile> checkpoints = new ArrayList<>(); UfsStatus[] statuses = journal.getUfs().listStatus(journal.getCheckpointDir().toString()); if (statuses != null) { for (UfsStatus status : statuses) { UfsJournalFile file = UfsJournalFile.decodeCheckpointFile(journal, status.getName()); if (file != null) { checkpoints.add(file); } } Collections.sort(checkpoints); } if (checkpoints.isEmpty()) { return 0; } return checkpoints.get(checkpoints.size() - 1).getEnd(); } }