Ejemplo n.º 1
0
        /// <summary>
        /// Scan a term buffer for a block of messages from and offset up to a limit.
        /// </summary>
        /// <param name="termBuffer"> to scan for messages. </param>
        /// <param name="offset">     at which the scan should begin. </param>
        /// <param name="limit">      at which the scan should stop. </param>
        /// <returns> the offset at which the scan terminated. </returns>
        public static int Scan(DirectBuffer termBuffer, int offset, int limit)
        {
            do
            {
                int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, offset);
                if (frameLength <= 0)
                {
                    break;
                }

                int alignedFrameLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
                offset += alignedFrameLength;
                if (offset >= limit)
                {
                    if (offset > limit)
                    {
                        offset -= alignedFrameLength;
                    }

                    break;
                }
            }while (true);

            return(offset);
        }
Ejemplo n.º 2
0
        public static long Read(
            DirectBuffer termBuffer,
            int offset,
            OnAppendHandler handler,
            int fragmentsLimit,
            ErrorHandler errorHandler)
        {
            int fragmentsRead = 0;
            int capacity      = (int)termBuffer.Length;

            try {
                do
                {
                    int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, offset);
                    if (frameLength <= 0)
                    {
                        break;
                    }

                    int termOffset = offset;
                    offset += BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
                    // TODO check for padding
                    if (!FrameDescriptor.IsPaddingFrame(termBuffer, termOffset))
                    {
                        var messageBuffer = new DirectBuffer(frameLength, termBuffer.Data + termOffset);
                        handler?.Invoke(messageBuffer);
                        ++fragmentsRead;
                    }
                }while (fragmentsRead < fragmentsLimit && offset < capacity);
            } catch (Exception t) {
                errorHandler?.Invoke(t);
            }

            return(Pack(offset, fragmentsRead));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 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>
        /// </summary>
        /// <param name="logMetaDataBuffer"> containing the default headers </param>
        /// <param name="termBuffer">        to unblock </param>
        /// <param name="blockedOffset">     to unblock at </param>
        /// <param name="tailOffset">        to unblock up to </param>
        /// <param name="termId">            for the current term. </param>
        /// <returns> whether unblocking was done, not done, or applied to end of term </returns>

        public static TermUnblockerStatus Unblock(
            DirectBuffer logMetaDataBuffer,
            DirectBuffer termBuffer,
            int blockedOffset,
            int tailOffset,
            int termId)
        {
            var status      = TermUnblockerStatus.NO_ACTION;
            int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, blockedOffset);

            if (frameLength < 0)
            {
                ResetHeader(logMetaDataBuffer, termBuffer, blockedOffset, termId, -frameLength);
                status = TermUnblockerStatus.UNBLOCKED;
            }
            else if (0 == frameLength)
            {
                int currentOffset = blockedOffset + FrameDescriptor.FRAME_ALIGNMENT;

                while (currentOffset < tailOffset)
                {
                    frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, currentOffset);

                    if (frameLength != 0)
                    {
                        if (ScanBackToConfirmZeroed(termBuffer, currentOffset, blockedOffset))
                        {
                            int length = currentOffset - blockedOffset;
                            ResetHeader(logMetaDataBuffer, termBuffer, blockedOffset, termId, length);
                            status = TermUnblockerStatus.UNBLOCKED;
                        }

                        break;
                    }

                    currentOffset += FrameDescriptor.FRAME_ALIGNMENT;
                }

                if (currentOffset == termBuffer.Length)
                {
                    if (0 == FrameDescriptor.FrameLengthVolatile(termBuffer, blockedOffset))
                    {
                        int length = currentOffset - blockedOffset;
                        ResetHeader(logMetaDataBuffer, termBuffer, blockedOffset, termId, length);
                        status = TermUnblockerStatus.UNBLOCKED_TO_END;
                    }
                }
            }

            return(status);
        }
Ejemplo n.º 4
0
        private static bool ScanBackToConfirmZeroed(DirectBuffer buffer, int from, int limit)
        {
            int  i        = from - FrameDescriptor.FRAME_ALIGNMENT;
            bool allZeros = true;

            while (i >= limit)
            {
                if (0 != FrameDescriptor.FrameLengthVolatile(buffer, i))
                {
                    allZeros = false;
                    break;
                }

                i -= FrameDescriptor.FRAME_ALIGNMENT;
            }

            return(allZeros);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Reads data from a term in a log buffer.
        ///
        /// If a fragmentsLimit of 0 or less is passed then at least one read will be attempted.
        /// </summary>
        /// <param name="termBuffer">     to be read for fragments. </param>
        /// <param name="offset">         offset within the buffer that the read should begin. </param>
        /// <param name="handler">        the handler for data that has been read </param>
        /// <param name="fragmentsLimit"> limit the number of fragments read. </param>
        /// <param name="header">         to be used for mapping over the header for a given fragment. </param>
        /// <param name="errorHandler">   to be notified if an error occurs during the callback. </param>
        /// <returns> the number of fragments read </returns>
        public static long Read(
            DirectBuffer termBuffer,
            int offset,
            FragmentHandler handler,
            int fragmentsLimit,
            Header header,
            ErrorHandler errorHandler)
        {
            int fragmentsRead = 0;
            int capacity      = (int)termBuffer.Length;

            try {
                do
                {
                    int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, offset);
                    if (frameLength <= 0)
                    {
                        break;
                    }

                    int termOffset = offset;
                    offset += BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);

                    if (!FrameDescriptor.IsPaddingFrame(termBuffer, termOffset))
                    {
                        header.Buffer = termBuffer;
                        header.Offset = termOffset;

                        handler?.Invoke(termBuffer, termOffset + DataHeaderFlyweight.HEADER_LENGTH, frameLength - DataHeaderFlyweight.HEADER_LENGTH, header);

                        ++fragmentsRead;
                    }
                }while (fragmentsRead < fragmentsLimit && offset < capacity);
            } catch (Exception t) {
                errorHandler?.Invoke(t);
            }

            return(Pack(offset, fragmentsRead));
        }
Ejemplo n.º 6
0
        /**
         * Scan the term buffer for availability of new messages from a given offset up to a maxLength of bytes.
         *
         * @param termBuffer to be scanned for new messages
         * @param offset     at which the scan should begin.
         * @param maxLength  in bytes of how much should be scanned.
         * @return resulting status of the scan which packs the available bytes and padding into a long.
         */
        public static long ScanForAvailability(DirectBuffer termBuffer, int offset, int maxLength)
        {
            checked
            {
                maxLength = Math.Min(maxLength, (int)termBuffer.Length - offset);
                int available = 0;
                int padding   = 0;

                do
                {
                    int termOffset  = offset + available;
                    int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, termOffset);
                    if (frameLength <= 0)
                    {
                        break;
                    }

                    int alignedFrameLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
                    if (FrameDescriptor.IsPaddingFrame(termBuffer, termOffset))
                    {
                        padding            = alignedFrameLength - DataHeaderFlyweight.HEADER_LENGTH;
                        alignedFrameLength = DataHeaderFlyweight.HEADER_LENGTH;
                    }

                    available += alignedFrameLength;

                    if (available > maxLength)
                    {
                        available -= alignedFrameLength;
                        padding    = 0;
                        break;
                    }
                } while (0 == padding && available < maxLength);

                return(Pack(padding, available));
            }
        }
Ejemplo n.º 7
0
        /**
         * Scan for gaps from the rebuildOffset up to the high-water-mark. Each gap will be reported to the {@link GapHandler}.
         *
         * @param termBuffer    to be scanned for a gap.
         * @param termId        of the current term buffer.
         * @param rebuildOffset at which to start scanning.
         * @param hwmOffset     at which to stop scanning.
         * @param handler       to call if a gap is found.
         * @return offset of last contiguous frame
         */
        public static int ScanForGap(
            DirectBuffer termBuffer, int termId, int rebuildOffset, int hwmOffset, GapHandler handler)
        {
            do
            {
                int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, rebuildOffset);
                if (frameLength <= 0)
                {
                    break;
                }

                rebuildOffset += BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            }while (rebuildOffset < hwmOffset);

            int gapBeginOffset = rebuildOffset;

            if (rebuildOffset < hwmOffset)
            {
                int limit = hwmOffset - ALIGNED_HEADER_LENGTH;
                while (rebuildOffset < limit)
                {
                    rebuildOffset += FrameDescriptor.FRAME_ALIGNMENT;

                    if (0 != termBuffer.VolatileReadInt32(rebuildOffset))
                    {
                        rebuildOffset -= ALIGNED_HEADER_LENGTH;
                        break;
                    }
                }

                int gapLength = (rebuildOffset - gapBeginOffset) + ALIGNED_HEADER_LENGTH;
                handler?.Invoke(termId, termBuffer, gapBeginOffset, gapLength);
            }

            return(gapBeginOffset);
        }