Input: Has the candidate got unanimous support of the cluster? [CODESPLIT] public static boolean hasWonVoteOnFullCount ( final ClusterMember [ ] members , final long candidateTermId ) { int votes = 0 ; for ( final ClusterMember member : members ) { if ( null == member . vote || member . candidateTermId != candidateTermId ) { return false ; } votes += member . vote ? 1 : 0 ; } return votes >= ClusterMember . quorumThreshold ( members . length ) ; }


Input: Has sufficient votes being counted for a majority for all members observed during { @link Election . State#CANVASS } ? [CODESPLIT] public static boolean hasMajorityVoteWithCanvassMembers ( final ClusterMember [ ] members , final long candidateTermId ) { int votes = 0 ; for ( final ClusterMember member : members ) { if ( NULL_POSITION != member . logPosition && null == member . vote ) { return false ; } if ( Boolean . TRUE . equals ( member . vote ) && member . candidateTermId == candidateTermId ) { ++ votes ; } } return votes >= ClusterMember . quorumThreshold ( members . length ) ; }


Input: Has sufficient votes being counted for a majority? [CODESPLIT] public static boolean hasMajorityVote ( final ClusterMember [ ] clusterMembers , final long candidateTermId ) { int votes = 0 ; for ( final ClusterMember member : clusterMembers ) { if ( Boolean . TRUE . equals ( member . vote ) && member . candidateTermId == candidateTermId ) { ++ votes ; } } return votes >= ClusterMember . quorumThreshold ( clusterMembers . length ) ; }


Input: Determine which member of a cluster this is and check endpoints . [CODESPLIT] public static ClusterMember determineMember ( final ClusterMember [ ] clusterMembers , final int memberId , final String memberEndpoints ) { ClusterMember member = NULL_VALUE != memberId ? ClusterMember . findMember ( clusterMembers , memberId ) : null ; if ( ( null == clusterMembers || 0 == clusterMembers . length ) && null == member ) { member = ClusterMember . parseEndpoints ( NULL_VALUE , memberEndpoints ) ; } else { if ( null == member ) { throw new ClusterException ( "memberId=" + memberId + " not found in clusterMembers" ) ; } if ( ! "" . equals ( memberEndpoints ) ) { ClusterMember . validateMemberEndpoints ( member , memberEndpoints ) ; } } return member ; }


Input: Check the member with the memberEndpoints [CODESPLIT] public static void validateMemberEndpoints ( final ClusterMember member , final String memberEndpoints ) { final ClusterMember endpointMember = ClusterMember . parseEndpoints ( Aeron . NULL_VALUE , memberEndpoints ) ; if ( ! areSameEndpoints ( member , endpointMember ) ) { throw new ClusterException ( "clusterMembers and memberEndpoints differ: " + member . endpointsDetail ( ) + " != " + memberEndpoints ) ; } }


Input: Are two cluster members using the same endpoints? [CODESPLIT] public static boolean areSameEndpoints ( final ClusterMember lhs , final ClusterMember rhs ) { return lhs . clientFacingEndpoint ( ) . equals ( rhs . clientFacingEndpoint ( ) ) && lhs . memberFacingEndpoint ( ) . equals ( rhs . memberFacingEndpoint ( ) ) && lhs . logEndpoint ( ) . equals ( rhs . logEndpoint ( ) ) && lhs . transferEndpoint ( ) . equals ( rhs . transferEndpoint ( ) ) && lhs . archiveEndpoint ( ) . equals ( rhs . archiveEndpoint ( ) ) ; }


Input: Has the member achieved a unanimous view to be a suitable candidate in an election . [CODESPLIT] public static boolean isUnanimousCandidate ( final ClusterMember [ ] clusterMembers , final ClusterMember candidate ) { for ( final ClusterMember member : clusterMembers ) { if ( NULL_POSITION == member . logPosition || compareLog ( candidate , member ) < 0 ) { return false ; } } return true ; }


Input: Has the member achieved a quorum view to be a suitable candidate in an election . [CODESPLIT] public static boolean isQuorumCandidate ( final ClusterMember [ ] clusterMembers , final ClusterMember candidate ) { int possibleVotes = 0 ; for ( final ClusterMember member : clusterMembers ) { if ( NULL_POSITION == member . logPosition || compareLog ( candidate , member ) < 0 ) { continue ; } ++ possibleVotes ; } return possibleVotes >= ClusterMember . quorumThreshold ( clusterMembers . length ) ; }


Input: The result is positive if lhs has the more recent log zero if logs are equal and negative if rhs has the more recent log . [CODESPLIT] public static int compareLog ( final long lhsLogLeadershipTermId , final long lhsLogPosition , final long rhsLogLeadershipTermId , final long rhsLogPosition ) { if ( lhsLogLeadershipTermId > rhsLogLeadershipTermId ) { return 1 ; } else if ( lhsLogLeadershipTermId < rhsLogLeadershipTermId ) { return - 1 ; } else if ( lhsLogPosition > rhsLogPosition ) { return 1 ; } else if ( lhsLogPosition < rhsLogPosition ) { return - 1 ; } return 0 ; }


Input: The result is positive if lhs has the more recent log zero if logs are equal and negative if rhs has the more recent log . [CODESPLIT] public static int compareLog ( final ClusterMember lhs , final ClusterMember rhs ) { return compareLog ( lhs . leadershipTermId , lhs . logPosition , rhs . leadershipTermId , rhs . logPosition ) ; }


Input: Is the string of member endpoints not duplicated in the members . [CODESPLIT] public static boolean isNotDuplicateEndpoints ( final ClusterMember [ ] members , final String memberEndpoints ) { for ( final ClusterMember member : members ) { if ( member . endpointsDetail ( ) . equals ( memberEndpoints ) ) { return false ; } } return true ; }


Input: Find the index at which a member id is present . [CODESPLIT] public static int findMemberIndex ( final ClusterMember [ ] clusterMembers , final int memberId ) { final int length = clusterMembers . length ; int index = ArrayUtil . UNKNOWN_INDEX ; for ( int i = 0 ; i < length ; i ++ ) { if ( clusterMembers [ i ] . id ( ) == memberId ) { index = i ; } } return index ; }


Input: Find a { @link ClusterMember } with a given id . [CODESPLIT] public static ClusterMember findMember ( final ClusterMember [ ] clusterMembers , final int memberId ) { for ( final ClusterMember member : clusterMembers ) { if ( member . id ( ) == memberId ) { return member ; } } return null ; }


Input: Add a new member to an array of { @link ClusterMember } s . [CODESPLIT] public static ClusterMember [ ] addMember ( final ClusterMember [ ] oldMembers , final ClusterMember newMember ) { return ArrayUtil . add ( oldMembers , newMember ) ; }


Input: Remove a member from an array if found otherwise return the array unmodified . [CODESPLIT] public static ClusterMember [ ] removeMember ( final ClusterMember [ ] oldMembers , final int memberId ) { return ArrayUtil . remove ( oldMembers , findMemberIndex ( oldMembers , memberId ) ) ; }


Input: Find the highest member id in an array of members . [CODESPLIT] public static int highMemberId ( final ClusterMember [ ] clusterMembers ) { int highId = Aeron . NULL_VALUE ; for ( final ClusterMember member : clusterMembers ) { highId = Math . max ( highId , member . id ( ) ) ; } return highId ; }


Input: Create a string of member facing endpoints by id in format { @code id = endpoint id = endpoint ... } . [CODESPLIT] public static String clientFacingEndpoints ( final ClusterMember [ ] members ) { final StringBuilder builder = new StringBuilder ( 100 ) ; for ( int i = 0 , length = members . length ; i < length ; i ++ ) { if ( 0 != i ) { builder . append ( ' ' ) ; } final ClusterMember member = members [ i ] ; builder . append ( member . id ( ) ) . append ( ' ' ) . append ( member . clientFacingEndpoint ( ) ) ; } return builder . toString ( ) ; }


Input: { [CODESPLIT] public long onIdle ( final long timeNs , final long senderLimit , final long senderPosition , final boolean isEos ) { long minPosition = Long . MAX_VALUE ; long minLimitPosition = Long . MAX_VALUE ; final ArrayList < Receiver > receiverList = this . receiverList ; for ( int lastIndex = receiverList . size ( ) - 1 , i = lastIndex ; i >= 0 ; i -- ) { final Receiver receiver = receiverList . get ( i ) ; if ( ( receiver . timeOfLastStatusMessageNs + RECEIVER_TIMEOUT ) - timeNs < 0 ) { ArrayListUtil . fastUnorderedRemove ( receiverList , i , lastIndex -- ) ; } else { minPosition = Math . min ( minPosition , receiver . lastPosition ) ; minLimitPosition = Math . min ( minLimitPosition , receiver . lastPositionPlusWindow ) ; } } if ( isEos && shouldLinger ) { if ( 0 == receiverList . size ( ) || minPosition >= senderPosition ) { shouldLinger = false ; } } return receiverList . size ( ) > 0 ? minLimitPosition : senderLimit ; }


Input: Attempt to unblock the current term at the current offset . <ol > <li > Current position length is &gt ; 0 then return< / li > <li > Current position length is 0 scan forward by frame alignment until one of the following : <ol > <li > reach a non - 0 length unblock up to indicated position ( check original frame length for non - 0 ) < / li > <li > reach end of term and tail position &gt ; = end of term unblock up to end of term ( check original frame length for non - 0 ) < / li > <li > reach tail position &lt ; end of term do NOT unblock< / li > < / ol > < / li > < / ol > [CODESPLIT] public static Status unblock ( final UnsafeBuffer logMetaDataBuffer , final UnsafeBuffer termBuffer , final int blockedOffset , final int tailOffset , final int termId ) { Status status = NO_ACTION ; int frameLength = frameLengthVolatile ( termBuffer , blockedOffset ) ; if ( frameLength < 0 ) { resetHeader ( logMetaDataBuffer , termBuffer , blockedOffset , termId , - frameLength ) ; status = UNBLOCKED ; } else if ( 0 == frameLength ) { int currentOffset = blockedOffset + FRAME_ALIGNMENT ; while ( currentOffset < tailOffset ) { frameLength = frameLengthVolatile ( termBuffer , currentOffset ) ; if ( frameLength != 0 ) { if ( scanBackToConfirmZeroed ( termBuffer , currentOffset , blockedOffset ) ) { final int length = currentOffset - blockedOffset ; resetHeader ( logMetaDataBuffer , termBuffer , blockedOffset , termId , length ) ; status = UNBLOCKED ; } break ; } currentOffset += FRAME_ALIGNMENT ; } if ( currentOffset == termBuffer . capacity ( ) ) { if ( 0 == frameLengthVolatile ( termBuffer , blockedOffset ) ) { final int length = currentOffset - blockedOffset ; resetHeader ( logMetaDataBuffer , termBuffer , blockedOffset , termId , length ) ; status = UNBLOCKED_TO_END ; } } } return status ; }


Input: Map the CnC file if it exists . [CODESPLIT] public MappedByteBuffer mapExistingCncFile ( final Consumer < String > logger ) { final File cncFile = new File ( aeronDirectory , CncFileDescriptor . CNC_FILE ) ; if ( cncFile . exists ( ) && cncFile . length ( ) > 0 ) { if ( null != logger ) { logger . accept ( "INFO: Aeron CnC file exists: " + cncFile ) ; } return IoUtil . mapExistingFile ( cncFile , CncFileDescriptor . CNC_FILE ) ; } return null ; }


Input: Is a media driver active in the given directory? [CODESPLIT] public static boolean isDriverActive ( final File directory , final long driverTimeoutMs , final Consumer < String > logger ) { final File cncFile = new File ( directory , CncFileDescriptor . CNC_FILE ) ; if ( cncFile . exists ( ) && cncFile . length ( ) > 0 ) { logger . accept ( "INFO: Aeron CnC file exists: " + cncFile ) ; final MappedByteBuffer cncByteBuffer = IoUtil . mapExistingFile ( cncFile , "CnC file" ) ; try { return isDriverActive ( driverTimeoutMs , logger , cncByteBuffer ) ; } finally { IoUtil . unmap ( cncByteBuffer ) ; } } return false ; }


Input: Is a media driver active in the current Aeron directory? [CODESPLIT] public boolean isDriverActive ( final long driverTimeoutMs , final Consumer < String > logger ) { final MappedByteBuffer cncByteBuffer = mapExistingCncFile ( logger ) ; try { return isDriverActive ( driverTimeoutMs , logger , cncByteBuffer ) ; } finally { IoUtil . unmap ( cncByteBuffer ) ; } }


Input: Is a media driver active in the current mapped CnC buffer? If the driver is mid start then it will wait for up to the driverTimeoutMs by checking for the cncVersion being set . [CODESPLIT] public static boolean isDriverActive ( final long driverTimeoutMs , final Consumer < String > logger , final ByteBuffer cncByteBuffer ) { if ( null == cncByteBuffer ) { return false ; } final UnsafeBuffer cncMetaDataBuffer = CncFileDescriptor . createMetaDataBuffer ( cncByteBuffer ) ; final long startTimeMs = System . currentTimeMillis ( ) ; int cncVersion ; while ( 0 == ( cncVersion = cncMetaDataBuffer . getIntVolatile ( CncFileDescriptor . cncVersionOffset ( 0 ) ) ) ) { if ( System . currentTimeMillis ( ) > ( startTimeMs + driverTimeoutMs ) ) { throw new DriverTimeoutException ( "CnC file is created but not initialised." ) ; } sleep ( 1 ) ; } if ( CNC_VERSION != cncVersion ) { throw new AeronException ( "Aeron CnC version does not match: required=" + CNC_VERSION + " version=" + cncVersion ) ; } final ManyToOneRingBuffer toDriverBuffer = new ManyToOneRingBuffer ( CncFileDescriptor . createToDriverBuffer ( cncByteBuffer , cncMetaDataBuffer ) ) ; final long timestamp = toDriverBuffer . consumerHeartbeatTime ( ) ; final long now = System . currentTimeMillis ( ) ; final long timestampAge = now - timestamp ; logger . accept ( "INFO: Aeron toDriver consumer heartbeat is (ms): " + timestampAge ) ; return timestampAge <= driverTimeoutMs ; }


Input: Request a driver to run its termination hook . [CODESPLIT] public static boolean requestDriverTermination ( final File directory , final DirectBuffer tokenBuffer , final int tokenOffset , final int tokenLength ) { final File cncFile = new File ( directory , CncFileDescriptor . CNC_FILE ) ; if ( cncFile . exists ( ) && cncFile . length ( ) > 0 ) { final MappedByteBuffer cncByteBuffer = IoUtil . mapExistingFile ( cncFile , "CnC file" ) ; try { final UnsafeBuffer cncMetaDataBuffer = CncFileDescriptor . createMetaDataBuffer ( cncByteBuffer ) ; final int cncVersion = cncMetaDataBuffer . getIntVolatile ( cncVersionOffset ( 0 ) ) ; if ( CncFileDescriptor . CNC_VERSION != cncVersion ) { throw new AeronException ( "Aeron CnC version does not match: required=" + CNC_VERSION + " version=" + cncVersion ) ; } final ManyToOneRingBuffer toDriverBuffer = new ManyToOneRingBuffer ( CncFileDescriptor . createToDriverBuffer ( cncByteBuffer , cncMetaDataBuffer ) ) ; final long clientId = toDriverBuffer . nextCorrelationId ( ) ; final DriverProxy driverProxy = new DriverProxy ( toDriverBuffer , clientId ) ; return driverProxy . terminateDriver ( tokenBuffer , tokenOffset , tokenLength ) ; } finally { IoUtil . unmap ( cncByteBuffer ) ; } } return false ; }


Input: Read the error log to a given { @link PrintStream } [CODESPLIT] public int saveErrorLog ( final PrintStream out ) { final MappedByteBuffer cncByteBuffer = mapExistingCncFile ( null ) ; try { return saveErrorLog ( out , cncByteBuffer ) ; } finally { IoUtil . unmap ( cncByteBuffer ) ; } }


Input: Read the error log to a given { @link PrintStream } [CODESPLIT] public int saveErrorLog ( final PrintStream out , final ByteBuffer cncByteBuffer ) { if ( null == cncByteBuffer ) { return 0 ; } final UnsafeBuffer cncMetaDataBuffer = CncFileDescriptor . createMetaDataBuffer ( cncByteBuffer ) ; final int cncVersion = cncMetaDataBuffer . getInt ( CncFileDescriptor . cncVersionOffset ( 0 ) ) ; if ( CNC_VERSION != cncVersion ) { throw new AeronException ( "Aeron CnC version does not match: required=" + CNC_VERSION + " version=" + cncVersion ) ; } int distinctErrorCount = 0 ; final AtomicBuffer buffer = CncFileDescriptor . createErrorLogBuffer ( cncByteBuffer , cncMetaDataBuffer ) ; if ( ErrorLogReader . hasErrors ( buffer ) ) { final SimpleDateFormat dateFormat = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss.SSSZ" ) ; final ErrorConsumer errorConsumer = ( count , firstTimestamp , lastTimestamp , ex ) -> formatError ( out , dateFormat , count , firstTimestamp , lastTimestamp , ex ) ; distinctErrorCount = ErrorLogReader . read ( buffer , errorConsumer ) ; } out . println ( ) ; out . println ( distinctErrorCount + " distinct errors observed." ) ; return distinctErrorCount ; }


Input: Get the length of a frame from the header as a volatile read . [CODESPLIT] public static int frameLengthVolatile ( final UnsafeBuffer buffer , final int termOffset ) { int frameLength = buffer . getIntVolatile ( termOffset ) ; if ( ByteOrder . nativeOrder ( ) != LITTLE_ENDIAN ) { frameLength = Integer . reverseBytes ( frameLength ) ; } return frameLength ; }


Input: Write the length header for a frame in a memory ordered fashion . [CODESPLIT] public static void frameLengthOrdered ( final UnsafeBuffer buffer , final int termOffset , final int frameLength ) { int length = frameLength ; if ( ByteOrder . nativeOrder ( ) != LITTLE_ENDIAN ) { length = Integer . reverseBytes ( frameLength ) ; } buffer . putIntOrdered ( termOffset , length ) ; }


Input: Write the type field for a frame . [CODESPLIT] public static void frameType ( final UnsafeBuffer buffer , final int termOffset , final int type ) { buffer . putShort ( typeOffset ( termOffset ) , ( short ) type , LITTLE_ENDIAN ) ; }


Input: Write the flags field for a frame . [CODESPLIT] public static void frameFlags ( final UnsafeBuffer buffer , final int termOffset , final byte flags ) { buffer . putByte ( flagsOffset ( termOffset ) , flags ) ; }


Input: Write the term offset field for a frame . [CODESPLIT] public static void frameTermOffset ( final UnsafeBuffer buffer , final int termOffset ) { buffer . putInt ( termOffsetOffset ( termOffset ) , termOffset , LITTLE_ENDIAN ) ; }


Input: Write the term id field for a frame . [CODESPLIT] public static void frameTermId ( final UnsafeBuffer buffer , final int termOffset , final int termId ) { buffer . putInt ( termIdOffset ( termOffset ) , termId , LITTLE_ENDIAN ) ; }


Input: Called from the { @link Sender } to add information to the control packet dispatcher . [CODESPLIT] public void registerForSend ( final NetworkPublication publication ) { publicationBySessionAndStreamId . put ( publication . sessionId ( ) , publication . streamId ( ) , publication ) ; }


Input: Send contents of a { @link ByteBuffer } to connected address . This is used on the sender side for performance over send ( ByteBuffer SocketAddress ) . [CODESPLIT] public int send ( final ByteBuffer buffer ) { int bytesSent = 0 ; if ( null != sendDatagramChannel ) { final int bytesToSend = buffer . remaining ( ) ; if ( null == multiDestination ) { try { sendHook ( buffer , connectAddress ) ; if ( sendDatagramChannel . isConnected ( ) ) { bytesSent = sendDatagramChannel . write ( buffer ) ; } } catch ( final PortUnreachableException ignore ) { } catch ( final IOException ex ) { sendError ( bytesToSend , ex , connectAddress ) ; } } else { bytesSent = multiDestination . send ( sendDatagramChannel , buffer , this , bytesToSend ) ; } } return bytesSent ; }


Input: Find the active counter id for a stream based on the recording id . [CODESPLIT] 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 ++ ) { if ( countersReader . getCounterState ( i ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( i ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECORDING_POSITION_TYPE_ID && buffer . getLong ( recordOffset + KEY_OFFSET + RECORDING_ID_OFFSET ) == recordingId ) { return i ; } } } return NULL_COUNTER_ID ; }


Input: Find the active counter id for a stream based on the session id . [CODESPLIT] 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 ++ ) { if ( countersReader . getCounterState ( i ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( i ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECORDING_POSITION_TYPE_ID && buffer . getInt ( recordOffset + KEY_OFFSET + SESSION_ID_OFFSET ) == sessionId ) { return i ; } } } return NULL_COUNTER_ID ; }


Input: Get the recording id for a given counter id . [CODESPLIT] public static long getRecordingId ( final CountersReader countersReader , final int counterId ) { final DirectBuffer buffer = countersReader . metaDataBuffer ( ) ; if ( countersReader . getCounterState ( counterId ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( counterId ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECORDING_POSITION_TYPE_ID ) { return buffer . getLong ( recordOffset + KEY_OFFSET + RECORDING_ID_OFFSET ) ; } } return NULL_RECORDING_ID ; }


Input: Get the { @link Image#sourceIdentity () } for the recording . [CODESPLIT] public static String getSourceIdentity ( final CountersReader countersReader , final int counterId ) { final DirectBuffer buffer = countersReader . metaDataBuffer ( ) ; if ( countersReader . getCounterState ( counterId ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( counterId ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECORDING_POSITION_TYPE_ID ) { return buffer . getStringAscii ( recordOffset + KEY_OFFSET + SOURCE_IDENTITY_LENGTH_OFFSET ) ; } } return null ; }


Input: Is the recording counter still active . [CODESPLIT] public static boolean isActive ( final CountersReader countersReader , final int counterId , final long recordingId ) { final DirectBuffer buffer = countersReader . metaDataBuffer ( ) ; if ( countersReader . getCounterState ( counterId ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( counterId ) ; return buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECORDING_POSITION_TYPE_ID && buffer . getLong ( recordOffset + KEY_OFFSET + RECORDING_ID_OFFSET ) == recordingId ; } return false ; }


Input: Utility for parsing socket addresses from a { @link CharSequence } . Supports hostname : port ipV4Address : port and [ ipV6Address ] : port [CODESPLIT] static InetSocketAddress parse ( final CharSequence cs ) { if ( null == cs || cs . length ( ) == 0 ) { throw new NullPointerException ( "Input string must not be null or empty" ) ; } InetSocketAddress address = tryParseIpV4 ( cs ) ; if ( null == address ) { address = tryParseIpV6 ( cs ) ; } if ( null == address ) { throw new IllegalArgumentException ( "Invalid format: " + cs ) ; } return address ; }


Input: { [CODESPLIT] public long onStatusMessage ( final StatusMessageFlyweight flyweight , final InetSocketAddress receiverAddress , final long senderLimit , final int initialTermId , final int positionBitsToShift , final long timeNs ) { final long position = computePosition ( flyweight . consumptionTermId ( ) , flyweight . consumptionTermOffset ( ) , positionBitsToShift , initialTermId ) ; final long windowLength = flyweight . receiverWindowLength ( ) ; final long receiverId = flyweight . receiverId ( ) ; final boolean isFromPreferred = isFromPreferred ( flyweight ) ; final long lastPositionPlusWindow = position + windowLength ; boolean isExisting = false ; long minPosition = Long . MAX_VALUE ; final ArrayList < Receiver > receiverList = this . receiverList ; for ( int i = 0 , size = receiverList . size ( ) ; i < size ; i ++ ) { final Receiver receiver = receiverList . get ( i ) ; if ( isFromPreferred && receiverId == receiver . receiverId ) { receiver . lastPosition = Math . max ( position , receiver . lastPosition ) ; receiver . lastPositionPlusWindow = lastPositionPlusWindow ; receiver . timeOfLastStatusMessageNs = timeNs ; isExisting = true ; } minPosition = Math . min ( minPosition , receiver . lastPositionPlusWindow ) ; } if ( isFromPreferred && ! isExisting ) { receiverList . add ( new Receiver ( position , lastPositionPlusWindow , timeNs , receiverId , receiverAddress ) ) ; minPosition = Math . min ( minPosition , lastPositionPlusWindow ) ; } return receiverList . size ( ) > 0 ? Math . max ( senderLimit , minPosition ) : Math . max ( senderLimit , lastPositionPlusWindow ) ; }


Input: Scan for gaps from the scanOffset up to a limit offset . Each gap will be reported to the { @link GapHandler } . [CODESPLIT] public static int scanForGap ( final UnsafeBuffer termBuffer , final int termId , final int termOffset , final int limitOffset , final GapHandler handler ) { int offset = termOffset ; do { final int frameLength = frameLengthVolatile ( termBuffer , offset ) ; if ( frameLength <= 0 ) { break ; } offset += align ( frameLength , FRAME_ALIGNMENT ) ; } while ( offset < limitOffset ) ; final int gapBeginOffset = offset ; if ( offset < limitOffset ) { final int limit = limitOffset - ALIGNED_HEADER_LENGTH ; while ( offset < limit ) { offset += FRAME_ALIGNMENT ; if ( 0 != termBuffer . getIntVolatile ( offset ) ) { offset -= ALIGNED_HEADER_LENGTH ; break ; } } final int gapLength = ( offset - gapBeginOffset ) + ALIGNED_HEADER_LENGTH ; handler . onGap ( termId , gapBeginOffset , gapLength ) ; } return gapBeginOffset ; }


Input: Launch a new { @link ClusteredMediaDriver } with provided contexts . [CODESPLIT] public static ClusteredMediaDriver launch ( final MediaDriver . Context driverCtx , final Archive . Context archiveCtx , final ConsensusModule . Context consensusModuleCtx ) { final MediaDriver driver = MediaDriver . launch ( driverCtx . spiesSimulateConnection ( true ) ) ; final Archive archive = Archive . launch ( archiveCtx . mediaDriverAgentInvoker ( driver . sharedAgentInvoker ( ) ) . errorHandler ( driverCtx . errorHandler ( ) ) . errorCounter ( driverCtx . systemCounters ( ) . get ( SystemCounterDescriptor . ERRORS ) ) ) ; final ConsensusModule consensusModule = ConsensusModule . launch ( consensusModuleCtx ) ; return new ClusteredMediaDriver ( driver , archive , consensusModule ) ; }


Input: Identifier for the receiver to distinguish them for FlowControl strategies . [CODESPLIT] public long receiverId ( ) { final long value ; if ( ByteOrder . nativeOrder ( ) == LITTLE_ENDIAN ) { value = ( ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 7 ) ) << 56 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 6 ) & 0xFF ) << 48 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 5 ) & 0xFF ) << 40 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 4 ) & 0xFF ) << 32 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 3 ) & 0xFF ) << 24 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 2 ) & 0xFF ) << 16 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 1 ) & 0xFF ) << 8 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 0 ) & 0xFF ) ) ) ; } else { value = ( ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 0 ) ) << 56 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 1 ) & 0xFF ) << 48 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 2 ) & 0xFF ) << 40 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 3 ) & 0xFF ) << 32 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 4 ) & 0xFF ) << 24 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 5 ) & 0xFF ) << 16 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 6 ) & 0xFF ) << 8 ) | ( ( ( long ) getByte ( RECEIVER_ID_FIELD_OFFSET + 7 ) & 0xFF ) ) ) ; } return value ; }


Input: Identifier for the receiver to distinguish them for FlowControl strategies . [CODESPLIT] public StatusMessageFlyweight receiverId ( final long id ) { if ( ByteOrder . nativeOrder ( ) == LITTLE_ENDIAN ) { putByte ( RECEIVER_ID_FIELD_OFFSET + 7 , ( byte ) ( id >> 56 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 6 , ( byte ) ( id >> 48 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 5 , ( byte ) ( id >> 40 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 4 , ( byte ) ( id >> 32 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 3 , ( byte ) ( id >> 24 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 2 , ( byte ) ( id >> 16 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 1 , ( byte ) ( id >> 8 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 0 , ( byte ) ( id ) ) ; } else { putByte ( RECEIVER_ID_FIELD_OFFSET + 0 , ( byte ) ( id >> 56 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 1 , ( byte ) ( id >> 48 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 2 , ( byte ) ( id >> 40 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 3 , ( byte ) ( id >> 32 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 4 , ( byte ) ( id >> 24 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 5 , ( byte ) ( id >> 16 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 6 , ( byte ) ( id >> 8 ) ) ; putByte ( RECEIVER_ID_FIELD_OFFSET + 7 , ( byte ) ( id ) ) ; } return this ; }


Input: Retrieve the Application Specific Feedback ( if present ) from the Status Message . [CODESPLIT] public int applicationSpecificFeedback ( final byte [ ] destination ) { final int frameLength = frameLength ( ) ; int result = 0 ; if ( frameLength > HEADER_LENGTH ) { if ( frameLength > capacity ( ) ) { throw new AeronException ( String . format ( "SM application specific feedback (%d) is truncated (%d)" , frameLength - HEADER_LENGTH , capacity ( ) - HEADER_LENGTH ) ) ; } final int copyLength = Math . min ( destination . length , frameLength - HEADER_LENGTH ) ; getBytes ( APP_SPECIFIC_FEEDBACK_FIELD_OFFSET , destination , 0 , copyLength ) ; result = copyLength ; } return result ; }


Input: Set the Application Specific Feedback for the Status Message . [CODESPLIT] public StatusMessageFlyweight applicationSpecificFeedback ( final byte [ ] source , final int offset , final int length ) { frameLength ( HEADER_LENGTH + length ) ; putBytes ( APP_SPECIFIC_FEEDBACK_FIELD_OFFSET , source , offset , length ) ; return this ; }


Input: Reload the log from disk . [CODESPLIT] public void reload ( ) { entries . clear ( ) ; indexByLeadershipTermIdMap . clear ( ) ; indexByLeadershipTermIdMap . compact ( ) ; nextEntryIndex = 0 ; byteBuffer . clear ( ) ; try { while ( true ) { final int bytes = fileChannel . read ( byteBuffer ) ; if ( byteBuffer . remaining ( ) == 0 ) { byteBuffer . flip ( ) ; captureEntriesFromBuffer ( byteBuffer , buffer , entries ) ; byteBuffer . clear ( ) ; } if ( - 1 == bytes ) { if ( byteBuffer . position ( ) > 0 ) { byteBuffer . flip ( ) ; captureEntriesFromBuffer ( byteBuffer , buffer , entries ) ; byteBuffer . clear ( ) ; } break ; } } } catch ( final IOException ex ) { LangUtil . rethrowUnchecked ( ex ) ; } }


Input: Find the last recording id used for a leader ship term . If not found then { @link RecordingPos#NULL_RECORDING_ID } . [CODESPLIT] public long findLastTermRecordingId ( ) { for ( int i = entries . size ( ) - 1 ; i >= 0 ; i -- ) { final Entry entry = entries . get ( i ) ; if ( ENTRY_TYPE_TERM == entry . type ) { return entry . recordingId ; } } return RecordingPos . NULL_RECORDING_ID ; }


Input: Find the last leadership term in the recording log . [CODESPLIT] public Entry findLastTerm ( ) { for ( int i = entries . size ( ) - 1 ; i >= 0 ; i -- ) { final Entry entry = entries . get ( i ) ; if ( ENTRY_TYPE_TERM == entry . type ) { return entry ; } } return null ; }


Input: Get the term { @link Entry } for a given leadership term id . [CODESPLIT] public Entry getTermEntry ( final long leadershipTermId ) { final int index = ( int ) indexByLeadershipTermIdMap . get ( leadershipTermId ) ; if ( NULL_VALUE == index ) { throw new ClusterException ( "unknown leadershipTermId=" + leadershipTermId ) ; } return entries . get ( index ) ; }


Input: Create a recovery plan for the cluster that when the steps are replayed will bring the cluster back to the latest stable state . [CODESPLIT] public RecoveryPlan createRecoveryPlan ( final AeronArchive archive , final int serviceCount ) { final ArrayList < Snapshot > snapshots = new ArrayList <> ( ) ; final ArrayList < Log > logs = new ArrayList <> ( ) ; planRecovery ( snapshots , logs , entries , archive , serviceCount ) ; long lastLeadershipTermId = NULL_VALUE ; long lastTermBaseLogPosition = 0 ; long committedLogPosition = - 1 ; long appendedLogPosition = 0 ; final int snapshotStepsSize = snapshots . size ( ) ; if ( snapshotStepsSize > 0 ) { final Snapshot snapshot = snapshots . get ( 0 ) ; lastLeadershipTermId = snapshot . leadershipTermId ; lastTermBaseLogPosition = snapshot . termBaseLogPosition ; appendedLogPosition = snapshot . logPosition ; committedLogPosition = snapshot . logPosition ; } if ( ! logs . isEmpty ( ) ) { final Log log = logs . get ( 0 ) ; lastLeadershipTermId = log . leadershipTermId ; lastTermBaseLogPosition = log . termBaseLogPosition ; appendedLogPosition = log . stopPosition ; committedLogPosition = log . logPosition ; } return new RecoveryPlan ( lastLeadershipTermId , lastTermBaseLogPosition , appendedLogPosition , committedLogPosition , snapshots , logs ) ; }


Input: Create a recovery plan that has only snapshots . Used for dynamicJoin snapshot load . [CODESPLIT] public static RecoveryPlan createRecoveryPlan ( final ArrayList < RecordingLog . Snapshot > snapshots ) { long lastLeadershipTermId = NULL_VALUE ; long lastTermBaseLogPosition = 0 ; long committedLogPosition = - 1 ; long appendedLogPosition = 0 ; final int snapshotStepsSize = snapshots . size ( ) ; if ( snapshotStepsSize > 0 ) { final Snapshot snapshot = snapshots . get ( 0 ) ; lastLeadershipTermId = snapshot . leadershipTermId ; lastTermBaseLogPosition = snapshot . termBaseLogPosition ; appendedLogPosition = snapshot . logPosition ; committedLogPosition = snapshot . logPosition ; } return new RecoveryPlan ( lastLeadershipTermId , lastTermBaseLogPosition , appendedLogPosition , committedLogPosition , snapshots , new ArrayList <> ( ) ) ; }


Input: Append a log entry for a leadership term . [CODESPLIT] public void appendTerm ( final long recordingId , final long leadershipTermId , final long termBaseLogPosition , final long timestamp ) { final int size = entries . size ( ) ; if ( size > 0 ) { final Entry lastEntry = entries . get ( size - 1 ) ; if ( lastEntry . type != NULL_VALUE && lastEntry . leadershipTermId >= leadershipTermId ) { throw new ClusterException ( "leadershipTermId out of sequence: previous " + lastEntry . leadershipTermId + " this " + leadershipTermId ) ; } } indexByLeadershipTermIdMap . put ( leadershipTermId , nextEntryIndex ) ; append ( ENTRY_TYPE_TERM , recordingId , leadershipTermId , termBaseLogPosition , NULL_POSITION , timestamp , NULL_VALUE ) ; }


Input: Append a log entry for a snapshot . [CODESPLIT] public void appendSnapshot ( final long recordingId , final long leadershipTermId , final long termBaseLogPosition , final long logPosition , final long timestamp , final int serviceId ) { final int size = entries . size ( ) ; if ( size > 0 ) { final Entry entry = entries . get ( size - 1 ) ; if ( entry . type == ENTRY_TYPE_TERM && entry . leadershipTermId != leadershipTermId ) { throw new ClusterException ( "leadershipTermId out of sequence: previous " + entry . leadershipTermId + " this " + leadershipTermId ) ; } } append ( ENTRY_TYPE_SNAPSHOT , recordingId , leadershipTermId , termBaseLogPosition , logPosition , timestamp , serviceId ) ; }


Input: Commit the position reached in a leadership term before a clean shutdown . [CODESPLIT] public void commitLogPosition ( final long leadershipTermId , final long logPosition ) { final int index = getLeadershipTermEntryIndex ( leadershipTermId ) ; commitEntryValue ( index , logPosition , LOG_POSITION_OFFSET ) ; final Entry entry = entries . get ( index ) ; entries . set ( index , new Entry ( entry . recordingId , entry . leadershipTermId , entry . termBaseLogPosition , logPosition , entry . timestamp , entry . serviceId , entry . type , entry . entryIndex ) ) ; }


Input: Tombstone an entry in the log so it is no longer valid . [CODESPLIT] public void tombstoneEntry ( final long leadershipTermId , final int entryIndex ) { int index = - 1 ; for ( int i = 0 , size = entries . size ( ) ; i < size ; i ++ ) { final Entry entry = entries . get ( i ) ; if ( entry . leadershipTermId == leadershipTermId && entry . entryIndex == entryIndex ) { index = entry . entryIndex ; if ( ENTRY_TYPE_TERM == entry . type ) { indexByLeadershipTermIdMap . remove ( leadershipTermId ) ; } break ; } } if ( - 1 == index ) { throw new ClusterException ( "unknown entry index: " + entryIndex ) ; } buffer . putInt ( 0 , NULL_VALUE , LITTLE_ENDIAN ) ; byteBuffer . limit ( SIZE_OF_INT ) . position ( 0 ) ; final long filePosition = ( index * ( long ) ENTRY_LENGTH ) + ENTRY_TYPE_OFFSET ; try { if ( SIZE_OF_INT != fileChannel . write ( byteBuffer , filePosition ) ) { throw new ClusterException ( "failed to write field atomically" ) ; } } catch ( final Exception ex ) { LangUtil . rethrowUnchecked ( ex ) ; } }


Input: Connect to the cluster providing { @link Context } for configuration . [CODESPLIT] public static AeronCluster connect ( final AeronCluster . Context ctx ) { Subscription subscription = null ; AsyncConnect asyncConnect = null ; try { ctx . conclude ( ) ; final Aeron aeron = ctx . aeron ( ) ; final long deadlineNs = aeron . context ( ) . nanoClock ( ) . nanoTime ( ) + ctx . messageTimeoutNs ( ) ; subscription = aeron . addSubscription ( ctx . egressChannel ( ) , ctx . egressStreamId ( ) ) ; final IdleStrategy idleStrategy = ctx . idleStrategy ( ) ; asyncConnect = new AsyncConnect ( ctx , subscription , deadlineNs ) ; final AgentInvoker aeronClientInvoker = aeron . conductorAgentInvoker ( ) ; AeronCluster aeronCluster ; while ( null == ( aeronCluster = asyncConnect . poll ( ) ) ) { if ( null != aeronClientInvoker ) { aeronClientInvoker . invoke ( ) ; } idleStrategy . idle ( ) ; } return aeronCluster ; } catch ( final Exception ex ) { if ( ! ctx . ownsAeronClient ( ) ) { CloseHelper . close ( subscription ) ; CloseHelper . close ( asyncConnect ) ; } ctx . close ( ) ; throw ex ; } }


Input: Begin an attempt at creating a connection which can be completed by calling { @link AsyncConnect#poll () } until it returns the client before complete it will return null . [CODESPLIT] public static AsyncConnect asyncConnect ( final Context ctx ) { Subscription subscription = null ; try { ctx . conclude ( ) ; final long deadlineNs = ctx . aeron ( ) . context ( ) . nanoClock ( ) . nanoTime ( ) + ctx . messageTimeoutNs ( ) ; subscription = ctx . aeron ( ) . addSubscription ( ctx . egressChannel ( ) , ctx . egressStreamId ( ) ) ; return new AsyncConnect ( ctx , subscription , deadlineNs ) ; } catch ( final Exception ex ) { if ( ! ctx . ownsAeronClient ( ) ) { CloseHelper . quietClose ( subscription ) ; } ctx . close ( ) ; throw ex ; } }


Input: Close session and release associated resources . [CODESPLIT] public void close ( ) { if ( null != publication && publication . isConnected ( ) ) { closeSession ( ) ; } if ( ! ctx . ownsAeronClient ( ) ) { CloseHelper . close ( subscription ) ; CloseHelper . close ( publication ) ; } ctx . close ( ) ; }


Input: Non - blocking publish of a partial buffer containing a message plus session header to a cluster . <p > This version of the method will set the timestamp value in the header to zero . [CODESPLIT] public long offer ( final DirectBuffer buffer , final int offset , final int length ) { return publication . offer ( headerBuffer , 0 , INGRESS_HEADER_LENGTH , buffer , offset , length , null ) ; }


Input: Non - blocking publish by gathering buffer vectors into a message . The first vector will be replaced by the cluster ingress header so must be left unused . [CODESPLIT] public long offer ( final DirectBufferVector [ ] vectors ) { if ( headerVector != vectors [ 0 ] ) { vectors [ 0 ] = headerVector ; } return publication . offer ( vectors , null ) ; }


Input: Send a keep alive message to the cluster to keep this session open . <p > <b > Note : < / b > keepalives can fail during a leadership transition . The consumer should continue to call { @link #pollEgress () } to ensure a connection to the new leader is established . [CODESPLIT] public boolean sendKeepAlive ( ) { idleStrategy . reset ( ) ; int attempts = SEND_ATTEMPTS ; while ( true ) { final long result = publication . offer ( keepaliveMsgBuffer , 0 , keepaliveMsgBuffer . capacity ( ) , null ) ; if ( result > 0 ) { return true ; } if ( result == Publication . NOT_CONNECTED || result == Publication . CLOSED ) { return false ; } if ( result == Publication . MAX_POSITION_EXCEEDED ) { throw new ClusterException ( "unexpected publication state: " + result ) ; } if ( -- attempts <= 0 ) { break ; } idleStrategy . idle ( ) ; } return false ; }


Input: To be called when a new leader event is delivered . This method needs to be called when using the { @link EgressAdapter } or { @link EgressPoller } rather than { @link #pollEgress () } method . [CODESPLIT] public void onNewLeader ( final long clusterSessionId , final long leadershipTermId , final int leaderMemberId , final String memberEndpoints ) { if ( clusterSessionId != this . clusterSessionId ) { throw new ClusterException ( "invalid clusterSessionId=" + clusterSessionId + " expected " + this . clusterSessionId ) ; } this . leadershipTermId = leadershipTermId ; this . leaderMemberId = leaderMemberId ; ingressMessageHeaderEncoder . leadershipTermId ( leadershipTermId ) ; sessionKeepAliveEncoder . leadershipTermId ( leadershipTermId ) ; if ( ctx . clusterMemberEndpoints ( ) != null ) { CloseHelper . close ( publication ) ; ctx . clusterMemberEndpoints ( memberEndpoints ) ; updateMemberEndpoints ( memberEndpoints , leaderMemberId ) ; } fragmentAssembler . clear ( ) ; controlledFragmentAssembler . clear ( ) ; egressListener . newLeader ( clusterSessionId , leadershipTermId , leaderMemberId , memberEndpoints ) ; controlledEgressListener . newLeader ( clusterSessionId , leadershipTermId , leaderMemberId , memberEndpoints ) ; }


Input: Attempt to unblock a log buffer at given position [CODESPLIT] public static boolean unblock ( final UnsafeBuffer [ ] termBuffers , final UnsafeBuffer logMetaDataBuffer , final long blockedPosition , final int termLength ) { final int positionBitsToShift = LogBufferDescriptor . positionBitsToShift ( termLength ) ; final int blockedTermCount = ( int ) ( blockedPosition >> positionBitsToShift ) ; final int blockedOffset = ( int ) blockedPosition & ( termLength - 1 ) ; final int activeTermCount = activeTermCount ( logMetaDataBuffer ) ; if ( activeTermCount == ( blockedTermCount - 1 ) && blockedOffset == 0 ) { final int currentTermId = termId ( rawTailVolatile ( logMetaDataBuffer , indexByTermCount ( activeTermCount ) ) ) ; return rotateLog ( logMetaDataBuffer , activeTermCount , currentTermId ) ; } final int blockedIndex = indexByTermCount ( blockedTermCount ) ; final long rawTail = rawTailVolatile ( logMetaDataBuffer , blockedIndex ) ; final int termId = termId ( rawTail ) ; final int tailOffset = termOffset ( rawTail , termLength ) ; final UnsafeBuffer termBuffer = termBuffers [ blockedIndex ] ; switch ( TermUnblocker . unblock ( logMetaDataBuffer , termBuffer , blockedOffset , tailOffset , termId ) ) { case UNBLOCKED_TO_END : rotateLog ( logMetaDataBuffer , blockedTermCount , termId ) ; // fall through case UNBLOCKED : return true ; } return false ; }


Input: Get the channel field as ASCII [CODESPLIT] public String channel ( ) { final int length = buffer . getInt ( offset + CHANNEL_OFFSET ) ; lengthOfChannel = SIZE_OF_INT + length ; return buffer . getStringAscii ( offset + CHANNEL_OFFSET , length ) ; }


Input: Set the channel field as ASCII [CODESPLIT] public ImageMessageFlyweight channel ( final String channel ) { lengthOfChannel = buffer . putStringAscii ( offset + CHANNEL_OFFSET , channel ) ; return this ; }


Input: Check that term length is valid and alignment is valid . [CODESPLIT] public static void checkTermLength ( final int termLength ) { if ( termLength < TERM_MIN_LENGTH ) { throw new IllegalStateException ( "Term length less than min length of " + TERM_MIN_LENGTH + ": length=" + termLength ) ; } if ( termLength > TERM_MAX_LENGTH ) { throw new IllegalStateException ( "Term length more than max length of " + TERM_MAX_LENGTH + ": length=" + termLength ) ; } if ( ! BitUtil . isPowerOfTwo ( termLength ) ) { throw new IllegalStateException ( "Term length not a power of 2: length=" + termLength ) ; } }


Input: Check that page size is valid and alignment is valid . [CODESPLIT] public static void checkPageSize ( final int pageSize ) { if ( pageSize < PAGE_MIN_SIZE ) { throw new IllegalStateException ( "Page size less than min size of " + PAGE_MIN_SIZE + ": page size=" + pageSize ) ; } if ( pageSize > PAGE_MAX_SIZE ) { throw new IllegalStateException ( "Page size more than max size of " + PAGE_MAX_SIZE + ": page size=" + pageSize ) ; } if ( ! BitUtil . isPowerOfTwo ( pageSize ) ) { throw new IllegalStateException ( "Page size not a power of 2: page size=" + pageSize ) ; } }


Input: Compare and set the value of the current active term count . [CODESPLIT] public static boolean casActiveTermCount ( final UnsafeBuffer metadataBuffer , final int expectedTermCount , final int updateTermCount ) { return metadataBuffer . compareAndSetInt ( LOG_ACTIVE_TERM_COUNT_OFFSET , expectedTermCount , updateTermCount ) ; }


Input: Compute the current position in absolute number of bytes . [CODESPLIT] public static long computePosition ( final int activeTermId , final int termOffset , final int positionBitsToShift , final int initialTermId ) { final long termCount = activeTermId - initialTermId ; // copes with negative activeTermId on rollover return ( termCount << positionBitsToShift ) + termOffset ; }


Input: Compute the total length of a log file given the term length . [CODESPLIT] public static long computeLogLength ( final int termLength , final int filePageSize ) { if ( termLength < ( 1024 * 1024 * 1024 ) ) { return align ( ( termLength * PARTITION_COUNT ) + LOG_META_DATA_LENGTH , filePageSize ) ; } return ( PARTITION_COUNT * ( long ) termLength ) + align ( LOG_META_DATA_LENGTH , filePageSize ) ; }


Input: Store the default frame header to the log meta data buffer . [CODESPLIT] public static void storeDefaultFrameHeader ( final UnsafeBuffer metadataBuffer , final DirectBuffer defaultHeader ) { if ( defaultHeader . capacity ( ) != HEADER_LENGTH ) { throw new IllegalArgumentException ( "Default header length not equal to HEADER_LENGTH: length=" + defaultHeader . capacity ( ) ) ; } metadataBuffer . putInt ( LOG_DEFAULT_FRAME_HEADER_LENGTH_OFFSET , HEADER_LENGTH ) ; metadataBuffer . putBytes ( LOG_DEFAULT_FRAME_HEADER_OFFSET , defaultHeader , 0 , HEADER_LENGTH ) ; }


Input: Apply the default header for a message in a term . [CODESPLIT] public static void applyDefaultHeader ( final UnsafeBuffer metadataBuffer , final UnsafeBuffer termBuffer , final int termOffset ) { termBuffer . putBytes ( termOffset , metadataBuffer , LOG_DEFAULT_FRAME_HEADER_OFFSET , HEADER_LENGTH ) ; }


Input: Rotate the log and update the tail counter for the new term . [CODESPLIT] public static boolean rotateLog ( final UnsafeBuffer metadataBuffer , final int termCount , final int termId ) { final int nextTermId = termId + 1 ; final int nextTermCount = termCount + 1 ; final int nextIndex = indexByTermCount ( nextTermCount ) ; final int expectedTermId = nextTermId - PARTITION_COUNT ; long rawTail ; do { rawTail = rawTail ( metadataBuffer , nextIndex ) ; if ( expectedTermId != termId ( rawTail ) ) { break ; } } while ( ! casRawTail ( metadataBuffer , nextIndex , rawTail , packTail ( nextTermId , 0 ) ) ) ; return casActiveTermCount ( metadataBuffer , termCount , nextTermCount ) ; }


Input: Set the initial value for the termId in the upper bits of the tail counter . [CODESPLIT] public static void initialiseTailWithTermId ( final UnsafeBuffer metadataBuffer , final int partitionIndex , final int termId ) { metadataBuffer . putLong ( TERM_TAIL_COUNTERS_OFFSET + ( partitionIndex * SIZE_OF_LONG ) , packTail ( termId , 0 ) ) ; }


Input: Read the termOffset from a packed raw tail value . [CODESPLIT] public static int termOffset ( final long rawTail , final long termLength ) { final long tail = rawTail & 0xFFFF_FFFF  L ; return ( int ) Math . min ( tail , termLength ) ; }


Input: Set the raw value of the tail for the given partition . [CODESPLIT] public static void rawTail ( final UnsafeBuffer metadataBuffer , final int partitionIndex , final long rawTail ) { metadataBuffer . putLong ( TERM_TAIL_COUNTERS_OFFSET + ( SIZE_OF_LONG * partitionIndex ) , rawTail ) ; }


Input: Set the raw value of the tail for the given partition . [CODESPLIT] public static void rawTailVolatile ( final UnsafeBuffer metadataBuffer , final int partitionIndex , final long rawTail ) { metadataBuffer . putLongVolatile ( TERM_TAIL_COUNTERS_OFFSET + ( SIZE_OF_LONG * partitionIndex ) , rawTail ) ; }


Input: Get the raw value of the tail for the current active partition . [CODESPLIT] public static long rawTailVolatile ( final UnsafeBuffer metadataBuffer ) { final int partitionIndex = indexByTermCount ( activeTermCount ( metadataBuffer ) ) ; return metadataBuffer . getLongVolatile ( TERM_TAIL_COUNTERS_OFFSET + ( SIZE_OF_LONG * partitionIndex ) ) ; }


Input: Compare and set the raw value of the tail for the given partition . [CODESPLIT] public static boolean casRawTail ( final UnsafeBuffer metadataBuffer , final int partitionIndex , final long expectedRawTail , final long updateRawTail ) { final int index = TERM_TAIL_COUNTERS_OFFSET + ( SIZE_OF_LONG * partitionIndex ) ; return metadataBuffer . compareAndSetLong ( index , expectedRawTail , updateRawTail ) ; }


Input: Launch an { @link Archive } with that communicates with an out of process { @link io . aeron . driver . MediaDriver } and await a shutdown signal . [CODESPLIT] public static void main ( final String [ ] args ) { loadPropertiesFiles ( args ) ; try ( Archive ignore = launch ( ) ) { new ShutdownSignalBarrier ( ) . await ( ) ; System . out . println ( "Shutdown Archive..." ) ; } }


Input: Fill the token buffer . [CODESPLIT] public TerminateDriverFlyweight tokenBuffer ( final DirectBuffer tokenBuffer , final int tokenOffset , final int tokenLength ) { buffer . putInt ( TOKEN_LENGTH_OFFSET , tokenLength ) ; if ( null != tokenBuffer && tokenLength > 0 ) { buffer . putBytes ( tokenBufferOffset ( ) , tokenBuffer , tokenOffset , tokenLength ) ; } return this ; }


Input: Allocate a counter to represent the snapshot services should load on start . [CODESPLIT] public static Counter allocate ( final Aeron aeron , final MutableDirectBuffer tempBuffer , final long leadershipTermId , final long logPosition , final long timestamp , final boolean hasReplay , final long ... snapshotRecordingIds ) { tempBuffer . putLong ( LEADERSHIP_TERM_ID_OFFSET , leadershipTermId ) ; tempBuffer . putLong ( LOG_POSITION_OFFSET , logPosition ) ; tempBuffer . putLong ( TIMESTAMP_OFFSET , timestamp ) ; tempBuffer . putInt ( REPLAY_FLAG_OFFSET , hasReplay ? 1 : 0 ) ; final int serviceCount = snapshotRecordingIds . length ; tempBuffer . putInt ( SERVICE_COUNT_OFFSET , serviceCount ) ; final int keyLength = SNAPSHOT_RECORDING_IDS_OFFSET + ( serviceCount * SIZE_OF_LONG ) ; if ( keyLength > MAX_KEY_LENGTH ) { throw new ClusterException ( keyLength + " exceeds max key length " + MAX_KEY_LENGTH ) ; } for ( int i = 0 ; i < serviceCount ; i ++ ) { tempBuffer . putLong ( SNAPSHOT_RECORDING_IDS_OFFSET + ( i * SIZE_OF_LONG ) , snapshotRecordingIds [ i ] ) ; } final int labelOffset = BitUtil . align ( keyLength , SIZE_OF_INT ) ; int labelLength = 0 ; labelLength += tempBuffer . putStringWithoutLengthAscii ( labelOffset + labelLength , NAME ) ; labelLength += tempBuffer . putLongAscii ( keyLength + labelLength , leadershipTermId ) ; labelLength += tempBuffer . putStringWithoutLengthAscii ( labelOffset + labelLength , " logPosition=" ) ; labelLength += tempBuffer . putLongAscii ( labelOffset + labelLength , logPosition ) ; labelLength += tempBuffer . putStringWithoutLengthAscii ( labelOffset + labelLength , " hasReplay=" + hasReplay ) ; return aeron . addCounter ( RECOVERY_STATE_TYPE_ID , tempBuffer , 0 , keyLength , tempBuffer , labelOffset , labelLength ) ; }


Input: Find the active counter id for recovery state . [CODESPLIT] public static int findCounterId ( final CountersReader counters ) { final DirectBuffer buffer = counters . metaDataBuffer ( ) ; for ( int i = 0 , size = counters . maxCounterId ( ) ; i < size ; i ++ ) { if ( counters . getCounterState ( i ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( i ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECOVERY_STATE_TYPE_ID ) { return i ; } } } return NULL_COUNTER_ID ; }


Input: Get the position at which the snapshot was taken . { @link Aeron#NULL_VALUE } if no snapshot for recovery . [CODESPLIT] public static long getLogPosition ( final CountersReader counters , final int counterId ) { final DirectBuffer buffer = counters . metaDataBuffer ( ) ; if ( counters . getCounterState ( counterId ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( counterId ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECOVERY_STATE_TYPE_ID ) { return buffer . getLong ( recordOffset + KEY_OFFSET + LOG_POSITION_OFFSET ) ; } } return NULL_VALUE ; }


Input: Has the recovery process got a log to replay? [CODESPLIT] public static boolean hasReplay ( final CountersReader counters , final int counterId ) { final DirectBuffer buffer = counters . metaDataBuffer ( ) ; if ( counters . getCounterState ( counterId ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( counterId ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECOVERY_STATE_TYPE_ID ) { return buffer . getInt ( recordOffset + KEY_OFFSET + REPLAY_FLAG_OFFSET ) == 1 ; } } return false ; }


Input: Get the recording id of the snapshot for a service . [CODESPLIT] public static long getSnapshotRecordingId ( final CountersReader counters , final int counterId , final int serviceId ) { final DirectBuffer buffer = counters . metaDataBuffer ( ) ; if ( counters . getCounterState ( counterId ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( counterId ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == RECOVERY_STATE_TYPE_ID ) { final int serviceCount = buffer . getInt ( recordOffset + KEY_OFFSET + SERVICE_COUNT_OFFSET ) ; if ( serviceId < 0 || serviceId >= serviceCount ) { throw new ClusterException ( "invalid serviceId " + serviceId + " for count of " + serviceCount ) ; } return buffer . getLong ( recordOffset + KEY_OFFSET + SNAPSHOT_RECORDING_IDS_OFFSET + ( serviceId * SIZE_OF_LONG ) ) ; } } throw new ClusterException ( "Active counter not found " + counterId ) ; }


Input: Convert header flags to an array of chars to be human readable . [CODESPLIT] public static char [ ] flagsToChars ( final short flags ) { final char [ ] chars = new char [ ] { ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } ; final int length = chars . length ; short mask = ( short ) ( 1 << ( length - 1 ) ) ; for ( int i = 0 ; i < length ; i ++ ) { if ( ( flags & mask ) == mask ) { chars [ i ] = ' ' ; } mask >>= 1 ; } return chars ; }


Input: Create a new entry for recording loss on a given stream . <p > If not space is remaining in the error report then null is returned . [CODESPLIT] public ReportEntry createEntry ( final long initialBytesLost , final long timestampMs , final int sessionId , final int streamId , final String channel , final String source ) { ReportEntry reportEntry = null ; final int requiredCapacity = CHANNEL_OFFSET + ( SIZE_OF_INT * 2 ) + channel . length ( ) + source . length ( ) ; if ( requiredCapacity <= ( buffer . capacity ( ) - nextRecordOffset ) ) { final int offset = nextRecordOffset ; buffer . putLong ( offset + TOTAL_BYTES_LOST_OFFSET , initialBytesLost ) ; buffer . putLong ( offset + FIRST_OBSERVATION_OFFSET , timestampMs ) ; buffer . putLong ( offset + LAST_OBSERVATION_OFFSET , timestampMs ) ; buffer . putInt ( offset + SESSION_ID_OFFSET , sessionId ) ; buffer . putInt ( offset + STREAM_ID_OFFSET , streamId ) ; final int encodedChannelLength = buffer . putStringAscii ( offset + CHANNEL_OFFSET , channel ) ; buffer . putStringAscii ( offset + CHANNEL_OFFSET + encodedChannelLength , source ) ; buffer . putLongOrdered ( offset + OBSERVATION_COUNT_OFFSET , 1 ) ; reportEntry = new ReportEntry ( buffer , offset ) ; nextRecordOffset += BitUtil . align ( requiredCapacity , ENTRY_ALIGNMENT ) ; } return reportEntry ; }


Input: Non - blocking publish of a partial buffer containing a message plus session header to a cluster . <p > This version of the method will set the timestamp value in the header to { @link Aeron#NULL_VALUE } . [CODESPLIT] public long offer ( final Publication publication , final DirectBuffer buffer , final int offset , final int length ) { return publication . offer ( headerBuffer , 0 , HEADER_LENGTH , buffer , offset , length , null ) ; }


Input: Set the channel field in ASCII [CODESPLIT] public PublicationMessageFlyweight channel ( final String channel ) { lengthOfChannel = buffer . putStringAscii ( offset + CHANNEL_OFFSET , channel ) ; return this ; }


Input: Try to gap fill the current term at a given offset if the gap contains no data . <p > Note : the gap offset plus gap length must end on a { @link FrameDescriptor#FRAME_ALIGNMENT } boundary . [CODESPLIT] public static boolean tryFillGap ( final UnsafeBuffer logMetaDataBuffer , final UnsafeBuffer termBuffer , final int termId , final int gapOffset , final int gapLength ) { int offset = ( gapOffset + gapLength ) - FRAME_ALIGNMENT ; while ( offset >= gapOffset ) { if ( 0 != termBuffer . getInt ( offset ) ) { return false ; } offset -= FRAME_ALIGNMENT ; } applyDefaultHeader ( logMetaDataBuffer , termBuffer , gapOffset ) ; frameType ( termBuffer , gapOffset , HDR_TYPE_PAD ) ; frameTermOffset ( termBuffer , gapOffset ) ; frameTermId ( termBuffer , gapOffset , termId ) ; frameLengthOrdered ( termBuffer , gapOffset , gapLength ) ; return true ; }


Input: Reads data from a term in a log buffer and updates a passed { @link Position } so progress is not lost in the event of an exception . [CODESPLIT] public static int read ( final UnsafeBuffer termBuffer , final int termOffset , final FragmentHandler handler , final int fragmentsLimit , final Header header , final ErrorHandler errorHandler , final long currentPosition , final Position subscriberPosition ) { int fragmentsRead = 0 ; int offset = termOffset ; final int capacity = termBuffer . capacity ( ) ; header . buffer ( termBuffer ) ; try { while ( fragmentsRead < fragmentsLimit && offset < capacity ) { final int frameLength = frameLengthVolatile ( termBuffer , offset ) ; if ( frameLength <= 0 ) { break ; } final int frameOffset = offset ; offset += BitUtil . align ( frameLength , FRAME_ALIGNMENT ) ; if ( ! isPaddingFrame ( termBuffer , frameOffset ) ) { header . offset ( frameOffset ) ; handler . onFragment ( termBuffer , frameOffset + HEADER_LENGTH , frameLength - HEADER_LENGTH , header ) ; ++ fragmentsRead ; } } } catch ( final Throwable t ) { errorHandler . onError ( t ) ; } finally { final long newPosition = currentPosition + ( offset - termOffset ) ; if ( newPosition > currentPosition ) { subscriberPosition . setOrdered ( newPosition ) ; } } return fragmentsRead ; }


Input: Write a header to the term buffer in { @link ByteOrder#LITTLE_ENDIAN } format using the minimum instructions . [CODESPLIT] public void write ( final UnsafeBuffer termBuffer , final int offset , final int length , final int termId ) { termBuffer . putLongOrdered ( offset + FRAME_LENGTH_FIELD_OFFSET , versionFlagsType | ( ( - length ) & 0xFFFF_FFFF L ) ) ; UnsafeAccess . UNSAFE . storeFence ( ) ; termBuffer . putLong ( offset + TERM_OFFSET_FIELD_OFFSET , sessionId | offset ) ; termBuffer . putLong ( offset + STREAM_ID_FIELD_OFFSET , streamId | ( ( ( long ) termId ) << 32 ) ) ; }


Input: Non - blocking publish of a partial buffer containing a message to a cluster . [CODESPLIT] public long offer ( final DirectBuffer buffer , final int offset , final int length ) { return cluster . offer ( id , responsePublication , buffer , offset , length ) ; }


Input: Wrap a region of an underlying log buffer so can can represent a claimed space for use by a publisher . [CODESPLIT] public final void wrap ( final AtomicBuffer buffer , final int offset , final int length ) { this . buffer . wrap ( buffer , offset , length ) ; }


Input: Put bytes into the claimed buffer space for a message . To write multiple parts then use { @link #buffer () } and { @link #offset () } . [CODESPLIT] public final BufferClaim putBytes ( final DirectBuffer srcBuffer , final int srcIndex , final int length ) { buffer . putBytes ( HEADER_LENGTH , srcBuffer , srcIndex , length ) ; return this ; }


Input: Commit the message to the log buffer so that is it available to subscribers . [CODESPLIT] public final void commit ( ) { int frameLength = buffer . capacity ( ) ; if ( ByteOrder . nativeOrder ( ) != LITTLE_ENDIAN ) { frameLength = Integer . reverseBytes ( frameLength ) ; } buffer . putIntOrdered ( FRAME_LENGTH_FIELD_OFFSET , frameLength ) ; }


Input: Abort a claim of the message space to the log buffer so that the log can progress by ignoring this claim . [CODESPLIT] public final void abort ( ) { int frameLength = buffer . capacity ( ) ; if ( ByteOrder . nativeOrder ( ) != LITTLE_ENDIAN ) { frameLength = Integer . reverseBytes ( frameLength ) ; } buffer . putShort ( TYPE_FIELD_OFFSET , ( short ) HDR_TYPE_PAD , LITTLE_ENDIAN ) ; buffer . putIntOrdered ( FRAME_LENGTH_FIELD_OFFSET , frameLength ) ; }


Input: Start Media Driver as a stand - alone process . [CODESPLIT] public static void main ( final String [ ] args ) { loadPropertiesFiles ( args ) ; final ShutdownSignalBarrier barrier = new ShutdownSignalBarrier ( ) ; final MediaDriver . Context ctx = new MediaDriver . Context ( ) ; ctx . terminationHook ( barrier :: signal ) ; try ( MediaDriver ignore = MediaDriver . launch ( ctx ) ) { barrier . await ( ) ; System . out . println ( "Shutdown Driver..." ) ; } }


Input: Launch an isolated MediaDriver embedded in the current process with a provided configuration ctx and a generated aeronDirectoryName ( overwrites configured { @link Context#aeronDirectoryName () } ) that can be retrieved by calling aeronDirectoryName . <p > If the aeronDirectoryName is set as a system property or via context to something different than { @link CommonContext#AERON_DIR_PROP_DEFAULT } then this set value will be used . [CODESPLIT] public static MediaDriver launchEmbedded ( final Context ctx ) { if ( CommonContext . AERON_DIR_PROP_DEFAULT . equals ( ctx . aeronDirectoryName ( ) ) ) { ctx . aeronDirectoryName ( CommonContext . generateRandomDirName ( ) ) ; } return launch ( ctx ) ; }


Input: Shutdown the media driver by stopping all threads and freeing resources . [CODESPLIT] public void close ( ) { CloseHelper . close ( sharedRunner ) ; CloseHelper . close ( sharedNetworkRunner ) ; CloseHelper . close ( receiverRunner ) ; CloseHelper . close ( senderRunner ) ; CloseHelper . close ( conductorRunner ) ; CloseHelper . close ( sharedInvoker ) ; if ( ctx . useWindowsHighResTimer ( ) && SystemUtil . osName ( ) . startsWith ( "win" ) ) { if ( ! wasHighResTimerEnabled ) { HighResolutionTimer . disable ( ) ; } } }


Input: Poll for new messages in a stream . If new messages are found beyond the last consumed position then they will be delivered to the { @link FragmentHandler } up to a limited number of fragments as specified . <p > Use a { @link FragmentAssembler } to assemble messages which span multiple fragments . [CODESPLIT] public int poll ( final FragmentHandler fragmentHandler , final int fragmentLimit ) { if ( isClosed ) { return 0 ; } final long position = subscriberPosition . get ( ) ; return TermReader . read ( activeTermBuffer ( position ) , ( int ) position & termLengthMask , fragmentHandler , fragmentLimit , header , errorHandler , position , subscriberPosition ) ; }


Input: Poll for new messages in a stream . If new messages are found beyond the last consumed position then they will be delivered to the { @link ControlledFragmentHandler } up to a limited number of fragments as specified . <p > Use a { @link ControlledFragmentAssembler } to assemble messages which span multiple fragments . [CODESPLIT] public int controlledPoll ( final ControlledFragmentHandler handler , final int fragmentLimit ) { if ( isClosed ) { return 0 ; } int fragmentsRead = 0 ; long initialPosition = subscriberPosition . get ( ) ; int initialOffset = ( int ) initialPosition & termLengthMask ; int resultingOffset = initialOffset ; final UnsafeBuffer termBuffer = activeTermBuffer ( initialPosition ) ; final int capacity = termBuffer . capacity ( ) ; final Header header = this . header ; header . buffer ( termBuffer ) ; try { while ( fragmentsRead < fragmentLimit && resultingOffset < capacity ) { final int length = frameLengthVolatile ( termBuffer , resultingOffset ) ; if ( length <= 0 ) { break ; } final int frameOffset = resultingOffset ; final int alignedLength = BitUtil . align ( length , FRAME_ALIGNMENT ) ; resultingOffset += alignedLength ; if ( isPaddingFrame ( termBuffer , frameOffset ) ) { continue ; } header . offset ( frameOffset ) ; final Action action = handler . onFragment ( termBuffer , frameOffset + HEADER_LENGTH , length - HEADER_LENGTH , header ) ; if ( action == ABORT ) { resultingOffset -= alignedLength ; break ; } ++ fragmentsRead ; if ( action == BREAK ) { break ; } else if ( action == COMMIT ) { initialPosition += ( resultingOffset - initialOffset ) ; initialOffset = resultingOffset ; subscriberPosition . setOrdered ( initialPosition ) ; } } } catch ( final Throwable t ) { errorHandler . onError ( t ) ; } finally { final long resultingPosition = initialPosition + ( resultingOffset - initialOffset ) ; if ( resultingPosition > initialPosition ) { subscriberPosition . setOrdered ( resultingPosition ) ; } } return fragmentsRead ; }


Input: Peek for new messages in a stream by scanning forward from an initial position . If new messages are found then they will be delivered to the { @link ControlledFragmentHandler } up to a limited position . <p > Use a { @link ControlledFragmentAssembler } to assemble messages which span multiple fragments . Scans must also start at the beginning of a message so that the assembler is reset . [CODESPLIT] public long controlledPeek ( final long initialPosition , final ControlledFragmentHandler handler , final long limitPosition ) { if ( isClosed ) { return 0 ; } validatePosition ( initialPosition ) ; int initialOffset = ( int ) initialPosition & termLengthMask ; int offset = initialOffset ; long position = initialPosition ; final UnsafeBuffer termBuffer = activeTermBuffer ( initialPosition ) ; final int capacity = termBuffer . capacity ( ) ; final Header header = this . header ; header . buffer ( termBuffer ) ; long resultingPosition = initialPosition ; try { while ( position < limitPosition && offset < capacity ) { final int length = frameLengthVolatile ( termBuffer , offset ) ; if ( length <= 0 ) { break ; } final int frameOffset = offset ; final int alignedLength = BitUtil . align ( length , FRAME_ALIGNMENT ) ; offset += alignedLength ; if ( isPaddingFrame ( termBuffer , frameOffset ) ) { position += ( offset - initialOffset ) ; initialOffset = offset ; resultingPosition = position ; continue ; } header . offset ( frameOffset ) ; final Action action = handler . onFragment ( termBuffer , frameOffset + HEADER_LENGTH , length - HEADER_LENGTH , header ) ; if ( action == ABORT ) { break ; } position += ( offset - initialOffset ) ; initialOffset = offset ; if ( ( header . flags ( ) & END_FRAG_FLAG ) == END_FRAG_FLAG ) { resultingPosition = position ; } if ( action == BREAK ) { break ; } } } catch ( final Throwable t ) { errorHandler . onError ( t ) ; } return resultingPosition ; }


Input: Poll for new messages in a stream . If new messages are found beyond the last consumed position then they will be delivered to the { @link BlockHandler } up to a limited number of bytes . <p > A scan will terminate if a padding frame is encountered . If first frame in a scan is padding then a block for the padding is notified . If the padding comes after the first frame in a scan then the scan terminates at the offset the padding frame begins . Padding frames are delivered singularly in a block . <p > Padding frames may be for a greater range than the limit offset but only the header needs to be valid so relevant length of the frame is { @link io . aeron . protocol . DataHeaderFlyweight#HEADER_LENGTH } . [CODESPLIT] public int blockPoll ( final BlockHandler handler , final int blockLengthLimit ) { if ( isClosed ) { return 0 ; } final long position = subscriberPosition . get ( ) ; final int termOffset = ( int ) position & termLengthMask ; final UnsafeBuffer termBuffer = activeTermBuffer ( position ) ; final int limitOffset = Math . min ( termOffset + blockLengthLimit , termBuffer . capacity ( ) ) ; final int resultingOffset = TermBlockScanner . scan ( termBuffer , termOffset , limitOffset ) ; final int length = resultingOffset - termOffset ; if ( resultingOffset > termOffset ) { try { final int termId = termBuffer . getInt ( termOffset + TERM_ID_FIELD_OFFSET , LITTLE_ENDIAN ) ; handler . onBlock ( termBuffer , termOffset , length , sessionId , termId ) ; } catch ( final Throwable t ) { errorHandler . onError ( t ) ; } finally { subscriberPosition . setOrdered ( position + length ) ; } } return length ; }


Input: Poll for new messages in a stream . If new messages are found beyond the last consumed position then they will be delivered to the { @link RawBlockHandler } up to a limited number of bytes . <p > This method is useful for operations like bulk archiving a stream to file . <p > A scan will terminate if a padding frame is encountered . If first frame in a scan is padding then a block for the padding is notified . If the padding comes after the first frame in a scan then the scan terminates at the offset the padding frame begins . Padding frames are delivered singularly in a block . <p > Padding frames may be for a greater range than the limit offset but only the header needs to be valid so relevant length of the frame is { @link io . aeron . protocol . DataHeaderFlyweight#HEADER_LENGTH } . [CODESPLIT] public int rawPoll ( final RawBlockHandler handler , final int blockLengthLimit ) { if ( isClosed ) { return 0 ; } final long position = subscriberPosition . get ( ) ; final int termOffset = ( int ) position & termLengthMask ; final int activeIndex = indexByPosition ( position , positionBitsToShift ) ; final UnsafeBuffer termBuffer = termBuffers [ activeIndex ] ; final int capacity = termBuffer . capacity ( ) ; final int limitOffset = Math . min ( termOffset + blockLengthLimit , capacity ) ; final int resultingOffset = TermBlockScanner . scan ( termBuffer , termOffset , limitOffset ) ; final int length = resultingOffset - termOffset ; if ( resultingOffset > termOffset ) { try { final long fileOffset = ( ( long ) capacity * activeIndex ) + termOffset ; final int termId = termBuffer . getInt ( termOffset + TERM_ID_FIELD_OFFSET , LITTLE_ENDIAN ) ; handler . onBlock ( logBuffers . fileChannel ( ) , fileOffset , termBuffer , termOffset , length , sessionId , termId ) ; } catch ( final Throwable t ) { errorHandler . onError ( t ) ; } finally { subscriberPosition . setOrdered ( position + length ) ; } } return length ; }


Input: Get the current position to which the image has advanced on reading this message . [CODESPLIT] public final long position ( ) { final int resultingOffset = BitUtil . align ( termOffset ( ) + frameLength ( ) , FRAME_ALIGNMENT ) ; return computePosition ( termId ( ) , resultingOffset , positionBitsToShift , initialTermId ) ; }


Input: Set channel field in ASCII [CODESPLIT] public SubscriptionMessageFlyweight channel ( final String channel ) { lengthOfChannel = buffer . putStringAscii ( offset + CHANNEL_OFFSET , channel ) ; return this ; }


Input: Create new { @link RawLog } in the publications directory for the supplied triplet . [CODESPLIT] public RawLog newPublication ( final String channel , final int sessionId , final int streamId , final long correlationId , final int termBufferLength , final boolean useSparseFiles ) { return newInstance ( publicationsDir , channel , sessionId , streamId , correlationId , termBufferLength , useSparseFiles ) ; }


Input: Create new { @link RawLog } in the rebuilt publication images directory for the supplied triplet . [CODESPLIT] public RawLog newImage ( final String channel , final int sessionId , final int streamId , final long correlationId , final int termBufferLength , final boolean useSparseFiles ) { return newInstance ( imagesDir , channel , sessionId , streamId , correlationId , termBufferLength , useSparseFiles ) ; }


Input: Allocate a counter to represent the heartbeat of a clustered service . [CODESPLIT] public static Counter allocate ( final Aeron aeron , final MutableDirectBuffer tempBuffer , final int serviceId ) { tempBuffer . putInt ( SERVICE_ID_OFFSET , serviceId ) ; final int labelOffset = BitUtil . align ( KEY_LENGTH , SIZE_OF_INT ) ; int labelLength = 0 ; labelLength += tempBuffer . putStringWithoutLengthAscii ( labelOffset + labelLength , NAME ) ; labelLength += tempBuffer . putIntAscii ( labelOffset + labelLength , serviceId ) ; return aeron . addCounter ( SERVICE_HEARTBEAT_TYPE_ID , tempBuffer , 0 , KEY_LENGTH , tempBuffer , labelOffset , labelLength ) ; }


Input: Find the active counter id for heartbeat of a given service id . [CODESPLIT] public static int findCounterId ( final CountersReader counters , final int serviceId ) { final DirectBuffer buffer = counters . metaDataBuffer ( ) ; for ( int i = 0 , size = counters . maxCounterId ( ) ; i < size ; i ++ ) { if ( counters . getCounterState ( i ) == RECORD_ALLOCATED ) { final int recordOffset = CountersReader . metaDataOffset ( i ) ; if ( buffer . getInt ( recordOffset + TYPE_ID_OFFSET ) == SERVICE_HEARTBEAT_TYPE_ID && buffer . getInt ( recordOffset + KEY_OFFSET + SERVICE_ID_OFFSET ) == serviceId ) { return i ; } } } return NULL_COUNTER_ID ; }


Input: Take a snapshot of all the backlog information and group by stream . [CODESPLIT] public Map < StreamCompositeKey , StreamBacklog > snapshot ( ) { final Map < StreamCompositeKey , StreamBacklog > streams = new HashMap <> ( ) ; counters . forEach ( ( counterId , typeId , keyBuffer , label ) -> { if ( ( typeId >= PUBLISHER_LIMIT_TYPE_ID && typeId <= RECEIVER_POS_TYPE_ID ) || typeId == SENDER_LIMIT_TYPE_ID || typeId == PER_IMAGE_TYPE_ID || typeId == PUBLISHER_POS_TYPE_ID ) { final StreamCompositeKey key = new StreamCompositeKey ( keyBuffer . getInt ( SESSION_ID_OFFSET ) , keyBuffer . getInt ( STREAM_ID_OFFSET ) , keyBuffer . getStringAscii ( CHANNEL_OFFSET ) ) ; final StreamBacklog streamBacklog = streams . computeIfAbsent ( key , ( ignore ) - > new StreamBacklog ( ) ) ; final long registrationId = keyBuffer . getLong ( REGISTRATION_ID_OFFSET ) ; final long value = counters . getCounterValue ( counterId ) ; switch ( typeId ) { case PublisherLimit . PUBLISHER_LIMIT_TYPE_ID : streamBacklog . createPublisherIfAbsent ( ) . registrationId ( registrationId ) ; streamBacklog . createPublisherIfAbsent ( ) . limit ( value ) ; break ; case PublisherPos . PUBLISHER_POS_TYPE_ID : streamBacklog . createPublisherIfAbsent ( ) . registrationId ( registrationId ) ; streamBacklog . createPublisherIfAbsent ( ) . position ( value ) ; break ; case SenderPos . SENDER_POSITION_TYPE_ID : streamBacklog . createSenderIfAbsent ( ) . registrationId ( registrationId ) ; streamBacklog . createSenderIfAbsent ( ) . position ( value ) ; break ; case SenderLimit . SENDER_LIMIT_TYPE_ID : streamBacklog . createSenderIfAbsent ( ) . registrationId ( registrationId ) ; streamBacklog . createSenderIfAbsent ( ) . limit ( value ) ; break ; case ReceiverHwm . RECEIVER_HWM_TYPE_ID : streamBacklog . createReceiverIfAbsent ( ) . registrationId ( registrationId ) ; streamBacklog . createReceiverIfAbsent ( ) . highWaterMark ( value ) ; break ; case ReceiverPos . RECEIVER_POS_TYPE_ID : streamBacklog . createReceiverIfAbsent ( ) . registrationId ( registrationId ) ; streamBacklog . createReceiverIfAbsent ( ) . position ( value ) ; break ; case SubscriberPos . SUBSCRIBER_POSITION_TYPE_ID : streamBacklog . subscriberBacklogs ( ) . put ( registrationId , new Subscriber ( value ) ) ; break ; } } } ) ; return streams ; }


Input: Print a snapshot of the stream backlog with some explanation to a { @link PrintStream } . <p > Each stream will be printed in its own section . [CODESPLIT] public void print ( final PrintStream out ) { final StringBuilder builder = new StringBuilder ( ) ; for ( final Map . Entry < StreamCompositeKey , StreamBacklog > entry : snapshot ( ) . entrySet ( ) ) { builder . setLength ( 0 ) ; final StreamCompositeKey key = entry . getKey ( ) ; builder . append ( "sessionId=" ) . append ( key . sessionId ( ) ) . append ( " streamId=" ) . append ( key . streamId ( ) ) . append ( " channel=" ) . append ( key . channel ( ) ) . append ( " : " ) ; final StreamBacklog streamBacklog = entry . getValue ( ) ; if ( streamBacklog . publisher ( ) != null ) { builder . append ( "\n┌─for publisher ")  . append ( streamBacklog . publisher ( ) . registrationId ( ) ) . append ( " the last sampled position is " ) . append ( streamBacklog . publisher ( ) . position ( ) ) . append ( " (~" ) . append ( streamBacklog . publisher ( ) . remainingWindow ( ) ) . append ( " bytes before back-pressure)" ) ; final Sender sender = streamBacklog . sender ( ) ; if ( sender != null ) { final long senderBacklog = sender . backlog ( streamBacklog . publisher ( ) . position ( ) ) ; builder . append ( "\n└─sender ").ap p e nd(sen d er.reg i strationId());     if ( senderBacklog >= 0 ) { builder . append ( " has to send " ) . append ( senderBacklog ) . append ( " bytes" ) ; } else { builder . append ( " is at position " ) . append ( sender . position ( ) ) ; } builder . append ( " (" ) . append ( sender . window ( ) ) . append ( " bytes remaining in the sender window)" ) ; } else { builder . append ( "\n└─no sender yet...");   } } if ( streamBacklog . receiver ( ) != null ) { builder . append ( "\n┌─receiver ")  . append ( streamBacklog . receiver ( ) . registrationId ( ) ) . append ( " is at position " ) . append ( streamBacklog . receiver ( ) . position ( ) ) ; final Iterator < Map . Entry < Long , Subscriber > > subscriberIterator = streamBacklog . subscriberBacklogs ( ) . entrySet ( ) . iterator ( ) ; while ( subscriberIterator . hasNext ( ) ) { final Map . Entry < Long , Subscriber > subscriber = subscriberIterator . next ( ) ; builder . append ( subscriberIterator . hasNext ( ) ? "\n├" : " n└")  . append ( "─subscriber ")  . append ( subscriber . getKey ( ) ) . append ( " has " ) . append ( subscriber . getValue ( ) . backlog ( streamBacklog . receiver ( ) . highWaterMark ( ) ) ) . append ( " backlog bytes" ) ; } } builder . append ( ' ' ) ; out . println ( builder ) ; } }


Input: Scan for gaps and handle received data . <p > The handler keeps track from scan to scan what is a gap and what must have been repaired . [CODESPLIT] public long scan ( final UnsafeBuffer termBuffer , final long rebuildPosition , final long hwmPosition , final long nowNs , final int termLengthMask , final int positionBitsToShift , final int initialTermId ) { boolean lossFound = false ; int rebuildOffset = ( int ) rebuildPosition & termLengthMask ; if ( rebuildPosition < hwmPosition ) { final int rebuildTermCount = ( int ) ( rebuildPosition >>> positionBitsToShift ) ; final int hwmTermCount = ( int ) ( hwmPosition >>> positionBitsToShift ) ; final int rebuildTermId = initialTermId + rebuildTermCount ; final int hwmTermOffset = ( int ) hwmPosition & termLengthMask ; final int limitOffset = rebuildTermCount == hwmTermCount ? hwmTermOffset : termLengthMask + 1 ; rebuildOffset = scanForGap ( termBuffer , rebuildTermId , rebuildOffset , limitOffset , this ) ; if ( rebuildOffset < limitOffset ) { if ( scannedTermOffset != activeTermOffset || scannedTermId != activeTermId ) { activateGap ( nowNs ) ; lossFound = true ; } checkTimerExpiry ( nowNs ) ; } } return pack ( rebuildOffset , lossFound ) ; }


Input: Non - blocking publish of a partial buffer containing a message . [CODESPLIT] public long offer ( final DirectBuffer buffer , final int offset , final int length , final ReservedValueSupplier reservedValueSupplier ) { long newPosition = CLOSED ; if ( ! isClosed ) { final long limit = positionLimit . getVolatile ( ) ; final int termCount = activeTermCount ( logMetaDataBuffer ) ; final TermAppender termAppender = termAppenders [ indexByTermCount ( termCount ) ] ; final long rawTail = termAppender . rawTailVolatile ( ) ; final long termOffset = rawTail & 0xFFFF_FFFF  L ; final int termId = termId ( rawTail ) ; final long position = computeTermBeginPosition ( termId , positionBitsToShift , initialTermId ) + termOffset ; if ( termCount != ( termId - initialTermId ) ) { return ADMIN_ACTION ; } if ( position < limit ) { final int resultingOffset ; if ( length <= maxPayloadLength ) { checkPositiveLength ( length ) ; resultingOffset = termAppender . appendUnfragmentedMessage ( headerWriter , buffer , offset , length , reservedValueSupplier , termId ) ; } else { checkMaxMessageLength ( length ) ; resultingOffset = termAppender . appendFragmentedMessage ( headerWriter , buffer , offset , length , maxPayloadLength , reservedValueSupplier , termId ) ; } newPosition = newPosition ( termCount , ( int ) termOffset , termId , position , resultingOffset ) ; } else { newPosition = backPressureStatus ( position , length ) ; } } return newPosition ; }


Input: Non - blocking publish of a message composed of two parts e . g . a header and encapsulated payload . [CODESPLIT] public long offer ( final DirectBuffer bufferOne , final int offsetOne , final int lengthOne , final DirectBuffer bufferTwo , final int offsetTwo , final int lengthTwo , final ReservedValueSupplier reservedValueSupplier ) { long newPosition = CLOSED ; if ( ! isClosed ) { final long limit = positionLimit . getVolatile ( ) ; final int termCount = activeTermCount ( logMetaDataBuffer ) ; final TermAppender termAppender = termAppenders [ indexByTermCount ( termCount ) ] ; final long rawTail = termAppender . rawTailVolatile ( ) ; final long termOffset = rawTail & 0xFFFF_FFFF  L ; final int termId = termId ( rawTail ) ; final long position = computeTermBeginPosition ( termId , positionBitsToShift , initialTermId ) + termOffset ; if ( termCount != ( termId - initialTermId ) ) { return ADMIN_ACTION ; } final int length = validateAndComputeLength ( lengthOne , lengthTwo ) ; if ( position < limit ) { final int resultingOffset ; if ( length <= maxPayloadLength ) { resultingOffset = termAppender . appendUnfragmentedMessage ( headerWriter , bufferOne , offsetOne , lengthOne , bufferTwo , offsetTwo , lengthTwo , reservedValueSupplier , termId ) ; } else { checkMaxMessageLength ( length ) ; resultingOffset = termAppender . appendFragmentedMessage ( headerWriter , bufferOne , offsetOne , lengthOne , bufferTwo , offsetTwo , lengthTwo , maxPayloadLength , reservedValueSupplier , termId ) ; } newPosition = newPosition ( termCount , ( int ) termOffset , termId , position , resultingOffset ) ; } else { newPosition = backPressureStatus ( position , length ) ; } } return newPosition ; }


Input: Try to claim a range in the publication log into which a message can be written with zero copy semantics . Once the message has been written then { @link BufferClaim#commit () } should be called thus making it available . <p > <b > Note : < / b > This method can only be used for message lengths less than MTU length minus header . If the claim is held for more than the aeron . publication . unblock . timeout system property then the driver will assume the publication thread is dead and will unblock the claim thus allowing other threads to make progress or to reach end - of - stream ( EOS ) . <pre > { @code final BufferClaim bufferClaim = new BufferClaim () ; // Can be stored and reused to avoid allocation [CODESPLIT] public long tryClaim ( final int length , final BufferClaim bufferClaim ) { checkPayloadLength ( length ) ; long newPosition = CLOSED ; if ( ! isClosed ) { final long limit = positionLimit . getVolatile ( ) ; final int termCount = activeTermCount ( logMetaDataBuffer ) ; final TermAppender termAppender = termAppenders [ indexByTermCount ( termCount ) ] ; final long rawTail = termAppender . rawTailVolatile ( ) ; final long termOffset = rawTail & 0xFFFF_FFFF  L ; final int termId = termId ( rawTail ) ; final long position = computeTermBeginPosition ( termId , positionBitsToShift , initialTermId ) + termOffset ; if ( termCount != ( termId - initialTermId ) ) { return ADMIN_ACTION ; } if ( position < limit ) { final int resultingOffset = termAppender . claim ( headerWriter , length , bufferClaim , termId ) ; newPosition = newPosition ( termCount , ( int ) termOffset , termId , position , resultingOffset ) ; } else { newPosition = backPressureStatus ( position , length ) ; } } return newPosition ; }


Input: Scan a term buffer for a block of message fragments from an offset up to a limitOffset . <p > A scan will terminate if a padding frame is encountered . If first frame in a scan is padding then a block for the padding is notified . If the padding comes after the first frame in a scan then the scan terminates at the offset the padding frame begins . Padding frames are delivered singularly in a block . <p > Padding frames may be for a greater range than the limit offset but only the header needs to be valid so relevant length of the frame is { @link io . aeron . protocol . DataHeaderFlyweight#HEADER_LENGTH } . [CODESPLIT] public static int scan ( final UnsafeBuffer termBuffer , final int termOffset , final int limitOffset ) { int offset = termOffset ; while ( offset < limitOffset ) { final int frameLength = frameLengthVolatile ( termBuffer , offset ) ; if ( frameLength <= 0 ) { break ; } final int alignedFrameLength = align ( frameLength , FRAME_ALIGNMENT ) ; if ( isPaddingFrame ( termBuffer , offset ) ) { if ( termOffset == offset ) { offset += alignedFrameLength ; } break ; } if ( offset + alignedFrameLength > limitOffset ) { break ; } offset += alignedFrameLength ; } return offset ; }


Input: Launch an { @link ConsensusModule } with that communicates with an out of process { @link io . aeron . archive . Archive } and { @link io . aeron . driver . MediaDriver } then awaits shutdown signal . [CODESPLIT] public static void main ( final String [ ] args ) { loadPropertiesFiles ( args ) ; try ( ConsensusModule consensusModule = launch ( ) ) { consensusModule . context ( ) . shutdownSignalBarrier ( ) . await ( ) ; System . out . println ( "Shutdown ConsensusModule..." ) ; } }


Input: Allocate a counter for tracking the last heartbeat of an entity . [CODESPLIT] public static AtomicCounter allocate ( final MutableDirectBuffer tempBuffer , final String name , final int typeId , final CountersManager countersManager , final long registrationId ) { return new AtomicCounter ( countersManager . valuesBuffer ( ) , allocateCounterId ( tempBuffer , name , typeId , countersManager , registrationId ) , countersManager ) ; }


Input: Create an Aeron instance and connect to the media driver . <p > Threads required for interacting with the media driver are created and managed within the Aeron instance . <p > If an exception occurs while trying to establish a connection then the { @link Context#close () } method will be called on the passed context . [CODESPLIT] public static Aeron connect ( final Context ctx ) { try { final Aeron aeron = new Aeron ( ctx ) ; if ( ctx . useConductorAgentInvoker ( ) ) { aeron . conductorInvoker . start ( ) ; } else { AgentRunner . startOnThread ( aeron . conductorRunner , ctx . threadFactory ( ) ) ; } return aeron ; } catch ( final Exception ex ) { ctx . close ( ) ; throw ex ; } }


Input: Print out the values from { @link #countersReader () } which can be useful for debugging . [CODESPLIT] public void printCounters ( final PrintStream out ) { final CountersReader counters = countersReader ( ) ; counters . forEach ( ( value , id , label ) -> out . format ( "%3d: %,20d - %s%n" , id , value , label ) ) ; }


Input: Add a new { @link Subscription } for subscribing to messages from publishers . <p > This method will override the default handlers from the { @link Aeron . Context } i . e . { @link Aeron . Context#availableImageHandler ( AvailableImageHandler ) } and { @link Aeron . Context#unavailableImageHandler ( UnavailableImageHandler ) } . Null values are valid and will result in no action being taken . [CODESPLIT] public Subscription addSubscription ( final String channel , final int streamId , final AvailableImageHandler availableImageHandler , final UnavailableImageHandler unavailableImageHandler ) { return conductor . addSubscription ( channel , streamId , availableImageHandler , unavailableImageHandler ) ; }


Input: Allocate a counter on the media driver and return a { @link Counter } for it . <p > The counter should be freed by calling { @link Counter#close () } . [CODESPLIT] public Counter addCounter ( final int typeId , final DirectBuffer keyBuffer , final int keyOffset , final int keyLength , final DirectBuffer labelBuffer , final int labelOffset , final int labelLength ) { return conductor . addCounter ( typeId , keyBuffer , keyOffset , keyLength , labelBuffer , labelOffset , labelLength ) ; }


Input: This is called automatically by { @link Aeron#connect ( Aeron . Context ) } and its overloads . There is no need to call it from a client application . It is responsible for providing default values for options that are not individually changed through field setters . [CODESPLIT] public Context conclude ( ) { super . conclude ( ) ; if ( null == clientLock ) { clientLock = new ReentrantLock ( ) ; } if ( null == epochClock ) { epochClock = new SystemEpochClock ( ) ; } if ( null == nanoClock ) { nanoClock = new SystemNanoClock ( ) ; } if ( null == idleStrategy ) { idleStrategy = new SleepingMillisIdleStrategy ( Configuration . IDLE_SLEEP_MS ) ; } if ( cncFile ( ) != null ) { connectToDriver ( ) ; } interServiceTimeoutNs = CncFileDescriptor . clientLivenessTimeout ( cncMetaDataBuffer ) ; if ( interServiceTimeoutNs <= keepAliveIntervalNs ) { throw new ConfigurationException ( "interServiceTimeoutNs=" + interServiceTimeoutNs + " <= keepAliveIntervalNs=" + keepAliveIntervalNs ) ; } if ( null == toDriverBuffer ) { toDriverBuffer = new ManyToOneRingBuffer ( CncFileDescriptor . createToDriverBuffer ( cncByteBuffer , cncMetaDataBuffer ) ) ; } if ( null == toClientBuffer ) { toClientBuffer = new CopyBroadcastReceiver ( new BroadcastReceiver ( CncFileDescriptor . createToClientsBuffer ( cncByteBuffer , cncMetaDataBuffer ) ) ) ; } if ( countersMetaDataBuffer ( ) == null ) { countersMetaDataBuffer ( CncFileDescriptor . createCountersMetaDataBuffer ( cncByteBuffer , cncMetaDataBuffer ) ) ; } if ( countersValuesBuffer ( ) == null ) { countersValuesBuffer ( CncFileDescriptor . createCountersValuesBuffer ( cncByteBuffer , cncMetaDataBuffer ) ) ; } if ( null == logBuffersFactory ) { logBuffersFactory = new MappedLogBuffersFactory ( ) ; } if ( null == errorHandler ) { errorHandler = Configuration . DEFAULT_ERROR_HANDLER ; } if ( null == driverProxy ) { clientId = toDriverBuffer . nextCorrelationId ( ) ; driverProxy = new DriverProxy ( toDriverBuffer , clientId ) ; } return this ; }


Input: Clean up all resources that the client uses to communicate with the Media Driver . [CODESPLIT] public void close ( ) { final MappedByteBuffer cncByteBuffer = this . cncByteBuffer ; this . cncByteBuffer = null ; IoUtil . unmap ( cncByteBuffer ) ; super . close ( ) ; }


Input: Dispatch a descriptor message to a consumer by reading the fields in the correct order . [CODESPLIT] public static void dispatchDescriptor ( final RecordingDescriptorDecoder decoder , final RecordingDescriptorConsumer consumer ) { consumer . onRecordingDescriptor ( decoder . controlSessionId ( ) , decoder . correlationId ( ) , decoder . recordingId ( ) , decoder . startTimestamp ( ) , decoder . stopTimestamp ( ) , decoder . startPosition ( ) , decoder . stopPosition ( ) , decoder . initialTermId ( ) , decoder . segmentFileLength ( ) , decoder . termBufferLength ( ) , decoder . mtuLength ( ) , decoder . sessionId ( ) , decoder . streamId ( ) , decoder . strippedChannel ( ) , decoder . originalChannel ( ) , decoder . sourceIdentity ( ) ) ; }


Input: Insert a packet of frames into the log at the appropriate termOffset as indicated by the term termOffset header . <p > If the packet has already been inserted then this is a noop . [CODESPLIT] public static void insert ( final UnsafeBuffer termBuffer , final int termOffset , final UnsafeBuffer packet , final int length ) { if ( 0 == termBuffer . getInt ( termOffset ) ) { termBuffer . putBytes ( termOffset + HEADER_LENGTH , packet , HEADER_LENGTH , length - HEADER_LENGTH ) ; termBuffer . putLong ( termOffset + 24 , packet . getLong ( 24 ) ) ; termBuffer . putLong ( termOffset + 16 , packet . getLong ( 16 ) ) ; termBuffer . putLong ( termOffset + 8 , packet . getLong ( 8 ) ) ; termBuffer . putLongOrdered ( termOffset , packet . getLong ( 0 ) ) ; } }


Input: Construct a CapacityByteArrayOutputStream configured such that its initial slab size is determined by { @link #initialSlabSizeHeuristic } with targetCapacity == maxCapacityHint [CODESPLIT] public static CapacityByteArrayOutputStream withTargetNumSlabs ( int minSlabSize , int maxCapacityHint , int targetNumSlabs , ByteBufferAllocator allocator ) { return new CapacityByteArrayOutputStream ( initialSlabSizeHeuristic ( minSlabSize , maxCapacityHint , targetNumSlabs ) , maxCapacityHint , allocator ) ; }


Input: the new slab is guaranteed to be at least minimumSize [CODESPLIT] private void addSlab ( int minimumSize ) { int nextSlabSize ; if ( bytesUsed == 0 ) { nextSlabSize = initialSlabSize ; } else if ( bytesUsed > maxCapacityHint / 5 ) { // to avoid an overhead of up to twice the needed size, we get linear when approaching target page size nextSlabSize = maxCapacityHint / 5 ; } else { // double the size every time nextSlabSize = bytesUsed ; } if ( nextSlabSize < minimumSize ) { LOG . debug ( "slab size {} too small for value of size {}. Bumping up slab size" , nextSlabSize , minimumSize ) ; nextSlabSize = minimumSize ; } LOG . debug ( "used {} slabs, adding new slab of size {}" , slabs . size ( ) , nextSlabSize ) ; this . currentSlab = allocator . allocate ( nextSlabSize ) ; this . slabs . add ( currentSlab ) ; this . bytesAllocated += nextSlabSize ; this . currentSlabIndex = 0 ; }


Input: Writes the complete contents of this buffer to the specified output stream argument . the output stream s write method <code > out . write ( slab 0 slab . length ) < / code > ) will be called once per slab . [CODESPLIT] public void writeTo ( OutputStream out ) throws IOException { for ( int i = 0 ; i < slabs . size ( ) - 1 ; i ++ ) { writeToOutput ( out , slabs . get ( i ) , slabs . get ( i ) . position ( ) ) ; } writeToOutput ( out , currentSlab , currentSlabIndex ) ; }


Input: When re - using an instance with reset it will adjust slab size based on previous data size . The intent is to reuse the same instance for the same type of data ( for example the same column ) . The assumption is that the size in the buffer will be consistent . [CODESPLIT] public void reset ( ) { // readjust slab size. // 7 = 2^3 - 1 so that doubling the initial size 3 times will get to the same size this . initialSlabSize = max ( bytesUsed / 7 , initialSlabSize ) ; LOG . debug ( "initial slab of size {}" , initialSlabSize ) ; for ( ByteBuffer slab : slabs ) { allocator . release ( slab ) ; } this . slabs . clear ( ) ; this . bytesAllocated = 0 ; this . bytesUsed = 0 ; this . currentSlab = EMPTY_SLAB ; this . currentSlabIndex = 0 ; }


Input: Replace the byte stored at position index in this stream with value [CODESPLIT] public void setByte ( long index , byte value ) { checkArgument ( index < bytesUsed , "Index: " + index + " is >= the current size of: " + bytesUsed ) ; long seen = 0 ; for ( int i = 0 ; i < slabs . size ( ) ; i ++ ) { ByteBuffer slab = slabs . get ( i ) ; if ( index < seen + slab . limit ( ) ) { // ok found index slab . put ( ( int ) ( index - seen ) , value ) ; break ; } seen += slab . limit ( ) ; } }


Input: Adds the data from the specified statistics to this builder [CODESPLIT] public void add ( Statistics < ? > stats ) { if ( stats . hasNonNullValue ( ) ) { nullPages . add ( false ) ; Object min = stats . genericGetMin ( ) ; Object max = stats . genericGetMax ( ) ; addMinMax ( min , max ) ; pageIndexes . add ( nextPageIndex ) ; minMaxSize += sizeOf ( min ) ; minMaxSize += sizeOf ( max ) ; } else { nullPages . add ( true ) ; } nullCounts . add ( stats . getNumNulls ( ) ) ; ++ nextPageIndex ; }


Input: min [ i ] > = min [ i + 1 ] && max [ i ] > = max [ i + 1 ] [CODESPLIT] private boolean isDescending ( PrimitiveComparator < Binary > comparator ) { for ( int i = 1 , n = pageIndexes . size ( ) ; i < n ; ++ i ) { if ( compareMinValues ( comparator , i - 1 , i ) < 0 || compareMaxValues ( comparator , i - 1 , i ) < 0 ) { return false ; } } return true ; }


Input: Called to initialize the column reader from a part of a page . [CODESPLIT] @ Deprecated public void initFromPage ( int valueCount , ByteBuffer page , int offset ) throws IOException { if ( offset < 0 ) { throw new IllegalArgumentException ( "Illegal offset: " + offset ) ; } actualOffset = offset ; ByteBuffer pageWithOffset = page . duplicate ( ) ; pageWithOffset . position ( offset ) ; initFromPage ( valueCount , ByteBufferInputStream . wrap ( pageWithOffset ) ) ; actualOffset = - 1 ; }


Input: Same functionality as method of the same name that takes a ByteBuffer instead of a byte [] . [CODESPLIT] @ Deprecated public void initFromPage ( int valueCount , byte [ ] page , int offset ) throws IOException { this . initFromPage ( valueCount , ByteBuffer . wrap ( page ) , offset ) ; }


Input: Called to initialize the column reader from a part of a page . [CODESPLIT] public void initFromPage ( int valueCount , ByteBufferInputStream in ) throws IOException { if ( actualOffset != - 1 ) { throw new UnsupportedOperationException ( "Either initFromPage(int, ByteBuffer, int) or initFromPage(int, ByteBufferInputStream) must be implemented in " + getClass ( ) . getName ( ) ) ; } initFromPage ( valueCount , in . slice ( valueCount ) , 0 ) ; }


Input: Set the subset of columns to read ( projection pushdown ) . Specified as an Avro schema the requested projection is converted into a Parquet schema for Parquet column projection . <p > This is useful if the full schema is large and you only want to read a few columns since it saves time by not reading unused columns . <p > If a requested projection is set then the Avro schema used for reading must be compatible with the projection . For instance if a column is not included in the projection then it must either not be included or be optional in the read schema . Use { [CODESPLIT] public static void setRequestedProjection ( Job job , Schema requestedProjection ) { AvroReadSupport . setRequestedProjection ( ContextUtil . getConfiguration ( job ) , requestedProjection ) ; }


Input: Override the Avro schema to use for reading . If not set the Avro schema used for writing is used . <p > Differences between the read and write schemas are resolved using <a href = http : // avro . apache . org / docs / current / spec . html#Schema + Resolution > Avro s schema resolution rules< / a > . [CODESPLIT] public static void setAvroReadSchema ( Job job , Schema avroReadSchema ) { AvroReadSupport . setAvroReadSchema ( ContextUtil . getConfiguration ( job ) , avroReadSchema ) ; }