/* * Copyright 2018-2020 Radicalbit S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.radicalbit.nsdb.commit_log import java.io.{File, FileInputStream} import io.radicalbit.nsdb.commit_log.CommitLogWriterActor._ import scala.collection.mutable.ListBuffer object CommitLogFile { /** * Useful to add the check entries feature to a File */ implicit class CommitLogFile(val file: File) { /** * Check if the entries of the file (It is supposed to be a valid commit log file) are balanced, * i.e. every [[ReceivedEntry]] or [[AccumulatedEntry]] must have its related [[PersistedEntry]] or [[RejectedEntry]] * @param serializer Serializer to use for deserialization purposes * @return the list of unbalanced entries, if exist. Empty list if the file is correctly balanced. */ def checkPendingEntries(implicit serializer: CommitLogSerializer): (List[Int], List[Int]) = { val pending: ListBuffer[Int] = ListBuffer.empty[Int] val closedEntries: ListBuffer[Int] = ListBuffer.empty[Int] val contents = new Array[Byte](5000) val inputStream = new FileInputStream(file) var r = inputStream.read(contents) while (r != -1) { val rawEntry = serializer.deserialize(contents) rawEntry match { case Some(e: ReceivedEntry) => if (!pending.contains(e.id)) pending += e.id case Some(e: AccumulatedEntry) => if (!pending.contains(e.id)) pending += e.id case Some(e: PersistedEntry) => if (!closedEntries.contains(e.id)) closedEntries += e.id case Some(e: RejectedEntry) => if (!closedEntries.contains(e.id)) closedEntries += e.id case Some(_) => case None => } r = inputStream.read(contents) } inputStream.close() (pending.toList, closedEntries.toList) } } }