/*
* Copyright 2014-2017 Real Logic Ltd.
*
* 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.aeron.archiver;
import io.aeron.archiver.codecs.RecordingDescriptorDecoder;
import org.agrona.IoUtil;
import org.agrona.concurrent.UnsafeBuffer;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Date;
import static java.nio.file.StandardOpenOption.READ;
import static java.nio.file.StandardOpenOption.WRITE;
public class ArchiveUtil
{
static String recordingMetaFileName(final long recordingId)
{
return recordingId + ".inf";
}
static String recordingDataFileName(
final long recordingId,
final int segmentIndex)
{
return recordingId + "." + segmentIndex + ".rec";
}
static String recordingDataFileName(
final long recordingId,
final int initialTermId,
final int termBufferLength,
final int termId,
final int segmentFileLength)
{
final int segmentIndex = segmentFileIndex(initialTermId, termId, termBufferLength, segmentFileLength);
return recordingDataFileName(recordingId, segmentIndex);
}
private static int segmentFileIndex(
final int initialTermId,
final int termId,
final int termBufferLength,
final int segmentFileLength)
{
return (int) (((termId - initialTermId) * (long)termBufferLength) / segmentFileLength);
}
static int segmentFileIndex(
final long joiningPosition,
final long position,
final int segmentFileLength)
{
return (int)((position - joiningPosition) / segmentFileLength);
}
static void printMetaFile(final File metaFile) throws IOException
{
final RecordingDescriptorDecoder formatDecoder = recordingMetaFileFormatDecoder(metaFile);
System.out.println("recordingId: " + formatDecoder.recordingId());
System.out.println("termBufferLength: " + formatDecoder.termBufferLength());
System.out.println("start time: " + new Date(formatDecoder.startTime()));
System.out.println("joining position: " + formatDecoder.joiningPosition());
System.out.println("last position: " + formatDecoder.lastPosition());
System.out.println("end time: " + new Date(formatDecoder.endTime()));
System.out.println("source: " + formatDecoder.source());
System.out.println("sessionId: " + formatDecoder.sessionId());
System.out.println("channel: " + formatDecoder.channel());
System.out.println("streamId: " + formatDecoder.streamId());
IoUtil.unmap(formatDecoder.buffer().byteBuffer());
}
static RecordingDescriptorDecoder recordingMetaFileFormatDecoder(final File metaFile)
throws IOException
{
try (FileChannel metadataFileChannel = FileChannel.open(metaFile.toPath(), READ, WRITE))
{
final ByteBuffer metaDataBuffer = ByteBuffer.allocate(Catalog.RECORD_LENGTH);
metadataFileChannel.read(metaDataBuffer);
final RecordingDescriptorDecoder decoder = new RecordingDescriptorDecoder();
return decoder.wrap(
new UnsafeBuffer(metaDataBuffer),
Catalog.CATALOG_FRAME_LENGTH,
RecordingDescriptorDecoder.BLOCK_LENGTH,
RecordingDescriptorDecoder.SCHEMA_VERSION);
}
}
static int recordingOffset(
final int termOffset,
final int termId,
final int initialTermId,
final int termsMask,
final int termBufferLength)
{
return ((termId - initialTermId) & termsMask) * termBufferLength + termOffset;
}
static long recordingFileFullLength(final RecordingDescriptorDecoder metaDecoder)
{
return metaDecoder.lastPosition() - metaDecoder.joiningPosition();
}
public static long recordingLength(
final int termBufferLength,
final int initialTermId,
final int initialTermOffset,
final int lastTermId, final int lastTermOffset)
{
return ((long)(lastTermId - initialTermId)) * termBufferLength +
(lastTermOffset - initialTermOffset);
}
}