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

org.opensearch.migrations.trafficcapture.CodedOutputStreamSizeUtil Maven / Gradle / Ivy

package org.opensearch.migrations.trafficcapture;

import java.time.Instant;

import com.google.protobuf.CodedOutputStream;
import com.google.protobuf.Timestamp;

import org.opensearch.migrations.trafficcapture.protos.TrafficObservation;
import org.opensearch.migrations.trafficcapture.protos.TrafficStream;

import io.netty.buffer.ByteBuf;

/**
 * Utility functions for computing sizes of fields to be added to a CodedOutputStream
 */
public class CodedOutputStreamSizeUtil {

    /**
     * Static class
     */
    private CodedOutputStreamSizeUtil() {}

    public static int getSizeOfTimestamp(Instant t) {
        long seconds = t.getEpochSecond();
        int nanos = t.getNano();
        var secSize = CodedOutputStream.computeInt64Size(Timestamp.SECONDS_FIELD_NUMBER, seconds);
        var nanoSize = nanos == 0 ? 0 : CodedOutputStream.computeInt32Size(Timestamp.NANOS_FIELD_NUMBER, nanos);
        return secSize + nanoSize;
    }

    /**
     * This function calculates the maximum bytes that would be needed to store a [Read/Write]SegmentObservation, if constructed
     * from the given ByteBuf and associated segment field numbers and values passed in. This estimate is essentially
     * the max size needed in the CodedOutputStream to store the provided ByteBuf data and its associated TrafficStream
     * overhead. The actual required bytes could be marginally smaller.
     */
    public static int maxBytesNeededForASegmentedObservation(
        Instant timestamp,
        int observationFieldNumber,
        int dataFieldNumber,
        ByteBuf buf
    ) {
        // Timestamp required bytes
        int tsContentSize = getSizeOfTimestamp(timestamp);
        int tsTagAndContentSize = CodedOutputStream.computeInt32Size(TrafficObservation.TS_FIELD_NUMBER, tsContentSize)
            + tsContentSize;

        // Capture required bytes
        int dataSize = computeByteBufRemainingSize(dataFieldNumber, buf);
        int captureTagAndContentSize = CodedOutputStream.computeInt32Size(observationFieldNumber, dataSize) + dataSize;

        // Observation and closing index required bytes
        return bytesNeededForObservationAndClosingIndex(
            tsTagAndContentSize + captureTagAndContentSize,
            Integer.MAX_VALUE
        );
    }

    /**
     * This function determines the number of bytes needed to write the readable bytes in a byteBuf and its tag.
     */
    public static int computeByteBufRemainingSize(int fieldNumber, ByteBuf buf) {
        return CodedOutputStream.computeTagSize(fieldNumber) + computeByteBufRemainingSizeNoTag(buf);
    }

    /**
     * This function determines the number of bytes needed to write the readable bytes in a byteBuf.
     */
    public static int computeByteBufRemainingSizeNoTag(ByteBuf buf) {
        int bufSize = buf.readableBytes();
        return CodedOutputStream.computeUInt32SizeNoTag(bufSize) + bufSize;
    }

    /**
     * This function determines the number of bytes needed to store a TrafficObservation and a closing index for a
     * TrafficStream, from the provided input.
     */
    public static int bytesNeededForObservationAndClosingIndex(
        int observationContentSize,
        int numberOfTrafficStreamsSoFar
    ) {
        int observationTagSize = CodedOutputStream.computeUInt32Size(
            TrafficStream.SUBSTREAM_FIELD_NUMBER,
            observationContentSize
        );

        // Size for TrafficStream index added when flushing, use arbitrary field to calculate
        int indexSize = CodedOutputStream.computeInt32Size(
            TrafficStream.NUMBEROFTHISLASTCHUNK_FIELD_NUMBER,
            numberOfTrafficStreamsSoFar
        );

        return observationTagSize + observationContentSize + indexSize;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy