/*
 * Copyright 2015 Real Logic Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package uk.co.real_logic.aeron.logbuffer;

import uk.co.real_logic.agrona.concurrent.UnsafeBuffer;

import static uk.co.real_logic.aeron.logbuffer.LogBufferDescriptor.*;
import static uk.co.real_logic.aeron.logbuffer.LogBufferDescriptor.indexByTerm;

/**
 * Provides the functionality to unblock a log at a given position.
 */
public class LogBufferUnblocker
{
    /**
     * Attempt to unblock a log buffer at given position
     *
     * @param logPartitions     for current blockedOffset
     * @param logMetaDataBuffer for log buffer
     * @param blockedPosition   to attempt to unblock
     * @return whether unblocked or not
     */
    public static boolean unblock(
        final LogBufferPartition[] logPartitions,
        final UnsafeBuffer logMetaDataBuffer,
        final long blockedPosition)
    {
        final int initialTermId = initialTermId(logMetaDataBuffer);
        final int activeTermId = activeTermId(logMetaDataBuffer);
        final int activeIndex = indexByTerm(initialTermId, activeTermId);
        final int currentTail = logPartitions[activeIndex].tailVolatile();
        final UnsafeBuffer termBuffer = logPartitions[activeIndex].termBuffer();
        final int positionBitsToShift = Integer.numberOfTrailingZeros(termBuffer.capacity());
        final int blockedOffset = computeTermOffsetFromPosition(blockedPosition, positionBitsToShift);

        boolean result = false;

        switch (TermPatcher.patch(termBuffer, blockedOffset, currentTail))
        {
            case PATCHED_TO_END:
                final int newTermId = activeTermId + 1;
                rotateLog(logPartitions, logMetaDataBuffer, activeIndex, newTermId);
                // fall through
            case PATCHED:
                result = true;
        }

        return result;
    }
}

@@ -761,88 +761,8 @@
 r.*;
-%0Aimport static uk.co.real_logic.aeron.logbuffer.LogBufferDescriptor.indexByTerm;
 %0A%0A/*

Simplify imports.