All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.aeron.archive.status.RecordingPos Maven / Gradle / Ivy

There is a newer version: 1.46.2
Show newest version
/*
 * Copyright 2014-2023 Real Logic Limited.
 *
 * 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
 *
 * https://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.archive.status;

import io.aeron.Aeron;
import io.aeron.AeronCounters;
import io.aeron.Counter;
import io.aeron.Image;
import io.aeron.archive.ArchiveCounters;
import org.agrona.BitUtil;
import org.agrona.DirectBuffer;
import org.agrona.concurrent.UnsafeBuffer;
import org.agrona.concurrent.status.CountersReader;

import static org.agrona.BitUtil.SIZE_OF_INT;
import static org.agrona.BitUtil.SIZE_OF_LONG;
import static org.agrona.concurrent.status.CountersReader.*;

/**
 * The position a recording has reached when being archived.
 * 

* Key has the following layout: *

 *   0                   1                   2                   3
 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |                        Recording ID                           |
 *  |                                                               |
 *  +---------------------------------------------------------------+
 *  |                         Session ID                            |
 *  +---------------------------------------------------------------+
 *  |                Source Identity for the Image                  |
 *  |                                                              ...
 * ...                                                              |
 *  +---------------------------------------------------------------+
 *  |                         Archive ID                            |
 *  |                                                               |
 *  +---------------------------------------------------------------+
 * 
*/ public final class RecordingPos { /** * Type id of a recording position counter. */ public static final int RECORDING_POSITION_TYPE_ID = AeronCounters.ARCHIVE_RECORDING_POSITION_TYPE_ID; /** * Represents a null recording id when not found. */ public static final long NULL_RECORDING_ID = Aeron.NULL_VALUE; /** * Human-readable name for the counter. */ public static final String NAME = "rec-pos"; private static final int RECORDING_ID_OFFSET = 0; private static final int SESSION_ID_OFFSET = RECORDING_ID_OFFSET + SIZE_OF_LONG; private static final int SOURCE_IDENTITY_LENGTH_OFFSET = SESSION_ID_OFFSET + SIZE_OF_INT; private static final int SOURCE_IDENTITY_OFFSET = SOURCE_IDENTITY_LENGTH_OFFSET + SIZE_OF_INT; /** * Allocated a recording position counter and populate the metadata. * * @param aeron on which the counter will be registered. * @param tempBuffer for encoding the metadata. * @param archiveId to which the counter belongs. * @param recordingId for the recording. * @param sessionId for the publication being recorded. * @param streamId for the publication being recorded. * @param strippedChannel for the recording subscription. * @param sourceIdentity for the publication. * @return the allocated counter. */ public static Counter allocate( final Aeron aeron, final UnsafeBuffer tempBuffer, final long archiveId, final long recordingId, final int sessionId, final int streamId, final String strippedChannel, final String sourceIdentity) { tempBuffer.putLong(RECORDING_ID_OFFSET, recordingId); tempBuffer.putInt(SESSION_ID_OFFSET, sessionId); final int sourceIdentityLength = Math.min( sourceIdentity.length(), MAX_KEY_LENGTH - SOURCE_IDENTITY_OFFSET - SIZE_OF_LONG); tempBuffer.putInt(SOURCE_IDENTITY_LENGTH_OFFSET, sourceIdentityLength); tempBuffer.putStringWithoutLengthAscii(SOURCE_IDENTITY_OFFSET, sourceIdentity, 0, sourceIdentityLength); final int archiveIdOffset = SOURCE_IDENTITY_OFFSET + sourceIdentityLength; tempBuffer.putLong(archiveIdOffset, archiveId); final int keyLength = archiveIdOffset + SIZE_OF_LONG; final int labelOffset = BitUtil.align(keyLength, SIZE_OF_INT); int labelLength = 0; labelLength += tempBuffer.putStringWithoutLengthAscii(labelOffset, NAME + ": "); labelLength += tempBuffer.putLongAscii(labelOffset + labelLength, recordingId); labelLength += tempBuffer.putStringWithoutLengthAscii(labelOffset + labelLength, " "); labelLength += tempBuffer.putIntAscii(labelOffset + labelLength, sessionId); labelLength += tempBuffer.putStringWithoutLengthAscii(labelOffset + labelLength, " "); labelLength += tempBuffer.putIntAscii(labelOffset + labelLength, streamId); labelLength += tempBuffer.putStringWithoutLengthAscii(labelOffset + labelLength, " "); labelLength += tempBuffer.putStringWithoutLengthAscii( labelOffset + labelLength, strippedChannel, 0, MAX_LABEL_LENGTH - labelLength - ArchiveCounters.lengthOfArchiveIdLabel(archiveId)); labelLength += ArchiveCounters.appendArchiveIdLabel(tempBuffer, labelOffset + labelLength, archiveId); return aeron.addCounter( RECORDING_POSITION_TYPE_ID, tempBuffer, 0, keyLength, tempBuffer, labelOffset, labelLength); } /** * Find the active counter id for a stream based on the recording id. * * @param countersReader to search within. * @param recordingId for the active recording. * @return the counter id if found otherwise {@link CountersReader#NULL_COUNTER_ID}. */ public static int findCounterIdByRecording(final CountersReader countersReader, final long recordingId) { final DirectBuffer buffer = countersReader.metaDataBuffer(); for (int i = 0, size = countersReader.maxCounterId(); i < size; i++) { final int counterState = countersReader.getCounterState(i); if (RECORD_ALLOCATED == counterState) { if (countersReader.getCounterTypeId(i) == RECORDING_POSITION_TYPE_ID && buffer.getLong(CountersReader.metaDataOffset(i) + KEY_OFFSET + RECORDING_ID_OFFSET) == recordingId) { return i; } } else if (RECORD_UNUSED == counterState) { break; } } return NULL_COUNTER_ID; } /** * Find the active counter id for a stream based on the session id. * * @param countersReader to search within. * @param sessionId for the active recording. * @return the counter id if found otherwise {@link CountersReader#NULL_COUNTER_ID}. */ public static int findCounterIdBySession(final CountersReader countersReader, final int sessionId) { final DirectBuffer buffer = countersReader.metaDataBuffer(); for (int i = 0, size = countersReader.maxCounterId(); i < size; i++) { final int counterState = countersReader.getCounterState(i); if (RECORD_ALLOCATED == counterState) { if (countersReader.getCounterTypeId(i) == RECORDING_POSITION_TYPE_ID && buffer.getInt(CountersReader.metaDataOffset(i) + KEY_OFFSET + SESSION_ID_OFFSET) == sessionId) { return i; } } else if (RECORD_UNUSED == counterState) { break; } } return NULL_COUNTER_ID; } /** * Get the recording id for a given counter id. * * @param countersReader to search within. * @param counterId for the active recording. * @return the counter id if found otherwise {@link #NULL_RECORDING_ID}. */ public static long getRecordingId(final CountersReader countersReader, final int counterId) { if (countersReader.getCounterState(counterId) == RECORD_ALLOCATED && countersReader.getCounterTypeId(counterId) == RECORDING_POSITION_TYPE_ID) { return countersReader.metaDataBuffer() .getLong(CountersReader.metaDataOffset(counterId) + KEY_OFFSET + RECORDING_ID_OFFSET); } return NULL_RECORDING_ID; } /** * Get the {@link Image#sourceIdentity()} for the recording. * * @param counters to search within. * @param counterId for the active recording. * @return {@link Image#sourceIdentity()} for the recording or null if not found. */ public static String getSourceIdentity(final CountersReader counters, final int counterId) { if (counters.getCounterState(counterId) == RECORD_ALLOCATED && counters.getCounterTypeId(counterId) == RECORDING_POSITION_TYPE_ID) { final int recordOffset = CountersReader.metaDataOffset(counterId); return counters.metaDataBuffer().getStringAscii(recordOffset + KEY_OFFSET + SOURCE_IDENTITY_LENGTH_OFFSET); } return null; } /** * Is the recording counter still active. * * @param counters to search within. * @param counterId to search for. * @param recordingId to confirm it is still the same value. * @return true if the counter is still active otherwise false. */ public static boolean isActive(final CountersReader counters, final int counterId, final long recordingId) { final int recordingIdOffset = metaDataOffset(counterId) + KEY_OFFSET + RECORDING_ID_OFFSET; return counters.getCounterState(counterId) == RECORD_ALLOCATED && counters.getCounterTypeId(counterId) == RECORDING_POSITION_TYPE_ID && counters.metaDataBuffer().getLong(recordingIdOffset) == recordingId; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy