/*
 * Copyright 2014 - 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;

/**
 * Base log buffer implementation containing common functionality for dealing with fragment terms.
 */
public class LogBufferPartition
{
    private final UnsafeBuffer termBuffer;
    private final UnsafeBuffer metaDataBuffer;

    public LogBufferPartition(final UnsafeBuffer termBuffer, final UnsafeBuffer metaDataBuffer)
    {
        LogBufferDescriptor.checkTermBuffer(termBuffer);
        LogBufferDescriptor.checkMetaDataBuffer(metaDataBuffer);
        termBuffer.verifyAlignment();
        metaDataBuffer.verifyAlignment();

        this.termBuffer = termBuffer;
        this.metaDataBuffer = metaDataBuffer;
    }

    /**
     * The log of messages for a term.
     *
     * @return the log of messages for a term.
     */
    public UnsafeBuffer termBuffer()
    {
        return termBuffer;
    }

    /**
     * The meta data describing the term.
     *
     * @return the meta data describing the term.
     */
    public UnsafeBuffer metaDataBuffer()
    {
        return metaDataBuffer;
    }


    /**
     * Clean down the buffers for reuse by zeroing them out.
     */
    public void clean()
    {
        termBuffer.setMemory(0, termBuffer.capacity(), (byte)0);
        metaDataBuffer.setMemory(0, metaDataBuffer.capacity(), (byte)0);
        statusOrdered(LogBufferDescriptor.CLEAN);
    }

    /**
     * What is the current status of the buffer.
     *
     * @return the status of buffer as described in {@link LogBufferDescriptor}
     */
    public int status()
    {
        return metaDataBuffer.getIntVolatile(LogBufferDescriptor.TERM_STATUS_OFFSET);
    }

    /**
     * Set the status of the log buffer with StoreStore memory ordering semantics.
     *
     * @param status to be set for the log buffer.
     */
    public void statusOrdered(final int status)
    {
        metaDataBuffer.putIntOrdered(LogBufferDescriptor.TERM_STATUS_OFFSET, status);
    }

    /**
     * Get the current tail value in a volatile memory ordering fashion. If raw tail is greater than
     * {@link #termBuffer()}.{@link uk.co.real_logic.agrona.DirectBuffer#capacity()} then capacity will be returned.
     *
     * @return the current tail value.
     */
    public int tailVolatile()
    {
        return Math.min(metaDataBuffer.getIntVolatile(LogBufferDescriptor.TERM_TAIL_COUNTER_OFFSET), termBuffer.capacity());
    }

    /**
     * Get the raw value current tail value in a volatile memory ordering fashion.
     *
     * @return the current tail value.
     */
    public int rawTailVolatile()
    {
        return metaDataBuffer.getIntVolatile(LogBufferDescriptor.TERM_TAIL_COUNTER_OFFSET);
    }

    /**
     * Get the current tail value.
     *
     * @return the current tail value.
     */
    public int tail()
    {
        return Math.min(metaDataBuffer.getInt(LogBufferDescriptor.TERM_TAIL_COUNTER_OFFSET), termBuffer.capacity());
    }
}

@@ -695,16 +695,181 @@
 uffer;%0A%0A
+import static uk.co.real_logic.aeron.logbuffer.LogBufferDescriptor.*;%0Aimport static uk.co.real_logic.aeron.logbuffer.LogBufferDescriptor.TERM_TAIL_COUNTER_OFFSET;%0A%0A%0A
 /**%0A * B
@@ -1202,36 +1202,16 @@
         
-LogBufferDescriptor.
 checkTer
@@ -1239,36 +1239,16 @@
         
-LogBufferDescriptor.
 checkMet
@@ -1999,32 +1999,33 @@
 ty(), (byte)0);%0A
+%0A
         metaData
@@ -2035,54 +2035,41 @@
 fer.
-setMemory(0, metaDataBuffer.capacity(), (byte)
+putInt(TERM_TAIL_COUNTER_OFFSET, 
 0);%0A
@@ -2090,36 +2090,16 @@
 Ordered(
-LogBufferDescriptor.
 CLEAN);%0A
@@ -2332,36 +2332,16 @@
 olatile(
-LogBufferDescriptor.
 TERM_STA
@@ -2608,36 +2608,16 @@
 Ordered(
-LogBufferDescriptor.
 TERM_STA
@@ -3014,36 +3014,16 @@
 olatile(
-LogBufferDescriptor.
 TERM_TAI
@@ -3301,36 +3301,16 @@
 olatile(
-LogBufferDescriptor.
 TERM_TAI
@@ -3452,32 +3452,32 @@
 nt tail()%0A    %7B%0A
+
         return M
@@ -3506,36 +3506,16 @@
 .getInt(
-LogBufferDescriptor.
 TERM_TAI

Make the cleaning of the log buffer partition less heavy weight.